@blade-hq/agent-react 2610.0.0-beta.3 → 2610.0.0-beta.31

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
  ## 快速开始
@@ -28,7 +32,6 @@ export function App() {
28
32
 
29
33
  - 不传 `sessionId` 自动创建新会话;未登录时 `ChatView` 自己渲染登录按钮(弹窗授权,见 agent-client 的 `client.auth.login()`)。
30
34
  - 同一 `BladeProvider` 下可以放多个 `ChatView`,各自独立会话、互不干扰。
31
- - 宿主只需要完成态消息时,可在 `BladeClient` 构造参数中传 `streamTokens: false`,不订阅逐 token 增量。
32
35
 
33
36
  ## BladeProvider
34
37
 
@@ -133,6 +136,9 @@ await replay.exitToAutonomous() // 退出回放,之后真的运
133
136
 
134
137
  完整聊天界面:消息列表(Markdown、代码高亮、工具调用、提问卡片)+ 输入框 + 连接状态条 + 登录引导。
135
138
 
139
+ `ChatView` 固定使用普通展示模式。产品内置 Web 的精简/开发者模式不属于 SDK 公共能力,
140
+ 因此没有 `renderMode` 等切换属性。
141
+
136
142
  ```tsx
137
143
  <ChatView
138
144
  sessionId={id} // 可选;不传自动建会话
@@ -150,7 +156,12 @@ await replay.exitToAutonomous() // 退出回放,之后真的运
150
156
 
151
157
  全部 props 见 `ChatViewProps`。样式说明:
152
158
 
159
+ `ChatView` 的普通展示模式不显示只供诊断的项目说明、可用能力和当前工作环境。需要自建诊断界面时,可直接使用独立的 `ContextCard`,属性见 `ContextCardProps`;状态到文案的映射来自 agent-client 的 `getContextDisplayState`,不需要接入方重复判断。一次输入通常会同时注入十几项上下文,把渲染序列里连续的几项用 `ContextGroupCard`(属性见 `ContextGroupCardProps`)折成一行更合适;哪几项算一组由 agent-client 的 `groupAdjacentContextRuns` 判定,折叠行文案来自 `getContextGroupDisplayState` / `ContextGroupDisplayState`。底层数据类型为 `ContextProjectionData` / `ContextProjectionFields`,展示结果为 `ContextDisplayState`,并保留 `ContextAction`、`ContextSourceInfo` 和 `contextProjectionData` 给 headless 消费方。
160
+
161
+ 记忆引用提示可通过 `MemoryRefsHint` 展示,`collectMemoryRefs` 用于从一轮消息中聚合引用,保证宿主自定义消息布局与 SDK 默认界面保持一致。
162
+
153
163
  `onFollowupInteraction` 使用 `FollowupInteractionEvent`,覆盖下一步建议展示/采纳、成果展示/打开/下载以及结果评分。SDK 不内置 PostHog 等分析厂商;宿主回调抛错也不会中断用户点击或下载。
164
+ 文件成果以文件名为文本的标准下载链接展示;Vue / 纯 HTML 使用的 `<blade-chat>` 与 `ChatView` 行为一致。
154
165
 
155
166
  - 必须引入一份样式,按宿主有没有 Tailwind 二选一:
156
167
  - **`style.full.css`**(默认选它):布局兜底 + 编译好的 Tailwind 产物,自包含,宿主没装 Tailwind 也是完整视觉。
@@ -261,6 +272,43 @@ models.filter((m) => m.serviceModelId)
261
272
  <MarkdownContent sessionId={sessionId}>{markdownText}</MarkdownContent>
262
273
  ```
263
274
 
275
+ `normalizeAdjacentUrlFormatting` 可在复用其他 Markdown 渲染器前,保护紧贴行内格式标记的 URL。
276
+
277
+ ## Canonical 引用消息
278
+
279
+ `ChatView` 会自动识别 ship-attack 会话中的 `[引用]` / `[用户输入]` canonical
280
+ 消息,并按原顺序展示引用来源、快照和用户输入。自建消息列表时可用
281
+ `parseWhatIfPrompt` 解析同一格式,再交给 `WhatIfUserBubble` 渲染;
282
+ `onQuoteClick` 可接入宿主的步骤跳转。
283
+
284
+ ```tsx
285
+ const parsed = parseWhatIfPrompt(messageText)
286
+ return parsed ? (
287
+ <WhatIfUserBubble parsed={parsed} onQuoteClick={jumpToStep} />
288
+ ) : null
289
+ ```
290
+
291
+ ## isAgentComputerCommand / isAgentComputerToolCall / classifyAgentComputerLaunchOutcome
292
+
293
+ 判断智能体是否在沙盒里启动了通用 GUI 应用镜像(`computer launch`)——后端 blade-agent 通过 `computer` CLI 驱动一块虚拟屏幕运行任意 GUI 软件,这些函数用于自行接入方判断要不要展示对应的实时画面入口(比如自建一个类似「电脑镜像」的标签页)。当前 SDK 侧还没有内置这块 UI,只导出判定规则,避免各接入方重新猜一遍匹配逻辑。
294
+
295
+ `isAgentComputerCommand`/`isAgentComputerToolCall` 只回答"这条命令是不是一次 launch 尝试",不回答"这次 launch 最终成不成功"——待处理、已失败的 launch 也会命中。要判断真实结果(比如决定要不要展示画面入口),用 `classifyAgentComputerLaunchOutcome`:它会解析工具调用的 `status`/`result`,返回 `"pending" | "succeeded" | "failed" | "unknown"`。`"unknown"` 表示 `status` 已经是终态但 `result` 字段本身缺失(常见于会话整理/compaction 之后的历史投影,归档时不会重新序列化完整 result),跟"result 回来了、里面确实没有成功标记"的 `"failed"` 是两种不同性质的证据——接入方要按自己的场景决定怎么处理(展示类场景可以偏宽松,当作足够展示;自动跳转/替用户做决定的场景应该偏保守,当作跟 `"failed"` 一样处理)。
296
+
297
+ ```ts
298
+ import {
299
+ isAgentComputerCommand,
300
+ isAgentComputerToolCall,
301
+ classifyAgentComputerLaunchOutcome,
302
+ } from "@blade-hq/agent-react"
303
+
304
+ isAgentComputerCommand("computer launch --exec /opt/apps/foo/bar") // true
305
+ isAgentComputerCommand("computer status") // false(只认 launch,不认查询类子命令)
306
+
307
+ isAgentComputerToolCall(toolCall.arguments) // 工具调用的 JSON 参数版本
308
+
309
+ classifyAgentComputerLaunchOutcome(toolCall) // "pending" | "succeeded" | "failed" | "unknown"
310
+ ```
311
+
264
312
  ## 选择模型
265
313
 
266
314
  SDK 的 ChatView / `<blade-chat>` 不内置模型选择器(默认用后端配置的模型)。指定模型有两种方式:
@@ -296,6 +344,10 @@ blade-chat { --primary: 262 83% 58%; height: 640px; }
296
344
  </blade-chat>
297
345
  ```
298
346
 
347
+ ## 自定义消息列表滚动
348
+
349
+ `ChatView`、`AgentChat` 和 `LlmChat` 已经处理好用户发言顶置,不用额外配置。自建消息列表时可用 `useMessagePin` 复用同一套触发、补白、视口 resize 和手动滚动接管逻辑;调用方只需提供滚动容器、目标消息与 spacer 的读写函数。完整参数见 [public-api.md](./public-api.md#usemessagepin-function)。
350
+
299
351
  ## 纯静态 HTML / Vue?
300
352
 
301
353
  不需要本包——用后端托管的单文件产物 `<script src=".../sdk/blade-agent.js">` + `<blade-chat>` 自定义元素,行为与 `ChatView` 一致;详见 agent-client README 与接入文档。
@@ -304,4 +356,4 @@ blade-chat { --primary: 262 83% 58%; height: 640px; }
304
356
 
305
357
  为方便单包引入,本包 re-export 了 agent-client 的全部公开声明(`BladeClient`、`AgentSession`、`SessionState`、协议类型等),文档一律见 [agent-client 的 README](../agent-client/README.md)。完整签名见 [public-api.md](./public-api.md)。
306
358
 
307
- 本包自有声明:`BladeProvider`、`BladeProviderProps`、`useBladeClient`、`useAgentSession`、`UseAgentSessionOptions`、`UseAgentSessionResult`、`useReplay`、`UseReplayResult`、`ReplayMismatch`、`ReplayBar`、`ReplayBarProps`、`ReplayMismatchPrompt`、`ReplayMismatchPromptProps`、`ChatView`、`ChatViewProps`、`ChatViewClassNames`、`ChatViewRenderers`、`ChatViewSlots`、`FollowupInteractionEvent`、`ToolCallRenderer`、`MarkdownContent`、`MarkdownContentProps`。
359
+ 本包自有声明:`BladeProvider`、`BladeProviderProps`、`useBladeClient`、`useAgentSession`、`UseAgentSessionOptions`、`UseAgentSessionResult`、`useMessagePin`、`UseMessagePinOptions`、`useReplay`、`UseReplayResult`、`ReplayMismatch`、`ReplayBar`、`ReplayBarProps`、`ReplayMismatchPrompt`、`ReplayMismatchPromptProps`、`ChatView`、`ChatViewProps`、`ChatViewClassNames`、`ChatViewRenderers`、`ChatViewSlots`、`FollowupInteractionEvent`、`ToolCallRenderer`、`MarkdownContent`、`MarkdownContentProps`、`parseWhatIfPrompt`、`ParsedWhatIfPrompt`、`WhatIfQuote`、`WhatIfUserBubble`、`WhatIfUserBubbleProps`。
@@ -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 {};
@@ -28,4 +28,13 @@ interface Props {
28
28
  export declare function AskUserQuestionBlock({ data, answered, toolCallId, sessionStatus, answerData, onAnswer, }: Props): import("react/jsx-runtime").JSX.Element;
29
29
  /** 解析 AskUserQuestion 的工具结果/参数,容错 LLM 把 questions 输出为字符串的情况。 */
30
30
  export declare function parseAskUserQuestion(toolResult: string | null | undefined): AskUserQuestionData | null;
31
+ export interface AskUserQuestionError {
32
+ message: string;
33
+ detail: string | null;
34
+ }
35
+ /**
36
+ * Keep this parser synchronized with apps/web/AskUserQuestionBlock.tsx.
37
+ * The built-in Web cannot import agent-react, and this is not a public SDK protocol API.
38
+ */
39
+ export declare function parseAskUserQuestionError(toolResult: string | null | undefined): AskUserQuestionError | null;
31
40
  export {};
@@ -1,4 +1,4 @@
1
- import type { AskUserAnswerData, ChatMessage } from "@blade-hq/agent-client";
1
+ import type { AskUserAnswerData, ChatMessage, MemoryRefInfo } from "@blade-hq/agent-client";
2
2
  import { type ToolCallRenderer } from "./ToolCallBlock";
3
3
  interface Props {
4
4
  messages: ChatMessage[];
@@ -10,9 +10,21 @@ 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;
26
+ export declare function collectMemoryRefs(messages: ChatMessage[]): MemoryRefInfo[];
27
+ export declare function MemoryRefsHint({ refs }: {
28
+ refs: MemoryRefInfo[];
29
+ }): import("react/jsx-runtime").JSX.Element;
18
30
  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,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;
@@ -1,3 +1,5 @@
1
+ /** Keep inline formatting markers from being consumed by URL autolinking. */
2
+ export declare function normalizeAdjacentUrlFormatting(value: string): string;
1
3
  export interface MarkdownContentProps {
2
4
  children: string;
3
5
  className?: string;
@@ -8,6 +8,7 @@ interface Props {
8
8
  answered?: boolean;
9
9
  answerData?: AskUserAnswerData;
10
10
  sessionStatus?: string;
11
+ isActiveQuestion?: boolean;
11
12
  renderer?: ToolCallRenderer;
12
13
  }
13
14
  /**
@@ -19,10 +20,11 @@ interface Props {
19
20
  * 会同时把已经回答过的旧提问重新变成可作答(历史加载不会带回 answerData),
20
21
  * 而且会盖住投影层的错误——这个 bug 就是这么藏住的。
21
22
  */
22
- export declare function resolveAskQuestionState({ toolStatus, hasAnswerData, fallbackAnswered, }: {
23
+ export declare function resolveAskQuestionState({ toolStatus, hasAnswerData, fallbackAnswered, fallbackAwaiting, }: {
23
24
  toolStatus: ToolCallInfo["status"];
24
25
  hasAnswerData: boolean;
25
26
  fallbackAnswered?: boolean;
27
+ fallbackAwaiting?: boolean;
26
28
  }): {
27
29
  awaitingAnswer: boolean;
28
30
  answered: boolean;
@@ -31,5 +33,5 @@ export declare function resolveAskQuestionState({ toolStatus, hasAnswerData, fal
31
33
  * 极简工具调用块:状态 + 展示名一行,点开后是参数/结果的 <pre> 折叠展示。
32
34
  * AskUserQuestion 特殊处理为提问选项卡片。
33
35
  */
34
- export declare function ToolCallBlock({ toolCall, onAnswer, answered, answerData, sessionStatus, renderer, }: Props): import("react/jsx-runtime").JSX.Element;
36
+ export declare function ToolCallBlock({ toolCall, onAnswer, answered, answerData, sessionStatus, isActiveQuestion, renderer, }: Props): import("react/jsx-runtime").JSX.Element;
35
37
  export {};
@@ -11,7 +11,7 @@ interface UserMessageProps {
11
11
  message: UserChatMessage;
12
12
  className?: string;
13
13
  }
14
- /** 用户消息气泡:文本 + 图片/文件附件展示(不含第一方的预览弹窗与 what-if 徽章)。 */
14
+ /** 用户消息气泡:文本、canonical 引用消息与图片/文件附件。 */
15
15
  export declare function UserMessageBubble({ message, className }: UserMessageProps): import("react/jsx-runtime").JSX.Element;
16
16
  /** 错误消息:居中红色提示条。 */
17
17
  export declare function ErrorMessageBlock({ message, className, }: {
@@ -0,0 +1,7 @@
1
+ import type { ParsedWhatIfPrompt } from "../lib/whatif-prompt";
2
+ export interface WhatIfUserBubbleProps {
3
+ parsed: ParsedWhatIfPrompt;
4
+ onQuoteClick?: (stepNumber: number) => void;
5
+ }
6
+ /** SDK 与内置 Web 共用的 canonical 引用消息渲染。 */
7
+ export declare function WhatIfUserBubble({ parsed, onQuoteClick }: WhatIfUserBubbleProps): 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,18 +18,27 @@ 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;
30
34
  isInboundEnvelope: typeof agentClient.isInboundEnvelope;
35
+ ComputersResource: typeof agentClient.ComputersResource;
36
+ canToggleComputer: typeof agentClient.canToggleComputer;
37
+ computerState: typeof agentClient.computerState;
38
+ sortComputers: typeof agentClient.sortComputers;
31
39
  ModelsResource: typeof agentClient.ModelsResource;
32
40
  buildMessageContent: typeof agentClient.buildMessageContent;
41
+ chatErrorForDisplay: typeof agentClient.chatErrorForDisplay;
33
42
  contentPreview: typeof agentClient.contentPreview;
34
43
  extractTextAttachments: typeof agentClient.extractTextAttachments;
35
44
  getFileParts: typeof agentClient.getFileParts;
@@ -39,6 +48,10 @@ declare const BladeAgent: {
39
48
  isHiddenInternalMessage: typeof agentClient.isHiddenInternalMessage;
40
49
  normalizeMessageContent: typeof agentClient.normalizeMessageContent;
41
50
  transformSlashCommand: typeof agentClient.transformSlashCommand;
51
+ contextProjectionData: typeof agentClient.contextProjectionData;
52
+ getContextDisplayState: typeof agentClient.getContextDisplayState;
53
+ getContextGroupDisplayState: typeof agentClient.getContextGroupDisplayState;
54
+ groupAdjacentContextRuns: typeof agentClient.groupAdjacentContextRuns;
42
55
  latestPostChatFollowup: typeof agentClient.latestPostChatFollowup;
43
56
  DEFAULT_REPLAY_SPEED: agentClient.ReplaySpeed;
44
57
  SessionInfo: import("arktype/internal/variants/object.ts").ObjectType<{
@@ -70,6 +83,7 @@ declare const BladeAgent: {
70
83
  disable_tools?: string[] | undefined;
71
84
  runtime_type?: string | null | undefined;
72
85
  daemon_id?: string | null | undefined;
86
+ agent_runtime_id?: string | null | undefined;
73
87
  workspace_path?: string | null | undefined;
74
88
  match?: unknown;
75
89
  }, {}>;
@@ -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";
@@ -14,10 +16,20 @@ export { LlmChat } from "./components/LlmChat";
14
16
  export type { LlmChatHandle, LlmChatProps } from "./components/LlmChat";
15
17
  export type { LlmAdvancedSettings, LlmOverride } from "./components/LlmAdvancedSettings";
16
18
  export { MarkdownContent } from "./components/MarkdownContent";
19
+ export { normalizeAdjacentUrlFormatting } from "./components/MarkdownContent";
17
20
  export type { MarkdownContentProps } from "./components/MarkdownContent";
21
+ export { WhatIfUserBubble } from "./components/WhatIfUserBubble";
22
+ export type { WhatIfUserBubbleProps } from "./components/WhatIfUserBubble";
23
+ export { parseWhatIfPrompt } from "./lib/whatif-prompt";
24
+ export type { ParsedWhatIfPrompt, WhatIfQuote } from "./lib/whatif-prompt";
18
25
  export { ReplayBar } from "./components/ReplayBar";
19
26
  export type { ReplayBarProps } from "./components/ReplayBar";
20
27
  export { ReplayMismatchPrompt } from "./components/ReplayMismatchPrompt";
21
28
  export type { ReplayMismatchPromptProps } from "./components/ReplayMismatchPrompt";
22
29
  export type { ToolCallRenderer } from "./components/ToolCallBlock";
30
+ export { ContextCard, ContextGroupCard } from "./components/ContextCard";
31
+ export type { ContextCardProps, ContextGroupCardProps } from "./components/ContextCard";
32
+ export { collectMemoryRefs, MemoryRefsHint } from "./components/AssistantTurnBlock";
33
+ export { isAgentComputerCommand, isAgentComputerToolCall, classifyAgentComputerLaunchOutcome, } from "./lib/agent-computer-command";
34
+ export type { AgentComputerLaunchOutcome } from "./lib/agent-computer-command";
23
35
  export * from "@blade-hq/agent-client";