@blade-hq/agent-react 2610.0.0-beta.15 → 2610.0.0-beta.17
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 +2 -0
- package/dist/components/ContextCard.d.ts +7 -0
- package/dist/components/display-utils.d.ts +7 -0
- package/dist/embed/entry.d.ts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +257 -127
- package/dist/index.js.map +1 -1
- package/dist/style.css +61 -0
- package/dist/style.full.css +62 -1
- package/package.json +2 -2
- package/public-api.md +87 -2
package/dist/index.js
CHANGED
|
@@ -1588,6 +1588,17 @@ function getStringArgValue(args, key) {
|
|
|
1588
1588
|
const value = args?.[key];
|
|
1589
1589
|
return typeof value === "string" ? value.trim() : "";
|
|
1590
1590
|
}
|
|
1591
|
+
var SKILL_ENTRY_FILE_NAMES = /* @__PURE__ */ new Set(["skill.md", "command.md"]);
|
|
1592
|
+
var NON_SKILL_DIR_NAMES = /* @__PURE__ */ new Set([".", "..", ".agent", ".agents", ".claude", "skill_data", "skills"]);
|
|
1593
|
+
function getSkillNameFromFilePath(filePath) {
|
|
1594
|
+
if (!filePath) return null;
|
|
1595
|
+
const segments = filePath.split(/[\\/]+/).filter(Boolean);
|
|
1596
|
+
const fileName = segments.pop();
|
|
1597
|
+
if (!fileName || !SKILL_ENTRY_FILE_NAMES.has(fileName.toLowerCase())) return null;
|
|
1598
|
+
const dirName = segments.pop();
|
|
1599
|
+
if (!dirName || NON_SKILL_DIR_NAMES.has(dirName.toLowerCase())) return null;
|
|
1600
|
+
return dirName;
|
|
1601
|
+
}
|
|
1591
1602
|
function formatToolName(name) {
|
|
1592
1603
|
const trimmed = name.trim();
|
|
1593
1604
|
if (!trimmed) return name;
|
|
@@ -1612,6 +1623,12 @@ function getToolDisplayLabel(toolCall) {
|
|
|
1612
1623
|
const skillName = getStringArgValue(args, "skill") || getStringArgValue(args, "skill_name");
|
|
1613
1624
|
return skillName ? `${baseLabel}\u300C${skillName}\u300D` : baseLabel;
|
|
1614
1625
|
}
|
|
1626
|
+
if (normalized === "Read") {
|
|
1627
|
+
const skillName = getSkillNameFromFilePath(
|
|
1628
|
+
getStringArgValue(args, "file_path") || getStringArgValue(args, "path")
|
|
1629
|
+
);
|
|
1630
|
+
if (skillName) return `\u8BFB\u53D6\u6280\u80FD\u300C${skillName}\u300D`;
|
|
1631
|
+
}
|
|
1615
1632
|
if (normalized === "FinishTask") {
|
|
1616
1633
|
const title = getStringArgValue(args, "title");
|
|
1617
1634
|
return title ? `${baseLabel}\uFF1A${title}` : baseLabel;
|
|
@@ -1858,6 +1875,7 @@ function AskUserQuestionBlock({
|
|
|
1858
1875
|
const [selections, setSelections] = useState8(/* @__PURE__ */ new Map());
|
|
1859
1876
|
const [customTexts, setCustomTexts] = useState8(/* @__PURE__ */ new Map());
|
|
1860
1877
|
const [usingCustom, setUsingCustom] = useState8(/* @__PURE__ */ new Set());
|
|
1878
|
+
const [note, setNote] = useState8("");
|
|
1861
1879
|
const [submitted, setSubmitted] = useState8(false);
|
|
1862
1880
|
useEffect6(() => {
|
|
1863
1881
|
if (sessionStatus === "failed" || sessionStatus === "interrupted") {
|
|
@@ -1866,7 +1884,7 @@ function AskUserQuestionBlock({
|
|
|
1866
1884
|
}, [sessionStatus]);
|
|
1867
1885
|
const displayAnswerState = useMemo6(() => {
|
|
1868
1886
|
if (!(answered && answerData)) {
|
|
1869
|
-
return { selections, customTexts, usingCustom };
|
|
1887
|
+
return { selections, customTexts, usingCustom, note };
|
|
1870
1888
|
}
|
|
1871
1889
|
const nextSelections = /* @__PURE__ */ new Map();
|
|
1872
1890
|
const nextCustomTexts = /* @__PURE__ */ new Map();
|
|
@@ -1882,9 +1900,10 @@ function AskUserQuestionBlock({
|
|
|
1882
1900
|
return {
|
|
1883
1901
|
selections: nextSelections,
|
|
1884
1902
|
customTexts: nextCustomTexts,
|
|
1885
|
-
usingCustom: nextUsingCustom
|
|
1903
|
+
usingCustom: nextUsingCustom,
|
|
1904
|
+
note: answerData.note ?? ""
|
|
1886
1905
|
};
|
|
1887
|
-
}, [answerData, answered, customTexts, selections, usingCustom]);
|
|
1906
|
+
}, [answerData, answered, customTexts, note, selections, usingCustom]);
|
|
1888
1907
|
const toggleOption = (qIdx, optIdx, multi) => {
|
|
1889
1908
|
if (answered || submitted) return;
|
|
1890
1909
|
setSelections((prev) => {
|
|
@@ -1932,6 +1951,7 @@ function AskUserQuestionBlock({
|
|
|
1932
1951
|
const allAnswered = data.questions.every((_, i) => getAnswer(i) !== null);
|
|
1933
1952
|
const handleSubmit = () => {
|
|
1934
1953
|
if (answered || submitted || !allAnswered || !onAnswer) return;
|
|
1954
|
+
const trimmedNote = note.trim();
|
|
1935
1955
|
const nextAnswerData = {
|
|
1936
1956
|
selections: Object.fromEntries(
|
|
1937
1957
|
Array.from(selections.entries()).map(([qIdx, optionIndexes]) => [
|
|
@@ -1941,13 +1961,17 @@ function AskUserQuestionBlock({
|
|
|
1941
1961
|
),
|
|
1942
1962
|
custom: Object.fromEntries(
|
|
1943
1963
|
Array.from(usingCustom).map((qIdx) => [qIdx, (customTexts.get(qIdx) ?? "").trim()]).filter(([, text2]) => text2.length > 0)
|
|
1944
|
-
)
|
|
1964
|
+
),
|
|
1965
|
+
...trimmedNote ? { note: trimmedNote } : {}
|
|
1945
1966
|
};
|
|
1946
1967
|
const parts = data.questions.map(
|
|
1947
1968
|
(q, i) => `- ${q.question} -> ${indentAnswerContinuationLines(getAnswer(i) ?? "")}`
|
|
1948
1969
|
);
|
|
1949
|
-
const text =
|
|
1950
|
-
|
|
1970
|
+
const text = [
|
|
1971
|
+
`\u5173\u4E8E\u9700\u8981\u786E\u8BA4\u7684\u95EE\u9898\uFF0C\u7528\u6237\u7684\u56DE\u7B54\u5982\u4E0B\uFF1A
|
|
1972
|
+
${parts.join("\n")}`,
|
|
1973
|
+
trimmedNote ? `\u8865\u5145\u8BF4\u660E\uFF1A${indentAnswerContinuationLines(trimmedNote)}` : ""
|
|
1974
|
+
].filter(Boolean).join("\n");
|
|
1951
1975
|
setSubmitted(true);
|
|
1952
1976
|
onAnswer(text, toolCallId, nextAnswerData);
|
|
1953
1977
|
};
|
|
@@ -1979,6 +2003,15 @@ ${parts.join("\n")}`;
|
|
|
1979
2003
|
},
|
|
1980
2004
|
q.question
|
|
1981
2005
|
)),
|
|
2006
|
+
/* @__PURE__ */ jsx9(
|
|
2007
|
+
NoteField,
|
|
2008
|
+
{
|
|
2009
|
+
answered,
|
|
2010
|
+
submitted,
|
|
2011
|
+
note: displayAnswerState.note,
|
|
2012
|
+
onChange: setNote
|
|
2013
|
+
}
|
|
2014
|
+
),
|
|
1982
2015
|
!answered && !submitted && onAnswer && /* @__PURE__ */ jsx9(
|
|
1983
2016
|
"button",
|
|
1984
2017
|
{
|
|
@@ -2124,6 +2157,49 @@ function QuestionCard({
|
|
|
2124
2157
|
] })
|
|
2125
2158
|
] });
|
|
2126
2159
|
}
|
|
2160
|
+
function NoteField({
|
|
2161
|
+
answered,
|
|
2162
|
+
submitted,
|
|
2163
|
+
note,
|
|
2164
|
+
onChange
|
|
2165
|
+
}) {
|
|
2166
|
+
const textareaRef = useAutoResizeTextarea(note);
|
|
2167
|
+
const readOnly = answered || submitted;
|
|
2168
|
+
if (answered && !note.trim()) return null;
|
|
2169
|
+
return /* @__PURE__ */ jsxs7(
|
|
2170
|
+
"label",
|
|
2171
|
+
{
|
|
2172
|
+
className: cn(
|
|
2173
|
+
"block rounded-lg border transition-all focus-within:ring-2 focus-within:ring-[hsl(var(--ring)/0.35)]",
|
|
2174
|
+
answered ? "px-2.5 py-1.5" : "px-3 py-2.5",
|
|
2175
|
+
note.trim() ? "border-[hsl(var(--ring)/0.6)] bg-[hsl(var(--accent))]" : "border-[hsl(var(--border))] hover:border-[hsl(var(--ring)/0.3)] hover:bg-[hsl(var(--accent))]",
|
|
2176
|
+
readOnly && "cursor-default opacity-70"
|
|
2177
|
+
),
|
|
2178
|
+
children: [
|
|
2179
|
+
/* @__PURE__ */ jsx9("span", { className: "mb-1.5 block text-xs text-[hsl(var(--muted-foreground))]", children: "\u8865\u5145\u8BF4\u660E\uFF08\u53EF\u9009\uFF09" }),
|
|
2180
|
+
/* @__PURE__ */ jsx9(
|
|
2181
|
+
"textarea",
|
|
2182
|
+
{
|
|
2183
|
+
ref: textareaRef,
|
|
2184
|
+
rows: 2,
|
|
2185
|
+
value: note,
|
|
2186
|
+
readOnly,
|
|
2187
|
+
onChange: (event) => {
|
|
2188
|
+
if (readOnly) return;
|
|
2189
|
+
onChange(event.target.value);
|
|
2190
|
+
},
|
|
2191
|
+
"aria-label": "\u8865\u5145\u8BF4\u660E",
|
|
2192
|
+
placeholder: "\u9009\u5B8C\u8FD8\u53EF\u4EE5\u518D\u8BB2\u4E24\u53E5\uFF0C\u7A7A\u7740\u5C31\u5F53\u6CA1\u6709",
|
|
2193
|
+
className: cn(
|
|
2194
|
+
"min-h-10 w-full resize-none bg-transparent leading-5 text-[hsl(var(--foreground))] outline-none placeholder:text-[hsl(var(--muted-foreground)/0.5)]",
|
|
2195
|
+
answered ? "text-xs" : "text-sm"
|
|
2196
|
+
)
|
|
2197
|
+
}
|
|
2198
|
+
)
|
|
2199
|
+
]
|
|
2200
|
+
}
|
|
2201
|
+
);
|
|
2202
|
+
}
|
|
2127
2203
|
function parseAskUserQuestion(toolResult) {
|
|
2128
2204
|
if (!toolResult) return null;
|
|
2129
2205
|
try {
|
|
@@ -2391,9 +2467,49 @@ function AssistantTurnBlock({
|
|
|
2391
2467
|
] });
|
|
2392
2468
|
}
|
|
2393
2469
|
|
|
2470
|
+
// src/components/ContextCard.tsx
|
|
2471
|
+
import {
|
|
2472
|
+
getContextDisplayState
|
|
2473
|
+
} from "@blade-hq/agent-client";
|
|
2474
|
+
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2475
|
+
function ContextCard({ context, className }) {
|
|
2476
|
+
const display = getContextDisplayState(context);
|
|
2477
|
+
return /* @__PURE__ */ jsxs10(
|
|
2478
|
+
"details",
|
|
2479
|
+
{
|
|
2480
|
+
className: `blade-chat-context-card group rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] text-sm ${className ?? ""}`,
|
|
2481
|
+
children: [
|
|
2482
|
+
/* @__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: [
|
|
2483
|
+
/* @__PURE__ */ jsx12(
|
|
2484
|
+
Layers,
|
|
2485
|
+
{
|
|
2486
|
+
size: 15,
|
|
2487
|
+
className: "blade-chat-context-icon shrink-0 text-[hsl(var(--muted-foreground))]",
|
|
2488
|
+
"aria-hidden": "true"
|
|
2489
|
+
}
|
|
2490
|
+
),
|
|
2491
|
+
/* @__PURE__ */ jsxs10("span", { className: "blade-chat-context-copy min-w-0 flex-1", children: [
|
|
2492
|
+
/* @__PURE__ */ jsx12("span", { className: "blade-chat-context-title block font-medium text-[hsl(var(--foreground))]", children: display.title }),
|
|
2493
|
+
/* @__PURE__ */ jsx12("span", { className: "blade-chat-context-status block truncate text-xs text-[hsl(var(--muted-foreground))]", children: display.summary })
|
|
2494
|
+
] }),
|
|
2495
|
+
/* @__PURE__ */ jsx12(
|
|
2496
|
+
ChevronDown,
|
|
2497
|
+
{
|
|
2498
|
+
size: 14,
|
|
2499
|
+
className: "blade-chat-context-chevron shrink-0 text-[hsl(var(--muted-foreground))] transition-transform group-open:rotate-180",
|
|
2500
|
+
"aria-hidden": "true"
|
|
2501
|
+
}
|
|
2502
|
+
)
|
|
2503
|
+
] }),
|
|
2504
|
+
/* @__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 })
|
|
2505
|
+
]
|
|
2506
|
+
}
|
|
2507
|
+
);
|
|
2508
|
+
}
|
|
2509
|
+
|
|
2394
2510
|
// src/components/RenderErrorBoundary.tsx
|
|
2395
2511
|
import { Component } from "react";
|
|
2396
|
-
import { jsx as
|
|
2512
|
+
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2397
2513
|
function getFirstComponentName(componentStack) {
|
|
2398
2514
|
const match = componentStack.match(/\n\s+at\s+([^\s(]+)/);
|
|
2399
2515
|
return match?.[1] ?? null;
|
|
@@ -2426,18 +2542,18 @@ var RenderErrorBoundary = class extends Component {
|
|
|
2426
2542
|
return children;
|
|
2427
2543
|
}
|
|
2428
2544
|
const componentName = getFirstComponentName(componentStack);
|
|
2429
|
-
return /* @__PURE__ */
|
|
2430
|
-
/* @__PURE__ */
|
|
2431
|
-
/* @__PURE__ */
|
|
2432
|
-
/* @__PURE__ */
|
|
2545
|
+
return /* @__PURE__ */ jsx13("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__ */ jsxs11("div", { className: "flex items-start gap-2", children: [
|
|
2546
|
+
/* @__PURE__ */ jsx13(TriangleAlert, { className: "mt-0.5 h-4 w-4 shrink-0 text-amber-300" }),
|
|
2547
|
+
/* @__PURE__ */ jsxs11("div", { className: "min-w-0 flex-1", children: [
|
|
2548
|
+
/* @__PURE__ */ jsxs11("div", { className: "font-medium", children: [
|
|
2433
2549
|
label,
|
|
2434
2550
|
"\u6E32\u67D3\u5931\u8D25"
|
|
2435
2551
|
] }),
|
|
2436
|
-
/* @__PURE__ */
|
|
2552
|
+
/* @__PURE__ */ jsxs11("div", { className: "mt-1 break-words text-xs leading-5 text-amber-100/75", children: [
|
|
2437
2553
|
componentName ? `\u7EC4\u4EF6\uFF1A${componentName}\u3002` : null,
|
|
2438
2554
|
error.message || "\u53D1\u751F\u4E86\u672A\u9884\u671F\u7684\u6E32\u67D3\u9519\u8BEF\u3002"
|
|
2439
2555
|
] }),
|
|
2440
|
-
details ? /* @__PURE__ */
|
|
2556
|
+
details ? /* @__PURE__ */ jsx13("div", { className: "mt-1 truncate text-xs text-amber-100/55", children: details }) : null
|
|
2441
2557
|
] })
|
|
2442
2558
|
] }) });
|
|
2443
2559
|
}
|
|
@@ -2445,7 +2561,7 @@ var RenderErrorBoundary = class extends Component {
|
|
|
2445
2561
|
|
|
2446
2562
|
// src/components/PostChatFollowupBlock.tsx
|
|
2447
2563
|
import { useCallback as useCallback5, useEffect as useEffect7, useRef as useRef8, useState as useState11 } from "react";
|
|
2448
|
-
import { Fragment as Fragment2, jsx as
|
|
2564
|
+
import { Fragment as Fragment2, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2449
2565
|
function emitInteraction(callback, event) {
|
|
2450
2566
|
try {
|
|
2451
2567
|
callback?.(event);
|
|
@@ -2467,7 +2583,7 @@ function ArtifactCard({
|
|
|
2467
2583
|
const [downloading, setDownloading] = useState11(false);
|
|
2468
2584
|
const name = artifact.label || basename(artifact.target);
|
|
2469
2585
|
if (artifact.kind === "link") {
|
|
2470
|
-
return /* @__PURE__ */
|
|
2586
|
+
return /* @__PURE__ */ jsxs12(
|
|
2471
2587
|
"a",
|
|
2472
2588
|
{
|
|
2473
2589
|
href: artifact.target,
|
|
@@ -2478,9 +2594,9 @@ function ArtifactCard({
|
|
|
2478
2594
|
${artifact.target}`,
|
|
2479
2595
|
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))]",
|
|
2480
2596
|
children: [
|
|
2481
|
-
/* @__PURE__ */
|
|
2482
|
-
/* @__PURE__ */
|
|
2483
|
-
/* @__PURE__ */
|
|
2597
|
+
/* @__PURE__ */ jsx14(Globe, { size: 15, className: "shrink-0 text-[hsl(var(--primary))]" }),
|
|
2598
|
+
/* @__PURE__ */ jsx14("span", { className: "min-w-0 flex-1 truncate font-medium", children: name }),
|
|
2599
|
+
/* @__PURE__ */ jsx14(ArrowUpRight, { size: 13, className: "absolute right-2 opacity-0 group-hover:opacity-100 group-focus-visible:opacity-100" })
|
|
2484
2600
|
]
|
|
2485
2601
|
}
|
|
2486
2602
|
);
|
|
@@ -2515,7 +2631,7 @@ ${artifact.target}`,
|
|
|
2515
2631
|
setDownloading(false);
|
|
2516
2632
|
}
|
|
2517
2633
|
};
|
|
2518
|
-
return /* @__PURE__ */
|
|
2634
|
+
return /* @__PURE__ */ jsx14(
|
|
2519
2635
|
"a",
|
|
2520
2636
|
{
|
|
2521
2637
|
href: downloadUrl,
|
|
@@ -2543,17 +2659,17 @@ function feedbackReasonLabel(reason) {
|
|
|
2543
2659
|
}
|
|
2544
2660
|
function HistoricalResultFeedback({ feedback }) {
|
|
2545
2661
|
const label = feedbackReasonLabel(feedback.reason);
|
|
2546
|
-
return /* @__PURE__ */
|
|
2662
|
+
return /* @__PURE__ */ jsxs12(
|
|
2547
2663
|
"section",
|
|
2548
2664
|
{
|
|
2549
2665
|
"aria-label": "\u5386\u53F2\u7ED3\u679C\u53CD\u9988",
|
|
2550
2666
|
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))]",
|
|
2551
2667
|
children: [
|
|
2552
|
-
/* @__PURE__ */
|
|
2668
|
+
/* @__PURE__ */ jsxs12("span", { children: [
|
|
2553
2669
|
"\u4F60\u5BF9\u6B64\u8F6E\u7ED3\u679C\u7684\u8BC4\u4EF7\uFF1A",
|
|
2554
2670
|
feedback.helpful ? "\u6709\u5E2E\u52A9" : "\u6CA1\u5E2E\u52A9"
|
|
2555
2671
|
] }),
|
|
2556
|
-
label ? /* @__PURE__ */
|
|
2672
|
+
label ? /* @__PURE__ */ jsxs12("span", { children: [
|
|
2557
2673
|
" \xB7 ",
|
|
2558
2674
|
label
|
|
2559
2675
|
] }) : null
|
|
@@ -2628,15 +2744,15 @@ function ResultFeedback({
|
|
|
2628
2744
|
[client, followup.assistant_entry_id, onFeedbackSaved, onInteraction, sessionId]
|
|
2629
2745
|
);
|
|
2630
2746
|
if (!eligible) return null;
|
|
2631
|
-
return /* @__PURE__ */
|
|
2747
|
+
return /* @__PURE__ */ jsxs12(
|
|
2632
2748
|
"section",
|
|
2633
2749
|
{
|
|
2634
2750
|
"aria-label": "\u7ED3\u679C\u53CD\u9988",
|
|
2635
2751
|
className: "flex flex-col gap-2 border-t border-[hsl(var(--border))] pt-3",
|
|
2636
2752
|
children: [
|
|
2637
|
-
/* @__PURE__ */
|
|
2638
|
-
/* @__PURE__ */
|
|
2639
|
-
/* @__PURE__ */
|
|
2753
|
+
/* @__PURE__ */ jsx14("div", { className: "text-xs font-medium text-[hsl(var(--muted-foreground))]", children: "\u76EE\u524D\u7684\u6574\u4F53\u7ED3\u679C\u6709\u5E2E\u52A9\u5417\uFF1F" }),
|
|
2754
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex flex-wrap gap-1.5", children: [
|
|
2755
|
+
/* @__PURE__ */ jsx14(
|
|
2640
2756
|
"button",
|
|
2641
2757
|
{
|
|
2642
2758
|
type: "button",
|
|
@@ -2647,7 +2763,7 @@ function ResultFeedback({
|
|
|
2647
2763
|
children: "\u6709\u5E2E\u52A9"
|
|
2648
2764
|
}
|
|
2649
2765
|
),
|
|
2650
|
-
/* @__PURE__ */
|
|
2766
|
+
/* @__PURE__ */ jsx14(
|
|
2651
2767
|
"button",
|
|
2652
2768
|
{
|
|
2653
2769
|
type: "button",
|
|
@@ -2659,7 +2775,7 @@ function ResultFeedback({
|
|
|
2659
2775
|
}
|
|
2660
2776
|
)
|
|
2661
2777
|
] }),
|
|
2662
|
-
helpful === false ? /* @__PURE__ */
|
|
2778
|
+
helpful === false ? /* @__PURE__ */ jsx14("div", { className: "flex flex-wrap gap-1.5", "aria-label": "\u6CA1\u5E2E\u52A9\u7684\u4E3B\u8981\u539F\u56E0", children: FEEDBACK_REASONS.map((item) => /* @__PURE__ */ jsx14(
|
|
2663
2779
|
"button",
|
|
2664
2780
|
{
|
|
2665
2781
|
type: "button",
|
|
@@ -2671,9 +2787,9 @@ function ResultFeedback({
|
|
|
2671
2787
|
},
|
|
2672
2788
|
item.value
|
|
2673
2789
|
)) }) : null,
|
|
2674
|
-
saveError ? /* @__PURE__ */
|
|
2675
|
-
/* @__PURE__ */
|
|
2676
|
-
/* @__PURE__ */
|
|
2790
|
+
saveError ? /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2 text-xs text-[hsl(var(--destructive))]", children: [
|
|
2791
|
+
/* @__PURE__ */ jsx14("span", { children: "\u53CD\u9988\u6682\u672A\u4FDD\u5B58\uFF0C\u53EF\u91CD\u8BD5" }),
|
|
2792
|
+
/* @__PURE__ */ jsx14(
|
|
2677
2793
|
"button",
|
|
2678
2794
|
{
|
|
2679
2795
|
type: "button",
|
|
@@ -2685,7 +2801,7 @@ function ResultFeedback({
|
|
|
2685
2801
|
children: "\u91CD\u8BD5"
|
|
2686
2802
|
}
|
|
2687
2803
|
)
|
|
2688
|
-
] }) : saved ? /* @__PURE__ */
|
|
2804
|
+
] }) : saved ? /* @__PURE__ */ jsx14("div", { className: "text-[11px] text-[hsl(var(--muted-foreground))]", children: "\u5DF2\u4FDD\u5B58\uFF0C\u53EF\u968F\u65F6\u4FEE\u6539" }) : null
|
|
2689
2805
|
]
|
|
2690
2806
|
}
|
|
2691
2807
|
);
|
|
@@ -2752,15 +2868,15 @@ function PostChatFollowupBlock({
|
|
|
2752
2868
|
);
|
|
2753
2869
|
if (!followup.recaption && artifacts.length === 0 && followup.suggestions.length === 0 && !followup.feedback_eligible)
|
|
2754
2870
|
return null;
|
|
2755
|
-
return /* @__PURE__ */
|
|
2756
|
-
followup.recaption || artifacts.length > 0 ? /* @__PURE__ */
|
|
2757
|
-
/* @__PURE__ */
|
|
2758
|
-
/* @__PURE__ */
|
|
2871
|
+
return /* @__PURE__ */ jsxs12("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: [
|
|
2872
|
+
followup.recaption || artifacts.length > 0 ? /* @__PURE__ */ jsxs12("section", { "aria-label": "\u672C\u8F6E\u5C0F\u7ED3", className: "flex flex-col gap-2", children: [
|
|
2873
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-1.5 text-xs font-medium text-[hsl(var(--muted-foreground))]", children: [
|
|
2874
|
+
/* @__PURE__ */ jsx14(Sparkles, { size: 14 }),
|
|
2759
2875
|
"\u672C\u8F6E\u5C0F\u7ED3"
|
|
2760
2876
|
] }),
|
|
2761
|
-
followup.recaption ? /* @__PURE__ */
|
|
2762
|
-
artifacts.length > 0 ? /* @__PURE__ */
|
|
2763
|
-
/* @__PURE__ */
|
|
2877
|
+
followup.recaption ? /* @__PURE__ */ jsx14("p", { className: "text-[13px] leading-5", children: followup.recaption }) : null,
|
|
2878
|
+
artifacts.length > 0 ? /* @__PURE__ */ jsxs12(Fragment2, { children: [
|
|
2879
|
+
/* @__PURE__ */ jsx14("div", { className: "grid max-w-full grid-cols-3 gap-1.5", children: visibleArtifacts.map((artifact, artifactIndex) => /* @__PURE__ */ jsx14(
|
|
2764
2880
|
ArtifactCard,
|
|
2765
2881
|
{
|
|
2766
2882
|
artifact,
|
|
@@ -2772,7 +2888,7 @@ function PostChatFollowupBlock({
|
|
|
2772
2888
|
},
|
|
2773
2889
|
`${artifact.kind}:${artifactIndex}`
|
|
2774
2890
|
)) }),
|
|
2775
|
-
artifacts.length > 3 ? /* @__PURE__ */
|
|
2891
|
+
artifacts.length > 3 ? /* @__PURE__ */ jsxs12(
|
|
2776
2892
|
"button",
|
|
2777
2893
|
{
|
|
2778
2894
|
type: "button",
|
|
@@ -2781,15 +2897,15 @@ function PostChatFollowupBlock({
|
|
|
2781
2897
|
className: "flex w-fit items-center gap-0.5 text-[11px] text-[hsl(var(--muted-foreground))]",
|
|
2782
2898
|
children: [
|
|
2783
2899
|
expanded ? "\u6536\u8D77" : `\u5C55\u5F00 ${artifacts.length - 3} \u4E2A`,
|
|
2784
|
-
/* @__PURE__ */
|
|
2900
|
+
/* @__PURE__ */ jsx14(ChevronDown, { size: 13, className: expanded ? "rotate-180" : void 0 })
|
|
2785
2901
|
]
|
|
2786
2902
|
}
|
|
2787
2903
|
) : null
|
|
2788
2904
|
] }) : null
|
|
2789
2905
|
] }) : null,
|
|
2790
|
-
followup.suggestions.length > 0 ? /* @__PURE__ */
|
|
2791
|
-
/* @__PURE__ */
|
|
2792
|
-
followup.suggestions.map((suggestion, suggestionIndex) => /* @__PURE__ */
|
|
2906
|
+
followup.suggestions.length > 0 ? /* @__PURE__ */ jsxs12("section", { "aria-label": "\u4E0B\u4E00\u6B65\u5EFA\u8BAE", className: "flex flex-col gap-1.5", children: [
|
|
2907
|
+
/* @__PURE__ */ jsx14("div", { className: "text-xs font-medium text-[hsl(var(--muted-foreground))]", children: "\u4E0B\u4E00\u6B65\u53EF\u4EE5" }),
|
|
2908
|
+
followup.suggestions.map((suggestion, suggestionIndex) => /* @__PURE__ */ jsxs12(
|
|
2793
2909
|
"button",
|
|
2794
2910
|
{
|
|
2795
2911
|
type: "button",
|
|
@@ -2808,14 +2924,14 @@ function PostChatFollowupBlock({
|
|
|
2808
2924
|
},
|
|
2809
2925
|
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",
|
|
2810
2926
|
children: [
|
|
2811
|
-
/* @__PURE__ */
|
|
2812
|
-
/* @__PURE__ */
|
|
2927
|
+
/* @__PURE__ */ jsx14("span", { children: suggestion }),
|
|
2928
|
+
/* @__PURE__ */ jsx14(ArrowRight, { size: 14, className: "ml-auto shrink-0" })
|
|
2813
2929
|
]
|
|
2814
2930
|
},
|
|
2815
2931
|
suggestion
|
|
2816
2932
|
))
|
|
2817
2933
|
] }) : null,
|
|
2818
|
-
/* @__PURE__ */
|
|
2934
|
+
/* @__PURE__ */ jsx14(
|
|
2819
2935
|
ResultFeedback,
|
|
2820
2936
|
{
|
|
2821
2937
|
followup,
|
|
@@ -2831,7 +2947,7 @@ function PostChatFollowupBlock({
|
|
|
2831
2947
|
|
|
2832
2948
|
// src/components/UserMessageBubble.tsx
|
|
2833
2949
|
import { getFileParts, getImageParts, getTextContent as getTextContent2 } from "@blade-hq/agent-client";
|
|
2834
|
-
import { jsx as
|
|
2950
|
+
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2835
2951
|
function isUserMessage(message) {
|
|
2836
2952
|
return message.role === "user";
|
|
2837
2953
|
}
|
|
@@ -2843,8 +2959,8 @@ function UserMessageBubble({ message, className }) {
|
|
|
2843
2959
|
const text = getTextContent2(message.content).trim();
|
|
2844
2960
|
const fileParts = getFileParts(message.content);
|
|
2845
2961
|
const imageParts = getImageParts(message.content);
|
|
2846
|
-
return /* @__PURE__ */
|
|
2847
|
-
imageParts.length > 0 && /* @__PURE__ */
|
|
2962
|
+
return /* @__PURE__ */ jsx15("div", { className: cn("blade-chat-user-row flex justify-end", className), children: /* @__PURE__ */ jsxs13("div", { className: "blade-chat-user-col flex max-w-[72%] flex-col items-end gap-3", children: [
|
|
2963
|
+
imageParts.length > 0 && /* @__PURE__ */ jsx15("div", { className: "grid gap-2", children: imageParts.map((part) => /* @__PURE__ */ jsx15(
|
|
2848
2964
|
"img",
|
|
2849
2965
|
{
|
|
2850
2966
|
src: part.image_url.url,
|
|
@@ -2853,21 +2969,21 @@ function UserMessageBubble({ message, className }) {
|
|
|
2853
2969
|
},
|
|
2854
2970
|
part.image_url.url
|
|
2855
2971
|
)) }),
|
|
2856
|
-
fileParts.length > 0 && /* @__PURE__ */
|
|
2972
|
+
fileParts.length > 0 && /* @__PURE__ */ jsx15("div", { className: "flex flex-col items-end gap-1.5", children: fileParts.map((part) => /* @__PURE__ */ jsxs13(
|
|
2857
2973
|
"div",
|
|
2858
2974
|
{
|
|
2859
2975
|
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))]",
|
|
2860
2976
|
children: [
|
|
2861
|
-
/* @__PURE__ */
|
|
2862
|
-
/* @__PURE__ */
|
|
2977
|
+
/* @__PURE__ */ jsx15(FileText, { size: 12, className: "shrink-0" }),
|
|
2978
|
+
/* @__PURE__ */ jsx15("span", { className: "max-w-56 truncate", title: part.name, children: part.name })
|
|
2863
2979
|
]
|
|
2864
2980
|
},
|
|
2865
2981
|
`${part.name}-${part.data.length}`
|
|
2866
2982
|
)) }),
|
|
2867
|
-
text && /* @__PURE__ */
|
|
2868
|
-
text && isSending(message) && /* @__PURE__ */
|
|
2869
|
-
/* @__PURE__ */
|
|
2870
|
-
/* @__PURE__ */
|
|
2983
|
+
text && /* @__PURE__ */ jsx15("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__ */ jsx15(MarkdownContent, { className: "blade-chat-prose", children: text }) }),
|
|
2984
|
+
text && isSending(message) && /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-1 pr-1 text-[11px] font-medium text-[hsl(var(--muted-foreground))/0.85]", children: [
|
|
2985
|
+
/* @__PURE__ */ jsx15(LoaderCircle, { size: 11, className: "animate-spin", "aria-hidden": "true" }),
|
|
2986
|
+
/* @__PURE__ */ jsx15("span", { children: "\u53D1\u9001\u4E2D" })
|
|
2871
2987
|
] })
|
|
2872
2988
|
] }) });
|
|
2873
2989
|
}
|
|
@@ -2876,11 +2992,11 @@ function ErrorMessageBlock({
|
|
|
2876
2992
|
className
|
|
2877
2993
|
}) {
|
|
2878
2994
|
const text = getTextContent2(message.content);
|
|
2879
|
-
return /* @__PURE__ */
|
|
2995
|
+
return /* @__PURE__ */ jsx15("div", { className: cn("blade-chat-error-row flex justify-center", className), children: /* @__PURE__ */ jsx15("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 }) });
|
|
2880
2996
|
}
|
|
2881
2997
|
|
|
2882
2998
|
// src/components/MessageList.tsx
|
|
2883
|
-
import { jsx as
|
|
2999
|
+
import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2884
3000
|
function parseModeChange(message) {
|
|
2885
3001
|
if (message.kind !== "mode_change" || typeof message.content !== "string") {
|
|
2886
3002
|
return null;
|
|
@@ -2933,6 +3049,7 @@ function MessageList({
|
|
|
2933
3049
|
const visible = messages.filter((message) => {
|
|
2934
3050
|
if ((message.loop_name ?? "root") !== "root") return false;
|
|
2935
3051
|
if (isHiddenInternalMessage(message)) return false;
|
|
3052
|
+
if (message.kind === "context") return Boolean(message.context);
|
|
2936
3053
|
if (message.kind === "compaction") return true;
|
|
2937
3054
|
return message.role !== "tool" || getPlanningDividerKind(message) !== null;
|
|
2938
3055
|
});
|
|
@@ -2967,6 +3084,15 @@ function MessageList({
|
|
|
2967
3084
|
blocks.push({ type: "compaction", key: message.entry_id ?? `compaction-${blocks.length}` });
|
|
2968
3085
|
continue;
|
|
2969
3086
|
}
|
|
3087
|
+
if (message.kind === "context" && message.context) {
|
|
3088
|
+
flushAssistant();
|
|
3089
|
+
blocks.push({
|
|
3090
|
+
type: "context",
|
|
3091
|
+
message,
|
|
3092
|
+
key: message.entry_id ?? `context-${blocks.length}`
|
|
3093
|
+
});
|
|
3094
|
+
continue;
|
|
3095
|
+
}
|
|
2970
3096
|
if (message.role === "assistant") {
|
|
2971
3097
|
assistantBuffer.push(message);
|
|
2972
3098
|
continue;
|
|
@@ -3002,15 +3128,15 @@ function MessageList({
|
|
|
3002
3128
|
}
|
|
3003
3129
|
return blocks;
|
|
3004
3130
|
}, [messages, isStreaming]);
|
|
3005
|
-
return /* @__PURE__ */
|
|
3006
|
-
/* @__PURE__ */
|
|
3007
|
-
renderBlocks.length === 0 ? emptyState ?? /* @__PURE__ */
|
|
3008
|
-
/* @__PURE__ */
|
|
3009
|
-
/* @__PURE__ */
|
|
3010
|
-
/* @__PURE__ */
|
|
3131
|
+
return /* @__PURE__ */ jsx16("div", { className: cn("blade-chat-messages relative min-h-0 flex-1", className), children: /* @__PURE__ */ jsxs14(StickToBottom, { className: "h-full overflow-y-hidden", initial: "instant", resize: "instant", children: [
|
|
3132
|
+
/* @__PURE__ */ jsx16(StickToBottom.Content, { className: "blade-chat-messages-scroll", children: /* @__PURE__ */ jsx16("div", { className: "blade-chat-messages-content mx-auto max-w-[748px]", children: /* @__PURE__ */ jsxs14("div", { className: "flex min-w-0 flex-col", children: [
|
|
3133
|
+
renderBlocks.length === 0 ? emptyState ?? /* @__PURE__ */ jsxs14("div", { className: "blade-chat-empty", children: [
|
|
3134
|
+
/* @__PURE__ */ jsx16(MessageSquare, { size: 40, strokeWidth: 1.5 }),
|
|
3135
|
+
/* @__PURE__ */ jsx16("span", { className: "text-base font-medium", children: "\u5F00\u59CB\u5BF9\u8BDD" }),
|
|
3136
|
+
/* @__PURE__ */ jsx16("span", { className: "text-sm opacity-60", children: "\u5728\u4E0B\u65B9\u8F93\u5165\u6D88\u606F\u5F00\u59CB\u804A\u5929" })
|
|
3011
3137
|
] }) : renderBlocks.map((block) => {
|
|
3012
3138
|
if (block.type === "message") {
|
|
3013
|
-
return /* @__PURE__ */
|
|
3139
|
+
return /* @__PURE__ */ jsx16("div", { "data-entry-id": block.message.entry_id, children: isUserMessage(block.message) ? /* @__PURE__ */ jsx16(UserMessageBubble, { message: block.message }) : isErrorMessage(block.message) ? /* @__PURE__ */ jsx16(ErrorMessageBlock, { message: block.message }) : null }, block.key);
|
|
3014
3140
|
}
|
|
3015
3141
|
if (block.type === "assistant_turn") {
|
|
3016
3142
|
const blockFeedback = block.messages.map(
|
|
@@ -3021,14 +3147,14 @@ function MessageList({
|
|
|
3021
3147
|
(message) => message.entry_id === postChatFollowup.assistant_entry_id
|
|
3022
3148
|
)
|
|
3023
3149
|
);
|
|
3024
|
-
return /* @__PURE__ */
|
|
3150
|
+
return /* @__PURE__ */ jsx16("div", { "data-entry-id": block.messages[0]?.entry_id, children: /* @__PURE__ */ jsxs14(
|
|
3025
3151
|
RenderErrorBoundary,
|
|
3026
3152
|
{
|
|
3027
3153
|
label: "\u52A9\u624B\u6D88\u606F",
|
|
3028
3154
|
details: block.key,
|
|
3029
3155
|
resetKey: getMessageResetSignature(block.messages),
|
|
3030
3156
|
children: [
|
|
3031
|
-
/* @__PURE__ */
|
|
3157
|
+
/* @__PURE__ */ jsx16(
|
|
3032
3158
|
AssistantTurnBlock,
|
|
3033
3159
|
{
|
|
3034
3160
|
messages: block.messages,
|
|
@@ -3040,8 +3166,8 @@ function MessageList({
|
|
|
3040
3166
|
sessionId
|
|
3041
3167
|
}
|
|
3042
3168
|
),
|
|
3043
|
-
blockFeedback && !hasActiveFollowup ? /* @__PURE__ */
|
|
3044
|
-
hasActiveFollowup && postChatFollowup ? /* @__PURE__ */
|
|
3169
|
+
blockFeedback && !hasActiveFollowup ? /* @__PURE__ */ jsx16(HistoricalResultFeedback, { feedback: blockFeedback }) : null,
|
|
3170
|
+
hasActiveFollowup && postChatFollowup ? /* @__PURE__ */ jsx16(
|
|
3045
3171
|
PostChatFollowupBlock,
|
|
3046
3172
|
{
|
|
3047
3173
|
followup: postChatFollowup,
|
|
@@ -3057,25 +3183,28 @@ function MessageList({
|
|
|
3057
3183
|
}
|
|
3058
3184
|
) }, block.key);
|
|
3059
3185
|
}
|
|
3186
|
+
if (block.type === "context") {
|
|
3187
|
+
return /* @__PURE__ */ jsx16("div", { "data-entry-id": block.message.entry_id, children: /* @__PURE__ */ jsx16(ContextCard, { context: block.message.context }) }, block.key);
|
|
3188
|
+
}
|
|
3060
3189
|
if (block.type === "compaction") {
|
|
3061
|
-
return /* @__PURE__ */
|
|
3190
|
+
return /* @__PURE__ */ jsxs14(
|
|
3062
3191
|
"div",
|
|
3063
3192
|
{
|
|
3064
3193
|
className: "flex items-center gap-2 text-xs text-[hsl(var(--muted-foreground))]",
|
|
3065
3194
|
children: [
|
|
3066
|
-
/* @__PURE__ */
|
|
3067
|
-
/* @__PURE__ */
|
|
3195
|
+
/* @__PURE__ */ jsx16(Layers, { size: 12 }),
|
|
3196
|
+
/* @__PURE__ */ jsx16("span", { children: "\u4E0A\u4E0B\u6587\u5DF2\u538B\u7F29" })
|
|
3068
3197
|
]
|
|
3069
3198
|
},
|
|
3070
3199
|
block.key
|
|
3071
3200
|
);
|
|
3072
3201
|
}
|
|
3073
|
-
return /* @__PURE__ */
|
|
3202
|
+
return /* @__PURE__ */ jsx16(PlanningDivider, { kind: block.kind }, block.key);
|
|
3074
3203
|
}),
|
|
3075
|
-
sessionStatus === "interrupted" && !isStreaming ? /* @__PURE__ */
|
|
3204
|
+
sessionStatus === "interrupted" && !isStreaming ? /* @__PURE__ */ jsx16("div", { className: "flex", children: /* @__PURE__ */ jsx16("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
|
|
3076
3205
|
] }) }) }),
|
|
3077
|
-
/* @__PURE__ */
|
|
3078
|
-
/* @__PURE__ */
|
|
3206
|
+
/* @__PURE__ */ jsx16(AutoScrollOnUserSend, { userMessageCount: messages.filter((m) => isUserMessage(m)).length }),
|
|
3207
|
+
/* @__PURE__ */ jsx16(ScrollToBottomButton, {})
|
|
3079
3208
|
] }) });
|
|
3080
3209
|
}
|
|
3081
3210
|
function AutoScrollOnUserSend({ userMessageCount }) {
|
|
@@ -3124,7 +3253,7 @@ function ScrollToBottomButton() {
|
|
|
3124
3253
|
scrollToBottom();
|
|
3125
3254
|
}, [scrollToBottom]);
|
|
3126
3255
|
if (!visible) return null;
|
|
3127
|
-
return /* @__PURE__ */
|
|
3256
|
+
return /* @__PURE__ */ jsxs14(
|
|
3128
3257
|
"button",
|
|
3129
3258
|
{
|
|
3130
3259
|
type: "button",
|
|
@@ -3132,25 +3261,25 @@ function ScrollToBottomButton() {
|
|
|
3132
3261
|
"aria-label": "\u6EDA\u52A8\u5230\u5E95\u90E8",
|
|
3133
3262
|
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))]",
|
|
3134
3263
|
children: [
|
|
3135
|
-
/* @__PURE__ */
|
|
3136
|
-
/* @__PURE__ */
|
|
3264
|
+
/* @__PURE__ */ jsx16(ChevronDown, { size: 14 }),
|
|
3265
|
+
/* @__PURE__ */ jsx16("span", { className: "blade-chat-scroll-bottom-label", children: "\u6EDA\u52A8\u5230\u5E95\u90E8" })
|
|
3137
3266
|
]
|
|
3138
3267
|
}
|
|
3139
3268
|
);
|
|
3140
3269
|
}
|
|
3141
3270
|
function PlanningDivider({ kind }) {
|
|
3142
|
-
return /* @__PURE__ */
|
|
3143
|
-
/* @__PURE__ */
|
|
3144
|
-
/* @__PURE__ */
|
|
3145
|
-
/* @__PURE__ */
|
|
3146
|
-
/* @__PURE__ */
|
|
3271
|
+
return /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-3 py-1", children: [
|
|
3272
|
+
/* @__PURE__ */ jsx16("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" }),
|
|
3273
|
+
/* @__PURE__ */ jsxs14("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: [
|
|
3274
|
+
/* @__PURE__ */ jsx16(Lightbulb, { size: 12 }),
|
|
3275
|
+
/* @__PURE__ */ jsx16("span", { children: kind === "enter" ? "\u8FDB\u5165\u89C4\u5212\u6A21\u5F0F" : "\u89C4\u5212\u5B8C\u6210" })
|
|
3147
3276
|
] }),
|
|
3148
|
-
/* @__PURE__ */
|
|
3277
|
+
/* @__PURE__ */ jsx16("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" })
|
|
3149
3278
|
] });
|
|
3150
3279
|
}
|
|
3151
3280
|
|
|
3152
3281
|
// src/components/ChatSurface.tsx
|
|
3153
|
-
import { jsx as
|
|
3282
|
+
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
3154
3283
|
function themeAttr(theme) {
|
|
3155
3284
|
return theme === "dark" ? "dark" : void 0;
|
|
3156
3285
|
}
|
|
@@ -3182,7 +3311,7 @@ function ChatSurface({
|
|
|
3182
3311
|
beforeInput,
|
|
3183
3312
|
banner
|
|
3184
3313
|
}) {
|
|
3185
|
-
return /* @__PURE__ */
|
|
3314
|
+
return /* @__PURE__ */ jsxs15(
|
|
3186
3315
|
"div",
|
|
3187
3316
|
{
|
|
3188
3317
|
"data-theme": themeAttr(theme),
|
|
@@ -3191,14 +3320,14 @@ function ChatSurface({
|
|
|
3191
3320
|
classNames?.root
|
|
3192
3321
|
),
|
|
3193
3322
|
children: [
|
|
3194
|
-
/* @__PURE__ */
|
|
3323
|
+
/* @__PURE__ */ jsx17(ConnectionBanner, { connection, className: classNames?.banner }),
|
|
3195
3324
|
banner,
|
|
3196
|
-
errorMessage && /* @__PURE__ */
|
|
3197
|
-
/* @__PURE__ */
|
|
3198
|
-
/* @__PURE__ */
|
|
3325
|
+
errorMessage && /* @__PURE__ */ jsxs15("div", { className: "blade-chat-error-bar flex items-start gap-2 border-b px-4 py-3 text-sm", children: [
|
|
3326
|
+
/* @__PURE__ */ jsx17(CircleAlert, { size: 16, className: "mt-0.5 shrink-0" }),
|
|
3327
|
+
/* @__PURE__ */ jsx17("span", { children: errorMessage })
|
|
3199
3328
|
] }),
|
|
3200
3329
|
slots?.header,
|
|
3201
|
-
/* @__PURE__ */
|
|
3330
|
+
/* @__PURE__ */ jsx17(
|
|
3202
3331
|
MessageList,
|
|
3203
3332
|
{
|
|
3204
3333
|
messages,
|
|
@@ -3219,7 +3348,7 @@ function ChatSurface({
|
|
|
3219
3348
|
}
|
|
3220
3349
|
),
|
|
3221
3350
|
beforeInput,
|
|
3222
|
-
/* @__PURE__ */
|
|
3351
|
+
/* @__PURE__ */ jsx17(
|
|
3223
3352
|
ChatInput,
|
|
3224
3353
|
{
|
|
3225
3354
|
value: inputText,
|
|
@@ -3239,7 +3368,7 @@ function ChatSurface({
|
|
|
3239
3368
|
}
|
|
3240
3369
|
|
|
3241
3370
|
// src/components/AgentChat.tsx
|
|
3242
|
-
import { Fragment as Fragment3, jsx as
|
|
3371
|
+
import { Fragment as Fragment3, jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
3243
3372
|
function isUnauthorizedError(error) {
|
|
3244
3373
|
return error instanceof BladeApiError && error.status === 401;
|
|
3245
3374
|
}
|
|
@@ -3258,11 +3387,11 @@ function LoginCard({ client, onLoggedIn }) {
|
|
|
3258
3387
|
setLoggingIn(false);
|
|
3259
3388
|
}
|
|
3260
3389
|
};
|
|
3261
|
-
return /* @__PURE__ */
|
|
3262
|
-
/* @__PURE__ */
|
|
3263
|
-
/* @__PURE__ */
|
|
3264
|
-
/* @__PURE__ */
|
|
3265
|
-
/* @__PURE__ */
|
|
3390
|
+
return /* @__PURE__ */ jsx18("div", { className: "blade-chat-login flex flex-1 items-center justify-center p-6", children: /* @__PURE__ */ jsxs16("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: [
|
|
3391
|
+
/* @__PURE__ */ jsx18(LockKeyhole, { size: 28, className: "text-[hsl(var(--muted-foreground))]" }),
|
|
3392
|
+
/* @__PURE__ */ jsx18("div", { className: "text-base font-medium text-[hsl(var(--foreground))]", children: "\u9700\u8981\u767B\u5F55\u540E\u4F7F\u7528" }),
|
|
3393
|
+
/* @__PURE__ */ jsx18("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" }),
|
|
3394
|
+
/* @__PURE__ */ jsx18(
|
|
3266
3395
|
"button",
|
|
3267
3396
|
{
|
|
3268
3397
|
type: "button",
|
|
@@ -3272,7 +3401,7 @@ function LoginCard({ client, onLoggedIn }) {
|
|
|
3272
3401
|
children: loggingIn ? "\u767B\u5F55\u4E2D\u2026" : "\u767B\u5F55"
|
|
3273
3402
|
}
|
|
3274
3403
|
),
|
|
3275
|
-
loginError && /* @__PURE__ */
|
|
3404
|
+
loginError && /* @__PURE__ */ jsx18("div", { className: "text-xs text-[hsl(var(--destructive))]", children: loginError })
|
|
3276
3405
|
] }) });
|
|
3277
3406
|
}
|
|
3278
3407
|
function AgentChat(props) {
|
|
@@ -3280,12 +3409,12 @@ function AgentChat(props) {
|
|
|
3280
3409
|
const [attempt, setAttempt] = useState13(0);
|
|
3281
3410
|
const [needLogin, setNeedLogin] = useState13(() => !client.hasToken());
|
|
3282
3411
|
if (needLogin) {
|
|
3283
|
-
return /* @__PURE__ */
|
|
3412
|
+
return /* @__PURE__ */ jsx18(
|
|
3284
3413
|
"div",
|
|
3285
3414
|
{
|
|
3286
3415
|
"data-theme": themeAttr(props.theme),
|
|
3287
3416
|
className: cn("blade-chat flex min-h-0 flex-1 flex-col", props.classNames?.root),
|
|
3288
|
-
children: /* @__PURE__ */
|
|
3417
|
+
children: /* @__PURE__ */ jsx18(
|
|
3289
3418
|
LoginCard,
|
|
3290
3419
|
{
|
|
3291
3420
|
client,
|
|
@@ -3298,7 +3427,7 @@ function AgentChat(props) {
|
|
|
3298
3427
|
}
|
|
3299
3428
|
);
|
|
3300
3429
|
}
|
|
3301
|
-
return /* @__PURE__ */
|
|
3430
|
+
return /* @__PURE__ */ jsx18(ChatSessionView, { ...props, onUnauthorized: () => setNeedLogin(true) }, attempt);
|
|
3302
3431
|
}
|
|
3303
3432
|
function ChatSessionView({
|
|
3304
3433
|
sessionId,
|
|
@@ -3407,7 +3536,7 @@ ${content}`);
|
|
|
3407
3536
|
setStopRequested(true);
|
|
3408
3537
|
void session?.stop();
|
|
3409
3538
|
};
|
|
3410
|
-
return /* @__PURE__ */
|
|
3539
|
+
return /* @__PURE__ */ jsx18(
|
|
3411
3540
|
ChatSurface,
|
|
3412
3541
|
{
|
|
3413
3542
|
theme,
|
|
@@ -3417,8 +3546,8 @@ ${content}`);
|
|
|
3417
3546
|
slots,
|
|
3418
3547
|
placeholder,
|
|
3419
3548
|
connection: state?.connection ?? "connecting",
|
|
3420
|
-
banner: /* @__PURE__ */
|
|
3421
|
-
/* @__PURE__ */
|
|
3549
|
+
banner: /* @__PURE__ */ jsxs16(Fragment3, { children: [
|
|
3550
|
+
/* @__PURE__ */ jsx18(
|
|
3422
3551
|
ReplayBar,
|
|
3423
3552
|
{
|
|
3424
3553
|
isReplay: replay.isReplay,
|
|
@@ -3428,7 +3557,7 @@ ${content}`);
|
|
|
3428
3557
|
onExit: () => void replay.exitToAutonomous()
|
|
3429
3558
|
}
|
|
3430
3559
|
),
|
|
3431
|
-
/* @__PURE__ */
|
|
3560
|
+
/* @__PURE__ */ jsx18(ReplayMismatchPrompt, { mismatch: replay.mismatch })
|
|
3432
3561
|
] }),
|
|
3433
3562
|
errorMessage,
|
|
3434
3563
|
messages: state?.messages ?? [],
|
|
@@ -3461,7 +3590,7 @@ import { useEffect as useEffect10, useMemo as useMemo9, useState as useState15 }
|
|
|
3461
3590
|
|
|
3462
3591
|
// src/components/LlmAdvancedSettings.tsx
|
|
3463
3592
|
import { useState as useState14 } from "react";
|
|
3464
|
-
import { jsx as
|
|
3593
|
+
import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
3465
3594
|
var FIELDS = [
|
|
3466
3595
|
{ id: "baseURL", label: "\u6A21\u578B\u670D\u52A1\u5730\u5740", placeholder: "http://\u5185\u7F51\u5730\u5740/v1" },
|
|
3467
3596
|
{ id: "model", label: "\u6A21\u578B", placeholder: "\u6A21\u578B\u540D\u79F0" },
|
|
@@ -3512,8 +3641,8 @@ function LlmAdvancedSettingsBar({ settings, defaults, override, onChange }) {
|
|
|
3512
3641
|
if (!normalized) return null;
|
|
3513
3642
|
const fields = FIELDS.filter((field) => normalized[field.id]);
|
|
3514
3643
|
const dirty = Object.keys(override).length > 0;
|
|
3515
|
-
return /* @__PURE__ */
|
|
3516
|
-
/* @__PURE__ */
|
|
3644
|
+
return /* @__PURE__ */ jsxs17("div", { className: "blade-chat-advanced border-t border-[hsl(var(--border))] px-4 py-2 text-xs", children: [
|
|
3645
|
+
/* @__PURE__ */ jsxs17(
|
|
3517
3646
|
"button",
|
|
3518
3647
|
{
|
|
3519
3648
|
type: "button",
|
|
@@ -3523,16 +3652,16 @@ function LlmAdvancedSettingsBar({ settings, defaults, override, onChange }) {
|
|
|
3523
3652
|
},
|
|
3524
3653
|
className: "flex items-center gap-1.5 text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))]",
|
|
3525
3654
|
children: [
|
|
3526
|
-
/* @__PURE__ */
|
|
3655
|
+
/* @__PURE__ */ jsx19(Settings2, { size: 13 }),
|
|
3527
3656
|
"\u9AD8\u7EA7\u8BBE\u7F6E",
|
|
3528
|
-
dirty && /* @__PURE__ */
|
|
3657
|
+
dirty && /* @__PURE__ */ jsx19("span", { className: "text-[hsl(var(--primary))]", children: "\uFF08\u5DF2\u81EA\u5B9A\u4E49\uFF09" })
|
|
3529
3658
|
]
|
|
3530
3659
|
}
|
|
3531
3660
|
),
|
|
3532
|
-
open && /* @__PURE__ */
|
|
3533
|
-
fields.map((field) => /* @__PURE__ */
|
|
3534
|
-
/* @__PURE__ */
|
|
3535
|
-
/* @__PURE__ */
|
|
3661
|
+
open && /* @__PURE__ */ jsxs17("div", { className: "mt-2 flex flex-col gap-2", children: [
|
|
3662
|
+
fields.map((field) => /* @__PURE__ */ jsxs17("label", { className: "flex flex-col gap-1", children: [
|
|
3663
|
+
/* @__PURE__ */ jsx19("span", { className: "text-[hsl(var(--muted-foreground))]", children: field.label }),
|
|
3664
|
+
/* @__PURE__ */ jsx19(
|
|
3536
3665
|
"input",
|
|
3537
3666
|
{
|
|
3538
3667
|
type: field.secret ? "password" : "text",
|
|
@@ -3543,9 +3672,9 @@ function LlmAdvancedSettingsBar({ settings, defaults, override, onChange }) {
|
|
|
3543
3672
|
}
|
|
3544
3673
|
)
|
|
3545
3674
|
] }, field.id)),
|
|
3546
|
-
normalized.apiKey && /* @__PURE__ */
|
|
3547
|
-
/* @__PURE__ */
|
|
3548
|
-
/* @__PURE__ */
|
|
3675
|
+
normalized.apiKey && /* @__PURE__ */ jsx19("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" }),
|
|
3676
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex gap-2", children: [
|
|
3677
|
+
/* @__PURE__ */ jsx19(
|
|
3549
3678
|
"button",
|
|
3550
3679
|
{
|
|
3551
3680
|
type: "button",
|
|
@@ -3560,7 +3689,7 @@ function LlmAdvancedSettingsBar({ settings, defaults, override, onChange }) {
|
|
|
3560
3689
|
children: "\u4FDD\u5B58"
|
|
3561
3690
|
}
|
|
3562
3691
|
),
|
|
3563
|
-
/* @__PURE__ */
|
|
3692
|
+
/* @__PURE__ */ jsx19(
|
|
3564
3693
|
"button",
|
|
3565
3694
|
{
|
|
3566
3695
|
type: "button",
|
|
@@ -3579,7 +3708,7 @@ function LlmAdvancedSettingsBar({ settings, defaults, override, onChange }) {
|
|
|
3579
3708
|
}
|
|
3580
3709
|
|
|
3581
3710
|
// src/components/LlmChat.tsx
|
|
3582
|
-
import { jsx as
|
|
3711
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
3583
3712
|
function LlmChat({
|
|
3584
3713
|
classNames,
|
|
3585
3714
|
renderers,
|
|
@@ -3608,7 +3737,7 @@ ${text}` : text),
|
|
|
3608
3737
|
useEffect10(() => {
|
|
3609
3738
|
onReady?.(handle);
|
|
3610
3739
|
}, [handle, onReady]);
|
|
3611
|
-
return /* @__PURE__ */
|
|
3740
|
+
return /* @__PURE__ */ jsx20(
|
|
3612
3741
|
ChatSurface,
|
|
3613
3742
|
{
|
|
3614
3743
|
theme,
|
|
@@ -3633,7 +3762,7 @@ ${text}` : text),
|
|
|
3633
3762
|
setStopRequested(true);
|
|
3634
3763
|
stop();
|
|
3635
3764
|
},
|
|
3636
|
-
beforeInput: advanced ? /* @__PURE__ */
|
|
3765
|
+
beforeInput: advanced ? /* @__PURE__ */ jsx20(
|
|
3637
3766
|
LlmAdvancedSettingsBar,
|
|
3638
3767
|
{
|
|
3639
3768
|
settings: advanced,
|
|
@@ -3651,14 +3780,14 @@ ${text}` : text),
|
|
|
3651
3780
|
}
|
|
3652
3781
|
|
|
3653
3782
|
// src/components/ChatView.tsx
|
|
3654
|
-
import { jsx as
|
|
3783
|
+
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
3655
3784
|
function ChatView(props) {
|
|
3656
3785
|
const { mode, llm, onLlmReady, ...rest } = props;
|
|
3657
3786
|
if (mode === "llm") {
|
|
3658
3787
|
if (!llm) {
|
|
3659
3788
|
throw new Error('ChatView: mode="llm" \u9700\u8981\u540C\u65F6\u4F20 llm={{ baseURL, model }}');
|
|
3660
3789
|
}
|
|
3661
|
-
return /* @__PURE__ */
|
|
3790
|
+
return /* @__PURE__ */ jsx21(
|
|
3662
3791
|
LlmChat,
|
|
3663
3792
|
{
|
|
3664
3793
|
...llm,
|
|
@@ -3671,7 +3800,7 @@ function ChatView(props) {
|
|
|
3671
3800
|
}
|
|
3672
3801
|
);
|
|
3673
3802
|
}
|
|
3674
|
-
return /* @__PURE__ */
|
|
3803
|
+
return /* @__PURE__ */ jsx21(AgentChat, { ...rest });
|
|
3675
3804
|
}
|
|
3676
3805
|
|
|
3677
3806
|
// src/index.ts
|
|
@@ -3680,6 +3809,7 @@ export {
|
|
|
3680
3809
|
AgentChat,
|
|
3681
3810
|
BladeProvider,
|
|
3682
3811
|
ChatView,
|
|
3812
|
+
ContextCard,
|
|
3683
3813
|
LlmChat,
|
|
3684
3814
|
MarkdownContent,
|
|
3685
3815
|
ReplayBar,
|