@blade-hq/agent-react 2610.0.0-beta.7 → 2610.0.0-beta.71
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 +308 -8
- package/dist/chunk-G3PMV62Z.js +36 -0
- package/dist/{chunk-ZXXLY4RM.js → chunk-IA6J2NTB.js} +9 -32
- package/dist/{chunk-ZXXLY4RM.js.map → chunk-IA6J2NTB.js.map} +1 -1
- package/dist/components/AgentChat.d.ts +3 -0
- package/dist/components/AgentLoopBlock.d.ts +3 -5
- package/dist/components/AskUserQuestionBlock.d.ts +12 -1
- package/dist/components/AssistantTurnBlock.d.ts +26 -8
- package/dist/components/ChatInput.d.ts +21 -1
- package/dist/components/ChatSurface.d.ts +133 -2
- package/dist/components/ChatView.d.ts +1 -1
- package/dist/components/ConnectorPanel.d.ts +41 -0
- package/dist/components/ContextCard.d.ts +20 -0
- package/dist/components/MarkdownContent.d.ts +2 -0
- package/dist/components/McpAppCard.d.ts +14 -0
- package/dist/components/MessageList.d.ts +38 -4
- package/dist/components/PlanUpdateBlock.d.ts +32 -0
- package/dist/components/PluginConnectorList.d.ts +47 -0
- package/dist/components/PluginTriggerStack.d.ts +22 -0
- package/dist/components/PostChatFollowupBlock.d.ts +5 -1
- package/dist/components/SessionMemoryToggle.d.ts +19 -0
- package/dist/components/SessionPluginConfigDialog.d.ts +10 -0
- package/dist/components/SessionPluginConfigForm.d.ts +14 -0
- package/dist/components/SessionPluginIcon.d.ts +30 -0
- package/dist/components/SessionPluginSelector.d.ts +10 -0
- package/dist/components/SessionQueuePanel.d.ts +74 -0
- package/dist/components/ToolCallBlock.d.ts +9 -3
- package/dist/components/ToolUiCardView.d.ts +9 -0
- package/dist/components/TurnNavRail.d.ts +23 -0
- package/dist/components/UserMessageBubble.d.ts +7 -3
- package/dist/components/WhatIfUserBubble.d.ts +7 -0
- package/dist/components/connector-panel-types.d.ts +37 -0
- package/dist/components/display-utils.d.ts +10 -0
- package/dist/components/plugin-config-draft.d.ts +13 -0
- package/dist/components/plugin-config-schema.d.ts +6 -0
- package/dist/components/plugin-connector.d.ts +40 -0
- package/dist/components/queue-panel-adjacency.d.ts +1 -0
- package/dist/components/use-session-plugin-activation.d.ts +40 -0
- package/dist/context.d.ts +1 -0
- package/dist/embed/blade-chat-element.d.ts +4 -3
- package/dist/embed/entry.d.ts +48 -0
- package/dist/{highlighted-body-B3W2YXNL-YD7FAP6V.js → highlighted-body-B3W2YXNL-YF4GVJGP.js} +3 -2
- package/dist/{highlighted-body-B3W2YXNL-YD7FAP6V.js.map → highlighted-body-B3W2YXNL-YF4GVJGP.js.map} +1 -1
- package/dist/hooks/use-agent-session.d.ts +5 -0
- package/dist/hooks/use-message-pin.d.ts +28 -0
- package/dist/hooks/use-turn-navigation.d.ts +117 -0
- package/dist/hooks/use-typewriter-reveal.d.ts +32 -0
- package/dist/index.d.ts +49 -1
- package/dist/index.js +45645 -1787
- package/dist/index.js.map +1 -1
- package/dist/lib/agent-computer-command.d.ts +34 -0
- package/dist/lib/random-id.d.ts +10 -0
- package/dist/lib/utils.d.ts +17 -2
- package/dist/lib/whatif-prompt.d.ts +18 -0
- package/dist/mermaid-3ZIDBTTL-QL4YGD6I.js +9 -0
- package/dist/mermaid-3ZIDBTTL-QL4YGD6I.js.map +1 -0
- package/dist/style.css +488 -402
- package/dist/style.full.css +499 -406
- package/dist/webapi-W3IB5DO4.js +2481 -0
- package/dist/webapi-W3IB5DO4.js.map +1 -0
- package/package.json +2 -2
- package/public-api.md +1657 -76
- package/dist/mermaid-3ZIDBTTL-N7YKJ3SM.js +0 -8
- /package/dist/{mermaid-3ZIDBTTL-N7YKJ3SM.js.map → chunk-G3PMV62Z.js.map} +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AgentSession, CreateSessionRequest } from "@blade-hq/agent-client";
|
|
2
|
+
import { type ReactNode } from "react";
|
|
2
3
|
import { type ChatPresentationProps } from "./ChatSurface";
|
|
3
4
|
import type { FollowupInteractionEvent } from "./PostChatFollowupBlock";
|
|
4
5
|
export interface AgentChatProps extends ChatPresentationProps {
|
|
@@ -13,6 +14,8 @@ export interface AgentChatProps extends ChatPresentationProps {
|
|
|
13
14
|
onSessionReady?: (session: AgentSession) => void;
|
|
14
15
|
/** 智能体下发给宿主页面的指令处理器(action → handler)。 */
|
|
15
16
|
commands?: Record<string, (data: unknown) => void>;
|
|
17
|
+
/** 覆盖默认会话插件选择器。 */
|
|
18
|
+
sessionPluginControls?: (sessionId: string) => ReactNode;
|
|
16
19
|
}
|
|
17
20
|
/**
|
|
18
21
|
* 智能体模式的聊天界面:连接(或新建)一个 Blade 会话,渲染消息流与输入框。
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import type { ToolCallInfo } from "@blade-hq/agent-client";
|
|
2
2
|
interface Props {
|
|
3
3
|
toolCall: ToolCallInfo;
|
|
4
|
+
className?: string;
|
|
4
5
|
}
|
|
5
|
-
/**
|
|
6
|
-
|
|
7
|
-
* 不再嵌套渲染子循环的完整消息流(那是第一方界面的能力)。
|
|
8
|
-
*/
|
|
9
|
-
export declare function AgentLoopBlock({ toolCall }: Props): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
/** SDK 没有第一方子循环消息流,只保留轻量意图行和可展开的最终结果。 */
|
|
7
|
+
export declare function AgentLoopBlock({ toolCall, className }: Props): import("react/jsx-runtime").JSX.Element;
|
|
10
8
|
export {};
|
|
@@ -23,9 +23,20 @@ interface Props {
|
|
|
23
23
|
sessionStatus: string;
|
|
24
24
|
answerData?: AskUserAnswerData | undefined;
|
|
25
25
|
onAnswer?: (answer: string, toolCallId: string, answerData: AskUserAnswerData) => void;
|
|
26
|
+
className?: string;
|
|
27
|
+
optionClassName?: string;
|
|
26
28
|
}
|
|
27
29
|
/** 提问选项卡片:单选/多选 + 自定义输入,回答通过 onAnswer 回调交还 ChatView。 */
|
|
28
|
-
export declare function AskUserQuestionBlock({ data, answered, toolCallId, sessionStatus, answerData, onAnswer, }: Props): import("react/jsx-runtime").JSX.Element;
|
|
30
|
+
export declare function AskUserQuestionBlock({ data, answered, toolCallId, sessionStatus, answerData, onAnswer, className, optionClassName, }: Props): import("react/jsx-runtime").JSX.Element;
|
|
29
31
|
/** 解析 AskUserQuestion 的工具结果/参数,容错 LLM 把 questions 输出为字符串的情况。 */
|
|
30
32
|
export declare function parseAskUserQuestion(toolResult: string | null | undefined): AskUserQuestionData | null;
|
|
33
|
+
export interface AskUserQuestionError {
|
|
34
|
+
message: string;
|
|
35
|
+
detail: string | null;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Keep this parser synchronized with apps/web/AskUserQuestionBlock.tsx.
|
|
39
|
+
* The built-in Web cannot import agent-react, and this is not a public SDK protocol API.
|
|
40
|
+
*/
|
|
41
|
+
export declare function parseAskUserQuestionError(toolResult: string | null | undefined): AskUserQuestionError | null;
|
|
31
42
|
export {};
|
|
@@ -1,18 +1,36 @@
|
|
|
1
|
-
import type { AskUserAnswerData, ChatMessage } from "@blade-hq/agent-client";
|
|
2
|
-
import {
|
|
1
|
+
import type { AskUserAnswerData, ChatMessage, MemoryRefInfo } from "@blade-hq/agent-client";
|
|
2
|
+
import type { ChatViewClassNames, ChatViewRenderers } from "./ChatSurface";
|
|
3
3
|
interface Props {
|
|
4
4
|
messages: ChatMessage[];
|
|
5
5
|
isStreaming?: boolean;
|
|
6
6
|
askAnswers?: Record<string, AskUserAnswerData>;
|
|
7
7
|
onAnswer?: (answer: string, toolCallId: string, answerData: AskUserAnswerData) => void;
|
|
8
8
|
sessionStatus?: string;
|
|
9
|
-
|
|
9
|
+
/** 各可见区块的 className 落点;键与元素上的 `blade-chat-*` 锚点一一对应。 */
|
|
10
|
+
classNames?: ChatViewClassNames;
|
|
11
|
+
/** 区块级渲染器;返回 null 走默认渲染。 */
|
|
12
|
+
renderers?: ChatViewRenderers;
|
|
13
|
+
/** Agent 模式把 update_plan 收口到输入框上方的任务面板;纯 LLM 同名工具照常展示。 */
|
|
14
|
+
hidePlanUpdateTools?: boolean;
|
|
10
15
|
/** 会话 id;传给 Markdown 渲染的统一上下文。 */
|
|
11
16
|
sessionId?: string;
|
|
12
17
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
export type TurnDisplayMode = "compact" | "detail";
|
|
19
|
+
export declare function resolveTurnDisplayMode({ isStreaming: _isStreaming, displayMode, }: {
|
|
20
|
+
isStreaming: boolean;
|
|
21
|
+
displayMode: TurnDisplayMode;
|
|
22
|
+
}): TurnDisplayMode;
|
|
23
|
+
export declare function formatExecutionDuration(durationMs: number): string;
|
|
24
|
+
export declare function getExecutionDurationMs({ messages, isStreaming, now, }: {
|
|
25
|
+
messages: ChatMessage[];
|
|
26
|
+
isStreaming: boolean;
|
|
27
|
+
now?: number;
|
|
28
|
+
}): number;
|
|
29
|
+
/** 一轮助手回复:执行过程默认折叠,最终正文始终显示在摘要下方。 */
|
|
30
|
+
export declare function AssistantTurnBlock({ messages, isStreaming, askAnswers, onAnswer, sessionStatus, classNames, renderers, hidePlanUpdateTools, sessionId, }: Props): import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
export declare function collectMemoryRefs(messages: ChatMessage[]): MemoryRefInfo[];
|
|
32
|
+
export declare function MemoryRefsHint({ refs, className }: {
|
|
33
|
+
refs: MemoryRefInfo[];
|
|
34
|
+
className?: string;
|
|
35
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
18
36
|
export {};
|
|
@@ -6,13 +6,33 @@ interface Props {
|
|
|
6
6
|
onStop: () => void;
|
|
7
7
|
isStreaming: boolean;
|
|
8
8
|
isStopping?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* 宿主是否渲染了队列面板。没有面板时不给"运行中提交"入口:消息进了队列却看不见,
|
|
11
|
+
* 比明确提示用户等一等更糟。ChatSurface 按 queuePanel 是否存在传入。
|
|
12
|
+
*/
|
|
13
|
+
queueWhileRunning?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* 上方紧贴着一个比自己窄的面板(队列面板)时置 true:上两角改直角。
|
|
16
|
+
*
|
|
17
|
+
* 面板比输入框窄一圈,输入框上角留圆弧的话,那两段弧会从面板两侧露出来,
|
|
18
|
+
* 看着就是两个尖角。跟内置 Web 的 ChatInput 是同一个判据。
|
|
19
|
+
*/
|
|
20
|
+
mergesWithPanelAbove?: boolean;
|
|
9
21
|
placeholder?: string;
|
|
10
22
|
className?: string;
|
|
23
|
+
/** 输入框卡片(`.blade-chat-input-inner`):边框、圆角、底色在这里。 */
|
|
24
|
+
innerClassName?: string;
|
|
25
|
+
/** 文本输入框(`.blade-chat-textarea`)。 */
|
|
26
|
+
textareaClassName?: string;
|
|
27
|
+
/** 右侧按钮组(`.blade-chat-input-toolbar`)。 */
|
|
28
|
+
toolbarClassName?: string;
|
|
29
|
+
queueKey?: string;
|
|
30
|
+
hasAttachments?: boolean;
|
|
11
31
|
}
|
|
12
32
|
/**
|
|
13
33
|
* 轻量聊天输入框:textarea(Enter 发送 / Shift+Enter 换行)+ 发送/停止按钮。
|
|
14
34
|
* 不含第一方版本的富文本编辑、@ 补全、技能菜单、语音输入与模型选择。
|
|
15
35
|
* 内容受控,session.attach() / insertText() 通过 ChatView 注入到这里。
|
|
16
36
|
*/
|
|
17
|
-
export declare function ChatInput({ value, onValueChange, onSend, onStop, isStreaming, isStopping, placeholder, className, }: Props): import("react/jsx-runtime").JSX.Element;
|
|
37
|
+
export declare function ChatInput({ value, onValueChange, onSend, onStop, isStreaming, isStopping, queueWhileRunning, mergesWithPanelAbove, placeholder, className, innerClassName, textareaClassName, toolbarClassName, queueKey, hasAttachments, }: Props): import("react/jsx-runtime").JSX.Element;
|
|
18
38
|
export {};
|
|
@@ -1,17 +1,119 @@
|
|
|
1
1
|
import type { AskUserAnswerData, ChatMessage, ConnectionStatus, PostChatFollowup } from "@blade-hq/agent-client";
|
|
2
|
-
import type
|
|
2
|
+
import { type ReactNode } from "react";
|
|
3
|
+
import type { TurnNavigationSource } from "../hooks/use-turn-navigation";
|
|
3
4
|
import type { ToolCallRenderer } from "./ToolCallBlock";
|
|
4
5
|
import type { FollowupInteractionEvent } from "./PostChatFollowupBlock";
|
|
5
6
|
import type { ResultFeedback } from "@blade-hq/agent-client";
|
|
7
|
+
import { type PlanUpdateData } from "./PlanUpdateBlock";
|
|
8
|
+
import type { AskUserQuestionData } from "./AskUserQuestionBlock";
|
|
9
|
+
/**
|
|
10
|
+
* 每个可见区块的 className 落点,键名与元素上的 `blade-chat-*` 语义锚点一一对应。
|
|
11
|
+
*
|
|
12
|
+
* 传进来的类会与 SDK 自己的类一起经过 `cn`(clsx + tailwind-merge),放在
|
|
13
|
+
* 最后一个参数,因此 `classNames={{ chatInput: "p-0" }}` 能盖掉组件内部的 `p-4`,
|
|
14
|
+
* 不依赖 CSS 输出顺序、也不需要 `!important`。锚点本身不带视觉规则(清单见
|
|
15
|
+
* README「样式定制」与 src/style.css 顶部),用普通 CSS 选它们同样稳定生效。
|
|
16
|
+
*/
|
|
6
17
|
export interface ChatViewClassNames {
|
|
18
|
+
/** 聊天根容器(`.blade-chat`)。 */
|
|
7
19
|
root?: string;
|
|
20
|
+
/** 连接状态提示条(`.blade-chat-banner`)。 */
|
|
8
21
|
banner?: string;
|
|
22
|
+
/** 顶部出错条(`.blade-chat-error-bar`)。 */
|
|
23
|
+
errorBar?: string;
|
|
24
|
+
/** 消息区(`.blade-chat-messages`)。 */
|
|
9
25
|
messageList?: string;
|
|
26
|
+
/** 消息区滚动内容(`.blade-chat-messages-scroll`):内边距在这里。 */
|
|
27
|
+
messagesScroll?: string;
|
|
28
|
+
/** 消息内容列(`.blade-chat-messages-content`):居中与最大宽度在这里。 */
|
|
29
|
+
messagesContent?: string;
|
|
30
|
+
/** 无消息时的空状态(`.blade-chat-empty`)。 */
|
|
31
|
+
empty?: string;
|
|
32
|
+
/** 「滚动到底部」按钮(`.blade-chat-scroll-bottom`)。 */
|
|
33
|
+
scrollToBottom?: string;
|
|
34
|
+
/** 用户消息行(`.blade-chat-user-row`)。 */
|
|
35
|
+
userMessage?: string;
|
|
36
|
+
/** 用户气泡(`.blade-chat-user-bubble`)。 */
|
|
37
|
+
userBubble?: string;
|
|
38
|
+
/** 消息里的文件附件卡(`.blade-chat-file-card`)。 */
|
|
39
|
+
fileCard?: string;
|
|
40
|
+
/** 消息流里的出错块(`.blade-chat-error-row`)。 */
|
|
41
|
+
errorMessage?: string;
|
|
42
|
+
/** 一轮助手回复(`.blade-chat-assistant-turn`)。 */
|
|
43
|
+
assistantTurn?: string;
|
|
44
|
+
/** 思考过程(`.blade-chat-thinking`)。 */
|
|
45
|
+
thinking?: string;
|
|
46
|
+
/** 助手正文(`.blade-chat-assistant-text`)。 */
|
|
47
|
+
assistantText?: string;
|
|
48
|
+
/** 记忆引用(`.blade-chat-memory-refs`)。 */
|
|
49
|
+
memoryRefs?: string;
|
|
50
|
+
/** 执行过程里的工具行(`.blade-chat-tool-row`):智能体模式下工具调用都走这条路径。 */
|
|
51
|
+
toolRow?: string;
|
|
52
|
+
/** 子智能体行(`.blade-chat-agent-loop`)。 */
|
|
53
|
+
agentLoop?: string;
|
|
54
|
+
/** 提问卡(`.blade-chat-ask-card`)。 */
|
|
55
|
+
askCard?: string;
|
|
56
|
+
/** 提问卡的每个选项(`.blade-chat-ask-option`)。 */
|
|
57
|
+
askOption?: string;
|
|
58
|
+
/** 计划面板(`.blade-chat-plan`)。 */
|
|
59
|
+
planPanel?: string;
|
|
60
|
+
/** 会话队列面板(`.blade-chat-queue`)。 */
|
|
61
|
+
queuePanel?: string;
|
|
62
|
+
/** 本轮小结与跟进区(`.blade-chat-followup`)。 */
|
|
63
|
+
followup?: string;
|
|
64
|
+
/** 跟进建议按钮(`.blade-chat-followup-action`)。 */
|
|
65
|
+
followupAction?: string;
|
|
66
|
+
/** 输入区外层(`.blade-chat-input`)。 */
|
|
10
67
|
chatInput?: string;
|
|
68
|
+
/** 输入框卡片(`.blade-chat-input-inner`):边框、圆角、底色在这里。 */
|
|
69
|
+
inputInner?: string;
|
|
70
|
+
/** 文本输入框(`.blade-chat-textarea`)。 */
|
|
71
|
+
textarea?: string;
|
|
72
|
+
/** 输入框右侧按钮组(`.blade-chat-input-toolbar`)。 */
|
|
73
|
+
inputToolbar?: string;
|
|
74
|
+
}
|
|
75
|
+
/** 用户消息渲染器:`message` 是投影层给出的用户消息。 */
|
|
76
|
+
export interface UserMessageRendererProps {
|
|
77
|
+
message: ChatMessage;
|
|
11
78
|
}
|
|
79
|
+
/** 助手正文渲染器:`compact` 为真时正文在执行过程里,字号更小。 */
|
|
80
|
+
export interface AssistantTextRendererProps {
|
|
81
|
+
message: ChatMessage;
|
|
82
|
+
streaming: boolean;
|
|
83
|
+
compact: boolean;
|
|
84
|
+
sessionId?: string;
|
|
85
|
+
}
|
|
86
|
+
/** 提问卡渲染器:字段与 `AskUserQuestionBlock` 的 props 一致。 */
|
|
87
|
+
export interface AskUserQuestionRendererProps {
|
|
88
|
+
data: AskUserQuestionData;
|
|
89
|
+
answered: boolean;
|
|
90
|
+
toolCallId: string;
|
|
91
|
+
sessionStatus: string;
|
|
92
|
+
answerData?: AskUserAnswerData;
|
|
93
|
+
onAnswer?: (answer: string, toolCallId: string, answerData: AskUserAnswerData) => void;
|
|
94
|
+
}
|
|
95
|
+
/** 计划面板渲染器:`plan` 是最近一次成功的 update_plan 解析结果。 */
|
|
96
|
+
export interface PlanUpdateRendererProps {
|
|
97
|
+
plan: PlanUpdateData;
|
|
98
|
+
running: boolean;
|
|
99
|
+
sessionId?: string;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* 区块级渲染器:每个都返回 `ReactNode`,返回 `null` 走 SDK 默认渲染。
|
|
103
|
+
*
|
|
104
|
+
* 与 `toolCall` 的老签名一致:参数是一个描述该区块的对象,而不是裸数据。
|
|
105
|
+
*/
|
|
12
106
|
export interface ChatViewRenderers {
|
|
13
107
|
/** 自定义工具调用渲染;返回 null 走默认渲染。 */
|
|
14
108
|
toolCall?: ToolCallRenderer;
|
|
109
|
+
/** 自定义用户消息渲染;返回 null 走默认渲染。 */
|
|
110
|
+
userMessage?: (props: UserMessageRendererProps) => ReactNode | null;
|
|
111
|
+
/** 自定义助手正文渲染;返回 null 走默认渲染。 */
|
|
112
|
+
assistantText?: (props: AssistantTextRendererProps) => ReactNode | null;
|
|
113
|
+
/** 自定义提问卡渲染;返回 null 走默认渲染。 */
|
|
114
|
+
askUserQuestion?: (props: AskUserQuestionRendererProps) => ReactNode | null;
|
|
115
|
+
/** 自定义计划面板渲染;返回 null 走默认渲染。 */
|
|
116
|
+
planUpdate?: (props: PlanUpdateRendererProps) => ReactNode | null;
|
|
15
117
|
}
|
|
16
118
|
export interface ChatViewSlots {
|
|
17
119
|
/** 消息列表上方的自定义区域。 */
|
|
@@ -55,8 +157,37 @@ interface ChatSurfaceProps extends ChatPresentationProps {
|
|
|
55
157
|
onResultFeedbackSaved?: (feedback: ResultFeedback) => void;
|
|
56
158
|
/** 输入框上方的内部区域(纯 LLM 模式的高级设置用)。不传时不渲染任何节点。 */
|
|
57
159
|
beforeInput?: ReactNode;
|
|
160
|
+
/** 输入框上方的会话队列面板(智能体模式用)。不传时不渲染任何节点。 */
|
|
161
|
+
queuePanel?: ReactNode;
|
|
162
|
+
/**
|
|
163
|
+
* 队列面板此刻是否真的占位(由面板的 `onVisibleChange` 上报)。
|
|
164
|
+
*
|
|
165
|
+
* 不能用 `queuePanel != null` 代替:面板有本地编辑态(编辑到一半、那条等待
|
|
166
|
+
* 消息被服务端拿走时仍留在原地保住草稿),这时它显示但 snapshot 里没有条目,
|
|
167
|
+
* 光看节点是否存在判不出来,输入框上两角就会在面板还开着的时候恢复成圆角。
|
|
168
|
+
*/
|
|
169
|
+
queuePanelVisible?: boolean;
|
|
170
|
+
/** 仅 Agent 模式启用 Blade 的 update_plan 面板。 */
|
|
171
|
+
showPlanUpdates?: boolean;
|
|
172
|
+
/** 仅实时成功的 update_plan 递增;历史 hydration 不得改变。 */
|
|
173
|
+
planRevealRevision?: number;
|
|
174
|
+
historyPaging?: {
|
|
175
|
+
hasOlder: boolean;
|
|
176
|
+
loading: boolean;
|
|
177
|
+
/** Resolves true only when the paging cursor advanced. */
|
|
178
|
+
loadOlder: (beforeCommit?: () => void) => Promise<boolean>;
|
|
179
|
+
};
|
|
180
|
+
/** 消息导航的数据源(目录 + 定位);不传就没有导航轨道。 */
|
|
181
|
+
turnNavigation?: TurnNavigationSource;
|
|
58
182
|
/** 连接状态条下方的横幅(回放模式条用)。不传时不渲染任何节点。 */
|
|
59
183
|
banner?: ReactNode;
|
|
184
|
+
/**
|
|
185
|
+
* 打字机式显示节流是否还没追平目标全文——调用方需要跟 isStreaming 做
|
|
186
|
+
* `||` 判断输入框"运行中"状态。
|
|
187
|
+
*/
|
|
188
|
+
onRevealingChange?: (revealing: boolean) => void;
|
|
189
|
+
/** 是否正在回放(演示 / 彩排)而非真正的实时直播——透传给 MessageList。 */
|
|
190
|
+
isReplay?: boolean;
|
|
60
191
|
}
|
|
61
192
|
/**
|
|
62
193
|
* 消息流 + 输入框:智能体模式与纯 LLM 模式共用同一套外观,差别只在谁喂数据。
|
|
@@ -64,5 +195,5 @@ interface ChatSurfaceProps extends ChatPresentationProps {
|
|
|
64
195
|
* 这里的 DOM 结构受 tests/chat-view-compat.test.tsx 的快照保护——接入方拿
|
|
65
196
|
* .blade-chat-* 类名写了自己的样式,结构一动他们的页面就歪。
|
|
66
197
|
*/
|
|
67
|
-
export declare function ChatSurface({ theme, classNames, renderers, slots, placeholder, connection, errorMessage, messages, postChatFollowup, isStreaming, isStopping, inputText, onInputChange, onSuggestion, onSend, onStop, sessionStatus, askAnswers, onAnswer, sessionId, isViewer, resultFeedbackByEntry, onResultFeedbackSaved, onFollowupInteraction, beforeInput, banner, }: ChatSurfaceProps): import("react/jsx-runtime").JSX.Element;
|
|
198
|
+
export declare function ChatSurface({ theme, classNames, renderers, slots, placeholder, connection, errorMessage, messages, postChatFollowup, isStreaming, isStopping, inputText, onInputChange, onSuggestion, onSend, onStop, sessionStatus, askAnswers, onAnswer, sessionId, isViewer, resultFeedbackByEntry, onResultFeedbackSaved, onFollowupInteraction, beforeInput, queuePanel, queuePanelVisible, showPlanUpdates, planRevealRevision, historyPaging, turnNavigation, banner, onRevealingChange, isReplay, }: ChatSurfaceProps): import("react/jsx-runtime").JSX.Element;
|
|
68
199
|
export {};
|
|
@@ -2,7 +2,7 @@ import { type AgentChatProps } from "./AgentChat";
|
|
|
2
2
|
import { type LlmChatHandle } from "./LlmChat";
|
|
3
3
|
import type { LlmAdvancedSettings, LlmOverride } from "./LlmAdvancedSettings";
|
|
4
4
|
import type { LlmChatOptions } from "../hooks/use-llm-chat";
|
|
5
|
-
export type { ChatViewClassNames, ChatViewRenderers, ChatViewSlots, } from "./ChatSurface";
|
|
5
|
+
export type { AssistantTextRendererProps, AskUserQuestionRendererProps, ChatViewClassNames, ChatViewRenderers, ChatViewSlots, PlanUpdateRendererProps, UserMessageRendererProps, } from "./ChatSurface";
|
|
6
6
|
export type { FollowupInteractionEvent } from "./PostChatFollowupBlock";
|
|
7
7
|
export interface ChatViewProps extends AgentChatProps {
|
|
8
8
|
/** 挂哪个下层组件。默认 `agent`——不传就是接 Blade 智能体会话的原有行为。 */
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { BladeClient, SessionPluginActivation } from "@blade-hq/agent-client";
|
|
2
|
+
import { type ReactNode } from "react";
|
|
3
|
+
import { type PluginConnectorItem } from "./plugin-connector";
|
|
4
|
+
import { type PluginConnectorSelection } from "./connector-panel-types";
|
|
5
|
+
export interface ConnectorPanelProps {
|
|
6
|
+
client: BladeClient;
|
|
7
|
+
/**
|
|
8
|
+
* `null` 表示首页:插件开关只记下本次输入的待选,不激活任何东西、不建会话、
|
|
9
|
+
* 不启动沙盒或 MCP。待选项随首条消息一起交给宿主处理。
|
|
10
|
+
*/
|
|
11
|
+
sessionId: string | null;
|
|
12
|
+
/** 首页待选插件;`sessionId` 为 null 时使用。 */
|
|
13
|
+
pendingPlugins?: PluginConnectorSelection[];
|
|
14
|
+
onPendingPluginsChange?: (next: PluginConnectorSelection[]) => void;
|
|
15
|
+
/** 首页候选开关不可用时的说明(例如软件工厂模式会先建项目再启动)。 */
|
|
16
|
+
pendingDisabledReason?: string | null;
|
|
17
|
+
/** 会话内插件启用/停用结果;宿主据此刷新技能统计。 */
|
|
18
|
+
onPluginsChanged?: (plugin: SessionPluginActivation) => void;
|
|
19
|
+
/**
|
|
20
|
+
* 当前已选(首页待选 / 会话内已启用)的插件,按行原样报给宿主。
|
|
21
|
+
*
|
|
22
|
+
* 触发器要在不打开面板时就能显示「选了哪几个、几个」,它自己拿不到这份状态,
|
|
23
|
+
* 所以由面板单向汇报;面板未挂载时宿主保留上一次的结果。
|
|
24
|
+
*/
|
|
25
|
+
onSelectedChange?: (items: PluginConnectorItem[]) => void;
|
|
26
|
+
/** 宿主注入:电脑分区。参数是搜索词,宿主自己决定怎么过滤。 */
|
|
27
|
+
renderComputerSection?: (query: string) => ReactNode;
|
|
28
|
+
/** 宿主注入:外部账号分区(飞书 / GitHub 等固定连接入口)。 */
|
|
29
|
+
renderExternalAccounts?: (query: string) => ReactNode;
|
|
30
|
+
/** 宿主注入:底部操作区;不注入就不渲染这一块。 */
|
|
31
|
+
renderFooterActions?: () => ReactNode;
|
|
32
|
+
className?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* 统一连接器面板:顶部搜索、按「电脑 / 插件 / 外部账号」分区、底部添加与管理。
|
|
36
|
+
*
|
|
37
|
+
* 插件分区是这一层唯一的共享实现:首页和会话用同一个列表、同一套启用判定,
|
|
38
|
+
* 判定不各写一份。电脑与外部账号由宿主注入——那些入口需要宿主的路由与 CLI
|
|
39
|
+
* 引导,SDK 不硬编码内部路径,也不替第三方决定跳到哪里。
|
|
40
|
+
*/
|
|
41
|
+
export declare function ConnectorPanel({ client, sessionId, pendingPlugins, onPendingPluginsChange, pendingDisabledReason, onPluginsChanged, onSelectedChange, renderComputerSection, renderExternalAccounts, renderFooterActions, className, }: ConnectorPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type ContextProjectionData } from "@blade-hq/agent-client";
|
|
2
|
+
export interface ContextCardProps {
|
|
3
|
+
context: ContextProjectionData;
|
|
4
|
+
className?: string;
|
|
5
|
+
}
|
|
6
|
+
/** Business-facing Context summary. Native details keeps every card collapsed by default. */
|
|
7
|
+
export declare function ContextCard({ context, className }: ContextCardProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export interface ContextGroupCardProps {
|
|
9
|
+
contexts: readonly ContextProjectionData[];
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* 一批上下文注入折叠成一行。会话首轮会一次注入十几个原子,一条一张卡片会把
|
|
14
|
+
* 真正的对话挤出屏幕。
|
|
15
|
+
*
|
|
16
|
+
* 单条和多条**共用同一个 details 外壳**,不在数量变化时切换组件:流式时第二条
|
|
17
|
+
* 到达会让这一行从单条变成多条,组件类型一换 React 就重挂 <details>,
|
|
18
|
+
* 用户刚展开的行会被收起来。同理,key 由调用方按组内第一条给,不能带数量。
|
|
19
|
+
*/
|
|
20
|
+
export declare function ContextGroupCard({ contexts, className }: ContextGroupCardProps): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { BladeClient } from "@blade-hq/agent-client";
|
|
2
|
+
export interface McpAppMessage {
|
|
3
|
+
sessionId: string;
|
|
4
|
+
sourceId: string;
|
|
5
|
+
label: string;
|
|
6
|
+
content: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const McpAppMessageContext: import("react").Context<((message: McpAppMessage) => void) | null>;
|
|
9
|
+
export declare function McpAppCard({ sessionId, sourceId, client: suppliedClient, onMessage: suppliedOnMessage }: {
|
|
10
|
+
sessionId: string;
|
|
11
|
+
sourceId: string;
|
|
12
|
+
client?: BladeClient;
|
|
13
|
+
onMessage?: (message: McpAppMessage) => void;
|
|
14
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { AskUserAnswerData, ChatMessage, PostChatFollowup, ResultFeedback } from "@blade-hq/agent-client";
|
|
2
2
|
import { type ReactNode } from "react";
|
|
3
|
+
import { type TurnNavigationSource } from "../hooks/use-turn-navigation";
|
|
3
4
|
import { type FollowupInteractionEvent } from "./PostChatFollowupBlock";
|
|
4
|
-
import type {
|
|
5
|
+
import type { ChatViewClassNames, ChatViewRenderers } from "./ChatSurface";
|
|
5
6
|
interface Props {
|
|
6
7
|
messages: ChatMessage[];
|
|
7
8
|
postChatFollowup?: PostChatFollowup | null;
|
|
@@ -10,19 +11,52 @@ interface Props {
|
|
|
10
11
|
sessionStatus?: string;
|
|
11
12
|
askAnswers?: Record<string, AskUserAnswerData>;
|
|
12
13
|
onAnswer?: (answer: string, toolCallId: string, answerData: AskUserAnswerData) => void;
|
|
13
|
-
|
|
14
|
+
hidePlanUpdateTools?: boolean;
|
|
15
|
+
/** 无消息时替换默认空状态。 */
|
|
14
16
|
emptyState?: ReactNode;
|
|
15
|
-
className
|
|
17
|
+
/** 各可见区块的 className 落点;键与元素上的 `blade-chat-*` 锚点一一对应。 */
|
|
18
|
+
classNames?: ChatViewClassNames;
|
|
19
|
+
/** 区块级渲染器;返回 null 走默认渲染。 */
|
|
20
|
+
renderers?: ChatViewRenderers;
|
|
16
21
|
/** 会话 id;传给助手消息的统一上下文。 */
|
|
17
22
|
sessionId?: string;
|
|
18
23
|
isViewer?: boolean;
|
|
19
24
|
onFollowupInteraction?: (event: FollowupInteractionEvent) => void;
|
|
20
25
|
resultFeedbackByEntry?: ReadonlyMap<string, ResultFeedback>;
|
|
21
26
|
onResultFeedbackSaved?: (feedback: ResultFeedback) => void;
|
|
27
|
+
historyPaging?: {
|
|
28
|
+
hasOlder: boolean;
|
|
29
|
+
loading: boolean;
|
|
30
|
+
/** Resolves true only when the paging cursor advanced. */
|
|
31
|
+
loadOlder: (beforeCommit?: () => void) => Promise<boolean>;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* 消息导航的数据源(目录 + 定位)。不传就没有导航轨道,也不会请求目录——
|
|
35
|
+
* 纯 LLM 会话与自带入口的宿主都属于这种。
|
|
36
|
+
*/
|
|
37
|
+
turnNavigation?: TurnNavigationSource;
|
|
38
|
+
/**
|
|
39
|
+
* 用户点了停止(还没等服务端确认)——打字机式显示节流要在这一刻立刻整段
|
|
40
|
+
* 显示已到达内容,不能等 chat:stop 的服务端回包才响应。跟 isStreaming
|
|
41
|
+
* 翻转成 false 不是一回事:那个信号来得晚,点击到服务端确认之间有一段
|
|
42
|
+
* 网络往返,这段时间里节流动画不该继续播。
|
|
43
|
+
*/
|
|
44
|
+
isStopping?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* 打字机式显示节流是否还没追平目标全文——调用方需要跟 isStreaming 做
|
|
47
|
+
* `||` 判断输入框"运行中"状态,否则输入框会先于文字播完就翻回可输入。
|
|
48
|
+
*/
|
|
49
|
+
onRevealingChange?: (revealing: boolean) => void;
|
|
50
|
+
/**
|
|
51
|
+
* 是否正在回放(演示 / 彩排)而非真正的实时直播——回放期间即使内容在
|
|
52
|
+
* 增长也不进入打字机式节流,直接整段显示:这是"流式与历史必须产生相同
|
|
53
|
+
* 结果"这条硬规则的一部分,节流只在真正的实时直播里生效。
|
|
54
|
+
*/
|
|
55
|
+
isReplay?: boolean;
|
|
22
56
|
}
|
|
23
57
|
/**
|
|
24
58
|
* 消息列表:use-stick-to-bottom 自动滚动 + 按轮次分组渲染。
|
|
25
59
|
* 相比第一方版本去掉了轮次导航栏、吸顶状态条与规划摘要卡片。
|
|
26
60
|
*/
|
|
27
|
-
export declare function MessageList({ messages, postChatFollowup, onSuggestion, isStreaming, sessionStatus, askAnswers, onAnswer,
|
|
61
|
+
export declare function MessageList({ messages, postChatFollowup, onSuggestion, isStreaming, sessionStatus, askAnswers, onAnswer, hidePlanUpdateTools, emptyState, classNames, renderers, sessionId, isViewer, onFollowupInteraction, resultFeedbackByEntry, onResultFeedbackSaved, historyPaging, turnNavigation, isStopping, onRevealingChange, isReplay, }: Props): import("react/jsx-runtime").JSX.Element;
|
|
28
62
|
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ChatMessage, ToolCallInfo } from "@blade-hq/agent-client";
|
|
2
|
+
export type PlanStepStatus = "pending" | "in_progress" | "completed";
|
|
3
|
+
export interface PlanUpdateData {
|
|
4
|
+
plan: Array<{
|
|
5
|
+
step: string;
|
|
6
|
+
status: PlanStepStatus;
|
|
7
|
+
}>;
|
|
8
|
+
}
|
|
9
|
+
export declare const PLAN_AUTO_COLLAPSE_MS = 5000;
|
|
10
|
+
export declare function isPlanUpdateTool(toolCall: Pick<ToolCallInfo, "name">): boolean;
|
|
11
|
+
export interface PlanUpdateDisplayState {
|
|
12
|
+
current: ToolCallInfo | null;
|
|
13
|
+
updating: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare function getPlanUpdateDisplayState(messages: ChatMessage[]): PlanUpdateDisplayState;
|
|
16
|
+
export declare function parsePlanUpdate(argumentsJson: string): PlanUpdateData | null;
|
|
17
|
+
export declare function pickCurrentPlanStep(plan: PlanUpdateData["plan"]): PlanUpdateData["plan"][number] | null;
|
|
18
|
+
export declare function PlanUpdateBlock({ toolCall, running, autoReveal, className, }: {
|
|
19
|
+
toolCall: ToolCallInfo;
|
|
20
|
+
running?: boolean;
|
|
21
|
+
/** 实时收到的新进度短暂展开;加载历史时保持默认收起。 */
|
|
22
|
+
autoReveal?: boolean;
|
|
23
|
+
className?: string;
|
|
24
|
+
}): import("react/jsx-runtime").JSX.Element | null;
|
|
25
|
+
export declare function CurrentPlanPanel({ messages, running, revealRevision, sessionId, className, }: {
|
|
26
|
+
messages: ChatMessage[];
|
|
27
|
+
running?: boolean;
|
|
28
|
+
/** 仅实时成功的 update_plan 递增;历史 hydration 不得改变。 */
|
|
29
|
+
revealRevision?: number;
|
|
30
|
+
sessionId?: string;
|
|
31
|
+
className?: string;
|
|
32
|
+
}): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { BladeClient, SessionPluginConfigState } from "@blade-hq/agent-client";
|
|
2
|
+
import type { PluginConnectorItem } from "./plugin-connector";
|
|
3
|
+
export interface ConfiguringPlugin {
|
|
4
|
+
name: string;
|
|
5
|
+
/**
|
|
6
|
+
* 这次打开表单是不是「为了启用它」。
|
|
7
|
+
*
|
|
8
|
+
* 只有用户在开关上表达了启用意图时才为 true:已经跑起来的插件再保存配置
|
|
9
|
+
* 不应该顺手重启 / 重新激活(见 SessionPluginSelector 的历史约定)。
|
|
10
|
+
*/
|
|
11
|
+
pendingActivation: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface PluginConnectorListProps {
|
|
14
|
+
client: BladeClient;
|
|
15
|
+
/** 会话内插件用会话接口取图标;首页候选(null)用账号级目录。 */
|
|
16
|
+
sessionId: string | null;
|
|
17
|
+
items: PluginConnectorItem[];
|
|
18
|
+
/** 正在提交意图的行;开关转圈,但仍然可点(点是取消)。 */
|
|
19
|
+
inFlight: Record<string, true>;
|
|
20
|
+
/** 有启用/停用请求在飞,会写服务端的行先锁住次要操作。 */
|
|
21
|
+
busy: boolean;
|
|
22
|
+
/** 上一次操作失败,给出重试入口。 */
|
|
23
|
+
mutationError: boolean;
|
|
24
|
+
onToggle: (item: PluginConnectorItem, next: boolean) => void;
|
|
25
|
+
onRetry: (item: PluginConnectorItem) => void;
|
|
26
|
+
onEditConfig: (item: PluginConnectorItem) => void;
|
|
27
|
+
configuring: ConfiguringPlugin | null;
|
|
28
|
+
onConfigSaved: (state: SessionPluginConfigState) => void;
|
|
29
|
+
onConfigClose: () => void;
|
|
30
|
+
/** 开关不可用时说明原因,而不是静默禁用。 */
|
|
31
|
+
disabledReason?: string | null;
|
|
32
|
+
/**
|
|
33
|
+
* 列表本身不可用(读取失败 / 搜索无结果)时的说明;有值时不再叠加「还没装插件」,
|
|
34
|
+
* 否则会把一次故障或一次没搜到说成「你这个账号没装东西」。
|
|
35
|
+
*/
|
|
36
|
+
unavailableText?: string | null;
|
|
37
|
+
emptyText: string;
|
|
38
|
+
/** 首页待选模式:开关的语义是"待选",不是"已经启用"。 */
|
|
39
|
+
draft?: boolean;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 连接器面板里的插件列表。
|
|
43
|
+
*
|
|
44
|
+
* 首页与会话共用同一份渲染:开关是开关,候选是候选,行的存在与状态无关——
|
|
45
|
+
* 没启用、没图标也要显示名称和占位,不隐藏整行。
|
|
46
|
+
*/
|
|
47
|
+
export declare function PluginConnectorList({ client, sessionId, items, inFlight, busy, mutationError, onToggle, onRetry, onEditConfig, configuring, onConfigSaved, onConfigClose, disabledReason, unavailableText, emptyText, draft, }: PluginConnectorListProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { BladeClient } from "@blade-hq/agent-client";
|
|
2
|
+
import type { TriggerSummary } from "./connector-panel-types";
|
|
3
|
+
export interface PluginTriggerStackProps {
|
|
4
|
+
client: BladeClient;
|
|
5
|
+
/** 会话内图标走会话接口;首页待选传 `null`(走账号级目录图标)。 */
|
|
6
|
+
sessionId: string | null;
|
|
7
|
+
/** 折叠结果,来自 `triggerSummary`——折叠规则只有那一处。 */
|
|
8
|
+
summary: TriggerSummary;
|
|
9
|
+
className?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* 触发器上的插件头像堆叠:前三枚圆形头像 + 其余折成 `+N`。
|
|
13
|
+
*
|
|
14
|
+
* 没有图标 token 的插件也用显示名首字占一枚圆——它和别的插件长得不一样,
|
|
15
|
+
* 「我选过它」就看得见;早先把这类项直接剔掉,选中后入口毫无变化。
|
|
16
|
+
*
|
|
17
|
+
* 圆环色取 `--background`(盖住被压住的那枚),与整站头像堆叠同一约定,见
|
|
18
|
+
* `apps/web/src/components/agent-board/ProjectMembers.tsx`:容器没有自己的底色时,
|
|
19
|
+
* 环就等于容器露出来的那层底。图标裁成圆形:插件 logo 多是方的,套在圆按钮里
|
|
20
|
+
* 「方套圆」才是那个视觉冲突的来源。
|
|
21
|
+
*/
|
|
22
|
+
export declare function PluginTriggerStack({ client, sessionId, summary, className }: PluginTriggerStackProps): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -48,7 +48,7 @@ export type FollowupInteractionEvent = {
|
|
|
48
48
|
export declare function HistoricalResultFeedback({ feedback }: {
|
|
49
49
|
feedback: SavedResultFeedback;
|
|
50
50
|
}): import("react/jsx-runtime").JSX.Element;
|
|
51
|
-
export declare function PostChatFollowupBlock({ followup, sessionId, onSuggestion, isViewer, onInteraction, savedFeedback, onFeedbackSaved, }: {
|
|
51
|
+
export declare function PostChatFollowupBlock({ followup, sessionId, onSuggestion, isViewer, onInteraction, savedFeedback, onFeedbackSaved, className, suggestionClassName, }: {
|
|
52
52
|
followup: PostChatFollowup;
|
|
53
53
|
sessionId?: string;
|
|
54
54
|
onSuggestion?: (value: string) => void;
|
|
@@ -56,4 +56,8 @@ export declare function PostChatFollowupBlock({ followup, sessionId, onSuggestio
|
|
|
56
56
|
onInteraction?: (event: FollowupInteractionEvent) => void;
|
|
57
57
|
savedFeedback?: SavedResultFeedback;
|
|
58
58
|
onFeedbackSaved?: (feedback: SavedResultFeedback) => void;
|
|
59
|
+
/** 追加到跟进区根节点的类(`ChatViewClassNames.followup`)。 */
|
|
60
|
+
className?: string;
|
|
61
|
+
/** 追加到每个「下一步」建议按钮的类(`ChatViewClassNames.followupAction`)。 */
|
|
62
|
+
suggestionClassName?: string;
|
|
59
63
|
}): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { BladeClient } from "@blade-hq/agent-client";
|
|
2
|
+
export interface SessionMemoryToggleProps {
|
|
3
|
+
sessionId: string;
|
|
4
|
+
enabled: boolean;
|
|
5
|
+
/** 不在 BladeProvider 内使用时显式传入,与宿主现有 BladeClient 复用连接和鉴权。 */
|
|
6
|
+
client?: BladeClient;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
label?: string;
|
|
9
|
+
className?: string;
|
|
10
|
+
labelClassName?: string;
|
|
11
|
+
inputClassName?: string;
|
|
12
|
+
onSaved?: (sessionId: string, enabled: boolean) => void;
|
|
13
|
+
onError?: (error: unknown) => void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* 当前会话记忆开关。同一 client + sessionId 的所有实例共享保存锁,避免多个聊天入口
|
|
17
|
+
* 或会话切换时发出乱序更新;服务端成功后才通过 onSaved 交还权威值。
|
|
18
|
+
*/
|
|
19
|
+
export declare function SessionMemoryToggle({ sessionId, enabled, client: clientProp, disabled, label, className, labelClassName, inputClassName, onSaved, onError, }: SessionMemoryToggleProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { BladeClient, SessionPlugin, SessionPluginConfigState } from "@blade-hq/agent-client";
|
|
2
|
+
export interface SessionPluginConfigDialogProps {
|
|
3
|
+
client: BladeClient;
|
|
4
|
+
sessionId: string;
|
|
5
|
+
plugin: Pick<SessionPlugin, "name" | "display_name" | "icon">;
|
|
6
|
+
/** Called after every successful save with the freshly published state. */
|
|
7
|
+
onSaved?: (state: SessionPluginConfigState) => void;
|
|
8
|
+
onClose: () => void;
|
|
9
|
+
}
|
|
10
|
+
export declare function SessionPluginConfigDialog({ client, sessionId, plugin, ...props }: SessionPluginConfigDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { SessionPluginConfigError, SessionPluginConfigSet, SessionPluginConfigState } from "@blade-hq/agent-client";
|
|
2
|
+
export interface SessionPluginConfigDraft {
|
|
3
|
+
set: SessionPluginConfigSet[];
|
|
4
|
+
remove: string[];
|
|
5
|
+
}
|
|
6
|
+
export interface SessionPluginConfigFormProps {
|
|
7
|
+
config: SessionPluginConfigState;
|
|
8
|
+
submitting: boolean;
|
|
9
|
+
errors: SessionPluginConfigError[];
|
|
10
|
+
failure: string | null;
|
|
11
|
+
onSubmit: (draft: SessionPluginConfigDraft) => void;
|
|
12
|
+
onCancel: () => void;
|
|
13
|
+
}
|
|
14
|
+
export declare function SessionPluginConfigForm({ config, submitting, errors, failure, onSubmit, onCancel, }: SessionPluginConfigFormProps): import("react/jsx-runtime").JSX.Element;
|