@blade-hq/agent-client 2610.0.0-beta.50 → 2610.0.0-beta.51

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
@@ -174,6 +174,41 @@ await client.sessions.getSessionTurnsPage(id, { before: page.nextBefore! })
174
174
  会话插件可通过 `client.sessions.listSessionPlugins(id)` 查询,并用
175
175
  `client.sessions.setSessionPluginActivation(id, name, active)` 切换当前会话。列表项为 `SessionPlugin`;修改结果为 `SessionPluginActivation`,只返回选择和准备状态,安装事实需从列表获取。
176
176
 
177
+ 插件可以在包内 `cn.com.bladeai.agent/config.schema.json` 用标准 JSON Schema
178
+ (Draft 2020-12)声明账号、token 或任意业务配置。声明了配置的插件用
179
+ `client.sessions.getSessionPluginConfig(id, name)` 读取声明与当前值,用
180
+ `client.sessions.updateSessionPluginConfig(id, name, { expected_revision, set, remove })`
181
+ 保存;两者都要等到插件包已准备(即已激活过)才有内容,没有声明的插件返回
182
+ `state: "not_required"`。
183
+
184
+ ```ts
185
+ const { config } = await client.sessions.getSessionPluginConfig(id, "crm")
186
+ // config: SessionPluginConfigState
187
+ // state "not_required" | "required" | "configured" | "error"
188
+ // schema 包内声明的 JSON Schema(Draft 2020-12)
189
+ // values 已存值,writeOnly 字段已被平台剔除
190
+ // write_only 当前有值的秘密字段 JSON Pointer
191
+ // revision 乐观并发用的版本号
192
+ // errors SessionPluginConfigError[],逐条 { path, message },不含用户输入
193
+ // 列表项 SessionPlugin.config 是 SessionPluginConfigSummary
194
+ // (SessionPluginConfigStateName 之外多一个 "unchecked":列表只报本地已知事实,
195
+ // 不伪报已配置)
196
+
197
+ await client.sessions.updateSessionPluginConfig(id, "crm", {
198
+ expected_revision: config.revision,
199
+ set: [{ path: "/login/password", value: password }], // SessionPluginConfigSet[]
200
+ remove: [],
201
+ } satisfies SessionPluginConfigUpdate)
202
+ ```
203
+
204
+ 图标用 `client.sessions.fetchSessionPluginIcon(id, name)` 取 `Blob`(自带凭据),
205
+ 或 `client.sessions.sessionPluginIconUrl(id, name)` 取已鉴权 URL。
206
+
207
+ `set`/`remove` 只表达显式改动:没出现的字段保持原值,因此表单不需要回传秘密;
208
+ `null` 是一个合法值,不是删除。校验不通过或版本过期时请求被拒绝,磁盘上的旧
209
+ 配置保持不变。平台只写用户 Home 下的 `~/.plugin/<plugin_id>/config.json`,不会
210
+ 重启 MCP、清缓存或刷新 token。
211
+
177
212
  ### 会话回放(演示 / 彩排)
178
213
 
179
214
  拿一个已经聊完的会话当素材,重现当时的回复和工具调用,**完全不调用模型**。
@@ -596,6 +631,38 @@ transformSlashCommand(skillId, prompt, { local: false, installed: false })
596
631
 
597
632
  不传第三个参数时按本地已有处理,和不带这个参数的老用法结果一致。
598
633
 
634
+ ### MCP App 卡片
635
+
636
+ MCP 工具可以通过 `_meta.ui` 在消息流里产出交互卡片(`tool_ui` block)。卡片的
637
+ 实例、守卫、可见性、身份和终态规则全部收敛在这一份共享判定里——内置 Web 与
638
+ SDK 渲染的是同一批卡片,不要自己再写一份判断:
639
+
640
+ ```ts
641
+ import {
642
+ collectInlineToolUiCards,
643
+ collectPreviewToolUiCards,
644
+ resolveToolUiCardContent,
645
+ buildToolUiCardKey,
646
+ isToolUiCard,
647
+ } from "@blade-hq/agent-client"
648
+
649
+ // 按可见性分类:inline 进消息流,preview 交给你的侧栏/面板(也随 toolPreview 事件推送)
650
+ const inlineCards = collectInlineToolUiCards(messages) // [{ key, toolCallId, card }]
651
+ const previewCards = collectPreviewToolUiCards(messages) // [{ key, toolCall, card, blocks }]
652
+
653
+ // 渲染前解析实际内容;archived 留档卡片只用留档 HTML,绝不回退 resourceUri
654
+ // (历史恢复/刷新不会因此重放一次 MCP 资源读取)
655
+ const resolved = resolveToolUiCardContent(card) // { type: "resource-html" | "resource-uri", content } | null
656
+
657
+ // 实例去重键:uri 卡片按内容、html 卡片按 toolCallId,与 toolPreview 事件、内置侧栏一致
658
+ const key = buildToolUiCardKey(toolCallId, resolved.type, resolved.content)
659
+ ```
660
+
661
+ 单个 block 判有效用 `isToolUiCard`(严格守卫:`target`/`height` 缺失、archived 无留档
662
+ HTML 一律判无效);`isInternalStatusToolUiCard` 识别内部「阶段进度」卡片(不对用户展示),
663
+ `isAppDevToolUiCard` 识别应用开发会话的预览卡。相关类型:`ToolUiCard`、
664
+ `ToolUiCardContentType`、`InlineToolUiCardEntry`、`PreviewToolUiCardEntry`。
665
+
599
666
  ## 常见问题
600
667
 
601
668
  | 现象 | 原因与解法 |
@@ -622,6 +689,12 @@ transformSlashCommand(skillId, prompt, { local: false, installed: false })
622
689
  - **会话状态机**:`SessionHub`、`SessionConnectOptions`、`SessionState`、`SendOptions`、`ConnectionStatus`、`AskUserAnswerData`、`AgentLoopInfo`、`ActiveCompactionState`、`createInitialSessionState`、`AgentSessionEventName`
623
690
  - **页面协作**:`EmbeddedChat`、`EmbeddedChatOptions`、`CommandHandler`、`CommandEnvelope`、`InboundAction`、`InboundEnvelope`、`isCommandEnvelope`、`isInboundEnvelope`
624
691
  - **消息与投影协议**:`MessageContent`、`MessageContentPart`、`TextContentPart`、`ImageUrlContentPart`、`FileContentPart`、`ToolCallInfo`、`ToolBridgeContent`、`CompactionInfo`、`ContextProjectionData`、`ContextProjectionFields`、`ContextDisplayState`、`ContextGroupDisplayState`、`ContextAction`、`ContextSourceInfo`、`MemoryRefInfo`、`ArchivedFileInfo`、`ArchivedToolCallInfo`、`TurnProjection`、`ContentBlock`、`PatchEnvelope`、`MemoryRef`、`PostChatFollowup`、`FinalArtifact`、`contextProjectionData`、`getContextDisplayState`、`getContextGroupDisplayState`、`groupAdjacentContextRuns`、`latestPostChatFollowup`、`buildMessageContent`、`normalizeMessageContent`、`isHiddenInternalMessage`、`transformSlashCommand`、`SkillMentionAvailability`、`extractTextAttachments`、`ParsedTextAttachment`、`ParsedTextContext`
692
+ - **MCP Apps 留档与卡片判定**:`McpAppData`、`isMcpAppData`、`McpAppContextState`、`McpAppContextUpdate`、`ToolUiCard`、`ToolUiCardContentType`、`InlineToolUiCardEntry`、`PreviewToolUiCardEntry`、`isToolUiCard`、`resolveToolUiCardContent`、`buildToolUiCardKey`、`isInternalStatusToolUiCard`、`isAppDevToolUiCard`、`collectInlineToolUiCards`、`collectPreviewToolUiCards`(`McpAppContextState` / `McpAppContextUpdate` 配合 `sessions.getMcpAppContext` / `sessions.updateMcpAppContext`:App 保存的状态在下一个新运行才进入模型上下文)
625
693
  - **Solution / 任务协议**:`Solution`、`SolutionAppField`、`SolutionAppState`、`SolutionAppUiConfig`、`SolutionRef`、`PublishedSolutionRef`、`ExistingSolutionRef`、`PreparedSolution`、`PreparedSolutionAsset`、`LayoutType`、`BizRole`、`TaskStatus`、`BackgroundTask`、`BackgroundTaskStopResult`
626
694
  - **Headless**:`HeadlessResource`、`RunOptions`、`RunResult`、`RunTrace`
627
695
  - **低层通道(apps/web 等高级集成)**:`createSocket`、`CreateSocketOptions`、`TypedSocket`、`AsrAudioPayload`、`AuthBusyReconnect`、`authBusyRetryDelayMs`、`ClientProjectionBuilder`、`RawEvent`、`acknowledgeTurnEvents`、`hasChatRunEvent`、`acceptedPostChatFollowupCompletesLatestRun`、`reconcileOptimisticUserTurns`、`reconcileHistoricalUserTurns`
696
+ ### MCP App 留档
697
+
698
+ `McpAppArchive` 是 `client.sessions.getMcpApp(sessionId, sourceId)` 经鉴权返回的归档,包含保存的 HTML 与最新留档输入/结果。`callMcpApp` 在会话 sandbox 内调用该卡片的归档能力;`onMcpAppChanged` 订阅结果变化,返回取消订阅函数。
699
+
700
+ 最新调用失败或完成状态未知时,归档同时提供 `previousToolInput` / `previousToolResult`,用于先恢复最后成功的界面再展示错误。读取这些留档不会重新执行工具。
package/dist/index.d.ts CHANGED
@@ -11,6 +11,8 @@ export type { AttachAppOptions, SendOptions } from "./session/agent-session";
11
11
  export { SessionHub } from "./session/hub";
12
12
  export type { SessionConnectOptions } from "./session/hub";
13
13
  export type { AgentSessionEvents, AgentSessionEventName } from "./session/events";
14
+ export { isMcpAppData } from "./schemas/mcp-app";
15
+ export type { McpAppArchive, McpAppContextState, McpAppContextUpdate, McpAppData, } from "./schemas/mcp-app";
14
16
  export { SessionSetupError } from "./session/definition";
15
17
  export type { SessionConfig, SessionDefinition, SessionSetupStage, SkillDefinition, TextFile, SolutionDefinition, } from "./session/definition";
16
18
  export { createInitialSessionState, reconcileHistoricalUserTurns, reconcileOptimisticUserTurns, toReplaySnapshot, } from "./session/state";
@@ -29,6 +31,7 @@ export { ModelsResource } from "./resources/models";
29
31
  export type { ModelCatalog, ModelOption } from "./resources/models";
30
32
  export type { SessionsResource } from "./resources/sessions";
31
33
  export type { SessionPlugin, SessionPluginActivation } from "./resources/sessions";
34
+ export type { SessionPluginConfigError, SessionPluginConfigSet, SessionPluginConfigState, SessionPluginConfigStateName, SessionPluginConfigSummary, SessionPluginConfigUpdate, } from "./resources/sessions";
32
35
  export { ChatProjectsResource } from "./resources/chat-projects";
33
36
  export type { ChatProject } from "./resources/chat-projects";
34
37
  export { hasChatRunEvent } from "./shared/projection";
@@ -40,6 +43,8 @@ export type { ContextAction, ContextDisplayState, ContextGroupDisplayState, Cont
40
43
  export type { ParsedTextAttachment, ParsedTextContext, SkillMentionAvailability, } from "./schemas/message-utils";
41
44
  export type { ContentBlock, FinalArtifact, MemoryRef, PatchEnvelope, PostChatFollowup, TurnProjection, } from "./schemas/projection";
42
45
  export { latestPostChatFollowup } from "./schemas/projection-utils";
46
+ export { buildToolUiCardKey, collectInlineToolUiCards, collectPreviewToolUiCards, isAppDevToolUiCard, isInternalStatusToolUiCard, isToolUiCard, resolveToolUiCardContent, } from "./shared/tool-ui-card";
47
+ export type { InlineToolUiCardEntry, PreviewToolUiCardEntry, ToolUiCard, ToolUiCardContentType, } from "./shared/tool-ui-card";
43
48
  export { prependOlder, replaceWindow } from "./session/history-page";
44
49
  export type { LiveRevisionState } from "./session/history-page";
45
50
  export { DEFAULT_REPLAY_SPEED } from "./schemas/session";
package/dist/index.js CHANGED
@@ -2541,6 +2541,36 @@ var SessionsResource = class {
2541
2541
  this.client = client;
2542
2542
  }
2543
2543
  client;
2544
+ getMcpApp(sessionId, sourceId, init) {
2545
+ return this.client.jsonFromInit(`/api/sessions/${encodeURIComponent(sessionId)}/mcp-apps/${encodeURIComponent(sourceId)}`, init);
2546
+ }
2547
+ onMcpAppChanged(sessionId, sourceId, listener) {
2548
+ let socket = this.client.socket();
2549
+ const changed = (payload) => {
2550
+ if (payload.session_id === sessionId && payload.source_id === sourceId) listener();
2551
+ };
2552
+ socket.on("mcp-app:changed", changed);
2553
+ socket.on("connect", listener);
2554
+ const off = this.client.onSocketReplaced(() => {
2555
+ socket.off("mcp-app:changed", changed);
2556
+ socket.off("connect", listener);
2557
+ socket = this.client.socket();
2558
+ socket.on("mcp-app:changed", changed);
2559
+ socket.on("connect", listener);
2560
+ });
2561
+ return () => {
2562
+ off();
2563
+ socket.off("mcp-app:changed", changed);
2564
+ socket.off("connect", listener);
2565
+ };
2566
+ }
2567
+ callMcpApp(sessionId, sourceId, request, init) {
2568
+ return this.client.jsonFromInit(`/api/sessions/${encodeURIComponent(sessionId)}/mcp-apps/${encodeURIComponent(sourceId)}/calls`, {
2569
+ ...init,
2570
+ method: "POST",
2571
+ body: JSON.stringify(request)
2572
+ });
2573
+ }
2544
2574
  /**
2545
2575
  * 连接一个已存在的会话,返回实时会话对象 AgentSession
2546
2576
  * (自动完成历史加载、Socket.IO 订阅、断线重连补数)。
@@ -2554,6 +2584,38 @@ var SessionsResource = class {
2554
2584
  setSessionPluginActivation(sessionId, name, active, init) {
2555
2585
  return this.client.jsonFromInit(`/api/sessions/${encodeURIComponent(sessionId)}/plugins/${encodeURIComponent(name)}:activation`, { method: "POST", body: JSON.stringify({ active }), ...init });
2556
2586
  }
2587
+ /**
2588
+ * Fetch a plugin's package-local icon as bytes.
2589
+ *
2590
+ * The request carries the client's own bearer credentials, so callers turn
2591
+ * the blob into an object URL instead of pointing `<img>` at an API path and
2592
+ * hoping the request is authenticated.
2593
+ */
2594
+ fetchSessionPluginIcon(sessionId, name) {
2595
+ return this.client.blob("GET", `/api/sessions/${encodeURIComponent(sessionId)}/plugins/${encodeURIComponent(name)}/icon`);
2596
+ }
2597
+ /** Authenticated URL for the icon; useful where a blob URL cannot be used. */
2598
+ sessionPluginIconUrl(sessionId, name) {
2599
+ return this.client.buildAuthedUrl(`/api/sessions/${encodeURIComponent(sessionId)}/plugins/${encodeURIComponent(name)}/icon`);
2600
+ }
2601
+ /**
2602
+ * Read a plugin's configuration contract and the user's stored values.
2603
+ *
2604
+ * Secrets are never returned: `write_only` lists the pointers that hold one.
2605
+ */
2606
+ getSessionPluginConfig(sessionId, name, init) {
2607
+ return this.client.jsonFromInit(`/api/sessions/${encodeURIComponent(sessionId)}/plugins/${encodeURIComponent(name)}/config`, init);
2608
+ }
2609
+ /**
2610
+ * Publish explicit set/remove operations to the user's keychain file.
2611
+ *
2612
+ * Fields absent from both lists keep their stored value, so a form never has
2613
+ * to round-trip a secret. Rejections leave the previous file untouched; the
2614
+ * call never restarts MCP servers.
2615
+ */
2616
+ updateSessionPluginConfig(sessionId, name, update, init) {
2617
+ return this.client.jsonFromInit(`/api/sessions/${encodeURIComponent(sessionId)}/plugins/${encodeURIComponent(name)}/config`, { method: "PUT", body: JSON.stringify(update), ...init });
2618
+ }
2557
2619
  /** 创建新会话并直接连接,返回可收发消息的 AgentSession。 */
2558
2620
  async create(request = {}) {
2559
2621
  if (isSessionDefinition(request)) {
@@ -2767,6 +2829,16 @@ var SessionsResource = class {
2767
2829
  currentMode: page.current_mode
2768
2830
  };
2769
2831
  }
2832
+ getMcpAppContext(sessionId, sourceId, init) {
2833
+ return this.client.jsonFromInit(`/api/sessions/${encodeURIComponent(sessionId)}/mcp-apps/${encodeURIComponent(sourceId)}/context`, init);
2834
+ }
2835
+ updateMcpAppContext(sessionId, sourceId, body, init) {
2836
+ return this.client.jsonFromInit(`/api/sessions/${encodeURIComponent(sessionId)}/mcp-apps/${encodeURIComponent(sourceId)}/context`, {
2837
+ ...init,
2838
+ method: "POST",
2839
+ body: JSON.stringify(body)
2840
+ });
2841
+ }
2770
2842
  async getSessionTurnCommands(sessionId) {
2771
2843
  const commands = await this.client.json("GET", `/api/sessions/${encodeURIComponent(sessionId)}/turn-commands`);
2772
2844
  return commands.map((command) => ({
@@ -3238,6 +3310,97 @@ function replaceWindow(current, page, liveRevisionAtStart, liveRevisions) {
3238
3310
  ]);
3239
3311
  }
3240
3312
 
3313
+ // src/schemas/mcp-app.ts
3314
+ function isMcpAppData(value) {
3315
+ return isRecord(value) && typeof value.sourceId === "string" && value.sourceId.length > 0 && typeof value.resourceUri === "string" && value.resourceUri.startsWith("ui://") && typeof value.mimeType === "string" && isRecord(value.resourceMeta) && isRecord(value.toolInput) && isRecord(value.toolResult);
3316
+ }
3317
+
3318
+ // src/shared/tool-ui-card.ts
3319
+ function isNonEmptyString(value) {
3320
+ return typeof value === "string" && value.trim().length > 0;
3321
+ }
3322
+ function isPositiveNumber(value) {
3323
+ return typeof value === "number" && Number.isFinite(value) && value > 0;
3324
+ }
3325
+ function isToolUiCard(value) {
3326
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
3327
+ return false;
3328
+ }
3329
+ const raw = value;
3330
+ if (raw.target !== "inline" && raw.target !== "preview") {
3331
+ return false;
3332
+ }
3333
+ if (!isPositiveNumber(raw.height)) {
3334
+ return false;
3335
+ }
3336
+ if (raw.archived === true && !isNonEmptyString(raw.resourceHTML)) {
3337
+ return false;
3338
+ }
3339
+ if (!isNonEmptyString(raw.resourceHTML) && !isNonEmptyString(raw.resourceUri) && !isNonEmptyString(raw.resourceURI)) {
3340
+ return false;
3341
+ }
3342
+ if (raw.title != null && !isNonEmptyString(raw.title)) {
3343
+ return false;
3344
+ }
3345
+ if (raw.mcpApp !== void 0 && !isMcpAppData(raw.mcpApp)) {
3346
+ return false;
3347
+ }
3348
+ return true;
3349
+ }
3350
+ function resolveToolUiCardContent(card) {
3351
+ if (isNonEmptyString(card.resourceHTML)) {
3352
+ return { type: "resource-html", content: card.resourceHTML };
3353
+ }
3354
+ if (card.archived) return null;
3355
+ const uri = isNonEmptyString(card.resourceUri) ? card.resourceUri : card.resourceURI;
3356
+ return isNonEmptyString(uri) ? { type: "resource-uri", content: uri } : null;
3357
+ }
3358
+ function buildToolUiCardKey(toolCallId, type3, content) {
3359
+ if (type3 === "resource-uri") {
3360
+ return `tool-preview-uri:${content}`;
3361
+ }
3362
+ return `tool-preview:${toolCallId}`;
3363
+ }
3364
+ function isInternalStatusToolUiCard(card) {
3365
+ return card?.title?.trim() === "\u9636\u6BB5\u8FDB\u5EA6";
3366
+ }
3367
+ function isAppDevToolUiCard(card, isAppDev) {
3368
+ return isAppDev && card.target === "preview" && !card.resourceHTML && Boolean(card.resourceUri || card.resourceURI);
3369
+ }
3370
+ function collectInlineToolUiCards(messages) {
3371
+ return messages.flatMap(
3372
+ (message) => (message.blocks ?? []).flatMap(
3373
+ (block, index) => block.type === "tool_ui" && block.tool_call_id && isToolUiCard(block.content) && block.content.target === "inline" ? [
3374
+ {
3375
+ key: `${message.entry_id ?? message.timestamp ?? "message"}-${block.tool_call_id}-${index}`,
3376
+ toolCallId: block.tool_call_id,
3377
+ card: block.content
3378
+ }
3379
+ ] : []
3380
+ )
3381
+ );
3382
+ }
3383
+ function collectPreviewToolUiCards(messages) {
3384
+ return messages.flatMap(
3385
+ (message) => (message.blocks ?? []).flatMap((block, index) => {
3386
+ if (block.type !== "tool_ui" || !block.tool_call_id || !isToolUiCard(block.content) || block.content.target !== "preview") {
3387
+ return [];
3388
+ }
3389
+ const toolCall = (message.tool_calls ?? []).find(
3390
+ (candidate) => candidate.id === block.tool_call_id
3391
+ );
3392
+ return toolCall ? [
3393
+ {
3394
+ key: `${message.entry_id ?? message.timestamp ?? "message"}-${block.tool_call_id}-${index}`,
3395
+ toolCall,
3396
+ card: block.content,
3397
+ blocks: message.blocks ?? []
3398
+ }
3399
+ ] : [];
3400
+ })
3401
+ );
3402
+ }
3403
+
3241
3404
  // src/schemas/message-utils.ts
3242
3405
  var SYSTEM_REMINDER_PATTERN = /^<system-reminder>\s*[\s\S]*?\s*<\/system-reminder>$/i;
3243
3406
  var SYSTEM_NOTIFICATION_PATTERN = /^<system-notification>\s*[\s\S]*?\s*<\/system-notification>$/i;
@@ -3993,9 +4156,6 @@ function extractTerminalChatEndStatus(events) {
3993
4156
  }
3994
4157
  return null;
3995
4158
  }
3996
- function isUiMetaLike(value) {
3997
- return isRecord(value) && ("resourceHTML" in value || "resourceUri" in value || "resourceURI" in value);
3998
- }
3999
4159
  var AgentSession = class _AgentSession {
4000
4160
  sessionId;
4001
4161
  state;
@@ -4854,21 +5014,21 @@ ${text}` } : block
4854
5014
  this.dispatchCommand(turn, block);
4855
5015
  continue;
4856
5016
  }
4857
- if (block.type === "tool_ui" && block.tool_call_id && isUiMetaLike(block.content)) {
5017
+ if (block.type === "tool_ui" && block.tool_call_id && isToolUiCard(block.content)) {
4858
5018
  const ui = block.content;
4859
5019
  if (ui.target !== "preview") continue;
4860
- const previewType = ui.resourceHTML ? "resource-html" : "resource-uri";
4861
- const previewContent = ui.resourceHTML ?? (ui.archived ? void 0 : ui.resourceUri ?? ui.resourceURI);
4862
- if (!previewContent) continue;
4863
- if (!previewContent) continue;
4864
- const key = `${block.tool_call_id}:${previewType}`;
4865
- if (this.deliveredToolPreviews.get(key) === previewContent) continue;
4866
- this.deliveredToolPreviews.set(key, previewContent);
5020
+ const resolved = resolveToolUiCardContent(ui);
5021
+ if (!resolved) continue;
5022
+ const key = buildToolUiCardKey(block.tool_call_id, resolved.type, resolved.content);
5023
+ const fingerprint = JSON.stringify([resolved.content, ui.mcpApp?.sourceId]);
5024
+ if (this.deliveredToolPreviews.get(key) === fingerprint) continue;
5025
+ this.deliveredToolPreviews.set(key, fingerprint);
4867
5026
  this.emitter.emit("toolPreview", {
4868
5027
  toolCallId: block.tool_call_id,
4869
- type: previewType,
4870
- content: previewContent,
4871
- title: ui.title ?? "\u5DE5\u5177\u9884\u89C8"
5028
+ type: resolved.type,
5029
+ content: resolved.content,
5030
+ title: ui.title ?? "\u5DE5\u5177\u9884\u89C8",
5031
+ ...ui.mcpApp ? { mcpApp: ui.mcpApp } : {}
4872
5032
  });
4873
5033
  }
4874
5034
  if (block.type === "system_notification" && isRecord(block.content)) {
@@ -6034,7 +6194,7 @@ function resolveServiceUrl(endpoints, name, path = "") {
6034
6194
 
6035
6195
  // src/version.ts
6036
6196
  var SDK_NAME = "agent-client";
6037
- var SDK_VERSION = true ? "2610.0.0-beta.50" : "1.1.1";
6197
+ var SDK_VERSION = true ? "2610.0.0-beta.51" : "1.1.1";
6038
6198
 
6039
6199
  // src/commands/protocol.ts
6040
6200
  function isCommandEnvelope(value) {
@@ -6159,8 +6319,11 @@ export {
6159
6319
  acknowledgeTurnEvents,
6160
6320
  authBusyRetryDelayMs,
6161
6321
  buildMessageContent,
6322
+ buildToolUiCardKey,
6162
6323
  canToggleComputer,
6163
6324
  chatErrorForDisplay,
6325
+ collectInlineToolUiCards,
6326
+ collectPreviewToolUiCards,
6164
6327
  computerDaemonVersion,
6165
6328
  computerOS,
6166
6329
  computerPlatformLabel,
@@ -6179,9 +6342,13 @@ export {
6179
6342
  groupAdjacentContextRuns,
6180
6343
  groupMessagesByLoop,
6181
6344
  hasChatRunEvent,
6345
+ isAppDevToolUiCard,
6182
6346
  isCommandEnvelope,
6183
6347
  isHiddenInternalMessage,
6184
6348
  isInboundEnvelope,
6349
+ isInternalStatusToolUiCard,
6350
+ isMcpAppData,
6351
+ isToolUiCard,
6185
6352
  latestPostChatFollowup,
6186
6353
  loadPlatformEndpoints,
6187
6354
  normalizeMessageContent,
@@ -6190,6 +6357,7 @@ export {
6190
6357
  reconcileOptimisticUserTurns,
6191
6358
  replaceWindow,
6192
6359
  resolveServiceUrl,
6360
+ resolveToolUiCardContent,
6193
6361
  sortComputers,
6194
6362
  toReplaySnapshot,
6195
6363
  transformSlashCommand