@blade-hq/agent-react 2610.0.0-beta.26 → 2610.0.0-beta.27
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/README.md +25 -2
- package/dist/components/AskUserQuestionBlock.d.ts +9 -0
- package/dist/components/ToolCallBlock.d.ts +4 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +470 -475
- package/dist/index.js.map +1 -1
- package/dist/lib/agent-computer-command.d.ts +34 -0
- package/dist/style.full.css +1 -1
- package/package.json +2 -2
- package/public-api.md +26 -3
package/dist/index.js
CHANGED
|
@@ -1831,7 +1831,6 @@ var TOOL_NAME_ALIASES = {
|
|
|
1831
1831
|
finish_task: "FinishTask",
|
|
1832
1832
|
glob: "Glob",
|
|
1833
1833
|
grep: "Grep",
|
|
1834
|
-
kb_search: "KbSearch",
|
|
1835
1834
|
ls: "Ls",
|
|
1836
1835
|
multi_edit: "MultiEdit",
|
|
1837
1836
|
read: "Read",
|
|
@@ -1850,7 +1849,6 @@ var TOOL_DISPLAY_LABELS = {
|
|
|
1850
1849
|
Ls: "\u5217\u51FA\u76EE\u5F55",
|
|
1851
1850
|
Glob: "\u5339\u914D\u6587\u4EF6",
|
|
1852
1851
|
Grep: "\u641C\u7D22\u6587\u672C",
|
|
1853
|
-
KbSearch: "\u68C0\u7D22\u77E5\u8BC6\u5E93",
|
|
1854
1852
|
WebSearch: "\u641C\u7D22\u7F51\u9875",
|
|
1855
1853
|
WebFetch: "\u6574\u7406\u7F51\u9875\u5185\u5BB9",
|
|
1856
1854
|
Agent: "\u6D3E\u751F\u5B50\u667A\u80FD\u4F53",
|
|
@@ -1861,16 +1859,6 @@ var TOOL_DISPLAY_LABELS = {
|
|
|
1861
1859
|
ListSessions: "\u5217\u51FA\u5386\u53F2\u4F1A\u8BDD",
|
|
1862
1860
|
GetSessionHistory: "\u8BFB\u53D6\u4F1A\u8BDD\u5386\u53F2"
|
|
1863
1861
|
};
|
|
1864
|
-
var PRIORITY_FILE_KEYS = [
|
|
1865
|
-
"file_path",
|
|
1866
|
-
"output_file",
|
|
1867
|
-
"output_path",
|
|
1868
|
-
"path",
|
|
1869
|
-
"filepath",
|
|
1870
|
-
"target_file",
|
|
1871
|
-
"destination",
|
|
1872
|
-
"filename"
|
|
1873
|
-
];
|
|
1874
1862
|
function safeParseJson(value) {
|
|
1875
1863
|
if (!value) return null;
|
|
1876
1864
|
try {
|
|
@@ -1879,38 +1867,6 @@ function safeParseJson(value) {
|
|
|
1879
1867
|
return null;
|
|
1880
1868
|
}
|
|
1881
1869
|
}
|
|
1882
|
-
function isPlainObject(value) {
|
|
1883
|
-
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
1884
|
-
}
|
|
1885
|
-
function findFileLikeValue(value, depth = 0, allowPlainString = false) {
|
|
1886
|
-
if (depth > 3) return null;
|
|
1887
|
-
if (typeof value === "string") {
|
|
1888
|
-
const trimmed = value.trim();
|
|
1889
|
-
if (!trimmed) return null;
|
|
1890
|
-
if (allowPlainString || trimmed.includes("/") || /\.[a-z0-9]{1,8}$/i.test(trimmed)) {
|
|
1891
|
-
return trimmed;
|
|
1892
|
-
}
|
|
1893
|
-
return null;
|
|
1894
|
-
}
|
|
1895
|
-
if (Array.isArray(value)) {
|
|
1896
|
-
for (const item of value) {
|
|
1897
|
-
const found = findFileLikeValue(item, depth + 1, allowPlainString);
|
|
1898
|
-
if (found) return found;
|
|
1899
|
-
}
|
|
1900
|
-
return null;
|
|
1901
|
-
}
|
|
1902
|
-
if (isPlainObject(value)) {
|
|
1903
|
-
for (const key of PRIORITY_FILE_KEYS) {
|
|
1904
|
-
const direct = findFileLikeValue(value[key], depth + 1, true);
|
|
1905
|
-
if (direct) return direct;
|
|
1906
|
-
}
|
|
1907
|
-
for (const nested of Object.values(value)) {
|
|
1908
|
-
const found = findFileLikeValue(nested, depth + 1, allowPlainString);
|
|
1909
|
-
if (found) return found;
|
|
1910
|
-
}
|
|
1911
|
-
}
|
|
1912
|
-
return null;
|
|
1913
|
-
}
|
|
1914
1870
|
function getStringArgValue(args, key) {
|
|
1915
1871
|
const value = args?.[key];
|
|
1916
1872
|
return typeof value === "string" ? value.trim() : "";
|
|
@@ -1933,15 +1889,6 @@ function formatToolName(name) {
|
|
|
1933
1889
|
const normalized = stripped.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[^a-zA-Z0-9]+/g, "_").replace(/^_+|_+$/g, "").toLowerCase();
|
|
1934
1890
|
return TOOL_NAME_ALIASES[normalized] ?? stripped;
|
|
1935
1891
|
}
|
|
1936
|
-
function extractToolFilePath(toolCall) {
|
|
1937
|
-
const formattedName = formatToolName(toolCall.name);
|
|
1938
|
-
if (formattedName !== "Read" && formattedName !== "Write" && formattedName !== "Edit" && formattedName !== "MultiEdit") {
|
|
1939
|
-
return null;
|
|
1940
|
-
}
|
|
1941
|
-
const filePath = findFileLikeValue(safeParseJson(toolCall.arguments));
|
|
1942
|
-
if (!filePath || filePath.split("/").pop()?.toLowerCase() === "phase.json") return null;
|
|
1943
|
-
return filePath;
|
|
1944
|
-
}
|
|
1945
1892
|
function getToolDisplayLabel(toolCall) {
|
|
1946
1893
|
const normalized = formatToolName(toolCall.name);
|
|
1947
1894
|
const args = safeParseJson(toolCall.arguments);
|
|
@@ -2543,6 +2490,26 @@ function parseAskUserQuestion(toolResult) {
|
|
|
2543
2490
|
}
|
|
2544
2491
|
return null;
|
|
2545
2492
|
}
|
|
2493
|
+
function parseAskUserQuestionError(toolResult) {
|
|
2494
|
+
if (!toolResult) return null;
|
|
2495
|
+
try {
|
|
2496
|
+
const parsed = JSON.parse(toolResult);
|
|
2497
|
+
let detail = null;
|
|
2498
|
+
if (typeof parsed.error === "string") detail = parsed.error;
|
|
2499
|
+
if (parsed.error && typeof parsed.error === "object") {
|
|
2500
|
+
const message = parsed.error.message;
|
|
2501
|
+
if (typeof message === "string") detail = message;
|
|
2502
|
+
}
|
|
2503
|
+
if (!detail && typeof parsed.message === "string") detail = parsed.message;
|
|
2504
|
+
if (!detail) return null;
|
|
2505
|
+
return {
|
|
2506
|
+
message: parsed.error_code === "invalid_questions" ? "\u63D0\u95EE\u5185\u5BB9\u4E0D\u5B8C\u6574\uFF0C\u5F53\u524D\u6CA1\u6709\u7B49\u5F85\u4F60\u56DE\u7B54\u3002\u8BF7\u8BA9\u667A\u80FD\u4F53\u91CD\u65B0\u63D0\u95EE\u3002" : "\u8FD9\u6B21\u63D0\u95EE\u6CA1\u6709\u6210\u529F\uFF0C\u5F53\u524D\u6CA1\u6709\u7B49\u5F85\u4F60\u56DE\u7B54\u3002\u8BF7\u8BA9\u667A\u80FD\u4F53\u91CD\u65B0\u63D0\u95EE\u3002",
|
|
2507
|
+
detail
|
|
2508
|
+
};
|
|
2509
|
+
} catch {
|
|
2510
|
+
return null;
|
|
2511
|
+
}
|
|
2512
|
+
}
|
|
2546
2513
|
function normalizeQuestionItem(value) {
|
|
2547
2514
|
if (!value || typeof value !== "object") return null;
|
|
2548
2515
|
const item = value;
|
|
@@ -2571,9 +2538,10 @@ import { Fragment, jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
|
2571
2538
|
function resolveAskQuestionState({
|
|
2572
2539
|
toolStatus,
|
|
2573
2540
|
hasAnswerData,
|
|
2574
|
-
fallbackAnswered
|
|
2541
|
+
fallbackAnswered,
|
|
2542
|
+
fallbackAwaiting
|
|
2575
2543
|
}) {
|
|
2576
|
-
const awaitingAnswer = !hasAnswerData && toolStatus === "awaiting_answer";
|
|
2544
|
+
const awaitingAnswer = !hasAnswerData && (toolStatus === "awaiting_answer" || toolStatus === "pending" && fallbackAwaiting === true);
|
|
2577
2545
|
return {
|
|
2578
2546
|
awaitingAnswer,
|
|
2579
2547
|
answered: hasAnswerData || !awaitingAnswer && (Boolean(fallbackAnswered) || toolStatus === "done" || toolStatus === "cancelled" || toolStatus === "error")
|
|
@@ -2585,6 +2553,7 @@ function ToolCallBlock({
|
|
|
2585
2553
|
answered,
|
|
2586
2554
|
answerData,
|
|
2587
2555
|
sessionStatus,
|
|
2556
|
+
isActiveQuestion,
|
|
2588
2557
|
renderer
|
|
2589
2558
|
}) {
|
|
2590
2559
|
const [expanded, setExpanded] = useState9(false);
|
|
@@ -2600,7 +2569,8 @@ function ToolCallBlock({
|
|
|
2600
2569
|
const questionState = resolveAskQuestionState({
|
|
2601
2570
|
toolStatus: toolCall.status,
|
|
2602
2571
|
hasAnswerData: Boolean(answerData),
|
|
2603
|
-
fallbackAnswered: answered
|
|
2572
|
+
fallbackAnswered: answered,
|
|
2573
|
+
fallbackAwaiting: isActiveQuestion === true && (sessionStatus === "paused" || sessionStatus === "waiting_for_input")
|
|
2604
2574
|
});
|
|
2605
2575
|
const canAnswer = questionState.awaitingAnswer && Boolean(onAnswer);
|
|
2606
2576
|
if (askData) {
|
|
@@ -2622,9 +2592,16 @@ function ToolCallBlock({
|
|
|
2622
2592
|
/* @__PURE__ */ jsx10("span", { children: "\u6B63\u5728\u51C6\u5907\u95EE\u9898\u2026" })
|
|
2623
2593
|
] });
|
|
2624
2594
|
}
|
|
2595
|
+
const errorDetail = parseAskUserQuestionError(
|
|
2596
|
+
typeof toolCall.result === "string" ? toolCall.result : null
|
|
2597
|
+
);
|
|
2625
2598
|
return /* @__PURE__ */ jsxs8("div", { className: "ml-4 max-w-lg rounded-xl border border-amber-500/35 bg-amber-500/10 p-4 text-sm text-[hsl(var(--foreground))]", children: [
|
|
2626
2599
|
/* @__PURE__ */ jsx10("div", { className: "font-semibold", children: "\u9009\u62E9\u9898\u5185\u5BB9\u6682\u65F6\u65E0\u6CD5\u663E\u793A" }),
|
|
2627
|
-
/* @__PURE__ */ jsx10("div", { className: "mt-1 text-xs leading-5 text-[hsl(var(--muted-foreground))]", children: "\u6536\u5230\u7684\u4EA4\u4E92\u6570\u636E\u4E0D\u5B8C\u6574\u3002\u8BF7\u8BA9\u667A\u80FD\u4F53\u91CD\u65B0\u63D0\u95EE\u3002" })
|
|
2600
|
+
/* @__PURE__ */ jsx10("div", { className: "mt-1 text-xs leading-5 text-[hsl(var(--muted-foreground))]", children: errorDetail?.message ?? "\u6536\u5230\u7684\u4EA4\u4E92\u6570\u636E\u4E0D\u5B8C\u6574\u3002\u8BF7\u8BA9\u667A\u80FD\u4F53\u91CD\u65B0\u63D0\u95EE\u3002" }),
|
|
2601
|
+
errorDetail?.detail ? /* @__PURE__ */ jsxs8("details", { className: "mt-2 text-xs text-[hsl(var(--muted-foreground))]", children: [
|
|
2602
|
+
/* @__PURE__ */ jsx10("summary", { className: "cursor-pointer", children: "\u67E5\u770B\u5177\u4F53\u539F\u56E0" }),
|
|
2603
|
+
/* @__PURE__ */ jsx10("div", { className: "mt-1 break-words font-mono", children: errorDetail.detail })
|
|
2604
|
+
] }) : null
|
|
2628
2605
|
] });
|
|
2629
2606
|
}
|
|
2630
2607
|
const tone = getToolTone(toolCall.status);
|
|
@@ -2690,6 +2667,7 @@ function buildAskUserPayload(argumentsJson) {
|
|
|
2690
2667
|
import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2691
2668
|
function ThinkingBlock({ reasoning, isStreaming }) {
|
|
2692
2669
|
const [open, setOpen] = useState10(false);
|
|
2670
|
+
if (!isStreaming) return null;
|
|
2693
2671
|
return /* @__PURE__ */ jsxs9("div", { className: "blade-chat-thinking text-xs", children: [
|
|
2694
2672
|
/* @__PURE__ */ jsxs9(
|
|
2695
2673
|
"button",
|
|
@@ -2699,7 +2677,7 @@ function ThinkingBlock({ reasoning, isStreaming }) {
|
|
|
2699
2677
|
"aria-expanded": open,
|
|
2700
2678
|
className: "group/thinking inline-flex items-center gap-1 text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))]",
|
|
2701
2679
|
children: [
|
|
2702
|
-
|
|
2680
|
+
/* @__PURE__ */ jsx11(Shimmer, { className: "text-xs", children: "\u6B63\u5728\u601D\u8003" }),
|
|
2703
2681
|
/* @__PURE__ */ jsx11(
|
|
2704
2682
|
ChevronRight,
|
|
2705
2683
|
{
|
|
@@ -2713,7 +2691,7 @@ function ThinkingBlock({ reasoning, isStreaming }) {
|
|
|
2713
2691
|
]
|
|
2714
2692
|
}
|
|
2715
2693
|
),
|
|
2716
|
-
open
|
|
2694
|
+
open ? /* @__PURE__ */ jsx11("div", { className: "mt-1.5 whitespace-pre-wrap text-xs leading-[22px] text-[hsl(var(--muted-foreground))]", children: reasoning }) : null
|
|
2717
2695
|
] });
|
|
2718
2696
|
}
|
|
2719
2697
|
function getMessageText(message) {
|
|
@@ -2811,6 +2789,12 @@ function executionSummaryLabel({
|
|
|
2811
2789
|
}
|
|
2812
2790
|
return completedLabel;
|
|
2813
2791
|
}
|
|
2792
|
+
function businessToolDisplayName(toolCall) {
|
|
2793
|
+
const displayName = toolCall.display_name?.trim() ?? "";
|
|
2794
|
+
if (!displayName) return "";
|
|
2795
|
+
const rawName = toolCall.name.trim();
|
|
2796
|
+
return displayName !== rawName && formatToolName(displayName) !== formatToolName(rawName) ? displayName : "";
|
|
2797
|
+
}
|
|
2814
2798
|
function executionToolTypeLabel(toolCall) {
|
|
2815
2799
|
switch (formatToolName(toolCall.name)) {
|
|
2816
2800
|
case "WebSearch":
|
|
@@ -2838,7 +2822,7 @@ function executionToolTypeLabel(toolCall) {
|
|
|
2838
2822
|
case "run_skill_tool":
|
|
2839
2823
|
return "\u6267\u884C\u6280\u80FD";
|
|
2840
2824
|
default:
|
|
2841
|
-
return toolCall
|
|
2825
|
+
return businessToolDisplayName(toolCall) || "\u6267\u884C\u6B65\u9AA4";
|
|
2842
2826
|
}
|
|
2843
2827
|
}
|
|
2844
2828
|
function executionToolIntent(toolCall) {
|
|
@@ -2854,7 +2838,7 @@ function executionToolIntent(toolCall) {
|
|
|
2854
2838
|
const value = args?.[key];
|
|
2855
2839
|
return typeof value === "string" ? value.trim() : "";
|
|
2856
2840
|
};
|
|
2857
|
-
const explicitIntent = getString("description") || getString("_meta_display_name") || getString("display_name") ||
|
|
2841
|
+
const explicitIntent = getString("description") || getString("_meta_display_name") || getString("display_name") || "";
|
|
2858
2842
|
if (explicitIntent) return explicitIntent;
|
|
2859
2843
|
if (normalizedName === "search_skills") return getString("query");
|
|
2860
2844
|
if (normalizedName === "get_skill_content" || normalizedName === "ReadSkill") {
|
|
@@ -2869,58 +2853,18 @@ function ExecutionToolRow({ toolCall }) {
|
|
|
2869
2853
|
const intent = executionToolIntent(toolCall);
|
|
2870
2854
|
const label = intent ? `${typeLabel}\uFF1A${intent}` : typeLabel;
|
|
2871
2855
|
const failed = toolCall.status === "error" || toolCall.status === "cancelled";
|
|
2872
|
-
const filePath = toolCall.status === "done" && (normalizedName === "Write" || normalizedName === "Edit" || normalizedName === "MultiEdit") ? extractToolFilePath(toolCall) : null;
|
|
2873
|
-
const [fileOpen, setFileOpen] = useState10(false);
|
|
2874
2856
|
const iconClass = cn(
|
|
2875
2857
|
"size-3.5 shrink-0",
|
|
2876
2858
|
failed ? "text-red-500" : "text-[hsl(var(--muted-foreground))]"
|
|
2877
2859
|
);
|
|
2878
|
-
const icon = toolCall.status === "pending" ? /* @__PURE__ */ jsx11(LoaderCircle, { className: cn(iconClass, "animate-spin"), "aria-hidden": "true" }) : toolCall.status === "error" ? /* @__PURE__ */ jsx11(CircleAlert, { className: iconClass, "aria-hidden": "true" }) : toolCall.status === "cancelled" ? /* @__PURE__ */ jsx11(X, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "WebSearch" || normalizedName === "WebFetch" ? /* @__PURE__ */ jsx11(Earth, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Bash" || normalizedName === "BgBash" ? /* @__PURE__ */ jsx11(Terminal, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Write" || normalizedName === "Edit" || normalizedName === "MultiEdit" ? /* @__PURE__ */ jsx11(FilePenLine, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Read" || normalizedName === "ReadSkill" ? /* @__PURE__ */ jsx11(BookOpen, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Grep" || normalizedName === "Glob" || normalizedName === "search_skills" ? /* @__PURE__ */ jsx11(Search, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "
|
|
2860
|
+
const icon = toolCall.status === "pending" ? /* @__PURE__ */ jsx11(LoaderCircle, { className: cn(iconClass, "animate-spin"), "aria-hidden": "true" }) : toolCall.status === "error" ? /* @__PURE__ */ jsx11(CircleAlert, { className: iconClass, "aria-hidden": "true" }) : toolCall.status === "cancelled" ? /* @__PURE__ */ jsx11(X, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "WebSearch" || normalizedName === "WebFetch" ? /* @__PURE__ */ jsx11(Earth, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Bash" || normalizedName === "BgBash" ? /* @__PURE__ */ jsx11(Terminal, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Write" || normalizedName === "Edit" || normalizedName === "MultiEdit" ? /* @__PURE__ */ jsx11(FilePenLine, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Read" || normalizedName === "ReadSkill" || normalizedName === "get_skill_content" ? /* @__PURE__ */ jsx11(BookOpen, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Grep" || normalizedName === "Glob" || normalizedName === "search_skills" ? /* @__PURE__ */ jsx11(Search, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Agent" ? /* @__PURE__ */ jsx11(Bot, { className: iconClass, "aria-hidden": "true" }) : /* @__PURE__ */ jsx11(Wrench, { className: iconClass, "aria-hidden": "true" });
|
|
2879
2861
|
const rowClassName = cn(
|
|
2880
2862
|
"flex min-w-0 items-center gap-1 py-1.5 text-xs leading-[22px]",
|
|
2881
2863
|
failed ? "text-red-500" : "text-[hsl(var(--muted-foreground))]"
|
|
2882
2864
|
);
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
/* @__PURE__ */ jsx11("span", { className: "min-w-0 truncate", children: label })
|
|
2887
|
-
] });
|
|
2888
|
-
}
|
|
2889
|
-
return /* @__PURE__ */ jsxs9("div", { className: "min-w-0", children: [
|
|
2890
|
-
/* @__PURE__ */ jsxs9(
|
|
2891
|
-
"button",
|
|
2892
|
-
{
|
|
2893
|
-
type: "button",
|
|
2894
|
-
"data-testid": "execution-tool-intent",
|
|
2895
|
-
className: cn(rowClassName, "w-full text-left"),
|
|
2896
|
-
title: label,
|
|
2897
|
-
"aria-expanded": fileOpen,
|
|
2898
|
-
onClick: () => setFileOpen((open) => !open),
|
|
2899
|
-
children: [
|
|
2900
|
-
icon,
|
|
2901
|
-
/* @__PURE__ */ jsx11("span", { className: "min-w-0 truncate", children: label }),
|
|
2902
|
-
/* @__PURE__ */ jsx11(
|
|
2903
|
-
ChevronRight,
|
|
2904
|
-
{
|
|
2905
|
-
size: 14,
|
|
2906
|
-
className: cn("shrink-0 transition-transform", fileOpen && "rotate-90"),
|
|
2907
|
-
"aria-hidden": "true"
|
|
2908
|
-
}
|
|
2909
|
-
)
|
|
2910
|
-
]
|
|
2911
|
-
}
|
|
2912
|
-
),
|
|
2913
|
-
fileOpen ? /* @__PURE__ */ jsxs9(
|
|
2914
|
-
"div",
|
|
2915
|
-
{
|
|
2916
|
-
className: "ml-[18px] truncate text-xs leading-[22px] text-[hsl(var(--muted-foreground))]",
|
|
2917
|
-
title: filePath,
|
|
2918
|
-
children: [
|
|
2919
|
-
"\u6587\u4EF6\uFF1A",
|
|
2920
|
-
filePath
|
|
2921
|
-
]
|
|
2922
|
-
}
|
|
2923
|
-
) : null
|
|
2865
|
+
return /* @__PURE__ */ jsxs9("div", { "data-testid": "execution-tool-intent", className: rowClassName, title: label, children: [
|
|
2866
|
+
icon,
|
|
2867
|
+
/* @__PURE__ */ jsx11("span", { className: "min-w-0 truncate", children: label })
|
|
2924
2868
|
] });
|
|
2925
2869
|
}
|
|
2926
2870
|
function AssistantTurnBlock({
|
|
@@ -2951,6 +2895,7 @@ function AssistantTurnBlock({
|
|
|
2951
2895
|
(toolCall) => formatToolName(toolCall.name) === "AskUserQuestion"
|
|
2952
2896
|
)
|
|
2953
2897
|
);
|
|
2898
|
+
const activeQuestionId = questionToolCalls.filter((toolCall) => toolCall.status === "pending").at(-1)?.id;
|
|
2954
2899
|
const [displayMode, setDisplayMode] = useState10(
|
|
2955
2900
|
() => isStreaming || hasActionableToolCall ? "detail" : "compact"
|
|
2956
2901
|
);
|
|
@@ -2975,132 +2920,146 @@ function AssistantTurnBlock({
|
|
|
2975
2920
|
}, [hasLiveStartTime, isStreaming]);
|
|
2976
2921
|
const liveExecutionDurationMs = isStreaming ? getExecutionDurationMs({ messages, isStreaming, now: clock }) : executionDurationMs;
|
|
2977
2922
|
if (!hasExecutionProcess) {
|
|
2978
|
-
return /* @__PURE__ */ jsxs9(
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
{
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2923
|
+
return /* @__PURE__ */ jsxs9(
|
|
2924
|
+
"div",
|
|
2925
|
+
{
|
|
2926
|
+
"aria-busy": isStreaming || void 0,
|
|
2927
|
+
className: "blade-chat-assistant-turn flex flex-col gap-3",
|
|
2928
|
+
children: [
|
|
2929
|
+
hasInterrupted && /* @__PURE__ */ jsx11("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" }),
|
|
2930
|
+
hasFailedWithoutContent && /* @__PURE__ */ jsx11("div", { className: "ml-4 w-fit rounded-full border border-red-500/30 bg-red-500/10 px-2.5 py-1 text-[10px] font-medium text-red-400", children: "\u751F\u6210\u5931\u8D25" }),
|
|
2931
|
+
messages.map((message, index) => {
|
|
2932
|
+
return hasRenderableMessageContent(message) ? /* @__PURE__ */ jsx11(
|
|
2933
|
+
"div",
|
|
2988
2934
|
{
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
2935
|
+
className: "flex flex-col gap-3",
|
|
2936
|
+
children: /* @__PURE__ */ jsx11(
|
|
2937
|
+
AssistantMessageContent,
|
|
2938
|
+
{
|
|
2939
|
+
message,
|
|
2940
|
+
sessionId,
|
|
2941
|
+
streaming: isStreaming && index === messages.length - 1
|
|
2942
|
+
}
|
|
2943
|
+
)
|
|
2944
|
+
},
|
|
2945
|
+
message.entry_id ?? `${message.timestamp ?? "assistant"}-${index}`
|
|
2946
|
+
) : null;
|
|
2947
|
+
})
|
|
2948
|
+
]
|
|
2949
|
+
}
|
|
2950
|
+
);
|
|
3000
2951
|
}
|
|
3001
|
-
return /* @__PURE__ */ jsxs9(
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
{
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
},
|
|
3022
|
-
"aria-expanded": effectiveMode === "detail",
|
|
3023
|
-
"aria-label": effectiveMode === "detail" ? "\u6536\u8D77\u6267\u884C\u8FC7\u7A0B" : "\u5C55\u5F00\u6267\u884C\u8FC7\u7A0B",
|
|
3024
|
-
"data-testid": "assistant-execution-summary",
|
|
3025
|
-
className: "inline-flex min-w-0 max-w-full select-none items-center gap-1 bg-transparent p-0 text-left text-xs leading-[22px] text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))] focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none",
|
|
3026
|
-
children: [
|
|
3027
|
-
/* @__PURE__ */ jsx11("span", { className: "min-w-0 truncate", children: executionSummaryLabel({
|
|
3028
|
-
messages,
|
|
3029
|
-
isStreaming,
|
|
3030
|
-
durationMs: liveExecutionDurationMs,
|
|
3031
|
-
sessionStatus,
|
|
3032
|
-
askAnswers
|
|
3033
|
-
}) }),
|
|
3034
|
-
/* @__PURE__ */ jsx11(
|
|
3035
|
-
ChevronRight,
|
|
3036
|
-
{
|
|
3037
|
-
size: 14,
|
|
3038
|
-
className: cn(
|
|
3039
|
-
"shrink-0 transition-transform duration-300",
|
|
3040
|
-
effectiveMode === "detail" && "rotate-90"
|
|
3041
|
-
),
|
|
3042
|
-
"aria-hidden": "true"
|
|
3043
|
-
}
|
|
3044
|
-
)
|
|
3045
|
-
]
|
|
3046
|
-
}
|
|
3047
|
-
),
|
|
3048
|
-
/* @__PURE__ */ jsx11("div", { className: "mt-3 h-px w-full bg-[hsl(var(--border)/0.75)]" })
|
|
3049
|
-
] })
|
|
3050
|
-
] }),
|
|
3051
|
-
effectiveMode === "detail" ? /* @__PURE__ */ jsx11("div", { className: "ml-10 flex flex-col gap-3 pt-1", children: messages.map((message, index) => {
|
|
3052
|
-
const isLast = index === messages.length - 1;
|
|
3053
|
-
const streamingThis = isStreaming && isLast;
|
|
3054
|
-
const text = getMessageText(message);
|
|
3055
|
-
const toolCalls = (message.tool_calls ?? []).filter(
|
|
3056
|
-
(toolCall) => formatToolName(toolCall.name) !== "AskUserQuestion"
|
|
3057
|
-
);
|
|
3058
|
-
const showReasoning = !!message.reasoning && (!isStreaming || index === latestReasoningIndex);
|
|
3059
|
-
return /* @__PURE__ */ jsxs9(
|
|
3060
|
-
"div",
|
|
3061
|
-
{
|
|
3062
|
-
className: "flex flex-col gap-3",
|
|
3063
|
-
children: [
|
|
3064
|
-
showReasoning && message.reasoning ? /* @__PURE__ */ jsx11(ThinkingBlock, { reasoning: message.reasoning, isStreaming: streamingThis && !text }) : null,
|
|
3065
|
-
hasRenderableMessageContent(message) && message !== finalMessage ? /* @__PURE__ */ jsx11(
|
|
3066
|
-
AssistantMessageContent,
|
|
2952
|
+
return /* @__PURE__ */ jsxs9(
|
|
2953
|
+
"div",
|
|
2954
|
+
{
|
|
2955
|
+
"aria-busy": isStreaming || void 0,
|
|
2956
|
+
className: "blade-chat-assistant-turn flex flex-col gap-3",
|
|
2957
|
+
children: [
|
|
2958
|
+
hasInterrupted && /* @__PURE__ */ jsx11("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" }),
|
|
2959
|
+
hasFailedWithoutContent && /* @__PURE__ */ jsx11("div", { className: "ml-4 w-fit rounded-full border border-red-500/30 bg-red-500/10 px-2.5 py-1 text-[10px] font-medium text-red-400", children: "\u751F\u6210\u5931\u8D25" }),
|
|
2960
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex w-full items-start gap-2.5", children: [
|
|
2961
|
+
/* @__PURE__ */ jsx11(
|
|
2962
|
+
"span",
|
|
2963
|
+
{
|
|
2964
|
+
className: "grid size-[30px] shrink-0 place-items-center rounded-full bg-[hsl(var(--muted)/0.55)] text-[hsl(var(--foreground))]",
|
|
2965
|
+
"aria-hidden": "true",
|
|
2966
|
+
children: /* @__PURE__ */ jsx11(Bot, { size: 16 })
|
|
2967
|
+
}
|
|
2968
|
+
),
|
|
2969
|
+
/* @__PURE__ */ jsxs9("div", { className: "min-w-0 flex-1 pt-0.5", children: [
|
|
2970
|
+
/* @__PURE__ */ jsxs9(
|
|
2971
|
+
"button",
|
|
3067
2972
|
{
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
2973
|
+
type: "button",
|
|
2974
|
+
onClick: () => {
|
|
2975
|
+
userSelectedDisplayModeRef.current = true;
|
|
2976
|
+
setDisplayMode(displayMode === "detail" ? "compact" : "detail");
|
|
2977
|
+
},
|
|
2978
|
+
"aria-expanded": effectiveMode === "detail",
|
|
2979
|
+
"aria-label": effectiveMode === "detail" ? "\u6536\u8D77\u6267\u884C\u8FC7\u7A0B" : "\u5C55\u5F00\u6267\u884C\u8FC7\u7A0B",
|
|
2980
|
+
"data-testid": "assistant-execution-summary",
|
|
2981
|
+
className: "inline-flex min-w-0 max-w-full select-none items-center gap-1 bg-transparent p-0 text-left text-xs leading-[22px] text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))] focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none",
|
|
2982
|
+
children: [
|
|
2983
|
+
/* @__PURE__ */ jsx11("span", { className: "min-w-0 truncate", children: executionSummaryLabel({
|
|
2984
|
+
messages,
|
|
2985
|
+
isStreaming,
|
|
2986
|
+
durationMs: liveExecutionDurationMs,
|
|
2987
|
+
sessionStatus,
|
|
2988
|
+
askAnswers
|
|
2989
|
+
}) }),
|
|
2990
|
+
/* @__PURE__ */ jsx11(
|
|
2991
|
+
ChevronRight,
|
|
2992
|
+
{
|
|
2993
|
+
size: 14,
|
|
2994
|
+
className: cn(
|
|
2995
|
+
"shrink-0 transition-transform duration-300",
|
|
2996
|
+
effectiveMode === "detail" && "rotate-90"
|
|
2997
|
+
),
|
|
2998
|
+
"aria-hidden": "true"
|
|
2999
|
+
}
|
|
3000
|
+
)
|
|
3001
|
+
]
|
|
3072
3002
|
}
|
|
3073
|
-
)
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3003
|
+
),
|
|
3004
|
+
/* @__PURE__ */ jsx11("div", { className: "mt-3 h-px w-full bg-[hsl(var(--border)/0.75)]" })
|
|
3005
|
+
] })
|
|
3006
|
+
] }),
|
|
3007
|
+
effectiveMode === "detail" ? /* @__PURE__ */ jsx11("div", { className: "ml-10 flex flex-col gap-3 pt-1", children: messages.map((message, index) => {
|
|
3008
|
+
const isLast = index === messages.length - 1;
|
|
3009
|
+
const streamingThis = isStreaming && isLast;
|
|
3010
|
+
const text = getMessageText(message);
|
|
3011
|
+
const toolCalls = (message.tool_calls ?? []).filter(
|
|
3012
|
+
(toolCall) => formatToolName(toolCall.name) !== "AskUserQuestion"
|
|
3013
|
+
);
|
|
3014
|
+
const showReasoning = !!message.reasoning && isStreaming && index === latestReasoningIndex;
|
|
3015
|
+
return /* @__PURE__ */ jsxs9(
|
|
3016
|
+
"div",
|
|
3017
|
+
{
|
|
3018
|
+
className: "flex flex-col gap-3",
|
|
3019
|
+
children: [
|
|
3020
|
+
showReasoning && message.reasoning ? /* @__PURE__ */ jsx11(ThinkingBlock, { reasoning: message.reasoning, isStreaming: streamingThis && !text }) : null,
|
|
3021
|
+
hasRenderableMessageContent(message) && message !== finalMessage ? /* @__PURE__ */ jsx11(
|
|
3022
|
+
AssistantMessageContent,
|
|
3023
|
+
{
|
|
3024
|
+
message,
|
|
3025
|
+
sessionId,
|
|
3026
|
+
streaming: streamingThis,
|
|
3027
|
+
compact: true
|
|
3028
|
+
}
|
|
3029
|
+
) : null,
|
|
3030
|
+
toolCalls.length > 0 ? /* @__PURE__ */ jsx11("div", { className: "flex flex-col gap-0.5", children: toolCalls.map((toolCall) => {
|
|
3031
|
+
const custom = toolCallRenderer?.(toolCall);
|
|
3032
|
+
return custom !== null && custom !== void 0 ? /* @__PURE__ */ jsx11("div", { children: custom }, toolCall.id) : formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */ jsx11(AgentLoopBlock, { toolCall }, toolCall.id) : /* @__PURE__ */ jsx11(ExecutionToolRow, { toolCall }, toolCall.id);
|
|
3033
|
+
}) }) : null
|
|
3034
|
+
]
|
|
3035
|
+
},
|
|
3036
|
+
message.entry_id ?? `${message.timestamp ?? "assistant"}-${index}`
|
|
3037
|
+
);
|
|
3038
|
+
}) }) : null,
|
|
3039
|
+
finalMessage ? /* @__PURE__ */ jsx11("div", { className: "ml-10", children: /* @__PURE__ */ jsx11(
|
|
3040
|
+
AssistantMessageContent,
|
|
3041
|
+
{
|
|
3042
|
+
message: finalMessage,
|
|
3043
|
+
sessionId,
|
|
3044
|
+
streaming: isStreaming && finalMessage === messages[messages.length - 1]
|
|
3045
|
+
}
|
|
3046
|
+
) }) : null,
|
|
3047
|
+
questionToolCalls.map((toolCall) => /* @__PURE__ */ jsx11(
|
|
3048
|
+
ToolCallBlock,
|
|
3049
|
+
{
|
|
3050
|
+
toolCall,
|
|
3051
|
+
answerData: askAnswers?.[toolCall.id],
|
|
3052
|
+
onAnswer,
|
|
3053
|
+
answered: sessionStatus !== "waiting_for_input",
|
|
3054
|
+
sessionStatus,
|
|
3055
|
+
isActiveQuestion: toolCall.id === activeQuestionId,
|
|
3056
|
+
renderer: toolCallRenderer
|
|
3057
|
+
},
|
|
3058
|
+
toolCall.id
|
|
3059
|
+
))
|
|
3060
|
+
]
|
|
3061
|
+
}
|
|
3062
|
+
);
|
|
3104
3063
|
}
|
|
3105
3064
|
function AssistantMessageContent({
|
|
3106
3065
|
message,
|
|
@@ -3165,49 +3124,9 @@ function AssistantMessageContent({
|
|
|
3165
3124
|
] });
|
|
3166
3125
|
}
|
|
3167
3126
|
|
|
3168
|
-
// src/components/ContextCard.tsx
|
|
3169
|
-
import {
|
|
3170
|
-
getContextDisplayState
|
|
3171
|
-
} from "@blade-hq/agent-client";
|
|
3172
|
-
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
3173
|
-
function ContextCard({ context, className }) {
|
|
3174
|
-
const display = getContextDisplayState(context);
|
|
3175
|
-
return /* @__PURE__ */ jsxs10(
|
|
3176
|
-
"details",
|
|
3177
|
-
{
|
|
3178
|
-
className: `blade-chat-context-card group rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] text-sm ${className ?? ""}`,
|
|
3179
|
-
children: [
|
|
3180
|
-
/* @__PURE__ */ jsxs10("summary", { className: "blade-chat-context-summary flex cursor-pointer list-none items-center gap-2 px-3 py-2.5 [&::-webkit-details-marker]:hidden", children: [
|
|
3181
|
-
/* @__PURE__ */ jsx12(
|
|
3182
|
-
Layers,
|
|
3183
|
-
{
|
|
3184
|
-
size: 15,
|
|
3185
|
-
className: "blade-chat-context-icon shrink-0 text-[hsl(var(--muted-foreground))]",
|
|
3186
|
-
"aria-hidden": "true"
|
|
3187
|
-
}
|
|
3188
|
-
),
|
|
3189
|
-
/* @__PURE__ */ jsxs10("span", { className: "blade-chat-context-copy min-w-0 flex-1", children: [
|
|
3190
|
-
/* @__PURE__ */ jsx12("span", { className: "blade-chat-context-title block font-medium text-[hsl(var(--foreground))]", children: display.title }),
|
|
3191
|
-
/* @__PURE__ */ jsx12("span", { className: "blade-chat-context-status block truncate text-xs text-[hsl(var(--muted-foreground))]", children: display.summary })
|
|
3192
|
-
] }),
|
|
3193
|
-
/* @__PURE__ */ jsx12(
|
|
3194
|
-
ChevronDown,
|
|
3195
|
-
{
|
|
3196
|
-
size: 14,
|
|
3197
|
-
className: "blade-chat-context-chevron shrink-0 text-[hsl(var(--muted-foreground))] transition-transform group-open:rotate-180",
|
|
3198
|
-
"aria-hidden": "true"
|
|
3199
|
-
}
|
|
3200
|
-
)
|
|
3201
|
-
] }),
|
|
3202
|
-
/* @__PURE__ */ jsx12("div", { className: "blade-chat-context-detail border-t border-[hsl(var(--border))] px-3 py-2.5 text-xs leading-5 text-[hsl(var(--muted-foreground))]", children: display.detail })
|
|
3203
|
-
]
|
|
3204
|
-
}
|
|
3205
|
-
);
|
|
3206
|
-
}
|
|
3207
|
-
|
|
3208
3127
|
// src/components/RenderErrorBoundary.tsx
|
|
3209
3128
|
import { Component } from "react";
|
|
3210
|
-
import { jsx as
|
|
3129
|
+
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
3211
3130
|
function getFirstComponentName(componentStack) {
|
|
3212
3131
|
const match = componentStack.match(/\n\s+at\s+([^\s(]+)/);
|
|
3213
3132
|
return match?.[1] ?? null;
|
|
@@ -3240,18 +3159,18 @@ var RenderErrorBoundary = class extends Component {
|
|
|
3240
3159
|
return children;
|
|
3241
3160
|
}
|
|
3242
3161
|
const componentName = getFirstComponentName(componentStack);
|
|
3243
|
-
return /* @__PURE__ */
|
|
3244
|
-
/* @__PURE__ */
|
|
3245
|
-
/* @__PURE__ */
|
|
3246
|
-
/* @__PURE__ */
|
|
3162
|
+
return /* @__PURE__ */ jsx12("div", { className: "blade-chat-render-error rounded-xl border border-amber-500/30 bg-amber-500/8 px-4 py-3 text-sm text-amber-100", children: /* @__PURE__ */ jsxs10("div", { className: "flex items-start gap-2", children: [
|
|
3163
|
+
/* @__PURE__ */ jsx12(TriangleAlert, { className: "mt-0.5 h-4 w-4 shrink-0 text-amber-300" }),
|
|
3164
|
+
/* @__PURE__ */ jsxs10("div", { className: "min-w-0 flex-1", children: [
|
|
3165
|
+
/* @__PURE__ */ jsxs10("div", { className: "font-medium", children: [
|
|
3247
3166
|
label,
|
|
3248
3167
|
"\u6E32\u67D3\u5931\u8D25"
|
|
3249
3168
|
] }),
|
|
3250
|
-
/* @__PURE__ */
|
|
3169
|
+
/* @__PURE__ */ jsxs10("div", { className: "mt-1 break-words text-xs leading-5 text-amber-100/75", children: [
|
|
3251
3170
|
componentName ? `\u7EC4\u4EF6\uFF1A${componentName}\u3002` : null,
|
|
3252
3171
|
error.message || "\u53D1\u751F\u4E86\u672A\u9884\u671F\u7684\u6E32\u67D3\u9519\u8BEF\u3002"
|
|
3253
3172
|
] }),
|
|
3254
|
-
details ? /* @__PURE__ */
|
|
3173
|
+
details ? /* @__PURE__ */ jsx12("div", { className: "mt-1 truncate text-xs text-amber-100/55", children: details }) : null
|
|
3255
3174
|
] })
|
|
3256
3175
|
] }) });
|
|
3257
3176
|
}
|
|
@@ -3259,7 +3178,7 @@ var RenderErrorBoundary = class extends Component {
|
|
|
3259
3178
|
|
|
3260
3179
|
// src/components/PostChatFollowupBlock.tsx
|
|
3261
3180
|
import { useCallback as useCallback6, useEffect as useEffect9, useRef as useRef10, useState as useState11 } from "react";
|
|
3262
|
-
import { Fragment as Fragment2, jsx as
|
|
3181
|
+
import { Fragment as Fragment2, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
3263
3182
|
function emitInteraction(callback, event) {
|
|
3264
3183
|
try {
|
|
3265
3184
|
callback?.(event);
|
|
@@ -3281,7 +3200,7 @@ function ArtifactCard({
|
|
|
3281
3200
|
const [downloading, setDownloading] = useState11(false);
|
|
3282
3201
|
const name = artifact.label || basename(artifact.target);
|
|
3283
3202
|
if (artifact.kind === "link") {
|
|
3284
|
-
return /* @__PURE__ */
|
|
3203
|
+
return /* @__PURE__ */ jsxs11(
|
|
3285
3204
|
"a",
|
|
3286
3205
|
{
|
|
3287
3206
|
href: artifact.target,
|
|
@@ -3292,9 +3211,9 @@ function ArtifactCard({
|
|
|
3292
3211
|
${artifact.target}`,
|
|
3293
3212
|
className: "group relative flex min-w-0 items-center gap-1.5 rounded-md border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-2 py-1.5 text-xs text-[hsl(var(--card-foreground))] hover:bg-[hsl(var(--accent))]",
|
|
3294
3213
|
children: [
|
|
3295
|
-
/* @__PURE__ */
|
|
3296
|
-
/* @__PURE__ */
|
|
3297
|
-
/* @__PURE__ */
|
|
3214
|
+
/* @__PURE__ */ jsx13(Globe, { size: 15, className: "shrink-0 text-[hsl(var(--primary))]" }),
|
|
3215
|
+
/* @__PURE__ */ jsx13("span", { className: "min-w-0 flex-1 truncate font-medium", children: name }),
|
|
3216
|
+
/* @__PURE__ */ jsx13(ArrowUpRight, { size: 13, className: "absolute right-2 opacity-0 group-hover:opacity-100 group-focus-visible:opacity-100" })
|
|
3298
3217
|
]
|
|
3299
3218
|
}
|
|
3300
3219
|
);
|
|
@@ -3329,7 +3248,7 @@ ${artifact.target}`,
|
|
|
3329
3248
|
setDownloading(false);
|
|
3330
3249
|
}
|
|
3331
3250
|
};
|
|
3332
|
-
return /* @__PURE__ */
|
|
3251
|
+
return /* @__PURE__ */ jsx13(
|
|
3333
3252
|
"a",
|
|
3334
3253
|
{
|
|
3335
3254
|
href: downloadUrl,
|
|
@@ -3357,17 +3276,17 @@ function feedbackReasonLabel(reason) {
|
|
|
3357
3276
|
}
|
|
3358
3277
|
function HistoricalResultFeedback({ feedback }) {
|
|
3359
3278
|
const label = feedbackReasonLabel(feedback.reason);
|
|
3360
|
-
return /* @__PURE__ */
|
|
3279
|
+
return /* @__PURE__ */ jsxs11(
|
|
3361
3280
|
"section",
|
|
3362
3281
|
{
|
|
3363
3282
|
"aria-label": "\u5386\u53F2\u7ED3\u679C\u53CD\u9988",
|
|
3364
3283
|
className: "mt-3 w-fit max-w-full rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted)/0.2)] px-3 py-2 text-xs text-[hsl(var(--muted-foreground))]",
|
|
3365
3284
|
children: [
|
|
3366
|
-
/* @__PURE__ */
|
|
3285
|
+
/* @__PURE__ */ jsxs11("span", { children: [
|
|
3367
3286
|
"\u4F60\u5BF9\u6B64\u8F6E\u7ED3\u679C\u7684\u8BC4\u4EF7\uFF1A",
|
|
3368
3287
|
feedback.helpful ? "\u6709\u5E2E\u52A9" : "\u6CA1\u5E2E\u52A9"
|
|
3369
3288
|
] }),
|
|
3370
|
-
label ? /* @__PURE__ */
|
|
3289
|
+
label ? /* @__PURE__ */ jsxs11("span", { children: [
|
|
3371
3290
|
" \xB7 ",
|
|
3372
3291
|
label
|
|
3373
3292
|
] }) : null
|
|
@@ -3442,15 +3361,15 @@ function ResultFeedback({
|
|
|
3442
3361
|
[client, followup.assistant_entry_id, onFeedbackSaved, onInteraction, sessionId]
|
|
3443
3362
|
);
|
|
3444
3363
|
if (!eligible) return null;
|
|
3445
|
-
return /* @__PURE__ */
|
|
3364
|
+
return /* @__PURE__ */ jsxs11(
|
|
3446
3365
|
"section",
|
|
3447
3366
|
{
|
|
3448
3367
|
"aria-label": "\u7ED3\u679C\u53CD\u9988",
|
|
3449
3368
|
className: "flex flex-col gap-2 border-t border-[hsl(var(--border))] pt-3",
|
|
3450
3369
|
children: [
|
|
3451
|
-
/* @__PURE__ */
|
|
3452
|
-
/* @__PURE__ */
|
|
3453
|
-
/* @__PURE__ */
|
|
3370
|
+
/* @__PURE__ */ jsx13("div", { className: "text-xs font-medium text-[hsl(var(--muted-foreground))]", children: "\u76EE\u524D\u7684\u6574\u4F53\u7ED3\u679C\u6709\u5E2E\u52A9\u5417\uFF1F" }),
|
|
3371
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex flex-wrap gap-1.5", children: [
|
|
3372
|
+
/* @__PURE__ */ jsx13(
|
|
3454
3373
|
"button",
|
|
3455
3374
|
{
|
|
3456
3375
|
type: "button",
|
|
@@ -3461,7 +3380,7 @@ function ResultFeedback({
|
|
|
3461
3380
|
children: "\u6709\u5E2E\u52A9"
|
|
3462
3381
|
}
|
|
3463
3382
|
),
|
|
3464
|
-
/* @__PURE__ */
|
|
3383
|
+
/* @__PURE__ */ jsx13(
|
|
3465
3384
|
"button",
|
|
3466
3385
|
{
|
|
3467
3386
|
type: "button",
|
|
@@ -3473,7 +3392,7 @@ function ResultFeedback({
|
|
|
3473
3392
|
}
|
|
3474
3393
|
)
|
|
3475
3394
|
] }),
|
|
3476
|
-
helpful === false ? /* @__PURE__ */
|
|
3395
|
+
helpful === false ? /* @__PURE__ */ jsx13("div", { className: "flex flex-wrap gap-1.5", "aria-label": "\u6CA1\u5E2E\u52A9\u7684\u4E3B\u8981\u539F\u56E0", children: FEEDBACK_REASONS.map((item) => /* @__PURE__ */ jsx13(
|
|
3477
3396
|
"button",
|
|
3478
3397
|
{
|
|
3479
3398
|
type: "button",
|
|
@@ -3485,9 +3404,9 @@ function ResultFeedback({
|
|
|
3485
3404
|
},
|
|
3486
3405
|
item.value
|
|
3487
3406
|
)) }) : null,
|
|
3488
|
-
saveError ? /* @__PURE__ */
|
|
3489
|
-
/* @__PURE__ */
|
|
3490
|
-
/* @__PURE__ */
|
|
3407
|
+
saveError ? /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 text-xs text-[hsl(var(--destructive))]", children: [
|
|
3408
|
+
/* @__PURE__ */ jsx13("span", { children: "\u53CD\u9988\u6682\u672A\u4FDD\u5B58\uFF0C\u53EF\u91CD\u8BD5" }),
|
|
3409
|
+
/* @__PURE__ */ jsx13(
|
|
3491
3410
|
"button",
|
|
3492
3411
|
{
|
|
3493
3412
|
type: "button",
|
|
@@ -3499,7 +3418,7 @@ function ResultFeedback({
|
|
|
3499
3418
|
children: "\u91CD\u8BD5"
|
|
3500
3419
|
}
|
|
3501
3420
|
)
|
|
3502
|
-
] }) : saved ? /* @__PURE__ */
|
|
3421
|
+
] }) : saved ? /* @__PURE__ */ jsx13("div", { className: "text-[11px] text-[hsl(var(--muted-foreground))]", children: "\u5DF2\u4FDD\u5B58\uFF0C\u53EF\u968F\u65F6\u4FEE\u6539" }) : null
|
|
3503
3422
|
]
|
|
3504
3423
|
}
|
|
3505
3424
|
);
|
|
@@ -3566,15 +3485,15 @@ function PostChatFollowupBlock({
|
|
|
3566
3485
|
);
|
|
3567
3486
|
if (!followup.recaption && artifacts.length === 0 && followup.suggestions.length === 0 && !followup.feedback_eligible)
|
|
3568
3487
|
return null;
|
|
3569
|
-
return /* @__PURE__ */
|
|
3570
|
-
followup.recaption || artifacts.length > 0 ? /* @__PURE__ */
|
|
3571
|
-
/* @__PURE__ */
|
|
3572
|
-
/* @__PURE__ */
|
|
3488
|
+
return /* @__PURE__ */ jsxs11("div", { className: "mt-3 flex w-fit max-w-full flex-col gap-3 rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--muted)/0.28)] p-3 sm:max-w-[680px]", children: [
|
|
3489
|
+
followup.recaption || artifacts.length > 0 ? /* @__PURE__ */ jsxs11("section", { "aria-label": "\u672C\u8F6E\u5C0F\u7ED3", className: "flex flex-col gap-2", children: [
|
|
3490
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1.5 text-xs font-medium text-[hsl(var(--muted-foreground))]", children: [
|
|
3491
|
+
/* @__PURE__ */ jsx13(Sparkles, { size: 14 }),
|
|
3573
3492
|
"\u672C\u8F6E\u5C0F\u7ED3"
|
|
3574
3493
|
] }),
|
|
3575
|
-
followup.recaption ? /* @__PURE__ */
|
|
3576
|
-
artifacts.length > 0 ? /* @__PURE__ */
|
|
3577
|
-
/* @__PURE__ */
|
|
3494
|
+
followup.recaption ? /* @__PURE__ */ jsx13("p", { className: "text-[13px] leading-5", children: followup.recaption }) : null,
|
|
3495
|
+
artifacts.length > 0 ? /* @__PURE__ */ jsxs11(Fragment2, { children: [
|
|
3496
|
+
/* @__PURE__ */ jsx13("div", { className: "grid max-w-full grid-cols-3 gap-1.5", children: visibleArtifacts.map((artifact, artifactIndex) => /* @__PURE__ */ jsx13(
|
|
3578
3497
|
ArtifactCard,
|
|
3579
3498
|
{
|
|
3580
3499
|
artifact,
|
|
@@ -3586,7 +3505,7 @@ function PostChatFollowupBlock({
|
|
|
3586
3505
|
},
|
|
3587
3506
|
`${artifact.kind}:${artifactIndex}`
|
|
3588
3507
|
)) }),
|
|
3589
|
-
artifacts.length > 3 ? /* @__PURE__ */
|
|
3508
|
+
artifacts.length > 3 ? /* @__PURE__ */ jsxs11(
|
|
3590
3509
|
"button",
|
|
3591
3510
|
{
|
|
3592
3511
|
type: "button",
|
|
@@ -3595,15 +3514,15 @@ function PostChatFollowupBlock({
|
|
|
3595
3514
|
className: "flex w-fit items-center gap-0.5 text-[11px] text-[hsl(var(--muted-foreground))]",
|
|
3596
3515
|
children: [
|
|
3597
3516
|
expanded ? "\u6536\u8D77" : `\u5C55\u5F00 ${artifacts.length - 3} \u4E2A`,
|
|
3598
|
-
/* @__PURE__ */
|
|
3517
|
+
/* @__PURE__ */ jsx13(ChevronDown, { size: 13, className: expanded ? "rotate-180" : void 0 })
|
|
3599
3518
|
]
|
|
3600
3519
|
}
|
|
3601
3520
|
) : null
|
|
3602
3521
|
] }) : null
|
|
3603
3522
|
] }) : null,
|
|
3604
|
-
followup.suggestions.length > 0 ? /* @__PURE__ */
|
|
3605
|
-
/* @__PURE__ */
|
|
3606
|
-
followup.suggestions.map((suggestion, suggestionIndex) => /* @__PURE__ */
|
|
3523
|
+
followup.suggestions.length > 0 ? /* @__PURE__ */ jsxs11("section", { "aria-label": "\u4E0B\u4E00\u6B65\u5EFA\u8BAE", className: "flex flex-col gap-1.5", children: [
|
|
3524
|
+
/* @__PURE__ */ jsx13("div", { className: "text-xs font-medium text-[hsl(var(--muted-foreground))]", children: "\u4E0B\u4E00\u6B65\u53EF\u4EE5" }),
|
|
3525
|
+
followup.suggestions.map((suggestion, suggestionIndex) => /* @__PURE__ */ jsxs11(
|
|
3607
3526
|
"button",
|
|
3608
3527
|
{
|
|
3609
3528
|
type: "button",
|
|
@@ -3622,14 +3541,14 @@ function PostChatFollowupBlock({
|
|
|
3622
3541
|
},
|
|
3623
3542
|
className: "group flex items-center gap-2 rounded-xl bg-[hsl(var(--muted)/0.62)] px-3 py-2 text-left text-[13px] disabled:cursor-default disabled:opacity-60",
|
|
3624
3543
|
children: [
|
|
3625
|
-
/* @__PURE__ */
|
|
3626
|
-
/* @__PURE__ */
|
|
3544
|
+
/* @__PURE__ */ jsx13("span", { children: suggestion }),
|
|
3545
|
+
/* @__PURE__ */ jsx13(ArrowRight, { size: 14, className: "ml-auto shrink-0" })
|
|
3627
3546
|
]
|
|
3628
3547
|
},
|
|
3629
3548
|
suggestion
|
|
3630
3549
|
))
|
|
3631
3550
|
] }) : null,
|
|
3632
|
-
/* @__PURE__ */
|
|
3551
|
+
/* @__PURE__ */ jsx13(
|
|
3633
3552
|
ResultFeedback,
|
|
3634
3553
|
{
|
|
3635
3554
|
followup,
|
|
@@ -3645,7 +3564,7 @@ function PostChatFollowupBlock({
|
|
|
3645
3564
|
|
|
3646
3565
|
// src/components/UserMessageBubble.tsx
|
|
3647
3566
|
import { getFileParts as getFileParts2, getImageParts as getImageParts2, getTextContent as getTextContent2 } from "@blade-hq/agent-client";
|
|
3648
|
-
import { jsx as
|
|
3567
|
+
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3649
3568
|
function isUserMessage(message) {
|
|
3650
3569
|
return message.role === "user";
|
|
3651
3570
|
}
|
|
@@ -3657,8 +3576,8 @@ function UserMessageBubble({ message, className }) {
|
|
|
3657
3576
|
const text = getTextContent2(message.content).trim();
|
|
3658
3577
|
const fileParts = getFileParts2(message.content);
|
|
3659
3578
|
const imageParts = getImageParts2(message.content);
|
|
3660
|
-
return /* @__PURE__ */
|
|
3661
|
-
imageParts.length > 0 && /* @__PURE__ */
|
|
3579
|
+
return /* @__PURE__ */ jsx14("div", { className: cn("blade-chat-user-row flex justify-end", className), children: /* @__PURE__ */ jsxs12("div", { className: "blade-chat-user-col flex max-w-[72%] flex-col items-end gap-3", children: [
|
|
3580
|
+
imageParts.length > 0 && /* @__PURE__ */ jsx14("div", { className: "grid gap-2", children: imageParts.map((part) => /* @__PURE__ */ jsx14(
|
|
3662
3581
|
"img",
|
|
3663
3582
|
{
|
|
3664
3583
|
src: part.image_url.url,
|
|
@@ -3667,21 +3586,21 @@ function UserMessageBubble({ message, className }) {
|
|
|
3667
3586
|
},
|
|
3668
3587
|
part.image_url.url
|
|
3669
3588
|
)) }),
|
|
3670
|
-
fileParts.length > 0 && /* @__PURE__ */
|
|
3589
|
+
fileParts.length > 0 && /* @__PURE__ */ jsx14("div", { className: "flex flex-col items-end gap-1.5", children: fileParts.map((part) => /* @__PURE__ */ jsxs12(
|
|
3671
3590
|
"div",
|
|
3672
3591
|
{
|
|
3673
3592
|
className: "flex items-center gap-1.5 rounded-lg border border-[hsl(var(--user-msg-border))] bg-[hsl(var(--muted)/0.3)] px-2.5 py-1.5 text-xs text-[hsl(var(--muted-foreground))]",
|
|
3674
3593
|
children: [
|
|
3675
|
-
/* @__PURE__ */
|
|
3676
|
-
/* @__PURE__ */
|
|
3594
|
+
/* @__PURE__ */ jsx14(FileText, { size: 12, className: "shrink-0" }),
|
|
3595
|
+
/* @__PURE__ */ jsx14("span", { className: "max-w-56 truncate", title: part.name, children: part.name })
|
|
3677
3596
|
]
|
|
3678
3597
|
},
|
|
3679
3598
|
`${part.name}-${part.data.length}`
|
|
3680
3599
|
)) }),
|
|
3681
|
-
text && /* @__PURE__ */
|
|
3682
|
-
text && isSending(message) && /* @__PURE__ */
|
|
3683
|
-
/* @__PURE__ */
|
|
3684
|
-
/* @__PURE__ */
|
|
3600
|
+
text && /* @__PURE__ */ jsx14("div", { className: "blade-chat-user-bubble max-w-full rounded-[20px] rounded-br-[6px] border border-[hsl(var(--user-msg-border))] bg-[hsl(var(--user-msg-bg))] px-[18px] py-[13px] text-sm leading-[1.65] text-[hsl(var(--user-msg-fg))]", children: /* @__PURE__ */ jsx14(MarkdownContent, { className: "blade-chat-prose", children: text }) }),
|
|
3601
|
+
text && isSending(message) && /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-1 pr-1 text-[11px] font-medium text-[hsl(var(--muted-foreground))/0.85]", children: [
|
|
3602
|
+
/* @__PURE__ */ jsx14(LoaderCircle, { size: 11, className: "animate-spin", "aria-hidden": "true" }),
|
|
3603
|
+
/* @__PURE__ */ jsx14("span", { children: "\u53D1\u9001\u4E2D" })
|
|
3685
3604
|
] })
|
|
3686
3605
|
] }) });
|
|
3687
3606
|
}
|
|
@@ -3690,11 +3609,11 @@ function ErrorMessageBlock({
|
|
|
3690
3609
|
className
|
|
3691
3610
|
}) {
|
|
3692
3611
|
const text = getTextContent2(message.content);
|
|
3693
|
-
return /* @__PURE__ */
|
|
3612
|
+
return /* @__PURE__ */ jsx14("div", { className: cn("blade-chat-error-row flex justify-center", className), children: /* @__PURE__ */ jsx14("div", { className: "blade-chat-error-block max-w-[85%] border-l-[3px] border-[hsl(var(--border))] px-4 py-1 text-sm leading-7 text-[hsl(var(--muted-foreground))]", children: text }) });
|
|
3694
3613
|
}
|
|
3695
3614
|
|
|
3696
3615
|
// src/components/MessageList.tsx
|
|
3697
|
-
import { jsx as
|
|
3616
|
+
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3698
3617
|
function parseModeChange(message) {
|
|
3699
3618
|
if (message.kind !== "mode_change" || typeof message.content !== "string") {
|
|
3700
3619
|
return null;
|
|
@@ -3750,7 +3669,7 @@ function MessageList({
|
|
|
3750
3669
|
const visible = messages.filter((message) => {
|
|
3751
3670
|
if ((message.loop_name ?? "root") !== "root") return false;
|
|
3752
3671
|
if (isHiddenInternalMessage(message)) return false;
|
|
3753
|
-
if (message.kind === "context") return
|
|
3672
|
+
if (message.kind === "context") return false;
|
|
3754
3673
|
if (message.kind === "compaction") return true;
|
|
3755
3674
|
return message.role !== "tool" || getPlanningDividerKind(message) !== null;
|
|
3756
3675
|
});
|
|
@@ -3785,15 +3704,6 @@ function MessageList({
|
|
|
3785
3704
|
blocks.push({ type: "compaction", key: message.entry_id ?? `compaction-${blocks.length}` });
|
|
3786
3705
|
continue;
|
|
3787
3706
|
}
|
|
3788
|
-
if (message.kind === "context" && message.context) {
|
|
3789
|
-
flushAssistant();
|
|
3790
|
-
blocks.push({
|
|
3791
|
-
type: "context",
|
|
3792
|
-
message,
|
|
3793
|
-
key: message.entry_id ?? `context-${blocks.length}`
|
|
3794
|
-
});
|
|
3795
|
-
continue;
|
|
3796
|
-
}
|
|
3797
3707
|
if (message.role === "assistant") {
|
|
3798
3708
|
assistantBuffer.push(message);
|
|
3799
3709
|
continue;
|
|
@@ -3829,101 +3739,101 @@ function MessageList({
|
|
|
3829
3739
|
}
|
|
3830
3740
|
return blocks;
|
|
3831
3741
|
}, [messages, isStreaming]);
|
|
3832
|
-
return /* @__PURE__ */
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
/* @__PURE__ */
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
{
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3742
|
+
return /* @__PURE__ */ jsxs13("div", { className: cn("blade-chat-messages relative min-h-0 flex-1", className), children: [
|
|
3743
|
+
isStreaming ? /* @__PURE__ */ jsx15("output", { className: "sr-only", children: "\u6B63\u5728\u751F\u6210\u56DE\u590D" }) : null,
|
|
3744
|
+
/* @__PURE__ */ jsxs13(
|
|
3745
|
+
StickToBottom,
|
|
3746
|
+
{
|
|
3747
|
+
className: "h-full overflow-y-hidden",
|
|
3748
|
+
initial: "instant",
|
|
3749
|
+
resize: "instant",
|
|
3750
|
+
children: [
|
|
3751
|
+
/* @__PURE__ */ jsx15(StickToBottom.Content, { className: "blade-chat-messages-scroll", children: /* @__PURE__ */ jsx15("div", { className: "blade-chat-messages-content mx-auto max-w-[748px]", children: /* @__PURE__ */ jsxs13("div", { className: "flex min-w-0 flex-col", children: [
|
|
3752
|
+
renderBlocks.length === 0 ? emptyState ?? /* @__PURE__ */ jsxs13("div", { className: "blade-chat-empty", children: [
|
|
3753
|
+
/* @__PURE__ */ jsx15(MessageSquare, { size: 40, strokeWidth: 1.5 }),
|
|
3754
|
+
/* @__PURE__ */ jsx15("span", { className: "text-base font-medium", children: "\u5F00\u59CB\u5BF9\u8BDD" }),
|
|
3755
|
+
/* @__PURE__ */ jsx15("span", { className: "text-sm opacity-60", children: "\u5728\u4E0B\u65B9\u8F93\u5165\u6D88\u606F\u5F00\u59CB\u804A\u5929" })
|
|
3756
|
+
] }) : renderBlocks.map((block) => {
|
|
3757
|
+
if (block.type === "message") {
|
|
3758
|
+
return /* @__PURE__ */ jsx15("div", { "data-entry-id": block.message.entry_id, children: isUserMessage(block.message) ? /* @__PURE__ */ jsx15(UserMessageBubble, { message: block.message }) : isErrorMessage(block.message) ? /* @__PURE__ */ jsx15(ErrorMessageBlock, { message: block.message }) : null }, block.key);
|
|
3759
|
+
}
|
|
3760
|
+
if (block.type === "assistant_turn") {
|
|
3761
|
+
const blockFeedback = block.messages.map(
|
|
3762
|
+
(message) => message.entry_id ? resultFeedbackByEntry.get(message.entry_id) : void 0
|
|
3763
|
+
).find((feedback) => feedback != null);
|
|
3764
|
+
const hasActiveFollowup = Boolean(
|
|
3765
|
+
postChatFollowup && block.messages.some(
|
|
3766
|
+
(message) => message.entry_id === postChatFollowup.assistant_entry_id
|
|
3767
|
+
)
|
|
3768
|
+
);
|
|
3769
|
+
return /* @__PURE__ */ jsx15("div", { "data-entry-id": block.messages[0]?.entry_id, children: /* @__PURE__ */ jsxs13(
|
|
3770
|
+
RenderErrorBoundary,
|
|
3771
|
+
{
|
|
3772
|
+
label: "\u52A9\u624B\u6D88\u606F",
|
|
3773
|
+
details: block.key,
|
|
3774
|
+
resetKey: getMessageResetSignature(block.messages),
|
|
3775
|
+
children: [
|
|
3776
|
+
/* @__PURE__ */ jsx15(
|
|
3777
|
+
AssistantTurnBlock,
|
|
3778
|
+
{
|
|
3779
|
+
messages: block.messages,
|
|
3780
|
+
isStreaming: block.isStreaming,
|
|
3781
|
+
askAnswers,
|
|
3782
|
+
onAnswer,
|
|
3783
|
+
sessionStatus,
|
|
3784
|
+
toolCallRenderer,
|
|
3785
|
+
sessionId
|
|
3786
|
+
}
|
|
3787
|
+
),
|
|
3788
|
+
blockFeedback && !hasActiveFollowup ? /* @__PURE__ */ jsx15(HistoricalResultFeedback, { feedback: blockFeedback }) : null,
|
|
3789
|
+
hasActiveFollowup && postChatFollowup ? /* @__PURE__ */ jsx15(
|
|
3790
|
+
PostChatFollowupBlock,
|
|
3791
|
+
{
|
|
3792
|
+
followup: postChatFollowup,
|
|
3793
|
+
sessionId,
|
|
3794
|
+
onSuggestion,
|
|
3795
|
+
isViewer,
|
|
3796
|
+
onInteraction: onFollowupInteraction,
|
|
3797
|
+
savedFeedback: blockFeedback,
|
|
3798
|
+
onFeedbackSaved: onResultFeedbackSaved
|
|
3799
|
+
}
|
|
3800
|
+
) : null
|
|
3801
|
+
]
|
|
3802
|
+
}
|
|
3803
|
+
) }, block.key);
|
|
3804
|
+
}
|
|
3805
|
+
if (block.type === "compaction") {
|
|
3806
|
+
return /* @__PURE__ */ jsxs13(
|
|
3807
|
+
"div",
|
|
3808
|
+
{
|
|
3809
|
+
className: "flex items-center gap-2 text-xs text-[hsl(var(--muted-foreground))]",
|
|
3810
|
+
children: [
|
|
3811
|
+
/* @__PURE__ */ jsx15(Layers, { size: 12 }),
|
|
3812
|
+
/* @__PURE__ */ jsx15("span", { children: "\u4E0A\u4E0B\u6587\u5DF2\u538B\u7F29" })
|
|
3813
|
+
]
|
|
3814
|
+
},
|
|
3815
|
+
block.key
|
|
3816
|
+
);
|
|
3817
|
+
}
|
|
3818
|
+
return /* @__PURE__ */ jsx15(PlanningDivider, { kind: block.kind }, block.key);
|
|
3819
|
+
}),
|
|
3820
|
+
sessionStatus === "interrupted" && !isStreaming ? /* @__PURE__ */ jsx15("div", { className: "flex", children: /* @__PURE__ */ jsx15("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
|
|
3821
|
+
] }) }) }),
|
|
3822
|
+
/* @__PURE__ */ jsx15(
|
|
3823
|
+
PinLatestUserMessage,
|
|
3824
|
+
{
|
|
3825
|
+
userMessageCount: userMessages.length,
|
|
3826
|
+
shouldPinLatestUser,
|
|
3827
|
+
targetKey: latestUserMessage?.render_id ?? latestUserMessage?.entry_id ?? (latestUserMessage ? `user:${userMessages.length}` : null)
|
|
3828
|
+
},
|
|
3829
|
+
sessionId ?? "no-session"
|
|
3830
|
+
),
|
|
3831
|
+
/* @__PURE__ */ jsx15(ScrollToBottomButton, {})
|
|
3832
|
+
]
|
|
3833
|
+
},
|
|
3834
|
+
sessionId ?? "no-session"
|
|
3835
|
+
)
|
|
3836
|
+
] });
|
|
3927
3837
|
}
|
|
3928
3838
|
function PinLatestUserMessage({
|
|
3929
3839
|
userMessageCount,
|
|
@@ -4004,7 +3914,7 @@ function ScrollToBottomButton() {
|
|
|
4004
3914
|
scrollToBottom();
|
|
4005
3915
|
}, [scrollToBottom]);
|
|
4006
3916
|
if (!visible) return null;
|
|
4007
|
-
return /* @__PURE__ */
|
|
3917
|
+
return /* @__PURE__ */ jsxs13(
|
|
4008
3918
|
"button",
|
|
4009
3919
|
{
|
|
4010
3920
|
type: "button",
|
|
@@ -4012,25 +3922,25 @@ function ScrollToBottomButton() {
|
|
|
4012
3922
|
"aria-label": "\u6EDA\u52A8\u5230\u5E95\u90E8",
|
|
4013
3923
|
className: "blade-chat-scroll-bottom 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))]",
|
|
4014
3924
|
children: [
|
|
4015
|
-
/* @__PURE__ */
|
|
4016
|
-
/* @__PURE__ */
|
|
3925
|
+
/* @__PURE__ */ jsx15(ChevronDown, { size: 14 }),
|
|
3926
|
+
/* @__PURE__ */ jsx15("span", { className: "blade-chat-scroll-bottom-label", children: "\u6EDA\u52A8\u5230\u5E95\u90E8" })
|
|
4017
3927
|
]
|
|
4018
3928
|
}
|
|
4019
3929
|
);
|
|
4020
3930
|
}
|
|
4021
3931
|
function PlanningDivider({ kind }) {
|
|
4022
|
-
return /* @__PURE__ */
|
|
4023
|
-
/* @__PURE__ */
|
|
4024
|
-
/* @__PURE__ */
|
|
4025
|
-
/* @__PURE__ */
|
|
4026
|
-
/* @__PURE__ */
|
|
3932
|
+
return /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-3 py-1", children: [
|
|
3933
|
+
/* @__PURE__ */ jsx15("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" }),
|
|
3934
|
+
/* @__PURE__ */ jsxs13("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: [
|
|
3935
|
+
/* @__PURE__ */ jsx15(Lightbulb, { size: 12 }),
|
|
3936
|
+
/* @__PURE__ */ jsx15("span", { children: kind === "enter" ? "\u8FDB\u5165\u89C4\u5212\u6A21\u5F0F" : "\u89C4\u5212\u5B8C\u6210" })
|
|
4027
3937
|
] }),
|
|
4028
|
-
/* @__PURE__ */
|
|
3938
|
+
/* @__PURE__ */ jsx15("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" })
|
|
4029
3939
|
] });
|
|
4030
3940
|
}
|
|
4031
3941
|
|
|
4032
3942
|
// src/components/ChatSurface.tsx
|
|
4033
|
-
import { jsx as
|
|
3943
|
+
import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
4034
3944
|
function themeAttr(theme) {
|
|
4035
3945
|
return theme === "dark" ? "dark" : void 0;
|
|
4036
3946
|
}
|
|
@@ -4062,7 +3972,7 @@ function ChatSurface({
|
|
|
4062
3972
|
beforeInput,
|
|
4063
3973
|
banner
|
|
4064
3974
|
}) {
|
|
4065
|
-
return /* @__PURE__ */
|
|
3975
|
+
return /* @__PURE__ */ jsxs14(
|
|
4066
3976
|
"div",
|
|
4067
3977
|
{
|
|
4068
3978
|
"data-theme": themeAttr(theme),
|
|
@@ -4071,14 +3981,14 @@ function ChatSurface({
|
|
|
4071
3981
|
classNames?.root
|
|
4072
3982
|
),
|
|
4073
3983
|
children: [
|
|
4074
|
-
/* @__PURE__ */
|
|
3984
|
+
/* @__PURE__ */ jsx16(ConnectionBanner, { connection, className: classNames?.banner }),
|
|
4075
3985
|
banner,
|
|
4076
|
-
errorMessage && /* @__PURE__ */
|
|
4077
|
-
/* @__PURE__ */
|
|
4078
|
-
/* @__PURE__ */
|
|
3986
|
+
errorMessage && /* @__PURE__ */ jsxs14("div", { className: "blade-chat-error-bar flex items-start gap-2 border-b px-4 py-3 text-sm", children: [
|
|
3987
|
+
/* @__PURE__ */ jsx16(CircleAlert, { size: 16, className: "mt-0.5 shrink-0" }),
|
|
3988
|
+
/* @__PURE__ */ jsx16("span", { children: errorMessage })
|
|
4079
3989
|
] }),
|
|
4080
3990
|
slots?.header,
|
|
4081
|
-
/* @__PURE__ */
|
|
3991
|
+
/* @__PURE__ */ jsx16(
|
|
4082
3992
|
MessageList,
|
|
4083
3993
|
{
|
|
4084
3994
|
messages,
|
|
@@ -4099,7 +4009,7 @@ function ChatSurface({
|
|
|
4099
4009
|
}
|
|
4100
4010
|
),
|
|
4101
4011
|
beforeInput,
|
|
4102
|
-
/* @__PURE__ */
|
|
4012
|
+
/* @__PURE__ */ jsx16(
|
|
4103
4013
|
ChatInput,
|
|
4104
4014
|
{
|
|
4105
4015
|
value: inputText,
|
|
@@ -4119,7 +4029,7 @@ function ChatSurface({
|
|
|
4119
4029
|
}
|
|
4120
4030
|
|
|
4121
4031
|
// src/components/AgentChat.tsx
|
|
4122
|
-
import { Fragment as Fragment3, jsx as
|
|
4032
|
+
import { Fragment as Fragment3, jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
4123
4033
|
function isUnauthorizedError(error) {
|
|
4124
4034
|
return error instanceof BladeApiError && error.status === 401;
|
|
4125
4035
|
}
|
|
@@ -4138,11 +4048,11 @@ function LoginCard({ client, onLoggedIn }) {
|
|
|
4138
4048
|
setLoggingIn(false);
|
|
4139
4049
|
}
|
|
4140
4050
|
};
|
|
4141
|
-
return /* @__PURE__ */
|
|
4142
|
-
/* @__PURE__ */
|
|
4143
|
-
/* @__PURE__ */
|
|
4144
|
-
/* @__PURE__ */
|
|
4145
|
-
/* @__PURE__ */
|
|
4051
|
+
return /* @__PURE__ */ jsx17("div", { className: "blade-chat-login flex flex-1 items-center justify-center p-6", children: /* @__PURE__ */ jsxs15("div", { className: "flex w-full max-w-sm flex-col items-center gap-4 rounded-2xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-6 py-8 text-center", children: [
|
|
4052
|
+
/* @__PURE__ */ jsx17(LockKeyhole, { size: 28, className: "text-[hsl(var(--muted-foreground))]" }),
|
|
4053
|
+
/* @__PURE__ */ jsx17("div", { className: "text-base font-medium text-[hsl(var(--foreground))]", children: "\u9700\u8981\u767B\u5F55\u540E\u4F7F\u7528" }),
|
|
4054
|
+
/* @__PURE__ */ jsx17("div", { className: "text-sm text-[hsl(var(--muted-foreground))]", children: "\u767B\u5F55\u540E\u5373\u53EF\u4E0E\u667A\u80FD\u4F53\u5BF9\u8BDD\uFF0C\u4F60\u7684\u4F1A\u8BDD\u5185\u5BB9\u4EC5\u81EA\u5DF1\u53EF\u89C1\u3002" }),
|
|
4055
|
+
/* @__PURE__ */ jsx17(
|
|
4146
4056
|
"button",
|
|
4147
4057
|
{
|
|
4148
4058
|
type: "button",
|
|
@@ -4152,7 +4062,7 @@ function LoginCard({ client, onLoggedIn }) {
|
|
|
4152
4062
|
children: loggingIn ? "\u767B\u5F55\u4E2D\u2026" : "\u767B\u5F55"
|
|
4153
4063
|
}
|
|
4154
4064
|
),
|
|
4155
|
-
loginError && /* @__PURE__ */
|
|
4065
|
+
loginError && /* @__PURE__ */ jsx17("div", { className: "text-xs text-[hsl(var(--destructive))]", children: loginError })
|
|
4156
4066
|
] }) });
|
|
4157
4067
|
}
|
|
4158
4068
|
function AgentChat(props) {
|
|
@@ -4160,12 +4070,12 @@ function AgentChat(props) {
|
|
|
4160
4070
|
const [attempt, setAttempt] = useState13(0);
|
|
4161
4071
|
const [needLogin, setNeedLogin] = useState13(() => !client.hasToken());
|
|
4162
4072
|
if (needLogin) {
|
|
4163
|
-
return /* @__PURE__ */
|
|
4073
|
+
return /* @__PURE__ */ jsx17(
|
|
4164
4074
|
"div",
|
|
4165
4075
|
{
|
|
4166
4076
|
"data-theme": themeAttr(props.theme),
|
|
4167
4077
|
className: cn("blade-chat flex min-h-0 flex-1 flex-col", props.classNames?.root),
|
|
4168
|
-
children: /* @__PURE__ */
|
|
4078
|
+
children: /* @__PURE__ */ jsx17(
|
|
4169
4079
|
LoginCard,
|
|
4170
4080
|
{
|
|
4171
4081
|
client,
|
|
@@ -4178,7 +4088,7 @@ function AgentChat(props) {
|
|
|
4178
4088
|
}
|
|
4179
4089
|
);
|
|
4180
4090
|
}
|
|
4181
|
-
return /* @__PURE__ */
|
|
4091
|
+
return /* @__PURE__ */ jsx17(ChatSessionView, { ...props, onUnauthorized: () => setNeedLogin(true) }, attempt);
|
|
4182
4092
|
}
|
|
4183
4093
|
function ChatSessionView({
|
|
4184
4094
|
sessionId,
|
|
@@ -4287,7 +4197,7 @@ ${content}`);
|
|
|
4287
4197
|
setStopRequested(true);
|
|
4288
4198
|
void session?.stop();
|
|
4289
4199
|
};
|
|
4290
|
-
return /* @__PURE__ */
|
|
4200
|
+
return /* @__PURE__ */ jsx17(
|
|
4291
4201
|
ChatSurface,
|
|
4292
4202
|
{
|
|
4293
4203
|
theme,
|
|
@@ -4297,8 +4207,8 @@ ${content}`);
|
|
|
4297
4207
|
slots,
|
|
4298
4208
|
placeholder,
|
|
4299
4209
|
connection: state?.connection ?? "connecting",
|
|
4300
|
-
banner: /* @__PURE__ */
|
|
4301
|
-
/* @__PURE__ */
|
|
4210
|
+
banner: /* @__PURE__ */ jsxs15(Fragment3, { children: [
|
|
4211
|
+
/* @__PURE__ */ jsx17(
|
|
4302
4212
|
ReplayBar,
|
|
4303
4213
|
{
|
|
4304
4214
|
isReplay: replay.isReplay,
|
|
@@ -4308,7 +4218,7 @@ ${content}`);
|
|
|
4308
4218
|
onExit: () => void replay.exitToAutonomous()
|
|
4309
4219
|
}
|
|
4310
4220
|
),
|
|
4311
|
-
/* @__PURE__ */
|
|
4221
|
+
/* @__PURE__ */ jsx17(ReplayMismatchPrompt, { mismatch: replay.mismatch })
|
|
4312
4222
|
] }),
|
|
4313
4223
|
errorMessage,
|
|
4314
4224
|
messages: state?.messages ?? [],
|
|
@@ -4341,7 +4251,7 @@ import { useEffect as useEffect12, useMemo as useMemo9, useState as useState15 }
|
|
|
4341
4251
|
|
|
4342
4252
|
// src/components/LlmAdvancedSettings.tsx
|
|
4343
4253
|
import { useState as useState14 } from "react";
|
|
4344
|
-
import { jsx as
|
|
4254
|
+
import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
4345
4255
|
var FIELDS = [
|
|
4346
4256
|
{ id: "baseURL", label: "\u6A21\u578B\u670D\u52A1\u5730\u5740", placeholder: "http://\u5185\u7F51\u5730\u5740/v1" },
|
|
4347
4257
|
{ id: "model", label: "\u6A21\u578B", placeholder: "\u6A21\u578B\u540D\u79F0" },
|
|
@@ -4392,8 +4302,8 @@ function LlmAdvancedSettingsBar({ settings, defaults, override, onChange }) {
|
|
|
4392
4302
|
if (!normalized) return null;
|
|
4393
4303
|
const fields = FIELDS.filter((field) => normalized[field.id]);
|
|
4394
4304
|
const dirty = Object.keys(override).length > 0;
|
|
4395
|
-
return /* @__PURE__ */
|
|
4396
|
-
/* @__PURE__ */
|
|
4305
|
+
return /* @__PURE__ */ jsxs16("div", { className: "blade-chat-advanced border-t border-[hsl(var(--border))] px-4 py-2 text-xs", children: [
|
|
4306
|
+
/* @__PURE__ */ jsxs16(
|
|
4397
4307
|
"button",
|
|
4398
4308
|
{
|
|
4399
4309
|
type: "button",
|
|
@@ -4403,16 +4313,16 @@ function LlmAdvancedSettingsBar({ settings, defaults, override, onChange }) {
|
|
|
4403
4313
|
},
|
|
4404
4314
|
className: "flex items-center gap-1.5 text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))]",
|
|
4405
4315
|
children: [
|
|
4406
|
-
/* @__PURE__ */
|
|
4316
|
+
/* @__PURE__ */ jsx18(Settings2, { size: 13 }),
|
|
4407
4317
|
"\u9AD8\u7EA7\u8BBE\u7F6E",
|
|
4408
|
-
dirty && /* @__PURE__ */
|
|
4318
|
+
dirty && /* @__PURE__ */ jsx18("span", { className: "text-[hsl(var(--primary))]", children: "\uFF08\u5DF2\u81EA\u5B9A\u4E49\uFF09" })
|
|
4409
4319
|
]
|
|
4410
4320
|
}
|
|
4411
4321
|
),
|
|
4412
|
-
open && /* @__PURE__ */
|
|
4413
|
-
fields.map((field) => /* @__PURE__ */
|
|
4414
|
-
/* @__PURE__ */
|
|
4415
|
-
/* @__PURE__ */
|
|
4322
|
+
open && /* @__PURE__ */ jsxs16("div", { className: "mt-2 flex flex-col gap-2", children: [
|
|
4323
|
+
fields.map((field) => /* @__PURE__ */ jsxs16("label", { className: "flex flex-col gap-1", children: [
|
|
4324
|
+
/* @__PURE__ */ jsx18("span", { className: "text-[hsl(var(--muted-foreground))]", children: field.label }),
|
|
4325
|
+
/* @__PURE__ */ jsx18(
|
|
4416
4326
|
"input",
|
|
4417
4327
|
{
|
|
4418
4328
|
type: field.secret ? "password" : "text",
|
|
@@ -4423,9 +4333,9 @@ function LlmAdvancedSettingsBar({ settings, defaults, override, onChange }) {
|
|
|
4423
4333
|
}
|
|
4424
4334
|
)
|
|
4425
4335
|
] }, field.id)),
|
|
4426
|
-
normalized.apiKey && /* @__PURE__ */
|
|
4427
|
-
/* @__PURE__ */
|
|
4428
|
-
/* @__PURE__ */
|
|
4336
|
+
normalized.apiKey && /* @__PURE__ */ jsx18("p", { className: "text-[hsl(var(--muted-foreground))]", children: "\u5BC6\u94A5\u4F1A\u5B58\u5728\u8FD9\u53F0\u6D4F\u89C8\u5668\u91CC\u3002\u53EA\u5728\u4F60\u4FE1\u5F97\u8FC7\u8FD9\u53F0\u673A\u5668\u65F6\u586B\u3002" }),
|
|
4337
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex gap-2", children: [
|
|
4338
|
+
/* @__PURE__ */ jsx18(
|
|
4429
4339
|
"button",
|
|
4430
4340
|
{
|
|
4431
4341
|
type: "button",
|
|
@@ -4440,7 +4350,7 @@ function LlmAdvancedSettingsBar({ settings, defaults, override, onChange }) {
|
|
|
4440
4350
|
children: "\u4FDD\u5B58"
|
|
4441
4351
|
}
|
|
4442
4352
|
),
|
|
4443
|
-
/* @__PURE__ */
|
|
4353
|
+
/* @__PURE__ */ jsx18(
|
|
4444
4354
|
"button",
|
|
4445
4355
|
{
|
|
4446
4356
|
type: "button",
|
|
@@ -4459,7 +4369,7 @@ function LlmAdvancedSettingsBar({ settings, defaults, override, onChange }) {
|
|
|
4459
4369
|
}
|
|
4460
4370
|
|
|
4461
4371
|
// src/components/LlmChat.tsx
|
|
4462
|
-
import { jsx as
|
|
4372
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
4463
4373
|
function LlmChat({
|
|
4464
4374
|
classNames,
|
|
4465
4375
|
renderers,
|
|
@@ -4488,7 +4398,7 @@ ${text}` : text),
|
|
|
4488
4398
|
useEffect12(() => {
|
|
4489
4399
|
onReady?.(handle);
|
|
4490
4400
|
}, [handle, onReady]);
|
|
4491
|
-
return /* @__PURE__ */
|
|
4401
|
+
return /* @__PURE__ */ jsx19(
|
|
4492
4402
|
ChatSurface,
|
|
4493
4403
|
{
|
|
4494
4404
|
theme,
|
|
@@ -4513,7 +4423,7 @@ ${text}` : text),
|
|
|
4513
4423
|
setStopRequested(true);
|
|
4514
4424
|
stop();
|
|
4515
4425
|
},
|
|
4516
|
-
beforeInput: advanced ? /* @__PURE__ */
|
|
4426
|
+
beforeInput: advanced ? /* @__PURE__ */ jsx19(
|
|
4517
4427
|
LlmAdvancedSettingsBar,
|
|
4518
4428
|
{
|
|
4519
4429
|
settings: advanced,
|
|
@@ -4531,14 +4441,14 @@ ${text}` : text),
|
|
|
4531
4441
|
}
|
|
4532
4442
|
|
|
4533
4443
|
// src/components/ChatView.tsx
|
|
4534
|
-
import { jsx as
|
|
4444
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
4535
4445
|
function ChatView(props) {
|
|
4536
4446
|
const { mode, llm, onLlmReady, ...rest } = props;
|
|
4537
4447
|
if (mode === "llm") {
|
|
4538
4448
|
if (!llm) {
|
|
4539
4449
|
throw new Error('ChatView: mode="llm" \u9700\u8981\u540C\u65F6\u4F20 llm={{ baseURL, model }}');
|
|
4540
4450
|
}
|
|
4541
|
-
return /* @__PURE__ */
|
|
4451
|
+
return /* @__PURE__ */ jsx20(
|
|
4542
4452
|
LlmChat,
|
|
4543
4453
|
{
|
|
4544
4454
|
...llm,
|
|
@@ -4551,7 +4461,89 @@ function ChatView(props) {
|
|
|
4551
4461
|
}
|
|
4552
4462
|
);
|
|
4553
4463
|
}
|
|
4554
|
-
return /* @__PURE__ */
|
|
4464
|
+
return /* @__PURE__ */ jsx20(AgentChat, { ...rest });
|
|
4465
|
+
}
|
|
4466
|
+
|
|
4467
|
+
// src/components/ContextCard.tsx
|
|
4468
|
+
import {
|
|
4469
|
+
getContextDisplayState
|
|
4470
|
+
} from "@blade-hq/agent-client";
|
|
4471
|
+
import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
4472
|
+
function ContextCard({ context, className }) {
|
|
4473
|
+
const display = getContextDisplayState(context);
|
|
4474
|
+
return /* @__PURE__ */ jsxs17(
|
|
4475
|
+
"details",
|
|
4476
|
+
{
|
|
4477
|
+
className: `blade-chat-context-card group rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] text-sm ${className ?? ""}`,
|
|
4478
|
+
children: [
|
|
4479
|
+
/* @__PURE__ */ jsxs17("summary", { className: "blade-chat-context-summary flex cursor-pointer list-none items-center gap-2 px-3 py-2.5 [&::-webkit-details-marker]:hidden", children: [
|
|
4480
|
+
/* @__PURE__ */ jsx21(
|
|
4481
|
+
Layers,
|
|
4482
|
+
{
|
|
4483
|
+
size: 15,
|
|
4484
|
+
className: "blade-chat-context-icon shrink-0 text-[hsl(var(--muted-foreground))]",
|
|
4485
|
+
"aria-hidden": "true"
|
|
4486
|
+
}
|
|
4487
|
+
),
|
|
4488
|
+
/* @__PURE__ */ jsxs17("span", { className: "blade-chat-context-copy min-w-0 flex-1", children: [
|
|
4489
|
+
/* @__PURE__ */ jsx21("span", { className: "blade-chat-context-title block font-medium text-[hsl(var(--foreground))]", children: display.title }),
|
|
4490
|
+
/* @__PURE__ */ jsx21("span", { className: "blade-chat-context-status block truncate text-xs text-[hsl(var(--muted-foreground))]", children: display.summary })
|
|
4491
|
+
] }),
|
|
4492
|
+
/* @__PURE__ */ jsx21(
|
|
4493
|
+
ChevronDown,
|
|
4494
|
+
{
|
|
4495
|
+
size: 14,
|
|
4496
|
+
className: "blade-chat-context-chevron shrink-0 text-[hsl(var(--muted-foreground))] transition-transform group-open:rotate-180",
|
|
4497
|
+
"aria-hidden": "true"
|
|
4498
|
+
}
|
|
4499
|
+
)
|
|
4500
|
+
] }),
|
|
4501
|
+
/* @__PURE__ */ jsx21("div", { className: "blade-chat-context-detail border-t border-[hsl(var(--border))] px-3 py-2.5 text-xs leading-5 text-[hsl(var(--muted-foreground))]", children: display.detail })
|
|
4502
|
+
]
|
|
4503
|
+
}
|
|
4504
|
+
);
|
|
4505
|
+
}
|
|
4506
|
+
|
|
4507
|
+
// src/lib/agent-computer-command.ts
|
|
4508
|
+
var COMPUTER_LAUNCH_COMMAND_PATTERN = /(?:^|[\n;&|(]\s*)computer\s+launch(?:\s|$)/;
|
|
4509
|
+
function isAgentComputerCommand(command) {
|
|
4510
|
+
return COMPUTER_LAUNCH_COMMAND_PATTERN.test(command);
|
|
4511
|
+
}
|
|
4512
|
+
function isAgentComputerToolCall(argumentsJson) {
|
|
4513
|
+
if (!argumentsJson) return false;
|
|
4514
|
+
let command;
|
|
4515
|
+
try {
|
|
4516
|
+
const parsed = JSON.parse(argumentsJson);
|
|
4517
|
+
if (typeof parsed !== "object" || parsed === null) return false;
|
|
4518
|
+
command = parsed.command;
|
|
4519
|
+
} catch {
|
|
4520
|
+
return false;
|
|
4521
|
+
}
|
|
4522
|
+
return typeof command === "string" && isAgentComputerCommand(command);
|
|
4523
|
+
}
|
|
4524
|
+
var LAUNCH_SUCCESS_MARKER = "\u5DF2\u542F\u52A8 ";
|
|
4525
|
+
function resultContainsLaunchSuccessMarker(result, depth = 0) {
|
|
4526
|
+
if (depth > 2) return false;
|
|
4527
|
+
if (typeof result === "string") {
|
|
4528
|
+
if (result.includes(LAUNCH_SUCCESS_MARKER)) return true;
|
|
4529
|
+
try {
|
|
4530
|
+
return resultContainsLaunchSuccessMarker(JSON.parse(result), depth + 1);
|
|
4531
|
+
} catch {
|
|
4532
|
+
return false;
|
|
4533
|
+
}
|
|
4534
|
+
}
|
|
4535
|
+
if (typeof result === "object" && result !== null) {
|
|
4536
|
+
for (const value of Object.values(result)) {
|
|
4537
|
+
if (typeof value === "string" && value.includes(LAUNCH_SUCCESS_MARKER)) return true;
|
|
4538
|
+
}
|
|
4539
|
+
}
|
|
4540
|
+
return false;
|
|
4541
|
+
}
|
|
4542
|
+
function classifyAgentComputerLaunchOutcome(toolCall) {
|
|
4543
|
+
if (toolCall.status === "error" || toolCall.status === "cancelled") return "failed";
|
|
4544
|
+
if (toolCall.status !== "done") return "pending";
|
|
4545
|
+
if (toolCall.result === void 0 || toolCall.result === null) return "unknown";
|
|
4546
|
+
return resultContainsLaunchSuccessMarker(toolCall.result) ? "succeeded" : "failed";
|
|
4555
4547
|
}
|
|
4556
4548
|
|
|
4557
4549
|
// src/index.ts
|
|
@@ -4565,6 +4557,9 @@ export {
|
|
|
4565
4557
|
MarkdownContent,
|
|
4566
4558
|
ReplayBar,
|
|
4567
4559
|
ReplayMismatchPrompt,
|
|
4560
|
+
classifyAgentComputerLaunchOutcome,
|
|
4561
|
+
isAgentComputerCommand,
|
|
4562
|
+
isAgentComputerToolCall,
|
|
4568
4563
|
useAgentSession,
|
|
4569
4564
|
useBladeClient,
|
|
4570
4565
|
useLlmChat,
|