@blade-hq/agent-react 2610.0.0 → 2610.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/ToolCallBlock.d.ts +2 -2
- package/dist/components/display-utils.d.ts +0 -22
- package/dist/index.js +54 -205
- package/dist/index.js.map +1 -1
- package/dist/style.full.css +1 -1
- package/package.json +2 -2
- package/public-api.md +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AskUserAnswerData, ToolCallInfo } from "@blade-hq/agent-client";
|
|
2
|
-
import {
|
|
2
|
+
import type { ReactNode } from "react";
|
|
3
3
|
import type { ChatViewClassNames, ChatViewRenderers } from "./ChatSurface";
|
|
4
4
|
/** 接入方自定义渲染器:返回 null 时回落到默认渲染。 */
|
|
5
5
|
export type ToolCallRenderer = (info: ToolCallInfo) => ReactNode | null;
|
|
@@ -37,5 +37,5 @@ export declare function resolveAskQuestionState({ toolStatus, hasAnswerData, fal
|
|
|
37
37
|
* 极简工具调用块:状态 + 展示名一行,点开后是参数/结果的 <pre> 折叠展示。
|
|
38
38
|
* AskUserQuestion 特殊处理为提问选项卡片。
|
|
39
39
|
*/
|
|
40
|
-
export declare function ToolCallBlock({ toolCall, onAnswer, answered, answerData, sessionStatus, isActiveQuestion, classNames, renderers, }: Props): import("react/jsx-runtime").JSX.Element;
|
|
40
|
+
export declare function ToolCallBlock({ toolCall, onAnswer, answered, answerData, sessionStatus, isActiveQuestion, classNames, renderers, }: Props): import("react/jsx-runtime").JSX.Element | undefined;
|
|
41
41
|
export {};
|
|
@@ -1,26 +1,4 @@
|
|
|
1
|
-
import type { ToolCallInfo } from "@blade-hq/agent-client";
|
|
2
|
-
export type ToolTone = "emerald" | "blue" | "amber" | "red";
|
|
3
|
-
/**
|
|
4
|
-
* 技能入口文件的所在目录就是技能名(`.agent/skills/<技能名>/SKILL.md`)。
|
|
5
|
-
* 只显示 "SKILL.md" 用户看不出读的是哪个技能。
|
|
6
|
-
*
|
|
7
|
-
* 改这里必须同步 apps/web/src/agent/components/chat/display-utils.ts 的同名函数。
|
|
8
|
-
*/
|
|
9
|
-
export declare function getSkillNameFromFilePath(filePath: string | null | undefined): string | null;
|
|
10
1
|
/** 归一化工具名:去掉命名空间前缀并映射到别名表(如 "fork:Agent" → "Agent")。 */
|
|
11
2
|
export declare function formatToolName(name: string): string;
|
|
12
|
-
export declare function extractToolFilePath(toolCall: ToolCallInfo): string | null;
|
|
13
|
-
/** 从文件类工具参数中提取全部可定位的文件路径(按出现顺序去重)。 */
|
|
14
|
-
export declare function extractToolFilePaths(toolCall: ToolCallInfo): string[];
|
|
15
|
-
/**
|
|
16
|
-
* 返回工具调用的中文展示标签:优先取参数里的 description,
|
|
17
|
-
* 其次取后端下发的 display_name / 系统工具中文名。
|
|
18
|
-
*/
|
|
19
|
-
export declare function getToolDisplayLabel(toolCall: ToolCallInfo): string;
|
|
20
|
-
export declare function getToolTone(status?: ToolCallInfo["status"]): ToolTone;
|
|
21
|
-
export declare function getToolStatusLabel(status?: ToolCallInfo["status"]): string;
|
|
22
|
-
export declare function formatToolDuration(ms: number): string;
|
|
23
|
-
/** 参数 JSON 美化:无法解析时按原文展示。 */
|
|
24
|
-
export declare function formatToolArgs(args: string): string;
|
|
25
3
|
/** 工具结果的文本化 + 截断:长结果只在折叠面板里展示前若干字符。 */
|
|
26
4
|
export declare function formatToolResult(result: unknown): string;
|
package/dist/index.js
CHANGED
|
@@ -3412,7 +3412,7 @@ var X = createLucideIcon("X", [
|
|
|
3412
3412
|
]);
|
|
3413
3413
|
|
|
3414
3414
|
// src/components/AgentChat.tsx
|
|
3415
|
-
import { useCallback as useCallback30, useEffect as useEffect26, useMemo as useMemo18, useRef as useRef28, useState as
|
|
3415
|
+
import { useCallback as useCallback30, useEffect as useEffect26, useMemo as useMemo18, useRef as useRef28, useState as useState35 } from "react";
|
|
3416
3416
|
|
|
3417
3417
|
// src/components/SessionPluginSelector.tsx
|
|
3418
3418
|
import { useEffect as useEffect14, useState as useState19 } from "react";
|
|
@@ -20758,50 +20758,6 @@ var TOOL_NAME_ALIASES = {
|
|
|
20758
20758
|
web_search: "WebSearch",
|
|
20759
20759
|
write: "Write"
|
|
20760
20760
|
};
|
|
20761
|
-
var TOOL_DISPLAY_LABELS = {
|
|
20762
|
-
Bash: "\u6267\u884C\u547D\u4EE4",
|
|
20763
|
-
BgBash: "\u540E\u53F0\u6267\u884C\u547D\u4EE4",
|
|
20764
|
-
Read: "\u8BFB\u53D6\u6587\u4EF6",
|
|
20765
|
-
Write: "\u5199\u5165\u6587\u4EF6",
|
|
20766
|
-
Edit: "\u7F16\u8F91\u6587\u4EF6",
|
|
20767
|
-
MultiEdit: "\u7F16\u8F91\u6587\u4EF6",
|
|
20768
|
-
Ls: "\u5217\u51FA\u76EE\u5F55",
|
|
20769
|
-
Glob: "\u5339\u914D\u6587\u4EF6",
|
|
20770
|
-
Grep: "\u641C\u7D22\u6587\u672C",
|
|
20771
|
-
KbSearch: "\u68C0\u7D22\u77E5\u8BC6\u5E93",
|
|
20772
|
-
WebSearch: "\u641C\u7D22\u7F51\u9875",
|
|
20773
|
-
WebFetch: "\u6574\u7406\u7F51\u9875\u5185\u5BB9",
|
|
20774
|
-
Agent: "\u6D3E\u751F\u5B50\u667A\u80FD\u4F53",
|
|
20775
|
-
AskUserQuestion: "\u5411\u7528\u6237\u63D0\u95EE",
|
|
20776
|
-
ReadSkill: "\u8BFB\u53D6\u6280\u80FD",
|
|
20777
|
-
FinishTask: "\u4EFB\u52A1\u5B8C\u6210",
|
|
20778
|
-
ExitPlanMode: "\u63D0\u4EA4\u8BA1\u5212",
|
|
20779
|
-
ListSessions: "\u5217\u51FA\u5386\u53F2\u4F1A\u8BDD",
|
|
20780
|
-
GetSessionHistory: "\u8BFB\u53D6\u4F1A\u8BDD\u5386\u53F2"
|
|
20781
|
-
};
|
|
20782
|
-
function safeParseJson(value) {
|
|
20783
|
-
if (!value) return null;
|
|
20784
|
-
try {
|
|
20785
|
-
return JSON.parse(value);
|
|
20786
|
-
} catch {
|
|
20787
|
-
return null;
|
|
20788
|
-
}
|
|
20789
|
-
}
|
|
20790
|
-
function getStringArgValue(args, key) {
|
|
20791
|
-
const value = args?.[key];
|
|
20792
|
-
return typeof value === "string" ? value.trim() : "";
|
|
20793
|
-
}
|
|
20794
|
-
var SKILL_ENTRY_FILE_NAMES = /* @__PURE__ */ new Set(["skill.md", "command.md"]);
|
|
20795
|
-
var NON_SKILL_DIR_NAMES = /* @__PURE__ */ new Set([".", "..", ".agent", ".agents", ".claude", "skill_data", "skills"]);
|
|
20796
|
-
function getSkillNameFromFilePath(filePath) {
|
|
20797
|
-
if (!filePath) return null;
|
|
20798
|
-
const segments = filePath.split(/[\\/]+/).filter(Boolean);
|
|
20799
|
-
const fileName = segments.pop();
|
|
20800
|
-
if (!fileName || !SKILL_ENTRY_FILE_NAMES.has(fileName.toLowerCase())) return null;
|
|
20801
|
-
const dirName = segments.pop();
|
|
20802
|
-
if (!dirName || NON_SKILL_DIR_NAMES.has(dirName.toLowerCase())) return null;
|
|
20803
|
-
return dirName;
|
|
20804
|
-
}
|
|
20805
20761
|
function formatToolName(name) {
|
|
20806
20762
|
const trimmed = name.trim();
|
|
20807
20763
|
if (!trimmed) return name;
|
|
@@ -20809,63 +20765,6 @@ function formatToolName(name) {
|
|
|
20809
20765
|
const normalized = stripped.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[^a-zA-Z0-9]+/g, "_").replace(/^_+|_+$/g, "").toLowerCase();
|
|
20810
20766
|
return TOOL_NAME_ALIASES[normalized] ?? stripped;
|
|
20811
20767
|
}
|
|
20812
|
-
function getToolDisplayLabel(toolCall) {
|
|
20813
|
-
const normalized = formatToolName(toolCall.name);
|
|
20814
|
-
const args = safeParseJson(toolCall.arguments);
|
|
20815
|
-
const displayName = toolCall.display_name?.trim() ?? "";
|
|
20816
|
-
const baseLabel = displayName || TOOL_DISPLAY_LABELS[normalized] || normalized;
|
|
20817
|
-
const metaDisplayName = getStringArgValue(args, "_meta_display_name");
|
|
20818
|
-
if (metaDisplayName) {
|
|
20819
|
-
return metaDisplayName;
|
|
20820
|
-
}
|
|
20821
|
-
const description = getStringArgValue(args, "description");
|
|
20822
|
-
if (normalized === "BgBash") {
|
|
20823
|
-
return description ? `\u540E\u53F0\u6267\u884C\uFF1A${description}` : "\u540E\u53F0\u6267\u884C\u547D\u4EE4";
|
|
20824
|
-
}
|
|
20825
|
-
if (normalized === "ReadSkill") {
|
|
20826
|
-
const skillName = getStringArgValue(args, "skill") || getStringArgValue(args, "skill_name");
|
|
20827
|
-
return skillName ? `${baseLabel}\u300C${skillName}\u300D` : baseLabel;
|
|
20828
|
-
}
|
|
20829
|
-
if (normalized === "Read") {
|
|
20830
|
-
const skillName = getSkillNameFromFilePath(
|
|
20831
|
-
getStringArgValue(args, "file_path") || getStringArgValue(args, "path")
|
|
20832
|
-
);
|
|
20833
|
-
if (skillName) return `\u8BFB\u53D6\u6280\u80FD\u300C${skillName}\u300D`;
|
|
20834
|
-
}
|
|
20835
|
-
if (normalized === "FinishTask") {
|
|
20836
|
-
const title = getStringArgValue(args, "title");
|
|
20837
|
-
return title ? `${baseLabel}\uFF1A${title}` : baseLabel;
|
|
20838
|
-
}
|
|
20839
|
-
return description || baseLabel;
|
|
20840
|
-
}
|
|
20841
|
-
function getToolTone(status) {
|
|
20842
|
-
if (status === "error" || status === "cancelled") return "red";
|
|
20843
|
-
if (status === "awaiting_answer") return "amber";
|
|
20844
|
-
if (status === "pending") return "blue";
|
|
20845
|
-
return "emerald";
|
|
20846
|
-
}
|
|
20847
|
-
function getToolStatusLabel(status) {
|
|
20848
|
-
if (status === "pending") return "\u8FD0\u884C\u4E2D";
|
|
20849
|
-
if (status === "awaiting_answer") return "\u7B49\u5F85\u56DE\u7B54";
|
|
20850
|
-
if (status === "error") return "\u9519\u8BEF";
|
|
20851
|
-
if (status === "cancelled") return "\u5DF2\u53D6\u6D88";
|
|
20852
|
-
return "\u5B8C\u6210";
|
|
20853
|
-
}
|
|
20854
|
-
function formatToolDuration(ms) {
|
|
20855
|
-
if (ms < 1e3) return `${Math.round(ms)}ms`;
|
|
20856
|
-
const seconds = ms / 1e3;
|
|
20857
|
-
if (seconds < 60) return `${seconds.toFixed(1)}s`;
|
|
20858
|
-
const minutes = Math.floor(seconds / 60);
|
|
20859
|
-
const remainingSeconds = Math.round(seconds % 60);
|
|
20860
|
-
return remainingSeconds > 0 ? `${minutes}m${remainingSeconds}s` : `${minutes}m`;
|
|
20861
|
-
}
|
|
20862
|
-
function formatToolArgs(args) {
|
|
20863
|
-
try {
|
|
20864
|
-
return JSON.stringify(JSON.parse(args), null, 2);
|
|
20865
|
-
} catch {
|
|
20866
|
-
return args;
|
|
20867
|
-
}
|
|
20868
|
-
}
|
|
20869
20768
|
var RESULT_PREVIEW_LIMIT = 4e3;
|
|
20870
20769
|
function formatToolResult(result) {
|
|
20871
20770
|
const text4 = typeof result === "string" ? result : JSON.stringify(result, null, 2);
|
|
@@ -21072,7 +20971,7 @@ function CurrentPlanPanel({
|
|
|
21072
20971
|
|
|
21073
20972
|
// src/components/ChatSurface.tsx
|
|
21074
20973
|
import { chatErrorForDisplay as chatErrorForDisplay2 } from "@blade-hq/agent-client";
|
|
21075
|
-
import { useMemo as useMemo17, useState as
|
|
20974
|
+
import { useMemo as useMemo17, useState as useState34 } from "react";
|
|
21076
20975
|
|
|
21077
20976
|
// src/lib/random-id.ts
|
|
21078
20977
|
function randomId() {
|
|
@@ -46431,7 +46330,7 @@ import {
|
|
|
46431
46330
|
useEffect as useEffect25,
|
|
46432
46331
|
useMemo as useMemo16,
|
|
46433
46332
|
useRef as useRef27,
|
|
46434
|
-
useState as
|
|
46333
|
+
useState as useState33
|
|
46435
46334
|
} from "react";
|
|
46436
46335
|
|
|
46437
46336
|
// ../../node_modules/.pnpm/use-stick-to-bottom@1.1.3_react@19.2.4/node_modules/use-stick-to-bottom/dist/useStickToBottom.js
|
|
@@ -46931,7 +46830,7 @@ import {
|
|
|
46931
46830
|
getTextContent as getTextContent2,
|
|
46932
46831
|
normalizeMessageContent as normalizeMessageContent2
|
|
46933
46832
|
} from "@blade-hq/agent-client";
|
|
46934
|
-
import { useEffect as useEffect23, useRef as useRef25, useState as
|
|
46833
|
+
import { useEffect as useEffect23, useRef as useRef25, useState as useState31 } from "react";
|
|
46935
46834
|
|
|
46936
46835
|
// src/components/AgentTaskCard.tsx
|
|
46937
46836
|
import { useEffect as useEffect20, useState as useState27 } from "react";
|
|
@@ -56044,9 +55943,6 @@ function Shimmer({ children = "\u6B63\u5728\u601D\u8003...", className }) {
|
|
|
56044
55943
|
return /* @__PURE__ */ jsx20("span", { className: cn("blade-shimmer-text text-sm font-medium", className), children });
|
|
56045
55944
|
}
|
|
56046
55945
|
|
|
56047
|
-
// src/components/ToolCallBlock.tsx
|
|
56048
|
-
import { useState as useState30 } from "react";
|
|
56049
|
-
|
|
56050
55946
|
// src/components/AskUserQuestionBlock.tsx
|
|
56051
55947
|
import { useEffect as useEffect21, useMemo as useMemo15, useRef as useRef24, useState as useState29 } from "react";
|
|
56052
55948
|
import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
@@ -56512,7 +56408,6 @@ function ToolCallBlock({
|
|
|
56512
56408
|
classNames,
|
|
56513
56409
|
renderers
|
|
56514
56410
|
}) {
|
|
56515
|
-
const [expanded, setExpanded] = useState30(false);
|
|
56516
56411
|
const normalizedName = formatToolName(toolCall.name);
|
|
56517
56412
|
const customQuestion = normalizedName === "AskUserQuestion" ? renderers?.askUserQuestion : void 0;
|
|
56518
56413
|
const customToolCall = normalizedName === "AskUserQuestion" && customQuestion ? null : renderers?.toolCall?.(toolCall);
|
|
@@ -56588,52 +56483,6 @@ function ToolCallBlock({
|
|
|
56588
56483
|
}
|
|
56589
56484
|
);
|
|
56590
56485
|
}
|
|
56591
|
-
const tone = getToolTone(toolCall.status);
|
|
56592
|
-
const displayName = getToolDisplayLabel(toolCall);
|
|
56593
|
-
const toneClass = tone === "red" ? "border-l-[hsl(var(--muted-foreground)/0.5)]" : tone === "amber" ? "border-l-amber-400" : tone === "blue" ? "border-l-blue-500" : "border-l-[hsl(var(--primary))]";
|
|
56594
|
-
const statusIcon = toolCall.status === "pending" ? /* @__PURE__ */ jsx22(LoaderCircle, { size: 11, className: "animate-spin" }) : toolCall.status === "awaiting_answer" ? /* @__PURE__ */ jsx22(MessageSquareMore, { size: 11 }) : toolCall.status === "cancelled" || toolCall.status === "error" ? /* @__PURE__ */ jsx22(X, { size: 11 }) : /* @__PURE__ */ jsx22(Check, { size: 11 });
|
|
56595
|
-
const statusTextClass = tone === "red" ? "text-[hsl(var(--muted-foreground))]" : tone === "amber" ? "text-amber-300" : tone === "blue" ? "text-blue-300" : "text-[hsl(var(--primary))]";
|
|
56596
|
-
return /* @__PURE__ */ jsxs17("div", { className: "ml-4 text-xs", children: [
|
|
56597
|
-
/* @__PURE__ */ jsxs17("div", { className: cn("border-l-[3px] flex items-center gap-2 min-h-7 px-3 leading-5", toneClass), children: [
|
|
56598
|
-
/* @__PURE__ */ jsxs17(
|
|
56599
|
-
"button",
|
|
56600
|
-
{
|
|
56601
|
-
type: "button",
|
|
56602
|
-
onClick: () => setExpanded(!expanded),
|
|
56603
|
-
className: "flex min-h-7 min-w-0 flex-1 items-center gap-2 text-left transition-colors hover:bg-white/3 focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none",
|
|
56604
|
-
"aria-expanded": expanded,
|
|
56605
|
-
children: [
|
|
56606
|
-
/* @__PURE__ */ jsx22(
|
|
56607
|
-
ChevronRight,
|
|
56608
|
-
{
|
|
56609
|
-
size: 11,
|
|
56610
|
-
className: cn(
|
|
56611
|
-
"shrink-0 text-[hsl(var(--muted-foreground))] transition-transform",
|
|
56612
|
-
expanded && "rotate-90"
|
|
56613
|
-
)
|
|
56614
|
-
}
|
|
56615
|
-
),
|
|
56616
|
-
/* @__PURE__ */ jsxs17("span", { className: cn("flex shrink-0 items-center gap-1 text-[10px]", statusTextClass), children: [
|
|
56617
|
-
statusIcon,
|
|
56618
|
-
/* @__PURE__ */ jsx22("span", { children: getToolStatusLabel(toolCall.status) })
|
|
56619
|
-
] }),
|
|
56620
|
-
/* @__PURE__ */ jsx22("span", { className: "min-w-0 flex-1 truncate font-medium text-[hsl(var(--foreground))]", children: displayName })
|
|
56621
|
-
]
|
|
56622
|
-
}
|
|
56623
|
-
),
|
|
56624
|
-
typeof toolCall.duration_ms === "number" && toolCall.duration_ms > 0 && /* @__PURE__ */ jsx22("span", { className: "shrink-0 font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: formatToolDuration(toolCall.duration_ms) })
|
|
56625
|
-
] }),
|
|
56626
|
-
expanded && /* @__PURE__ */ jsxs17("div", { className: "ml-4 mt-1 rounded-xl bg-[hsl(var(--card))] px-3 py-3", children: [
|
|
56627
|
-
/* @__PURE__ */ jsx22("div", { className: "mb-1 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u5DE5\u5177" }),
|
|
56628
|
-
/* @__PURE__ */ jsx22("div", { className: "mb-3 font-mono text-[11px] text-[hsl(var(--foreground))]", children: normalizedName }),
|
|
56629
|
-
/* @__PURE__ */ jsx22("div", { className: "mb-1 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u53C2\u6570" }),
|
|
56630
|
-
/* @__PURE__ */ jsx22("pre", { className: "overflow-auto whitespace-pre-wrap rounded-md bg-[hsl(var(--muted))] p-2 font-mono text-[11px] text-[hsl(var(--foreground))]", children: formatToolArgs(toolCall.arguments) }),
|
|
56631
|
-
toolCall.result != null && /* @__PURE__ */ jsxs17(Fragment7, { children: [
|
|
56632
|
-
/* @__PURE__ */ jsx22("div", { className: "mb-1 mt-3 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u7ED3\u679C" }),
|
|
56633
|
-
/* @__PURE__ */ jsx22("pre", { className: "max-h-[400px] overflow-auto whitespace-pre-wrap rounded-md bg-[hsl(var(--muted))] p-2 font-mono text-[11px] text-[hsl(var(--foreground))]", children: formatToolResult(toolCall.result) })
|
|
56634
|
-
] })
|
|
56635
|
-
] })
|
|
56636
|
-
] });
|
|
56637
56486
|
}
|
|
56638
56487
|
function buildAskUserPayload(argumentsJson) {
|
|
56639
56488
|
try {
|
|
@@ -56649,7 +56498,7 @@ function buildAskUserPayload(argumentsJson) {
|
|
|
56649
56498
|
|
|
56650
56499
|
// src/components/ToolUiCardView.tsx
|
|
56651
56500
|
import { resolveToolUiCardContent } from "@blade-hq/agent-client";
|
|
56652
|
-
import { useEffect as useEffect22, useState as
|
|
56501
|
+
import { useEffect as useEffect22, useState as useState30 } from "react";
|
|
56653
56502
|
import { jsx as jsx23, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
56654
56503
|
function ToolUiCardView({ card, sessionId }) {
|
|
56655
56504
|
if (card.mcpApp) return sessionId ? /* @__PURE__ */ jsx23(McpAppCard, { sessionId, sourceId: card.mcpApp.sourceId }) : null;
|
|
@@ -56676,9 +56525,9 @@ function ToolUiCardView({ card, sessionId }) {
|
|
|
56676
56525
|
}
|
|
56677
56526
|
function FileCard({ card, sessionId, path: path2 }) {
|
|
56678
56527
|
const client = useBladeClient();
|
|
56679
|
-
const [html, setHtml] =
|
|
56680
|
-
const [failed, setFailed] =
|
|
56681
|
-
const [refreshVersion, setRefreshVersion] =
|
|
56528
|
+
const [html, setHtml] = useState30(null);
|
|
56529
|
+
const [failed, setFailed] = useState30(false);
|
|
56530
|
+
const [refreshVersion, setRefreshVersion] = useState30(0);
|
|
56682
56531
|
useEffect22(() => {
|
|
56683
56532
|
const abort = new AbortController();
|
|
56684
56533
|
setHtml(null);
|
|
@@ -56745,7 +56594,7 @@ function ThinkingBlock({
|
|
|
56745
56594
|
isStreaming,
|
|
56746
56595
|
className
|
|
56747
56596
|
}) {
|
|
56748
|
-
const [open2, setOpen] =
|
|
56597
|
+
const [open2, setOpen] = useState31(false);
|
|
56749
56598
|
if (!isStreaming) return null;
|
|
56750
56599
|
return /* @__PURE__ */ jsxs19("div", { part: "thinking", className: cn("blade-chat-thinking ml-4 text-xs", className), children: [
|
|
56751
56600
|
/* @__PURE__ */ jsxs19(
|
|
@@ -57025,7 +56874,7 @@ function AssistantTurnBlock({
|
|
|
57025
56874
|
)
|
|
57026
56875
|
);
|
|
57027
56876
|
const activeQuestionId = questionToolCalls.filter((toolCall) => toolCall.status === "pending").at(-1)?.id;
|
|
57028
|
-
const [displayMode, setDisplayMode] =
|
|
56877
|
+
const [displayMode, setDisplayMode] = useState31(
|
|
57029
56878
|
() => isStreaming || hasActionableToolCall ? "detail" : "compact"
|
|
57030
56879
|
);
|
|
57031
56880
|
const userSelectedDisplayModeRef = useRef25(false);
|
|
@@ -57038,7 +56887,7 @@ function AssistantTurnBlock({
|
|
|
57038
56887
|
}, [hasActionableToolCall, isStreaming]);
|
|
57039
56888
|
const effectiveMode = resolveTurnDisplayMode({ isStreaming, displayMode });
|
|
57040
56889
|
const executionDurationMs = getExecutionDurationMs({ messages, isStreaming });
|
|
57041
|
-
const [clock, setClock] =
|
|
56890
|
+
const [clock, setClock] = useState31(() => Date.now());
|
|
57042
56891
|
const hasLiveStartTime = messages.some(
|
|
57043
56892
|
(message) => message.timestamp != null && Number.isFinite(Date.parse(message.timestamp))
|
|
57044
56893
|
);
|
|
@@ -57254,7 +57103,7 @@ function collectMemoryRefs(messages) {
|
|
|
57254
57103
|
return [...refs.values()];
|
|
57255
57104
|
}
|
|
57256
57105
|
function MemoryRefsHint({ refs, className }) {
|
|
57257
|
-
const [expanded, setExpanded] =
|
|
57106
|
+
const [expanded, setExpanded] = useState31(false);
|
|
57258
57107
|
const label = refs.some((ref) => ref.skill_name) ? "\u53C2\u8003\u4E86\u8BE5\u6280\u80FD\u7684\u5386\u53F2\u7ECF\u9A8C" : "\u53C2\u8003\u4E86\u5386\u53F2\u7ECF\u9A8C";
|
|
57259
57108
|
return /* @__PURE__ */ jsxs19("div", { part: "memory-refs", className: cn("blade-chat-memory-refs ml-1 w-full max-w-[680px]", className), children: [
|
|
57260
57109
|
/* @__PURE__ */ jsxs19("button", { type: "button", onClick: () => setExpanded((value) => !value), className: "inline-flex h-8 items-center gap-1.5 rounded-lg border border-[hsl(var(--primary)/0.22)] bg-[hsl(var(--primary)/0.07)] px-3 text-xs font-medium text-[hsl(var(--primary))]", children: [
|
|
@@ -57400,7 +57249,7 @@ var RenderErrorBoundary = class extends Component2 {
|
|
|
57400
57249
|
};
|
|
57401
57250
|
|
|
57402
57251
|
// src/components/PostChatFollowupBlock.tsx
|
|
57403
|
-
import { useCallback as useCallback28, useEffect as useEffect24, useRef as useRef26, useState as
|
|
57252
|
+
import { useCallback as useCallback28, useEffect as useEffect24, useRef as useRef26, useState as useState32 } from "react";
|
|
57404
57253
|
import { Fragment as Fragment8, jsx as jsx26, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
57405
57254
|
function emitInteraction(callback, event) {
|
|
57406
57255
|
try {
|
|
@@ -57420,7 +57269,7 @@ function ArtifactCard({
|
|
|
57420
57269
|
onArtifactOpened
|
|
57421
57270
|
}) {
|
|
57422
57271
|
const client = useBladeClient();
|
|
57423
|
-
const [downloading, setDownloading] =
|
|
57272
|
+
const [downloading, setDownloading] = useState32(false);
|
|
57424
57273
|
const name = artifact.label || basename(artifact.target);
|
|
57425
57274
|
if (artifact.kind === "link") {
|
|
57426
57275
|
return /* @__PURE__ */ jsxs21(
|
|
@@ -57526,11 +57375,11 @@ function ResultFeedback({
|
|
|
57526
57375
|
onFeedbackSaved
|
|
57527
57376
|
}) {
|
|
57528
57377
|
const client = useBladeClient();
|
|
57529
|
-
const [saved, setSaved] =
|
|
57530
|
-
const [helpful, setHelpful] =
|
|
57531
|
-
const [reason, setReason] =
|
|
57532
|
-
const [saving, setSaving] =
|
|
57533
|
-
const [saveError, setSaveError] =
|
|
57378
|
+
const [saved, setSaved] = useState32(savedFeedback ?? null);
|
|
57379
|
+
const [helpful, setHelpful] = useState32(savedFeedback?.helpful ?? null);
|
|
57380
|
+
const [reason, setReason] = useState32(savedFeedback?.reason ?? null);
|
|
57381
|
+
const [saving, setSaving] = useState32(false);
|
|
57382
|
+
const [saveError, setSaveError] = useState32(false);
|
|
57534
57383
|
const reportedShown = useRef26(false);
|
|
57535
57384
|
const latestChoice = useRef26(null);
|
|
57536
57385
|
const eligible = followup.feedback_eligible === true && Boolean(sessionId) && !isViewer;
|
|
@@ -57657,7 +57506,7 @@ function PostChatFollowupBlock({
|
|
|
57657
57506
|
className,
|
|
57658
57507
|
suggestionClassName
|
|
57659
57508
|
}) {
|
|
57660
|
-
const [expanded, setExpanded] =
|
|
57509
|
+
const [expanded, setExpanded] = useState32(false);
|
|
57661
57510
|
const adopted = useRef26(/* @__PURE__ */ new Set());
|
|
57662
57511
|
const reportedSuggestions = useRef26(false);
|
|
57663
57512
|
const reportedArtifacts = useRef26(/* @__PURE__ */ new Set());
|
|
@@ -58152,7 +58001,7 @@ function MessageList({
|
|
|
58152
58001
|
isEntryLoaded: (entryId) => findEntryRow(rootRef.current, entryId) !== null,
|
|
58153
58002
|
beforeSeek: () => stopAutoScrollRef.current?.()
|
|
58154
58003
|
});
|
|
58155
|
-
const [viewportNavTurnId, setViewportNavTurnId] =
|
|
58004
|
+
const [viewportNavTurnId, setViewportNavTurnId] = useState33(null);
|
|
58156
58005
|
const latestNavTurnId = turnNavItems.at(-1)?.id ?? null;
|
|
58157
58006
|
return /* @__PURE__ */ jsxs24(
|
|
58158
58007
|
"div",
|
|
@@ -58430,7 +58279,7 @@ function PinLatestUserMessage({
|
|
|
58430
58279
|
}
|
|
58431
58280
|
function ScrollToBottomButton({ className }) {
|
|
58432
58281
|
const { isAtBottom, scrollToBottom } = useStickToBottomContext();
|
|
58433
|
-
const [visible, setVisible] =
|
|
58282
|
+
const [visible, setVisible] = useState33(false);
|
|
58434
58283
|
const hideTimerRef = useRef27(null);
|
|
58435
58284
|
useEffect25(() => {
|
|
58436
58285
|
if (isAtBottom) {
|
|
@@ -58604,7 +58453,7 @@ function ChatSurface({
|
|
|
58604
58453
|
onRevealingChange,
|
|
58605
58454
|
isReplay
|
|
58606
58455
|
}) {
|
|
58607
|
-
const [pending, setPending] =
|
|
58456
|
+
const [pending, setPending] = useState34([]);
|
|
58608
58457
|
const currentPending = pending.filter((item) => item.sessionId === sessionId);
|
|
58609
58458
|
const sendWithApps = async (text4) => {
|
|
58610
58459
|
const content3 = [...currentPending.map((item) => `[${item.label}]
|
|
@@ -58726,8 +58575,8 @@ function isUnauthorizedError(error61) {
|
|
|
58726
58575
|
return error61 instanceof BladeApiError2 && error61.status === 401;
|
|
58727
58576
|
}
|
|
58728
58577
|
function LoginCard({ client, onLoggedIn }) {
|
|
58729
|
-
const [loggingIn, setLoggingIn] =
|
|
58730
|
-
const [loginError, setLoginError] =
|
|
58578
|
+
const [loggingIn, setLoggingIn] = useState35(false);
|
|
58579
|
+
const [loginError, setLoginError] = useState35(null);
|
|
58731
58580
|
const handleLogin = async () => {
|
|
58732
58581
|
setLoggingIn(true);
|
|
58733
58582
|
setLoginError(null);
|
|
@@ -58759,8 +58608,8 @@ function LoginCard({ client, onLoggedIn }) {
|
|
|
58759
58608
|
}
|
|
58760
58609
|
function AgentChat(props) {
|
|
58761
58610
|
const client = useBladeClient();
|
|
58762
|
-
const [attempt, setAttempt] =
|
|
58763
|
-
const [needLogin, setNeedLogin] =
|
|
58611
|
+
const [attempt, setAttempt] = useState35(0);
|
|
58612
|
+
const [needLogin, setNeedLogin] = useState35(() => !client.hasToken());
|
|
58764
58613
|
if (needLogin) {
|
|
58765
58614
|
return /* @__PURE__ */ jsx31(
|
|
58766
58615
|
"div",
|
|
@@ -58799,7 +58648,7 @@ function ChatSessionView({
|
|
|
58799
58648
|
onUnauthorized
|
|
58800
58649
|
}) {
|
|
58801
58650
|
const client = useBladeClient();
|
|
58802
|
-
const [planRevealRevisions, setPlanRevealRevisions] =
|
|
58651
|
+
const [planRevealRevisions, setPlanRevealRevisions] = useState35(
|
|
58803
58652
|
() => /* @__PURE__ */ new Map()
|
|
58804
58653
|
);
|
|
58805
58654
|
const handleSessionConnected = useCallback30((connectedSession) => {
|
|
@@ -58820,14 +58669,14 @@ function ChatSessionView({
|
|
|
58820
58669
|
onSessionConnected: handleSessionConnected
|
|
58821
58670
|
});
|
|
58822
58671
|
const replay = useReplay(session);
|
|
58823
|
-
const [stopRequested, setStopRequested] =
|
|
58824
|
-
const [isRevealing, setIsRevealing] =
|
|
58825
|
-
const [inputText, setInputText] =
|
|
58826
|
-
const [queueNotice, setQueueNotice] =
|
|
58827
|
-
const [queuePendingItemId, setQueuePendingItemId] =
|
|
58828
|
-
const [queuePanelVisible, setQueuePanelVisible] =
|
|
58829
|
-
const [resultFeedback, setResultFeedback] =
|
|
58830
|
-
const [timelineRewrite, setTimelineRewrite] =
|
|
58672
|
+
const [stopRequested, setStopRequested] = useState35(false);
|
|
58673
|
+
const [isRevealing, setIsRevealing] = useState35(false);
|
|
58674
|
+
const [inputText, setInputText] = useState35("");
|
|
58675
|
+
const [queueNotice, setQueueNotice] = useState35(null);
|
|
58676
|
+
const [queuePendingItemId, setQueuePendingItemId] = useState35(null);
|
|
58677
|
+
const [queuePanelVisible, setQueuePanelVisible] = useState35(false);
|
|
58678
|
+
const [resultFeedback, setResultFeedback] = useState35([]);
|
|
58679
|
+
const [timelineRewrite, setTimelineRewrite] = useState35(0);
|
|
58831
58680
|
const resolvedSessionId = session?.sessionId;
|
|
58832
58681
|
const isViewer = state?.viewerRole === "viewer";
|
|
58833
58682
|
const canUseQueue = !isViewer;
|
|
@@ -59075,10 +58924,10 @@ ${content3}`);
|
|
|
59075
58924
|
}
|
|
59076
58925
|
|
|
59077
58926
|
// src/components/LlmChat.tsx
|
|
59078
|
-
import { useEffect as useEffect27, useMemo as useMemo19, useState as
|
|
58927
|
+
import { useEffect as useEffect27, useMemo as useMemo19, useState as useState37 } from "react";
|
|
59079
58928
|
|
|
59080
58929
|
// src/components/LlmAdvancedSettings.tsx
|
|
59081
|
-
import { useState as
|
|
58930
|
+
import { useState as useState36 } from "react";
|
|
59082
58931
|
import { jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
59083
58932
|
var FIELDS = [
|
|
59084
58933
|
{ id: "baseURL", label: "\u6A21\u578B\u670D\u52A1\u5730\u5740", placeholder: "http://\u5185\u7F51\u5730\u5740/v1" },
|
|
@@ -59125,8 +58974,8 @@ function writeOverride(settings, baseURL, override) {
|
|
|
59125
58974
|
}
|
|
59126
58975
|
function LlmAdvancedSettingsBar({ settings, defaults: defaults2, override, onChange }) {
|
|
59127
58976
|
const normalized = normalizeAdvanced(settings);
|
|
59128
|
-
const [open2, setOpen] =
|
|
59129
|
-
const [draft, setDraft] =
|
|
58977
|
+
const [open2, setOpen] = useState36(false);
|
|
58978
|
+
const [draft, setDraft] = useState36(override);
|
|
59130
58979
|
if (!normalized) return null;
|
|
59131
58980
|
const fields2 = FIELDS.filter((field) => normalized[field.id]);
|
|
59132
58981
|
const dirty = Object.keys(override).length > 0;
|
|
@@ -59209,12 +59058,12 @@ function LlmChat({
|
|
|
59209
59058
|
onOverrideChange,
|
|
59210
59059
|
...options
|
|
59211
59060
|
}) {
|
|
59212
|
-
const [override, setOverride] =
|
|
59061
|
+
const [override, setOverride] = useState37(() => readOverride(advanced, options.baseURL));
|
|
59213
59062
|
const effective = { ...options, ...override };
|
|
59214
59063
|
const { messages, isStreaming, error: error61, send, stop, reset } = useLlmChat(effective);
|
|
59215
|
-
const [inputText, setInputText] =
|
|
59216
|
-
const [stopRequested, setStopRequested] =
|
|
59217
|
-
const [isRevealing, setIsRevealing] =
|
|
59064
|
+
const [inputText, setInputText] = useState37("");
|
|
59065
|
+
const [stopRequested, setStopRequested] = useState37(false);
|
|
59066
|
+
const [isRevealing, setIsRevealing] = useState37(false);
|
|
59218
59067
|
const isStreamingDisplay = isStreaming || isRevealing;
|
|
59219
59068
|
const handle = useMemo19(
|
|
59220
59069
|
() => ({
|
|
@@ -59296,7 +59145,7 @@ function ChatView(props) {
|
|
|
59296
59145
|
}
|
|
59297
59146
|
|
|
59298
59147
|
// src/components/ConnectorPanel.tsx
|
|
59299
|
-
import { useCallback as useCallback31, useEffect as useEffect28, useMemo as useMemo20, useRef as useRef29, useState as
|
|
59148
|
+
import { useCallback as useCallback31, useEffect as useEffect28, useMemo as useMemo20, useRef as useRef29, useState as useState38 } from "react";
|
|
59300
59149
|
|
|
59301
59150
|
// src/components/connector-panel-types.ts
|
|
59302
59151
|
function selectionFromItem(item) {
|
|
@@ -59338,10 +59187,10 @@ function ConnectorPanel({
|
|
|
59338
59187
|
renderFooterActions,
|
|
59339
59188
|
className
|
|
59340
59189
|
}) {
|
|
59341
|
-
const [query, setQuery] =
|
|
59342
|
-
const [pendingCatalog, setPendingCatalog] =
|
|
59343
|
-
const [pendingLoading, setPendingLoading] =
|
|
59344
|
-
const [pendingError, setPendingError] =
|
|
59190
|
+
const [query, setQuery] = useState38("");
|
|
59191
|
+
const [pendingCatalog, setPendingCatalog] = useState38(null);
|
|
59192
|
+
const [pendingLoading, setPendingLoading] = useState38(false);
|
|
59193
|
+
const [pendingError, setPendingError] = useState38(false);
|
|
59345
59194
|
const activation = useSessionPluginActivation({
|
|
59346
59195
|
client,
|
|
59347
59196
|
// 首页不会走这个分支:待选在下面自己处理开关,不碰会话接口。
|
|
@@ -59615,7 +59464,7 @@ function ContextGroupCard({ contexts, className }) {
|
|
|
59615
59464
|
}
|
|
59616
59465
|
|
|
59617
59466
|
// src/components/SessionMemoryToggle.tsx
|
|
59618
|
-
import { useCallback as useCallback32, useEffect as useEffect29, useRef as useRef30, useState as
|
|
59467
|
+
import { useCallback as useCallback32, useEffect as useEffect29, useRef as useRef30, useState as useState39, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
59619
59468
|
import { jsx as jsx38, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
59620
59469
|
var saveStates = /* @__PURE__ */ new WeakMap();
|
|
59621
59470
|
function getSaveState(client, sessionId) {
|
|
@@ -59673,7 +59522,7 @@ function SessionMemoryToggle({
|
|
|
59673
59522
|
getSaving,
|
|
59674
59523
|
getSaving
|
|
59675
59524
|
);
|
|
59676
|
-
const [draftEnabled, setDraftEnabled] =
|
|
59525
|
+
const [draftEnabled, setDraftEnabled] = useState39(enabled);
|
|
59677
59526
|
const activeSessionIdRef = useRef30(sessionId);
|
|
59678
59527
|
activeSessionIdRef.current = sessionId;
|
|
59679
59528
|
useEffect29(() => {
|
|
@@ -63245,7 +63094,7 @@ var Portal2 = TooltipPortal;
|
|
|
63245
63094
|
var Content2 = TooltipContent;
|
|
63246
63095
|
|
|
63247
63096
|
// src/components/SessionBranchPicker.tsx
|
|
63248
|
-
import { useMemo as useMemo26, useState as
|
|
63097
|
+
import { useMemo as useMemo26, useState as useState49 } from "react";
|
|
63249
63098
|
import { jsx as jsx48, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
63250
63099
|
var ROW_HEIGHT = 32;
|
|
63251
63100
|
var SVG_WIDTH = 44;
|
|
@@ -63254,8 +63103,8 @@ function SessionBranchPicker({
|
|
|
63254
63103
|
disabled = false,
|
|
63255
63104
|
onCheckout
|
|
63256
63105
|
}) {
|
|
63257
|
-
const [checkoutError, setCheckoutError] =
|
|
63258
|
-
const [pendingNodeId, setPendingNodeId] =
|
|
63106
|
+
const [checkoutError, setCheckoutError] = useState49(null);
|
|
63107
|
+
const [pendingNodeId, setPendingNodeId] = useState49(null);
|
|
63259
63108
|
const hasHistory = tree.nodes.length > 0;
|
|
63260
63109
|
const layout = useMemo26(() => buildLayoutNodes(tree), [tree]);
|
|
63261
63110
|
const nodeMap = useMemo26(() => new Map(tree.nodes.map((node3) => [node3.id, node3])), [tree]);
|