@blade-hq/agent-react 2610.0.0-beta.2 → 2610.0.0-beta.21

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 CHANGED
@@ -6,6 +6,10 @@ Blade Agent 的 React 绑定:`BladeProvider` + `useAgentSession` + 开箱即
6
6
  pnpm add @blade-hq/agent-client @blade-hq/agent-react
7
7
  ```
8
8
 
9
+ 默认装到的是当前长期支持版(LTS),厂内离线交付按它开发。要跟两周一发的公网版本,改用 `@next`。
10
+
11
+ 最稳妥的做法是先读目标 Server 的 `GET /api/version`,按返回的版本号在 `package.json` 里钉死——NPM 的 `latest` 不一定和目标环境跑的版本一致。
12
+
9
13
  > 注意两个包都要装:`agent-client` 是运行时依赖,只装 `agent-react` 在 pnpm 下会直接报错。
10
14
 
11
15
  ## 快速开始
@@ -150,7 +154,10 @@ await replay.exitToAutonomous() // 退出回放,之后真的运
150
154
 
151
155
  全部 props 见 `ChatViewProps`。样式说明:
152
156
 
157
+ `ChatView` 会把项目说明、可用能力和当前工作环境显示为默认折叠的业务卡片。自建消息列表可直接使用 `ContextCard`,属性见 `ContextCardProps`;状态到文案的映射来自 agent-client 的 `getContextDisplayState`,不需要接入方重复判断。底层数据类型为 `ContextProjectionData` / `ContextProjectionFields`,展示结果为 `ContextDisplayState`,并保留 `ContextAction`、`ContextSourceInfo` 和 `contextProjectionData` 给 headless 消费方。
158
+
153
159
  `onFollowupInteraction` 使用 `FollowupInteractionEvent`,覆盖下一步建议展示/采纳、成果展示/打开/下载以及结果评分。SDK 不内置 PostHog 等分析厂商;宿主回调抛错也不会中断用户点击或下载。
160
+ 文件成果以文件名为文本的标准下载链接展示;Vue / 纯 HTML 使用的 `<blade-chat>` 与 `ChatView` 行为一致。
154
161
 
155
162
  - 必须引入一份样式,按宿主有没有 Tailwind 二选一:
156
163
  - **`style.full.css`**(默认选它):布局兜底 + 编译好的 Tailwind 产物,自包含,宿主没装 Tailwind 也是完整视觉。
@@ -296,6 +303,10 @@ blade-chat { --primary: 262 83% 58%; height: 640px; }
296
303
  </blade-chat>
297
304
  ```
298
305
 
306
+ ## 自定义消息列表滚动
307
+
308
+ `ChatView`、`AgentChat` 和 `LlmChat` 已经处理好用户发言顶置,不用额外配置。自建消息列表时可用 `useMessagePin` 复用同一套触发、补白、视口 resize 和手动滚动接管逻辑;调用方只需提供滚动容器、目标消息与 spacer 的读写函数。完整参数见 [public-api.md](./public-api.md#usemessagepin-function)。
309
+
299
310
  ## 纯静态 HTML / Vue?
300
311
 
301
312
  不需要本包——用后端托管的单文件产物 `<script src=".../sdk/blade-agent.js">` + `<blade-chat>` 自定义元素,行为与 `ChatView` 一致;详见 agent-client README 与接入文档。
@@ -304,4 +315,4 @@ blade-chat { --primary: 262 83% 58%; height: 640px; }
304
315
 
305
316
  为方便单包引入,本包 re-export 了 agent-client 的全部公开声明(`BladeClient`、`AgentSession`、`SessionState`、协议类型等),文档一律见 [agent-client 的 README](../agent-client/README.md)。完整签名见 [public-api.md](./public-api.md)。
306
317
 
307
- 本包自有声明:`BladeProvider`、`BladeProviderProps`、`useBladeClient`、`useAgentSession`、`UseAgentSessionOptions`、`UseAgentSessionResult`、`useReplay`、`UseReplayResult`、`ReplayMismatch`、`ReplayBar`、`ReplayBarProps`、`ReplayMismatchPrompt`、`ReplayMismatchPromptProps`、`ChatView`、`ChatViewProps`、`ChatViewClassNames`、`ChatViewRenderers`、`ChatViewSlots`、`FollowupInteractionEvent`、`ToolCallRenderer`、`MarkdownContent`、`MarkdownContentProps`。
318
+ 本包自有声明:`BladeProvider`、`BladeProviderProps`、`useBladeClient`、`useAgentSession`、`UseAgentSessionOptions`、`UseAgentSessionResult`、`useMessagePin`、`UseMessagePinOptions`、`useReplay`、`UseReplayResult`、`ReplayMismatch`、`ReplayBar`、`ReplayBarProps`、`ReplayMismatchPrompt`、`ReplayMismatchPromptProps`、`ChatView`、`ChatViewProps`、`ChatViewClassNames`、`ChatViewRenderers`、`ChatViewSlots`、`FollowupInteractionEvent`、`ToolCallRenderer`、`MarkdownContent`、`MarkdownContentProps`。
@@ -2,9 +2,6 @@ import type { ToolCallInfo } from "@blade-hq/agent-client";
2
2
  interface Props {
3
3
  toolCall: ToolCallInfo;
4
4
  }
5
- /**
6
- * 子智能体(fork Agent)状态块的 SDK 简化版:只展示描述、状态与最终结果,
7
- * 不再嵌套渲染子循环的完整消息流(那是第一方界面的能力)。
8
- */
5
+ /** SDK 没有第一方子循环消息流,只保留轻量意图行和可展开的最终结果。 */
9
6
  export declare function AgentLoopBlock({ toolCall }: Props): import("react/jsx-runtime").JSX.Element;
10
7
  export {};
@@ -10,9 +10,17 @@ interface Props {
10
10
  /** 会话 id;传给 Markdown 渲染的统一上下文。 */
11
11
  sessionId?: string;
12
12
  }
13
- /**
14
- * 一轮助手回复:按消息顺序渲染 thinking 折叠块、正文 Markdown 与工具调用。
15
- * 相比第一方版本去掉了紧凑/详细模式切换、文件交付卡片与内联资源 iframe。
16
- */
13
+ export type TurnDisplayMode = "compact" | "detail";
14
+ export declare function resolveTurnDisplayMode({ isStreaming: _isStreaming, displayMode, }: {
15
+ isStreaming: boolean;
16
+ displayMode: TurnDisplayMode;
17
+ }): TurnDisplayMode;
18
+ export declare function formatExecutionDuration(durationMs: number): string;
19
+ export declare function getExecutionDurationMs({ messages, isStreaming, now, }: {
20
+ messages: ChatMessage[];
21
+ isStreaming: boolean;
22
+ now?: number;
23
+ }): number;
24
+ /** 一轮助手回复:执行过程默认折叠,最终正文始终显示在摘要下方。 */
17
25
  export declare function AssistantTurnBlock({ messages, isStreaming, askAnswers, onAnswer, sessionStatus, toolCallRenderer, sessionId, }: Props): import("react/jsx-runtime").JSX.Element;
18
26
  export {};
@@ -3,6 +3,6 @@ interface Props {
3
3
  connection: ConnectionStatus;
4
4
  className?: string;
5
5
  }
6
- /** 连接状态提示条:数据来自 SessionState.connection,正常连接时不渲染。 */
6
+ /** 连接状态提示条:短暂断线静默,超过容错时间后再逐级提示。 */
7
7
  export declare function ConnectionBanner({ connection, className }: Props): import("react/jsx-runtime").JSX.Element | null;
8
8
  export {};
@@ -0,0 +1,7 @@
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;
@@ -1,7 +1,15 @@
1
1
  import type { ToolCallInfo } from "@blade-hq/agent-client";
2
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;
3
10
  /** 归一化工具名:去掉命名空间前缀并映射到别名表(如 "fork:Agent" → "Agent")。 */
4
11
  export declare function formatToolName(name: string): string;
12
+ export declare function extractToolFilePath(toolCall: ToolCallInfo): string | null;
5
13
  /**
6
14
  * 返回工具调用的中文展示标签:优先取参数里的 description,
7
15
  * 其次取后端下发的 display_name / 系统工具中文名。
@@ -18,12 +18,16 @@ declare function getChat(element: Element | null): Promise<AgentSession>;
18
18
  declare const BladeAgent: {
19
19
  BladeClient: typeof agentClient.BladeClient;
20
20
  BladeApiError: typeof agentClient.BladeApiError;
21
+ EMPTY_PLATFORM_ENDPOINTS: agentClient.PlatformEndpoints;
22
+ loadPlatformEndpoints: typeof agentClient.loadPlatformEndpoints;
23
+ resolveServiceUrl: typeof agentClient.resolveServiceUrl;
21
24
  SDK_NAME: "agent-client";
22
25
  SDK_VERSION: string;
23
26
  AgentSession: typeof AgentSession;
24
27
  SessionHub: typeof agentClient.SessionHub;
25
28
  SessionSetupError: typeof agentClient.SessionSetupError;
26
29
  createInitialSessionState: typeof agentClient.createInitialSessionState;
30
+ reconcileOptimisticUserTurns: typeof agentClient.reconcileOptimisticUserTurns;
27
31
  toReplaySnapshot: typeof agentClient.toReplaySnapshot;
28
32
  connectEmbedded: typeof agentClient.connectEmbedded;
29
33
  isCommandEnvelope: typeof agentClient.isCommandEnvelope;
@@ -39,6 +43,8 @@ declare const BladeAgent: {
39
43
  isHiddenInternalMessage: typeof agentClient.isHiddenInternalMessage;
40
44
  normalizeMessageContent: typeof agentClient.normalizeMessageContent;
41
45
  transformSlashCommand: typeof agentClient.transformSlashCommand;
46
+ contextProjectionData: typeof agentClient.contextProjectionData;
47
+ getContextDisplayState: typeof agentClient.getContextDisplayState;
42
48
  latestPostChatFollowup: typeof agentClient.latestPostChatFollowup;
43
49
  DEFAULT_REPLAY_SPEED: agentClient.ReplaySpeed;
44
50
  SessionInfo: import("arktype/internal/variants/object.ts").ObjectType<{
@@ -0,0 +1,22 @@
1
+ export interface UseMessagePinOptions {
2
+ targetKey: string | null;
3
+ pinTarget: boolean;
4
+ layoutKey?: string;
5
+ getScrollElement: () => HTMLElement | null;
6
+ getContentElement?: () => HTMLElement | null;
7
+ getTargetElement: () => HTMLElement | null;
8
+ getTargetScrollTop?: (scroll: HTMLElement) => number | null;
9
+ getSpacerHeight: () => number;
10
+ setSpacerHeight: (height: number) => void;
11
+ stopAutoScroll: () => void;
12
+ scrollToBottom: () => void;
13
+ margin?: number;
14
+ }
15
+ /**
16
+ * 用户发言顶置的共享状态机。SDK 和内置轻量列表只提供 DOM/虚拟列表适配器,
17
+ * 触发、调度、resize、手动接管和跟随交还的决策只在这里维护。
18
+ */
19
+ export declare function useMessagePin({ targetKey, pinTarget, layoutKey, getScrollElement, getContentElement, getTargetElement, getTargetScrollTop, getSpacerHeight, setSpacerHeight, stopAutoScroll, scrollToBottom, margin, }: UseMessagePinOptions): {
20
+ release: () => void;
21
+ isActive: () => boolean;
22
+ };
package/dist/index.d.ts CHANGED
@@ -5,6 +5,8 @@ export type { UseAgentSessionOptions, UseAgentSessionResult } from "./hooks/use-
5
5
  export { useReplay } from "./hooks/use-replay";
6
6
  export type { ReplayMismatch, UseReplayResult } from "./hooks/use-replay";
7
7
  export { useLlmChat } from "./hooks/use-llm-chat";
8
+ export { useMessagePin } from "./hooks/use-message-pin";
9
+ export type { UseMessagePinOptions } from "./hooks/use-message-pin";
8
10
  export type { ChatCompletionTool, LlmChatOptions, LlmToolCall, UseLlmChatResult, } from "./hooks/use-llm-chat";
9
11
  export { ChatView } from "./components/ChatView";
10
12
  export type { ChatViewClassNames, ChatViewProps, ChatViewRenderers, ChatViewSlots, FollowupInteractionEvent, } from "./components/ChatView";
@@ -20,4 +22,6 @@ export type { ReplayBarProps } from "./components/ReplayBar";
20
22
  export { ReplayMismatchPrompt } from "./components/ReplayMismatchPrompt";
21
23
  export type { ReplayMismatchPromptProps } from "./components/ReplayMismatchPrompt";
22
24
  export type { ToolCallRenderer } from "./components/ToolCallBlock";
25
+ export { ContextCard } from "./components/ContextCard";
26
+ export type { ContextCardProps } from "./components/ContextCard";
23
27
  export * from "@blade-hq/agent-client";