langchain_agentx_stream_ui 0.2.0 → 0.2.2

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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  truncatePreview
3
- } from "./chunk-DP7V33X7.js";
3
+ } from "./chunk-6Z4ZF36Z.js";
4
4
  import {
5
5
  Agent,
6
6
  AskUserQuestion,
@@ -18,13 +18,13 @@ import {
18
18
  formatAgentTitle,
19
19
  numField,
20
20
  strField
21
- } from "./chunk-7CLAU74Y.js";
21
+ } from "./chunk-YUZXTGJJ.js";
22
22
  import {
23
23
  TruncatedContent,
24
24
  displayPath,
25
25
  formatBashTitle,
26
26
  formatPatternTitle
27
- } from "./chunk-4RIOBLGB.js";
27
+ } from "./chunk-GBY5DJ7L.js";
28
28
 
29
29
  // src/view/tools/ask_user_question/formatAskUserQuestionTitle.ts
30
30
  function firstQuestion(display, input) {
@@ -408,4 +408,4 @@ export {
408
408
  useInteractionBus,
409
409
  ToolCallShell
410
410
  };
411
- //# sourceMappingURL=chunk-6DYISADG.js.map
411
+ //# sourceMappingURL=chunk-T626YBJX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/view/tools/ask_user_question/formatAskUserQuestionTitle.ts","../src/view/tools/edit/formatEditTitle.ts","../src/view/tools/glob/formatGlobTitle.ts","../src/view/tools/grep/formatGrepTitle.ts","../src/view/tools/read/formatReadTitle.ts","../src/view/tools/skill/formatSkillTitle.ts","../src/view/tools/webfetch/formatWebFetchTitle.ts","../src/view/tools/websearch/formatWebSearchTitle.ts","../src/view/tools/write/formatWriteTitle.ts","../src/view/tools/formatToolTitle.ts","../src/view/tools/DefaultToolBody.tsx","../src/view/tools/resolveToolBody.ts","../src/core/interaction/InteractionBus.ts","../src/core/context/InteractionContext.tsx","../src/view/tools/ToolPermissionWait.tsx","../src/view/tools/ToolCallShell.tsx"],"sourcesContent":["/**\r\n * formatAskUserQuestionTitle.ts — AskUserQuestion 工具标题\r\n *\r\n * 对齐参考:CLI widgets/tools/ask_user_question/widget.py format_title\r\n */\r\nimport { asDisplayRecord, asInputRecord, numField } from '../displayRecord';\r\nimport { formatAskUserQuestionsPreview } from '../presentation/askUserHelpers';\r\nimport { truncatePreview } from '../presentation/textHelpers';\r\n\r\nfunction firstQuestion(\r\n display: Record<string, unknown> | null,\r\n input: Record<string, unknown>,\r\n): { header: string; question: string } {\r\n const items = display?.questions;\r\n if (Array.isArray(items) && items.length > 0) {\r\n const first = items[0];\r\n if (first != null && typeof first === 'object') {\r\n const row = first as Record<string, unknown>;\r\n return {\r\n header: String(row.header ?? '').trim(),\r\n question: String(row.question ?? '').trim(),\r\n };\r\n }\r\n }\r\n\r\n const questions = input.questions;\r\n if (Array.isArray(questions) && questions.length > 0) {\r\n const first = questions[0];\r\n if (first != null && typeof first === 'object') {\r\n const row = first as Record<string, unknown>;\r\n return {\r\n header: String(row.header ?? '').trim(),\r\n question: String(row.question ?? '').trim(),\r\n };\r\n }\r\n }\r\n\r\n return { header: '', question: '' };\r\n}\r\n\r\nexport function formatAskUserQuestionTitle(\r\n input: unknown,\r\n display: unknown,\r\n _summary?: string | null,\r\n): string {\r\n const d = asDisplayRecord(display);\r\n const inp = asInputRecord(input);\r\n const { header, question } = firstQuestion(d, inp);\r\n\r\n if (question) {\r\n const label = header ? `[${header}] ${question}` : question;\r\n return truncatePreview(label, 100);\r\n }\r\n\r\n const answered = numField(d ?? {}, 'answered_count');\r\n if (answered != null) return `Ask user (${answered} answered)`;\r\n\r\n return 'Ask user';\r\n}\r\n\r\nexport { formatAskUserQuestionsPreview };\r\n","/**\r\n * formatEditTitle.ts — edit 工具标题(Update / Create)\r\n *\r\n * 对齐参考:CLI widgets/tools/edit/widget.py format_title\r\n */\r\nimport { asInputRecord, strField } from '../displayRecord';\r\nimport { displayPath } from '../presentation/paths';\r\n\r\nexport function editAction(input: unknown): 'Update' | 'Create' {\r\n const inp = asInputRecord(input);\r\n if (Array.isArray(inp.edits) && inp.edits.length > 0) return 'Update';\r\n if ('old_string' in inp && inp.old_string === '') return 'Create';\r\n return 'Update';\r\n}\r\n\r\nexport function formatEditTitle(\r\n input: unknown,\r\n display: unknown,\r\n _summary?: string | null,\r\n): string {\r\n const inp = asInputRecord(input);\r\n const d =\r\n display != null && typeof display === 'object' && !Array.isArray(display)\r\n ? (display as Record<string, unknown>)\r\n : null;\r\n const path = displayPath(\r\n strField(d ?? {}, 'file_path') || strField(inp, 'file_path'),\r\n );\r\n const action = editAction(inp);\r\n if (!path) return action;\r\n return `${action}(${path})`;\r\n}\r\n","/**\r\n * formatGlobTitle.ts — glob 工具标题\r\n *\r\n * 对齐参考:CLI widgets/tools/glob/widget.py format_title\r\n */\r\nimport { formatPatternTitle } from '../presentation/searchHelpers';\r\nimport { asDisplayRecord, asInputRecord, numField, strField } from '../displayRecord';\r\n\r\nexport function formatGlobTitle(\r\n input: unknown,\r\n display: unknown,\r\n _summary?: string | null,\r\n): string {\r\n const d = asDisplayRecord(display);\r\n const inp = asInputRecord(input);\r\n const pattern = strField(d ?? {}, 'pattern') || strField(inp, 'pattern');\r\n\r\n if (!pattern) return 'Search';\r\n\r\n const path = strField(inp, 'path') || undefined;\r\n const suffix = formatPatternTitle(pattern, path);\r\n const numFiles = numField(d ?? {}, 'num_files');\r\n const countHint = numFiles != null ? ` · ${numFiles} files` : '';\r\n\r\n return `Search(${suffix}${countHint})`;\r\n}\r\n","/**\r\n * formatGrepTitle.ts — grep 工具标题\r\n *\r\n * 对齐参考:CLI widgets/tools/grep/widget.py format_title\r\n */\r\nimport { formatPatternTitle } from '../presentation/searchHelpers';\r\nimport { asDisplayRecord, asInputRecord, numField, strField } from '../displayRecord';\r\n\r\nexport function formatGrepTitle(\r\n input: unknown,\r\n display: unknown,\r\n _summary?: string | null,\r\n): string {\r\n const d = asDisplayRecord(display);\r\n const inp = asInputRecord(input);\r\n const pattern = strField(d ?? {}, 'pattern') || strField(inp, 'pattern');\r\n\r\n if (!pattern) return 'Search';\r\n\r\n const path = strField(inp, 'path') || undefined;\r\n const suffix = formatPatternTitle(pattern, path);\r\n const numMatches = numField(d ?? {}, 'num_matches');\r\n const countHint = numMatches != null ? ` · ${numMatches} matches` : '';\r\n\r\n return `Search(${suffix}${countHint})`;\r\n}\r\n","/**\r\n * formatReadTitle.ts — Read 工具标题\r\n *\r\n * 对齐参考:CLI widgets/tools/read/widget.py format_title\r\n */\r\nimport { displayPath } from '../presentation/paths';\r\nimport { asDisplayRecord, asInputRecord, numField, strField } from '../displayRecord';\r\n\r\nconst LINES_RANGE_RE = /lines (\\d+)-(\\d+) of (\\d+)/;\r\nconst READ_LINES_RE = /Read (\\d+) lines from/;\r\n\r\nfunction titleSuffixFromDisplay(display: unknown): string {\r\n const d = asDisplayRecord(display);\r\n if (!d) return '';\r\n\r\n if (d.type === 'text') {\r\n const start = numField(d, 'line_start');\r\n const end = numField(d, 'line_end');\r\n if (start != null && end != null) {\r\n return ` · lines ${start}-${end}`;\r\n }\r\n }\r\n\r\n if (d.type === 'pdf') {\r\n const ps = numField(d, 'page_start');\r\n const pe = numField(d, 'page_end');\r\n if (ps != null && pe != null) {\r\n return ` · pages ${ps}-${pe}`;\r\n }\r\n }\r\n\r\n return '';\r\n}\r\n\r\nfunction titleSuffixFromSummary(summary: string, input: unknown): string {\r\n const matchRange = summary.match(LINES_RANGE_RE);\r\n if (matchRange) {\r\n return ` · lines ${matchRange[1]}-${matchRange[2]}`;\r\n }\r\n\r\n const inp = asInputRecord(input);\r\n const offset = numField(inp, 'offset');\r\n const limit = numField(inp, 'limit');\r\n if (offset != null && limit != null) {\r\n return ` · lines ${offset}-${offset + limit - 1}`;\r\n }\r\n\r\n const matchLines = summary.match(READ_LINES_RE);\r\n if (matchLines) {\r\n return ` · ${matchLines[1]} lines`;\r\n }\r\n\r\n return '';\r\n}\r\n\r\nexport function formatReadTitle(input: unknown, display: unknown, summary?: string | null): string {\r\n const d = asDisplayRecord(display);\r\n const inp = asInputRecord(input);\r\n const path = displayPath(\r\n strField(d ?? {}, 'file_path') ||\r\n strField(inp, 'file_path') ||\r\n strField(inp, 'path'),\r\n );\r\n\r\n const suffix =\r\n titleSuffixFromDisplay(display) ||\r\n (summary ? titleSuffixFromSummary(summary, input) : '');\r\n\r\n if (!path) {\r\n return suffix ? `Read(${suffix.trim()})` : 'Read';\r\n }\r\n\r\n return `Read(${path}${suffix})`;\r\n}\r\n","/**\r\n * formatSkillTitle.ts — skill 工具标题\r\n *\r\n * 对齐参考:CLI widgets/tools/skill/widget.py format_title\r\n */\r\nimport { asDisplayRecord, asInputRecord, strField } from '../displayRecord';\r\n\r\nexport function formatSkillTitle(\r\n input: unknown,\r\n display: unknown,\r\n _summary?: string | null,\r\n): string {\r\n const d = asDisplayRecord(display);\r\n const inp = asInputRecord(input);\r\n const name = strField(d ?? {}, 'skill_name') || strField(inp, 'skill_name');\r\n if (!name) return 'Skill';\r\n\r\n if (d?.source === 'commands_DEPRECATED') {\r\n return `/${name}`;\r\n }\r\n return name;\r\n}\r\n","/**\r\n * formatWebFetchTitle.ts — WebFetch 工具标题\r\n *\r\n * 对齐参考:CLI widgets/tools/webfetch/widget.py format_title\r\n */\r\nimport { asDisplayRecord, asInputRecord, numField, strField } from '../displayRecord';\r\nimport { truncatePreview } from '../presentation/textHelpers';\r\n\r\nexport function formatWebFetchTitle(\r\n input: unknown,\r\n display: unknown,\r\n _summary?: string | null,\r\n): string {\r\n const d = asDisplayRecord(display);\r\n const inp = asInputRecord(input);\r\n const url = strField(d ?? {}, 'url') || strField(inp, 'url');\r\n if (!url) return 'Fetch';\r\n\r\n const code = numField(d ?? {}, 'http_code');\r\n const title =\r\n code != null ? `${url} · HTTP ${code}` : truncatePreview(url, 100);\r\n return `Fetch(${title})`;\r\n}\r\n","/**\r\n * formatWebSearchTitle.ts — WebSearch 工具标题\r\n *\r\n * 对齐参考:CLI widgets/tools/websearch/widget.py format_title\r\n */\r\nimport { asDisplayRecord, asInputRecord, numField, strField } from '../displayRecord';\r\nimport { truncatePreview } from '../presentation/textHelpers';\r\n\r\nexport function formatWebSearchTitle(\r\n input: unknown,\r\n display: unknown,\r\n _summary?: string | null,\r\n): string {\r\n const d = asDisplayRecord(display);\r\n const inp = asInputRecord(input);\r\n const query = strField(d ?? {}, 'query') || strField(inp, 'query');\r\n if (!query) return 'Web Search';\r\n\r\n let queryPart = `\"${truncatePreview(query, 100)}\"`;\r\n const hits = numField(d ?? {}, 'total_hits');\r\n if (hits != null) queryPart = `${queryPart} · ${hits} hits`;\r\n\r\n return `Web Search(${queryPart})`;\r\n}\r\n","/**\r\n * formatWriteTitle.ts — write 工具标题\r\n *\r\n * 对齐参考:CLI widgets/tools/write/widget.py format_title\r\n */\r\nimport { asDisplayRecord, asInputRecord, strField } from '../displayRecord';\r\nimport { displayPath } from '../presentation/paths';\r\n\r\nexport function formatWriteTitle(\r\n input: unknown,\r\n display: unknown,\r\n _summary?: string | null,\r\n): string {\r\n const inp = asInputRecord(input);\r\n const d = asDisplayRecord(display);\r\n const path = displayPath(\r\n strField(d ?? {}, 'file_path') || strField(inp, 'file_path'),\r\n );\r\n if (!path) return 'Write';\r\n return `Write(${path})`;\r\n}\r\n","/**\r\n * formatToolTitle.ts — 工具卡片标题格式化\r\n */\r\nimport { formatAgentTitle } from './presentation/agentHelpers';\r\nimport { formatAskUserQuestionTitle } from './ask_user_question/formatAskUserQuestionTitle';\r\nimport { formatBashTitle } from './presentation/bashHelpers';\r\nimport { formatEditTitle } from './edit/formatEditTitle';\r\nimport { formatGlobTitle } from './glob/formatGlobTitle';\r\nimport { formatGrepTitle } from './grep/formatGrepTitle';\r\nimport { formatReadTitle } from './read/formatReadTitle';\r\nimport { formatSkillTitle } from './skill/formatSkillTitle';\r\nimport { formatWebFetchTitle } from './webfetch/formatWebFetchTitle';\r\nimport { formatWebSearchTitle } from './websearch/formatWebSearchTitle';\r\nimport { formatWriteTitle } from './write/formatWriteTitle';\r\nimport {\r\n Agent,\r\n AskUserQuestion,\r\n Bash,\r\n Edit,\r\n Glob,\r\n Grep,\r\n Read,\r\n Skill,\r\n WebFetch,\r\n WebSearch,\r\n Write,\r\n} from './toolNames';\r\n\r\ntype TitleFormatter = (\r\n input: unknown,\r\n display: unknown,\r\n summary?: string | null,\r\n meta?: unknown,\r\n) => string;\r\n\r\nconst TITLE_FORMATTERS: Record<string, TitleFormatter> = {\r\n [Read]: formatReadTitle,\r\n [Grep]: formatGrepTitle,\r\n [Glob]: formatGlobTitle,\r\n [Edit]: formatEditTitle,\r\n [Write]: formatWriteTitle,\r\n [Bash]: formatBashTitle,\r\n [Agent]: formatAgentTitle,\r\n [Skill]: formatSkillTitle,\r\n [WebSearch]: formatWebSearchTitle,\r\n [WebFetch]: formatWebFetchTitle,\r\n [AskUserQuestion]: formatAskUserQuestionTitle,\r\n};\r\n\r\nexport function formatToolTitle(\r\n toolName: string,\r\n input: unknown,\r\n display: unknown,\r\n summary?: string | null,\r\n meta?: unknown,\r\n): string {\r\n const formatter = TITLE_FORMATTERS[toolName];\r\n if (formatter) {\r\n return formatter(input, display, summary, meta);\r\n }\r\n return toolName;\r\n}\r\n","/**\r\n * DefaultToolBody.tsx — 未注册工具回退 Body\r\n *\r\n * 职责:\r\n * summary + display JSON 预览(≥ V2);markdown/text 走 TruncatedContent。\r\n *\r\n * 链路位置:\r\n * resolveToolBody 最终回退。\r\n *\r\n * 当前裁剪范围:\r\n * 不渲染 blocks 主视图(折叠区保留在 ToolCallCard details)。\r\n *\r\n * 对齐参考:\r\n * CLI widgets/tools/base.py BaseToolWidget · V2 ToolCallCard JSON pre\r\n */\r\nimport { TruncatedContent } from './presentation/TruncatedContent';\r\nimport type { ToolDisplayProps } from './types';\r\n\r\nfunction formatDisplayJson(display: unknown): string {\r\n if (display == null) return '';\r\n if (typeof display === 'string') return display;\r\n try {\r\n return JSON.stringify(display, null, 2);\r\n } catch {\r\n return String(display);\r\n }\r\n}\r\n\r\nfunction extractTextContent(display: unknown): string | null {\r\n if (display == null) return null;\r\n if (typeof display === 'string') return display;\r\n if (typeof display === 'object') {\r\n const record = display as { content?: unknown; text?: unknown };\r\n if (typeof record.content === 'string') return record.content;\r\n if (typeof record.text === 'string') return record.text;\r\n }\r\n return null;\r\n}\r\n\r\nexport function DefaultToolBody({\r\n result,\r\n bodyMode,\r\n onBodyModeChange,\r\n}: ToolDisplayProps) {\r\n const summary = result?.summary;\r\n const displayBody = result?.display ?? null;\r\n const textContent = extractTextContent(displayBody);\r\n const jsonBody = textContent ?? formatDisplayJson(displayBody);\r\n\r\n return (\r\n <div className=\"lax-tool-body lax-tool-body--default\">\r\n {summary ? (\r\n <div className=\"lax-tool-card__summary\">{summary}</div>\r\n ) : null}\r\n\r\n {displayBody != null && displayBody !== '' && jsonBody ? (\r\n <div className=\"lax-tool-card__display\">\r\n {textContent != null ? (\r\n <TruncatedContent\r\n text={textContent}\r\n mode={bodyMode}\r\n onExpand={() => onBodyModeChange?.('full')}\r\n />\r\n ) : (\r\n <pre className=\"lax-tool-card__display-body\">{jsonBody}</pre>\r\n )}\r\n </div>\r\n ) : null}\r\n\r\n {result?.truncated ? (\r\n <div className=\"lax-tool-card__truncated\">结果已截断</div>\r\n ) : null}\r\n\r\n {result?.overflow_file ? (\r\n <div className=\"lax-tool-card__overflow\">\r\n 完整输出:\r\n <code>{result.overflow_file}</code>\r\n </div>\r\n ) : null}\r\n </div>\r\n );\r\n}\r\n","/**\r\n * resolveToolBody.ts — 工具 Body 路由纯函数\r\n *\r\n * 职责:\r\n * registry → display.type → DefaultToolBody(精确 tool_name 匹配,无 alias)。\r\n *\r\n * 链路位置:\r\n * ToolCallCard render。\r\n *\r\n * 当前裁剪范围:\r\n * T0 display.type 二级路由表为空;T1+ 注册专用 Widget 与 kind router。\r\n *\r\n * 对齐参考:\r\n * CLI widgets/tools/__init__.py resolve_tool_widget\r\n */\r\nimport { DefaultToolBody } from './DefaultToolBody';\r\nimport type { ToolDisplayRegistry } from './registry';\r\nimport type { ToolBodyComponent } from './types';\r\n\r\n/** display.type → Body;T0 空表,T1+ 填充。 */\r\nconst DISPLAY_KIND_ROUTER = new Map<string, ToolBodyComponent>();\r\n\r\nfunction getDisplayType(display: unknown): string | undefined {\r\n if (display == null || typeof display !== 'object') return undefined;\r\n const type = (display as { type?: unknown }).type;\r\n return typeof type === 'string' ? type : undefined;\r\n}\r\n\r\nexport function resolveToolBody(\r\n toolName: string,\r\n display: unknown,\r\n registry: ToolDisplayRegistry,\r\n): ToolBodyComponent {\r\n const byName = registry.resolve(toolName);\r\n if (byName) return byName;\r\n\r\n const displayType = getDisplayType(display);\r\n if (displayType) {\r\n const byKind = DISPLAY_KIND_ROUTER.get(displayType);\r\n if (byKind) return byKind;\r\n }\r\n\r\n return DefaultToolBody;\r\n}\r\n\r\n/** 测试 / 扩展用:注册 display.type 路由。 */\r\nexport function registerDisplayKind(\r\n displayType: string,\r\n body: ToolBodyComponent,\r\n): void {\r\n DISPLAY_KIND_ROUTER.set(displayType, body);\r\n}\r\n\r\n/** 测试用:清空 display kind 路由。 */\r\nexport function clearDisplayKindRouter(): void {\r\n DISPLAY_KIND_ROUTER.clear();\r\n}\r\n","/**\r\n * 职责:人类回写薄层 API;PermissionNode 触发,业务实现 HTTP 回写。\r\n * 链路位置:AgentSession interactionBus prop → PermissionNode 按钮。\r\n * 当前裁剪范围:permission resolve;不含 HITL 表单协议。\r\n */\r\n\r\nexport interface PermissionResolvePayload {\r\n requestId: string;\r\n allow: boolean;\r\n message?: string;\r\n}\r\n\r\nexport interface InteractionBus {\r\n resolvePermission: (payload: PermissionResolvePayload) => void | Promise<void>;\r\n}\r\n\r\nexport interface InteractionBusHandlers {\r\n onPermissionResolve?: (payload: PermissionResolvePayload) => void | Promise<void>;\r\n}\r\n\r\nconst noopBus: InteractionBus = {\r\n resolvePermission() {\r\n if (import.meta.env?.DEV) {\r\n console.warn('[langchain_agentx_stream_ui] resolvePermission without InteractionBus');\r\n }\r\n },\r\n};\r\n\r\nexport function createInteractionBus(handlers: InteractionBusHandlers = {}): InteractionBus {\r\n return {\r\n resolvePermission(payload) {\r\n return handlers.onPermissionResolve?.(payload);\r\n },\r\n };\r\n}\r\n\r\nexport function getNoopInteractionBus(): InteractionBus {\r\n return noopBus;\r\n}\r\n","/**\r\n * 职责:向 PermissionNode 注入 InteractionBus。\r\n * 链路位置:AgentSession / MultiAgentSession Provider。\r\n * 当前裁剪范围:单 bus;多会话共用同一 bus(业务按 requestId 路由)。\r\n */\r\nimport { createContext, useContext } from 'react';\r\n\r\nimport type { InteractionBus } from '../interaction/InteractionBus';\r\nimport { getNoopInteractionBus } from '../interaction/InteractionBus';\r\n\r\nexport const InteractionBusContext = createContext<InteractionBus>(getNoopInteractionBus());\r\n\r\nexport function useInteractionBus(): InteractionBus {\r\n return useContext(InteractionBusContext);\r\n}\r\n","/**\r\n * ToolPermissionWait.tsx — ToolCallShell 内嵌 permission 等待态(T4.6)\r\n *\r\n * 对齐参考:CC AssistantToolUseMessage「Waiting for permission…」分支\r\n */\r\nimport { useState } from 'react';\r\n\r\nimport { useInteractionBus } from '../../core/context/InteractionContext';\r\nimport type { PermissionNode } from '../../types/nodes';\r\nimport type { PermissionUiMode } from '../sessionViewOptions';\r\n\r\nexport interface ToolPermissionWaitProps {\r\n permission: PermissionNode;\r\n mode: PermissionUiMode;\r\n}\r\n\r\nexport function ToolPermissionWait({ permission, mode }: ToolPermissionWaitProps) {\r\n const bus = useInteractionBus();\r\n const [resolvedLocally, setResolvedLocally] = useState(false);\r\n\r\n if (permission.status !== 'pending' || resolvedLocally) return null;\r\n\r\n const showActions = mode === 'inline' || mode === 'both';\r\n\r\n const onAllow = () => {\r\n void bus.resolvePermission({ requestId: permission.requestId, allow: true });\r\n setResolvedLocally(true);\r\n };\r\n\r\n const onDeny = () => {\r\n void bus.resolvePermission({ requestId: permission.requestId, allow: false });\r\n setResolvedLocally(true);\r\n };\r\n\r\n return (\r\n <div className=\"lax-tool-shell__permission-wait\" role=\"status\">\r\n <div className=\"lax-tool-shell__permission-wait-text\">\r\n Waiting for permission…\r\n </div>\r\n {permission.message ? (\r\n <div className=\"lax-tool-shell__permission-wait-detail\">{permission.message}</div>\r\n ) : null}\r\n {showActions ? (\r\n <div className=\"lax-tool-shell__permission-actions\">\r\n <button type=\"button\" className=\"lax-permission-card__allow\" onClick={onAllow}>\r\n Allow\r\n </button>\r\n <button type=\"button\" className=\"lax-permission-card__deny\" onClick={onDeny}>\r\n Deny\r\n </button>\r\n </div>\r\n ) : null}\r\n </div>\r\n );\r\n}\r\n","/**\r\n * ToolCallShell.tsx — 工具卡片外壳\r\n *\r\n * 职责:\r\n * 状态圆点、标题、progress、error 边框;不含工具语义。\r\n *\r\n * 链路位置:\r\n * ToolCallCard 外层布局。\r\n *\r\n * 当前裁剪范围:\r\n * T4.6 内嵌 permission 等待态;Grouped 紧凑布局 variant。\r\n *\r\n * 对齐参考:\r\n * CLI base.py 状态圆点 · CC AssistantToolUseMessage.tsx 外层 Box\r\n */\r\nimport type { ReactNode } from 'react';\r\n\r\nimport type { ToolCallNode } from '../../types/nodes';\r\nimport type { PermissionNode } from '../../types/nodes';\r\nimport type { PermissionUiMode } from '../sessionViewOptions';\r\nimport { ToolPermissionWait } from './ToolPermissionWait';\r\n\r\nexport interface ToolCallShellProps {\r\n status: ToolCallNode['status'];\r\n title: string;\r\n progress?: ToolCallNode['progress'];\r\n errorMessage?: string | null;\r\n layout?: 'default' | 'grouped';\r\n permissionWait?: PermissionNode;\r\n permissionUiMode?: PermissionUiMode;\r\n children?: ReactNode;\r\n}\r\n\r\nexport function ToolCallShell({\r\n status,\r\n title,\r\n progress,\r\n errorMessage,\r\n layout = 'default',\r\n permissionWait,\r\n permissionUiMode = 'standalone',\r\n children,\r\n}: ToolCallShellProps) {\r\n const bare = !title.trim();\r\n const waitingForPermission =\r\n permissionWait &&\r\n permissionUiMode !== 'standalone' &&\r\n (status === 'running' || status === 'failed');\r\n\r\n return (\r\n <div\r\n className={[\r\n 'lax-tool-card',\r\n 'lax-tool-shell',\r\n bare ? 'lax-tool-shell--bare' : '',\r\n layout === 'grouped' ? 'lax-tool-shell--grouped' : '',\r\n waitingForPermission ? 'lax-tool-shell--permission-wait' : '',\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n data-status={status}\r\n data-error-kind={\r\n errorMessage ? 'error' : waitingForPermission ? 'permission' : undefined\r\n }\r\n >\r\n {!bare ? (\r\n <div className=\"lax-tool-shell__header lax-tool-card__header\">\r\n <span\r\n className=\"lax-tool-shell__status-dot lax-tool-card__status-dot\"\r\n data-status={status}\r\n aria-hidden\r\n >\r\n ●{' '}\r\n </span>\r\n <span className=\"lax-tool-shell__title lax-tool-card__name\">{title}</span>\r\n </div>\r\n ) : null}\r\n\r\n {progress ? (\r\n <div className=\"lax-tool-shell__progress lax-tool-card__progress\">\r\n {progress.message ?? `${progress.current}/${progress.total}`}\r\n </div>\r\n ) : null}\r\n\r\n {waitingForPermission && permissionWait ? (\r\n <ToolPermissionWait permission={permissionWait} mode={permissionUiMode} />\r\n ) : null}\r\n\r\n {children}\r\n\r\n {errorMessage && status === 'failed' ? (\r\n <div className=\"lax-tool-card__error\" role=\"alert\">\r\n {errorMessage}\r\n </div>\r\n ) : null}\r\n </div>\r\n );\r\n}\r\n"],"mappings":"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","names":["jsx","jsxs","jsx","jsxs"]}
@@ -13,7 +13,7 @@ import {
13
13
  resolveEditDiffText,
14
14
  truncateCommand,
15
15
  truncateLines
16
- } from "./chunk-4RIOBLGB.js";
16
+ } from "./chunk-GBY5DJ7L.js";
17
17
 
18
18
  // src/view/tools/toolNames.ts
19
19
  var Read = "Read";
@@ -1129,4 +1129,4 @@ export {
1129
1129
  ToolDisplayRegistry,
1130
1130
  createDefaultToolRegistry
1131
1131
  };
1132
- //# sourceMappingURL=chunk-7CLAU74Y.js.map
1132
+ //# sourceMappingURL=chunk-YUZXTGJJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/view/tools/toolNames.ts","../src/view/tools/presentation/agentProgressRenderer.ts","../src/view/tools/presentation/agentHelpers.ts","../src/view/tools/agent/AgentProgressLines.tsx","../src/view/tools/presentation/subagentTranscriptRenderer.ts","../src/view/tools/agent/SubagentTranscriptBlock.tsx","../src/view/tools/agent/AgentToolBody.tsx","../src/view/tools/displayRecord.ts","../src/view/tools/presentation/askUserHelpers.ts","../src/view/tools/ask_user_question/AskUserQuestionToolBody.tsx","../src/view/tools/bash/BashToolBody.tsx","../src/view/tools/edit/EditToolBody.tsx","../src/view/tools/glob/GlobToolBody.tsx","../src/view/tools/grep/GrepToolBody.tsx","../src/view/tools/read/ReadToolBody.tsx","../src/view/tools/skill/SkillToolBody.tsx","../src/view/tools/webfetch/WebFetchToolBody.tsx","../src/view/tools/websearch/WebSearchToolBody.tsx","../src/view/tools/write/WriteToolBody.tsx","../src/view/tools/registry.ts"],"sourcesContent":["/**\r\n * toolNames.ts — CC PascalCase 工具名 SSOT(对齐 SDK registry_names.py)\r\n *\r\n * 职责:Stream UI widget / projection / reducer 消费的工具名字面量唯一来源。\r\n * 链路位置:registry.ts、classify.ts、memoryPaths.ts、reducer.ts。\r\n * 当前裁剪范围:无 legacy alias、无 *Tool 后缀变体、无 REMOVED 双轨表。\r\n */\r\n\r\nexport const Read = 'Read';\r\nexport const Write = 'Write';\r\nexport const Edit = 'Edit';\r\nexport const Glob = 'Glob';\r\nexport const Grep = 'Grep';\r\nexport const Bash = 'Bash';\r\nexport const Skill = 'Skill';\r\nexport const Agent = 'Agent';\r\nexport const AskUserQuestion = 'AskUserQuestion';\r\nexport const WebSearch = 'WebSearch';\r\nexport const WebFetch = 'WebFetch';\r\n\r\nexport const TaskCreate = 'TaskCreate';\r\nexport const TaskUpdate = 'TaskUpdate';\r\nexport const TaskList = 'TaskList';\r\nexport const TaskGet = 'TaskGet';\r\nexport const TaskOutput = 'TaskOutput';\r\nexport const TaskStop = 'TaskStop';\r\n\r\n/** SSE 抑制 + Timeline hidden:SDK Task* 内部工具(仅 CC 注册名) */\r\nexport const SILENT_TASK_TOOL_NAMES: readonly string[] = [\r\n TaskCreate,\r\n TaskGet,\r\n TaskList,\r\n TaskUpdate,\r\n];\r\n\r\n/** reducer 不渲染的内部工具(= SILENT_TASK + TaskOutput/TaskStop) */\r\nexport const INTERNAL_TOOL_NAMES: ReadonlySet<string> = new Set([\r\n ...SILENT_TASK_TOOL_NAMES,\r\n TaskOutput,\r\n TaskStop,\r\n]);\r\n\r\n/** CC 核心文件/Shell 工具名(门禁:src 中禁止 legacy 小写 alias) */\r\nexport const CC_CORE_TOOL_NAMES: readonly string[] = [\r\n Read,\r\n Write,\r\n Edit,\r\n Glob,\r\n Grep,\r\n Bash,\r\n Skill,\r\n Agent,\r\n AskUserQuestion,\r\n WebSearch,\r\n WebFetch,\r\n];\r\n\r\n/** 单测负向样本:legacy 名不得出现在 src(由 TN-006 guard 扫描) */\r\nexport const LEGACY_TOOL_NAME_SAMPLES: readonly string[] = [\r\n 'read',\r\n 'read_file',\r\n 'write',\r\n 'edit',\r\n 'glob',\r\n 'grep',\r\n 'bash',\r\n 'skill',\r\n 'agent',\r\n 'Task',\r\n 'search',\r\n 'list',\r\n 'batch_edit',\r\n];\r\n","/**\n * agentProgressRenderer.ts — Agent 子工具 progress 行(对齐 CLI progress_renderer.py)\n */\nimport type { SubagentProgressEntry } from '../../../types/nodes';\nimport { truncateCommand } from './bashHelpers';\n\nexport const AGENT_PROGRESS_GUTTER = ' ⎿ ';\nexport const AGENT_PROGRESS_INDENT = ' ';\n\nfunction truncatePreview(text: string, maxChars = 80): string {\n const trimmed = text.trim();\n if (trimmed.length <= maxChars) return trimmed;\n return `${trimmed.slice(0, maxChars)}…`;\n}\n\nconst READ_TOOLS = new Set(['Read']);\nconst SEARCH_TOOLS = new Set(['Glob', 'Grep', 'SemanticSearch', 'Search']);\nconst BASH_TOOLS = new Set(['Bash']);\n\nexport interface ProcessedProgressLine {\n text: string;\n toolUseCount: number;\n}\n\nfunction toolInputRecord(input: unknown): Record<string, unknown> {\n if (input != null && typeof input === 'object' && !Array.isArray(input)) {\n return input as Record<string, unknown>;\n }\n return {};\n}\n\n/** 对齐 CLI format_subagent_tool_progress_line:Bash(cmd) / Read(path) / Glob(pattern)。 */\nexport function formatSubagentToolProgressLine(\n toolName: string,\n options: { summary?: string; toolInput?: unknown } = {},\n): string {\n const name = toolName.trim();\n const inp = toolInputRecord(options.toolInput);\n\n if (name === 'Bash') {\n const command = String(inp.command ?? inp.description ?? '').trim();\n if (command) return `Bash(${truncateCommand(command)})`;\n }\n if (name === 'Read') {\n const path = String(inp.path ?? inp.file_path ?? '').trim();\n if (path) return `Read(${truncatePreview(path, 60)})`;\n }\n if (name === 'Glob' || name === 'Grep') {\n const pattern = String(inp.pattern ?? inp.glob_pattern ?? '').trim();\n const path = String(inp.path ?? inp.glob ?? '').trim();\n if (pattern && path) {\n return `${name}(${truncatePreview(pattern, 40)}, ${truncatePreview(path, 40)})`;\n }\n if (pattern) return `${name}(${truncatePreview(pattern, 60)})`;\n if (path) return `${name}(${truncatePreview(path, 60)})`;\n }\n\n const summary = (options.summary ?? '').trim();\n const callingLower = `calling ${name.toLowerCase()}`;\n if (summary && summary.toLowerCase() !== callingLower) {\n return summary;\n }\n return name;\n}\n\nexport function formatSubagentProgressLine(entry: SubagentProgressEntry): string {\n return formatSubagentToolProgressLine(entry.toolName, {\n summary: entry.summary,\n toolInput: entry.toolInput,\n });\n}\n\nfunction isSubagentProgressEntry(value: unknown): value is SubagentProgressEntry {\n if (value == null || typeof value !== 'object' || Array.isArray(value)) return false;\n const row = value as SubagentProgressEntry;\n return typeof row.toolName === 'string' && row.toolName.length > 0;\n}\n\nfunction readProgressField<T>(\n row: Record<string, unknown>,\n camel: string,\n snake: string,\n): T | undefined {\n const camelValue = row[camel];\n if (camelValue !== undefined && camelValue !== null) return camelValue as T;\n const snakeValue = row[snake];\n if (snakeValue !== undefined && snakeValue !== null) return snakeValue as T;\n return undefined;\n}\n\n/** grouped_tool_use payload 内 subagent_progress → SubagentProgressEntry[] */\nexport function coerceSubagentProgressEntries(raw: unknown): SubagentProgressEntry[] {\n if (!Array.isArray(raw)) return [];\n const entries: SubagentProgressEntry[] = [];\n for (const item of raw) {\n if (item == null || typeof item !== 'object' || Array.isArray(item)) continue;\n const row = item as Record<string, unknown>;\n const toolName = readProgressField<string>(row, 'toolName', 'tool_name');\n const agentId = readProgressField<string>(row, 'agentId', 'agent_id');\n if (!toolName || !agentId) continue;\n const stepRaw = readProgressField<number>(row, 'step', 'step') ?? 0;\n const statusRaw = readProgressField<string>(row, 'status', 'status') ?? 'completed';\n const status: SubagentProgressEntry['status'] =\n statusRaw === 'running'\n ? 'running'\n : statusRaw === 'error' || statusRaw === 'failed'\n ? 'error'\n : 'completed';\n entries.push({\n agentId,\n subagentType: readProgressField<string>(row, 'subagentType', 'subagent_type'),\n step: stepRaw,\n toolName,\n summary: readProgressField<string>(row, 'summary', 'summary') ?? toolName,\n status,\n toolInput: readProgressField<unknown>(row, 'toolInput', 'tool_input'),\n childToolCallId: readProgressField<string>(row, 'childToolCallId', 'child_tool_call_id'),\n });\n }\n return entries.sort((a, b) => a.step - b.step || a.toolName.localeCompare(b.toolName));\n}\n\n/** 对齐 CLI extractLastToolInfoFromProgressEntries:分组子行 pending 态展示。 */\nexport function extractLastToolInfoFromProgress(\n progress: unknown,\n): string | null {\n if (!Array.isArray(progress) || progress.length === 0) return null;\n for (let index = progress.length - 1; index >= 0; index -= 1) {\n const entry = progress[index];\n if (!isSubagentProgressEntry(entry)) continue;\n const line = formatSubagentProgressLine(entry);\n if (line) return line;\n }\n return null;\n}\n\nfunction formatGroupText(\n toolName: string,\n display: string,\n count: number,\n isRead: boolean,\n isSearch: boolean,\n isRunning: boolean,\n): string {\n if (count > 1) {\n if (isRead) {\n const verb = isRunning ? 'Reading' : 'Read';\n const noun = count === 1 ? 'file' : 'files';\n return `${verb} ${count} ${noun}`;\n }\n if (isSearch) {\n return `${toolName} ${count} times`;\n }\n return `${toolName} ${count} times`;\n }\n return display;\n}\n\nfunction groupProgressEntries(\n entries: SubagentProgressEntry[],\n isRunning: boolean,\n): ProcessedProgressLine[] {\n const raw = entries.map((entry) => ({\n toolName: entry.toolName,\n display: formatSubagentProgressLine(entry),\n isError: false,\n }));\n\n const grouped: ProcessedProgressLine[] = [];\n let currentTool: string | null = null;\n let currentDisplay: string | null = null;\n let currentCount = 0;\n let currentIsRead = false;\n let currentIsSearch = false;\n\n const flush = () => {\n if (currentTool == null || currentCount === 0) return;\n grouped.push({\n text: formatGroupText(\n currentTool,\n currentDisplay ?? currentTool,\n currentCount,\n currentIsRead,\n currentIsSearch,\n isRunning,\n ),\n toolUseCount: currentCount,\n });\n currentTool = null;\n currentDisplay = null;\n currentCount = 0;\n currentIsRead = false;\n currentIsSearch = false;\n };\n\n for (const { toolName, display } of raw) {\n const isRead = READ_TOOLS.has(toolName);\n const isSearch = SEARCH_TOOLS.has(toolName);\n const isBash = BASH_TOOLS.has(toolName);\n const sameGroup =\n !isBash &&\n currentTool === toolName &&\n currentIsRead === isRead &&\n currentIsSearch === isSearch;\n\n if (sameGroup) {\n currentCount += 1;\n } else {\n flush();\n currentTool = toolName;\n currentDisplay = display;\n currentCount = 1;\n currentIsRead = isRead;\n currentIsSearch = isSearch;\n }\n }\n flush();\n return grouped;\n}\n\nexport function processAgentProgressLines(\n entries: SubagentProgressEntry[],\n options: { isRunning: boolean; maxVisible: number },\n): { visible: ProcessedProgressLine[]; hiddenToolUseCount: number } {\n const processed = groupProgressEntries(entries, options.isRunning);\n if (options.maxVisible >= processed.length) {\n return { visible: processed, hiddenToolUseCount: 0 };\n }\n const visible = processed.slice(-options.maxVisible);\n const hidden = processed.slice(0, processed.length - options.maxVisible);\n const hiddenToolUseCount = hidden.reduce((sum, line) => sum + line.toolUseCount, 0);\n return { visible, hiddenToolUseCount };\n}\n","/**\r\n * agentHelpers.ts — Agent 标题与完成摘要\r\n *\r\n * 对齐参考:CLI helpers.format_agent_title · parse_agent_done_summary\r\n */\r\nimport { truncateLines } from './searchHelpers';\r\nimport { formatSubagentToolProgressLine } from './agentProgressRenderer';\r\n\r\nconst DONE_LINE_RE = /Done \\((.+?)\\)/i;\r\nconst AGENT_STEPS_RE = /(\\d+)\\s+tool uses?/i;\r\nexport const AGENT_MAX_BODY_LINES = 25;\r\nexport const AGENT_PROGRESS_TAIL_LINES = 3;\r\n\r\nexport function truncatePreview(text: string, maxChars = 80): string {\r\n const trimmed = text.trim();\r\n if (trimmed.length <= maxChars) return trimmed;\r\n return `${trimmed.slice(0, maxChars)}…`;\r\n}\r\n\r\nexport function formatAgentTitle(input: unknown, display: unknown): string {\r\n const inp =\r\n input != null && typeof input === 'object' && !Array.isArray(input)\r\n ? (input as Record<string, unknown>)\r\n : {};\r\n const d =\r\n display != null && typeof display === 'object' && !Array.isArray(display)\r\n ? (display as Record<string, unknown>)\r\n : null;\r\n\r\n const merged = { ...inp };\r\n if (d?.subagent_type) merged.subagent_type = d.subagent_type;\r\n if (d?.description) merged.description = d.description;\r\n\r\n const subagent = String(merged.subagent_type ?? 'general-purpose').trim();\r\n const desc = String(merged.description ?? merged.prompt ?? '').trim();\r\n\r\n let title = desc ? `${subagent}(${truncatePreview(desc)})` : subagent;\r\n\r\n const model = merged.model;\r\n if (model) {\r\n const modelStr = String(model).trim();\r\n if (modelStr) title = `${title} ${modelStr}`;\r\n }\r\n\r\n return title;\r\n}\r\n\r\nexport function parseAgentDoneSummary(output: string): string | null {\r\n const text = output.trim();\r\n if (!text) return null;\r\n\r\n const doneMatch = text.match(DONE_LINE_RE);\r\n if (doneMatch) return `Done (${doneMatch[1].trim()})`;\r\n\r\n const stepsMatch = text.match(AGENT_STEPS_RE);\r\n if (stepsMatch) return `Done (${stepsMatch[1]} tool uses)`;\r\n\r\n const first = text.split('\\n', 1)[0]?.trim() ?? '';\r\n if (first.toLowerCase().startsWith('done')) return first;\r\n\r\n return null;\r\n}\r\n\r\nexport function buildAgentBodyText(display: unknown, summary: string): string {\r\n const d =\r\n display != null && typeof display === 'object' && !Array.isArray(display)\r\n ? (display as Record<string, unknown>)\r\n : null;\r\n\r\n let done: string | null = null;\r\n if (d?.total_steps != null && d.status === 'completed') {\r\n done = `Done (${d.total_steps} tool uses)`;\r\n } else {\r\n done = parseAgentDoneSummary(summary);\r\n }\r\n\r\n if (done) {\r\n let rest = summary.trim();\r\n if (rest.startsWith(done)) {\r\n rest = rest.slice(done.length).trimStart();\r\n }\r\n const parts = [done];\r\n if (rest) {\r\n const { text: truncated, truncated: was } = truncateLines(\r\n rest,\r\n AGENT_MAX_BODY_LINES,\r\n );\r\n parts.push(was ? `${truncated}\\n… 超过 ${AGENT_MAX_BODY_LINES} 行,已截断` : truncated);\r\n }\r\n return parts.join('\\n');\r\n }\r\n\r\n const text = summary.trim();\r\n if (!text) return '(done)';\r\n\r\n const { text: truncated, truncated: was } = truncateLines(text, AGENT_MAX_BODY_LINES);\r\n return was ? `${truncated}\\n… 超过 ${AGENT_MAX_BODY_LINES} 行,已截断` : truncated;\r\n}\r\n\r\nexport function formatSubagentProgressLine(entry: {\r\n toolName: string;\r\n summary: string;\r\n status: string;\r\n toolInput?: unknown;\r\n}): string {\r\n return formatSubagentToolProgressLine(entry.toolName, {\r\n summary: entry.summary,\r\n toolInput: entry.toolInput,\r\n });\r\n}\r\n\r\n/** 完成后展开 transcript:优先 display.tool_calls,否则用 reducer 积累的 progress。 */\r\nexport function buildAgentTranscriptText(\r\n display: unknown,\r\n subagentProgress?: { toolName: string; summary: string; status: string }[],\r\n): string {\r\n const d =\r\n display != null && typeof display === 'object' && !Array.isArray(display)\r\n ? (display as Record<string, unknown>)\r\n : null;\r\n const toolCalls = d?.tool_calls;\r\n if (Array.isArray(toolCalls) && toolCalls.length > 0) {\r\n return toolCalls\r\n .map((row) => {\r\n const item = row as Record<string, unknown>;\r\n const name = String(item.tool_name ?? 'tool');\r\n const summary = String(item.summary ?? '').trim();\r\n return summary ? `${name}: ${summary}` : name;\r\n })\r\n .join('\\n');\r\n }\r\n if (subagentProgress?.length) {\r\n return subagentProgress.map(formatSubagentProgressLine).join('\\n');\r\n }\r\n return '';\r\n}\r\n","/**\r\n * AgentProgressLines.tsx — Agent 子工具 progress 折叠行\r\n *\r\n * 对齐 CLI AgentProgressLineRenderer · CC AgentTool/UI.tsx renderToolUseProgressMessage\r\n */\r\nimport {\r\n AGENT_PROGRESS_GUTTER,\r\n AGENT_PROGRESS_INDENT,\r\n processAgentProgressLines,\r\n} from '../presentation/agentProgressRenderer';\r\nimport { AGENT_PROGRESS_TAIL_LINES } from '../presentation/agentHelpers';\r\nimport type { SubagentProgressEntry } from '../../../types/nodes';\r\nimport type { ToolBodyMode } from '../types';\r\n\r\nexport interface AgentProgressLinesProps {\r\n entries: SubagentProgressEntry[];\r\n mode: ToolBodyMode;\r\n maxVisible?: number;\r\n onExpand?: () => void;\r\n}\r\n\r\nexport function AgentProgressLines({\r\n entries,\r\n mode,\r\n maxVisible = AGENT_PROGRESS_TAIL_LINES,\r\n onExpand,\r\n}: AgentProgressLinesProps) {\r\n if (entries.length === 0) return null;\r\n\r\n const isRunning = entries.some((e) => e.status === 'running');\r\n const limit = mode === 'full' ? entries.length : maxVisible;\r\n const { visible, hiddenToolUseCount } = processAgentProgressLines(entries, {\r\n isRunning,\r\n maxVisible: limit,\r\n });\r\n\r\n return (\r\n <div className=\"lax-agent-progress\" data-testid=\"lax-agent-progress\">\r\n {visible.map((line, index) => (\r\n <div\r\n key={`${index}:${line.text}`}\r\n className=\"lax-agent-progress__line\"\r\n >\r\n <span className=\"lax-agent-progress__gutter\" aria-hidden>\r\n {index === 0 ? AGENT_PROGRESS_GUTTER : AGENT_PROGRESS_INDENT}\r\n </span>\r\n <span className=\"lax-agent-progress__text\">{line.text}</span>\r\n </div>\r\n ))}\r\n {hiddenToolUseCount > 0 && mode !== 'full' ? (\r\n <div className=\"lax-agent-progress__line lax-agent-progress__line--more\">\r\n <span className=\"lax-agent-progress__gutter\" aria-hidden>\r\n {AGENT_PROGRESS_INDENT}\r\n </span>\r\n <button\r\n type=\"button\"\r\n className=\"lax-agent-progress__more\"\r\n onClick={onExpand}\r\n >\r\n +{hiddenToolUseCount} more tool {hiddenToolUseCount === 1 ? 'use' : 'uses'}\r\n </button>\r\n </div>\r\n ) : null}\r\n </div>\r\n );\r\n}\r\n","/**\n * subagentTranscriptRenderer.ts — transcript lane 行渲染(对齐 CLI subagent_transcript_lane.py)\n */\nimport type { SubagentTranscriptEntry } from '../../../types/nodes';\nimport { truncatePreview } from './agentHelpers';\nimport { formatSubagentToolProgressLine } from './agentProgressRenderer';\n\nfunction toolCallsFromAssistant(message: Record<string, unknown>): Record<string, unknown>[] {\n const raw = message.tool_calls;\n if (!Array.isArray(raw)) return [];\n return raw.filter(\n (item): item is Record<string, unknown> =>\n item != null && typeof item === 'object' && !Array.isArray(item),\n );\n}\n\nfunction toolInputFromCall(call: Record<string, unknown>): Record<string, unknown> | null {\n const args = call.args;\n if (args != null && typeof args === 'object' && !Array.isArray(args)) {\n return args as Record<string, unknown>;\n }\n const input = call.input;\n if (input != null && typeof input === 'object' && !Array.isArray(input)) {\n return input as Record<string, unknown>;\n }\n return null;\n}\n\nfunction formatAssistantToolLine(\n toolName: string,\n step: number | undefined,\n toolInput: Record<string, unknown> | null,\n): string {\n const name = toolName.trim() || 'Tool';\n if (name === 'Bash' && toolInput) {\n const cmd = String(toolInput.command ?? toolInput.cmd ?? '').trim();\n if (cmd) return formatSubagentToolProgressLine('Bash', { toolInput: { command: cmd } });\n }\n if (['Read', 'Write', 'Edit', 'Glob', 'Grep'].includes(name) && toolInput) {\n return formatSubagentToolProgressLine(name, { toolInput });\n }\n if (typeof step === 'number') return `${name} step ${step}`;\n return name;\n}\n\nfunction renderUserToolResult(message: Record<string, unknown>): string {\n const content = message.content;\n if (typeof content === 'string' && content.trim()) {\n return truncatePreview(content.trim(), 240);\n }\n if (content != null && typeof content !== 'string') {\n try {\n return truncatePreview(JSON.stringify(content), 240);\n } catch {\n return truncatePreview(String(content), 240);\n }\n }\n const toolName = String(message.name ?? 'tool').trim();\n return `${toolName} result`;\n}\n\n/** 将单条 transcript lane entry 渲染为一行或多行(assistant tool_calls 可展开为多行)。 */\nexport function renderTranscriptEntryLines(entry: SubagentTranscriptEntry): string[] {\n const lines: string[] = [];\n const { messageKind, message, step, toolName } = entry;\n\n if (messageKind === 'assistant') {\n const toolCalls = toolCallsFromAssistant(message);\n if (toolCalls.length > 0) {\n for (const call of toolCalls) {\n const callName = String(call.name ?? toolName ?? 'Tool').trim();\n lines.push(\n formatAssistantToolLine(callName, step, toolInputFromCall(call)),\n );\n }\n return lines;\n }\n const text = String(message.content ?? '').trim();\n if (text) {\n lines.push(truncatePreview(text, 240));\n }\n return lines;\n }\n\n if (messageKind === 'user') {\n lines.push(renderUserToolResult(message));\n }\n return lines;\n}\n\nexport function renderTranscriptLaneLines(entries: SubagentTranscriptEntry[]): string[] {\n const lines: string[] = [];\n for (const entry of entries) {\n lines.push(...renderTranscriptEntryLines(entry));\n }\n return lines.filter((line) => line.length > 0);\n}\n","/**\n * SubagentTranscriptBlock.tsx — transcript lane 展开块(Capability C Phase 3)\n *\n * 对齐 CLI render_transcript_lane_text · CC VerboseAgentTranscript\n */\nimport type { SubagentTranscriptEntry } from '../../../types/nodes';\nimport {\n AGENT_PROGRESS_GUTTER,\n AGENT_PROGRESS_INDENT,\n} from '../presentation/agentProgressRenderer';\nimport { renderTranscriptEntryLines } from '../presentation/subagentTranscriptRenderer';\n\nexport interface SubagentTranscriptBlockProps {\n entries: SubagentTranscriptEntry[];\n /** transcript-lane | progress-fallback | trace-fallback */\n dataSource?: string;\n}\n\nexport function SubagentTranscriptBlock({\n entries,\n dataSource = 'transcript-lane',\n}: SubagentTranscriptBlockProps) {\n if (entries.length === 0) return null;\n\n const rendered: string[] = [];\n for (const entry of entries) {\n rendered.push(...renderTranscriptEntryLines(entry));\n }\n if (rendered.length === 0) return null;\n\n return (\n <div\n className=\"lax-agent-progress lax-agent-progress--transcript\"\n data-testid=\"lax-subagent-transcript-lane\"\n data-source={dataSource}\n >\n {rendered.map((text, index) => (\n <div key={`${index}:${text}`} className=\"lax-agent-progress__line\">\n <span className=\"lax-agent-progress__gutter\" aria-hidden>\n {index === 0 ? AGENT_PROGRESS_GUTTER : AGENT_PROGRESS_INDENT}\n </span>\n <span className=\"lax-agent-progress__text\">{text}</span>\n </div>\n ))}\n </div>\n );\n}\n","/**\n * AgentToolBody.tsx — Agent / Task 子代理正文\n *\n * 对齐参考:CLI widgets/tools/agent/widget.py · CC AgentTool/UI.tsx\n */\nimport {\n buildAgentBodyText,\n buildAgentTranscriptText,\n} from '../presentation/agentHelpers';\nimport { TruncatedContent } from '../presentation/TruncatedContent';\nimport type { ToolDisplayProps } from '../types';\nimport { AgentProgressLines } from './AgentProgressLines';\nimport { SubagentTranscriptBlock } from './SubagentTranscriptBlock';\n\nexport function AgentToolBody({\n result,\n bodyMode,\n onBodyModeChange,\n status,\n subagentProgress,\n subagentTranscript,\n}: ToolDisplayProps) {\n if (result?.error) {\n return (\n <div className=\"lax-tool-body lax-tool-body--agent\">\n <div className=\"lax-tool-body__block\" data-variant=\"error\">\n <pre className=\"lax-tool-body__text\">{result.error.message}</pre>\n </div>\n </div>\n );\n }\n\n const progress = subagentProgress ?? [];\n const transcriptLane = subagentTranscript ?? [];\n const bodyText = buildAgentBodyText(result?.display, result?.summary ?? '');\n const transcriptFallback = buildAgentTranscriptText(result?.display, progress);\n const showDoneSummary = status !== 'running' && bodyText.length > 0;\n const showTranscriptLane =\n bodyMode === 'full' && transcriptLane.length > 0;\n const showRunningProgress =\n status === 'running' && progress.length > 0 && !showTranscriptLane;\n const showTranscriptFallback =\n bodyMode === 'full' &&\n !showTranscriptLane &&\n transcriptFallback.length > 0;\n\n if (!showRunningProgress && !showDoneSummary && !showTranscriptLane && !showTranscriptFallback) {\n return (\n <div className=\"lax-tool-body lax-tool-body--agent\">\n <div className=\"lax-tool-body__block\" data-variant=\"dim\">\n <pre className=\"lax-tool-body__text\">(running)</pre>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"lax-tool-body lax-tool-body--agent\">\n {showRunningProgress ? (\n <AgentProgressLines\n entries={progress}\n mode={bodyMode}\n onExpand={() => onBodyModeChange?.('full')}\n />\n ) : null}\n {showDoneSummary ? (\n <TruncatedContent\n text={bodyText}\n mode={bodyMode}\n maxLines={12}\n onExpand={() => onBodyModeChange?.('full')}\n />\n ) : null}\n {showTranscriptLane ? (\n <SubagentTranscriptBlock entries={transcriptLane} dataSource=\"transcript-lane\" />\n ) : null}\n {showTranscriptFallback ? (\n <div\n className=\"lax-agent-progress lax-agent-progress--transcript\"\n data-source=\"trace-fallback\"\n >\n <div className=\"lax-agent-progress__label\">Transcript</div>\n <TruncatedContent text={transcriptFallback} mode=\"full\" />\n </div>\n ) : null}\n </div>\n );\n}\n","/**\r\n * displayRecord.ts — 从 input / display 安全取字段\r\n */\r\n\r\nexport function asDisplayRecord(\r\n display: unknown,\r\n): Record<string, unknown> | null {\r\n if (display != null && typeof display === 'object' && !Array.isArray(display)) {\r\n return display as Record<string, unknown>;\r\n }\r\n return null;\r\n}\r\n\r\nexport function asInputRecord(input: unknown): Record<string, unknown> {\r\n if (input != null && typeof input === 'object' && !Array.isArray(input)) {\r\n return input as Record<string, unknown>;\r\n }\r\n return {};\r\n}\r\n\r\nexport function strField(record: Record<string, unknown>, key: string): string {\r\n const value = record[key];\r\n return value == null ? '' : String(value).trim();\r\n}\r\n\r\nexport function numField(record: Record<string, unknown>, key: string): number | undefined {\r\n const value = record[key];\r\n if (typeof value === 'number' && Number.isFinite(value)) return value;\r\n if (typeof value === 'string' && value.trim() !== '') {\r\n const n = Number(value);\r\n if (Number.isFinite(n)) return n;\r\n }\r\n return undefined;\r\n}\r\n","/**\r\n * askUserHelpers.ts — AskUserQuestion 正文与预览\r\n *\r\n * 对齐参考:CLI widgets/tools/helpers.py format_ask_user_*\r\n */\r\nexport function formatAskUserDisplayBody(display: Record<string, unknown>): string {\r\n const items = display.questions;\r\n if (!Array.isArray(items) || items.length === 0) return '';\r\n\r\n const lines: string[] = [];\r\n for (const item of items) {\r\n if (item == null || typeof item !== 'object') continue;\r\n const row = item as Record<string, unknown>;\r\n const header = String(row.header ?? '').trim();\r\n const question = String(row.question ?? '').trim();\r\n const answer = String(row.answer ?? '').trim();\r\n const prefix = header ? `[${header}] ` : '';\r\n lines.push(`${prefix}${question}`);\r\n if (answer) lines.push(` → ${answer}`);\r\n const selected = row.selected_options;\r\n if (Array.isArray(selected) && selected.length > 0) {\r\n for (const label of selected) {\r\n lines.push(` · ${String(label)}`);\r\n }\r\n }\r\n }\r\n return lines.length > 0 ? lines.join('\\n') : '';\r\n}\r\n\r\nexport function formatAskUserQuestionsPreview(input: Record<string, unknown>): string {\r\n const questions = input.questions;\r\n if (!Array.isArray(questions) || questions.length === 0) {\r\n return '(waiting for answers)';\r\n }\r\n\r\n const lines: string[] = [];\r\n questions.forEach((raw, idx) => {\r\n if (raw == null || typeof raw !== 'object') return;\r\n const q = raw as Record<string, unknown>;\r\n const header = String(q.header ?? '').trim();\r\n const qtext = String(q.question ?? '').trim();\r\n const prefix = header ? `[${header}] ` : '';\r\n lines.push(`${idx + 1}. ${prefix}${qtext}`);\r\n const options = q.options;\r\n if (Array.isArray(options)) {\r\n for (const opt of options) {\r\n if (opt != null && typeof opt === 'object') {\r\n const label = String((opt as Record<string, unknown>).label ?? '').trim();\r\n if (label) lines.push(` · ${label}`);\r\n }\r\n }\r\n }\r\n });\r\n return lines.length > 0 ? lines.join('\\n') : '(waiting for answers)';\r\n}\r\n","/**\n * AskUserQuestionToolBody.tsx — AskUserQuestion 工具正文\n *\n * 对齐参考:CLI widgets/tools/ask_user_question/widget.py\n */\nimport { asDisplayRecord, asInputRecord } from '../displayRecord';\nimport {\n formatAskUserDisplayBody,\n formatAskUserQuestionsPreview,\n} from '../presentation/askUserHelpers';\nimport { truncateLines } from '../presentation/searchHelpers';\nimport { TruncatedContent } from '../presentation/TruncatedContent';\nimport type { ToolDisplayProps } from '../types';\n\nconst MAX_DISPLAY_LINES = 25;\nconst MAX_DISPLAY_CHARS = 1200;\n\nfunction buildAskUserBody(\n input: unknown,\n display: unknown,\n summary: string,\n): string {\n const d = asDisplayRecord(display);\n if (d) {\n const displayBody = formatAskUserDisplayBody(d);\n if (displayBody) {\n if (displayBody.length > MAX_DISPLAY_CHARS) {\n const { text, truncated } = truncateLines(displayBody, MAX_DISPLAY_LINES);\n return truncated ? `${text}\\n… 已截断` : text;\n }\n return displayBody;\n }\n }\n\n const text = summary.trim();\n if (text) return `Answered: ${text}`;\n\n return formatAskUserQuestionsPreview(asInputRecord(input));\n}\n\nexport function AskUserQuestionToolBody({\n input,\n result,\n bodyMode,\n onBodyModeChange,\n}: ToolDisplayProps) {\n if (result?.error) {\n return (\n <div className=\"lax-tool-body lax-tool-body--ask-user\">\n <div className=\"lax-tool-body__block\" data-variant=\"error\">\n <pre className=\"lax-tool-body__text\">{result.error.message}</pre>\n </div>\n </div>\n );\n }\n\n const bodyText = buildAskUserBody(input, result?.display, result?.summary ?? '');\n\n return (\n <div className=\"lax-tool-body lax-tool-body--ask-user\">\n <TruncatedContent\n text={bodyText}\n mode={bodyMode}\n maxLines={12}\n onExpand={() => onBodyModeChange?.('full')}\n />\n </div>\n );\n}\n","/**\r\n * BashToolBody.tsx — bash 工具多块 stdout/stderr 正文\r\n *\r\n * 对齐参考:CLI widgets/tools/bash/widget.py · CC BashTool/UI.tsx\r\n */\r\nimport { BodyBlockList } from '../presentation/BodyBlockList';\r\nimport { buildBashBodyBlocks } from '../presentation/bashHelpers';\r\nimport type { ToolDisplayProps } from '../types';\r\n\r\nexport function BashToolBody({\r\n result,\r\n bodyMode,\r\n onBodyModeChange,\r\n}: ToolDisplayProps) {\r\n const isError = result?.status === 'failed' || Boolean(result?.error);\r\n const summary = result?.summary ?? '';\r\n const { blocks, truncated, remainingLines } = buildBashBodyBlocks(\r\n result?.display,\r\n summary,\r\n result?.meta,\r\n bodyMode,\r\n isError,\r\n );\r\n\r\n return (\r\n <div className=\"lax-tool-body lax-tool-body--bash\">\r\n <BodyBlockList blocks={blocks} />\r\n {truncated && bodyMode === 'preview' ? (\r\n <button\r\n type=\"button\"\r\n className=\"lax-tool-body__expand\"\r\n onClick={() => onBodyModeChange?.('full')}\r\n >\r\n +{remainingLines} lines (点击展开)\r\n </button>\r\n ) : null}\r\n </div>\r\n );\r\n}\r\n","/**\n * EditToolBody.tsx — edit 工具正文(unified diff)\n *\n * 对齐参考:CLI widgets/tools/edit/widget.py · CC FileEditToolDiff.tsx\n */\nimport { resolveEditDiffText } from '../presentation/diffHelpers';\nimport { DiffView } from '../presentation/DiffView';\nimport type { ToolDisplayProps } from '../types';\n\nexport function EditToolBody({\n input,\n result,\n bodyMode,\n onBodyModeChange,\n}: ToolDisplayProps) {\n if (result?.error) {\n return (\n <div className=\"lax-tool-body lax-tool-body--edit\">\n <div className=\"lax-tool-body__block\" data-variant=\"error\">\n <pre className=\"lax-tool-body__text\">{result.error.message}</pre>\n </div>\n </div>\n );\n }\n\n const diff = resolveEditDiffText(\n result?.display,\n input,\n result?.summary ?? '',\n );\n\n return (\n <div className=\"lax-tool-body lax-tool-body--edit\">\n <DiffView\n diff={diff}\n mode={bodyMode}\n onExpand={() => onBodyModeChange?.('full')}\n />\n </div>\n );\n}\n","/**\n * GlobToolBody.tsx — glob 工具正文\n *\n * 对齐参考:CLI widgets/tools/glob/widget.py · helpers.format_search_result_body\n */\nimport { asDisplayRecord } from '../displayRecord';\nimport { formatSearchResultBody } from '../presentation/searchHelpers';\nimport { TruncatedContent } from '../presentation/TruncatedContent';\nimport type { ToolDisplayProps } from '../types';\n\nfunction buildGlobBodyText(result: ToolDisplayProps['result']): string {\n const d = asDisplayRecord(result?.display);\n\n if (d?.type === 'file_list') {\n const files = Array.isArray(d.files) ? d.files.map((f) => String(f)) : [];\n const numFiles =\n typeof d.num_files === 'number' ? d.num_files : files.length;\n const summary =\n numFiles > 0 ? `Found ${numFiles} files` : 'No files found';\n if (files.length > 0) {\n return formatSearchResultBody(`${summary}\\n${files.join('\\n')}`);\n }\n return summary;\n }\n\n if (Array.isArray(d?.files)) {\n const files = d.files.map((f) => String(f));\n const summary = `Found ${files.length} files`;\n return formatSearchResultBody(`${summary}\\n${files.join('\\n')}`);\n }\n\n const summary = result?.summary?.trim() ?? '';\n if (summary) return formatSearchResultBody(summary);\n\n return '(No output)';\n}\n\nexport function GlobToolBody({\n result,\n bodyMode,\n onBodyModeChange,\n}: ToolDisplayProps) {\n if (result?.error) {\n return (\n <div className=\"lax-tool-body lax-tool-body--glob\">\n <div className=\"lax-tool-body__block\" data-variant=\"error\">\n <pre className=\"lax-tool-body__text\">{result.error.message}</pre>\n </div>\n </div>\n );\n }\n\n const bodyText = buildGlobBodyText(result);\n\n return (\n <div className=\"lax-tool-body lax-tool-body--glob\">\n <TruncatedContent\n text={bodyText}\n mode={bodyMode}\n onExpand={() => onBodyModeChange?.('full')}\n />\n </div>\n );\n}\n","/**\n * GrepToolBody.tsx — grep 工具正文\n *\n * 对齐参考:CLI widgets/tools/grep/widget.py · helpers.format_search_result_body\n */\nimport { asDisplayRecord } from '../displayRecord';\nimport { formatSearchResultBody } from '../presentation/searchHelpers';\nimport { TruncatedContent } from '../presentation/TruncatedContent';\nimport type { ToolDisplayProps } from '../types';\n\nfunction buildGrepBodyText(result: ToolDisplayProps['result']): string {\n const d = asDisplayRecord(result?.display);\n\n if (d?.type === 'search_results') {\n const matches = Array.isArray(d.matches)\n ? d.matches.map((m) => String(m))\n : [];\n const numMatches =\n typeof d.num_matches === 'number' ? d.num_matches : matches.length;\n const summary =\n numMatches > 0\n ? `Found ${numMatches} matches`\n : 'No matches found';\n if (matches.length > 0) {\n return formatSearchResultBody(`${summary}\\n${matches.join('\\n')}`);\n }\n return summary;\n }\n\n if (Array.isArray(d?.matches)) {\n const matches = d.matches.map((m) => String(m));\n const summary = `Found ${matches.length} matches`;\n return formatSearchResultBody(`${summary}\\n${matches.join('\\n')}`);\n }\n\n const summary = result?.summary?.trim() ?? '';\n if (summary) return formatSearchResultBody(summary);\n\n return '(No output)';\n}\n\nexport function GrepToolBody({\n result,\n bodyMode,\n onBodyModeChange,\n}: ToolDisplayProps) {\n if (result?.error) {\n return (\n <div className=\"lax-tool-body lax-tool-body--grep\">\n <div className=\"lax-tool-body__block\" data-variant=\"error\">\n <pre className=\"lax-tool-body__text\">{result.error.message}</pre>\n </div>\n </div>\n );\n }\n\n const bodyText = buildGrepBodyText(result);\n\n return (\n <div className=\"lax-tool-body lax-tool-body--grep\">\n <TruncatedContent\n text={bodyText}\n mode={bodyMode}\n onExpand={() => onBodyModeChange?.('full')}\n />\n </div>\n );\n}\n","/**\n * ReadToolBody.tsx — Read 工具正文\n *\n * 对齐参考:CLI widgets/tools/read/widget.py format_body · CC FileReadTool/UI.tsx\n */\nimport { asDisplayRecord, numField, strField } from '../displayRecord';\nimport { BodyBlockList } from '../presentation/BodyBlockList';\nimport { MarkdownBlock } from '../presentation/MarkdownBlock';\nimport { MAX_PREVIEW_LINES } from '../presentation/TruncatedContent';\nimport type { ToolDisplayProps } from '../types';\n\nconst LINES_RANGE_RE = /lines (\\d+)-(\\d+) of (\\d+)/i;\nconst READ_LINES_RE = /Read (\\d+) lines from/i;\nconst EMPTY_RE = /\\(empty file\\)/i;\nconst NOTEBOOK_RE = /Read notebook.*?(\\d+) cells/i;\nconst IMAGE_RE = /Read image/i;\nconst PDF_RE = /Read PDF/i;\n\nfunction formatReadBodySummary(display: unknown, summary: string): string {\n const d = asDisplayRecord(display);\n\n if (d?.type === 'text') {\n const start = numField(d, 'line_start');\n const end = numField(d, 'line_end');\n const total = numField(d, 'total_lines');\n if (start != null && end != null && total != null) {\n return `Read lines ${start}–${end} of ${total}`;\n }\n const numLines = numField(d, 'num_lines');\n if (numLines != null) {\n return `Read ${numLines} lines`;\n }\n }\n\n if (d?.type === 'image') {\n const w = strField(d, 'width');\n const h = strField(d, 'height');\n if (w && h) return `Read image (${w}×${h})`;\n return 'Read image';\n }\n\n if (d?.type === 'pdf') {\n const ps = numField(d, 'page_start');\n const pe = numField(d, 'page_end');\n if (ps != null && pe != null) {\n return `Read PDF pages ${ps}–${pe}`;\n }\n return 'Read PDF';\n }\n\n const text = summary.trim();\n if (!text) return '(done)';\n\n if (EMPTY_RE.test(text)) return 'Empty file';\n const notebook = text.match(NOTEBOOK_RE);\n if (notebook) return `Read ${notebook[1]} cells`;\n if (IMAGE_RE.test(text)) return text.split('\\n', 1)[0]?.trim() || 'Read image';\n if (PDF_RE.test(text)) return text.split('\\n', 1)[0]?.trim() || 'Read PDF';\n\n const range = text.match(LINES_RANGE_RE);\n if (range) {\n return `Read lines ${range[1]}–${range[2]} of ${range[3]}`;\n }\n const readLines = text.match(READ_LINES_RE);\n if (readLines) return `Read ${readLines[1]} lines`;\n\n if (text.length > 500) {\n const lineCount = text.split('\\n').length;\n return `Read complete (${lineCount} lines in result)`;\n }\n\n return text.slice(0, 200) || '(done)';\n}\n\nfunction extractReadContent(display: unknown): string | null {\n const d = asDisplayRecord(display);\n if (!d) return null;\n if (d.type === 'markdown' || d.type === 'text') {\n const content = strField(d, 'content');\n if (content) return content;\n }\n return null;\n}\n\nexport function ReadToolBody({\n result,\n bodyMode,\n onBodyModeChange,\n}: ToolDisplayProps) {\n const display = result?.display ?? null;\n const summary = result?.summary ?? '';\n const bodyLine = formatReadBodySummary(display, summary);\n const content = extractReadContent(display);\n const d = asDisplayRecord(display);\n const isMarkdown = d?.type === 'markdown';\n\n // 构建文本 blocks(对齐 BashToolBody)\n const buildTextBlocks = () => {\n if (!content) return [];\n const lines = content.split('\\n');\n const isPreview = bodyMode === 'preview' && lines.length > MAX_PREVIEW_LINES;\n const text = isPreview ? lines.slice(0, MAX_PREVIEW_LINES).join('\\n') : content;\n return [{ text, variant: 'normal' as const }];\n };\n\n const textBlocks = buildTextBlocks();\n const hasMore = content && bodyMode === 'preview' && content.split('\\n').length > MAX_PREVIEW_LINES;\n\n return (\n <div className=\"lax-tool-body lax-tool-body--read\">\n <div className=\"lax-tool-body__summary\">{bodyLine}</div>\n {content ? (\n isMarkdown ? (\n <MarkdownBlock\n text={content}\n mode={bodyMode}\n onExpand={() => onBodyModeChange?.('full')}\n />\n ) : (\n <>\n <BodyBlockList blocks={textBlocks} />\n {hasMore ? (\n <button\n type=\"button\"\n className=\"lax-tool-body__expand\"\n onClick={() => onBodyModeChange?.('full')}\n >\n +{content.split('\\n').length - MAX_PREVIEW_LINES} lines (点击展开)\n </button>\n ) : null}\n </>\n )\n ) : null}\n {result?.truncated ? (\n <div className=\"lax-tool-card__truncated\">结果已截断</div>\n ) : null}\n {result?.overflow_file ? (\n <div className=\"lax-tool-card__overflow\">\n 完整输出:\n <code>{result.overflow_file}</code>\n </div>\n ) : null}\n </div>\n );\n}\n","/**\n * SkillToolBody.tsx — skill 工具正文\n *\n * 对齐参考:CLI widgets/tools/skill/widget.py · CC SkillTool/UI.tsx\n */\nimport { truncateLines } from '../presentation/searchHelpers';\nimport { TruncatedContent } from '../presentation/TruncatedContent';\nimport type { ToolDisplayProps } from '../types';\n\nconst MAX_BODY_LINES = 20;\n\nexport function SkillToolBody({\n result,\n bodyMode,\n onBodyModeChange,\n}: ToolDisplayProps) {\n if (result?.error) {\n return (\n <div className=\"lax-tool-body lax-tool-body--skill\">\n <div className=\"lax-tool-body__block\" data-variant=\"error\">\n <pre className=\"lax-tool-body__text\">{result.error.message}</pre>\n </div>\n </div>\n );\n }\n\n const text = result?.summary?.trim() ?? '';\n if (!text) {\n return (\n <div className=\"lax-tool-body lax-tool-body--skill\">\n <div className=\"lax-tool-body__block\" data-variant=\"dim\">\n <pre className=\"lax-tool-body__text\">(done)</pre>\n </div>\n </div>\n );\n }\n\n const { text: truncated, truncated: was } = truncateLines(text, MAX_BODY_LINES);\n const bodyText = was ? `${truncated}\\n… 已截断` : truncated;\n\n return (\n <div className=\"lax-tool-body lax-tool-body--skill\">\n <TruncatedContent\n text={bodyText}\n mode={bodyMode}\n maxLines={12}\n onExpand={() => onBodyModeChange?.('full')}\n />\n </div>\n );\n}\n","/**\n * WebFetchToolBody.tsx — WebFetch 工具正文\n *\n * 对齐参考:CLI widgets/tools/webfetch/widget.py · CC WebFetchTool/UI.tsx\n */\nimport { asDisplayRecord } from '../displayRecord';\nimport { truncateLines } from '../presentation/searchHelpers';\nimport { TruncatedContent } from '../presentation/TruncatedContent';\nimport type { ToolDisplayProps } from '../types';\n\nconst RECEIVED_RE = /Received\\s+.+/i;\nconst MAX_BODY_LINES = 15;\n\nfunction buildWebFetchBody(result: ToolDisplayProps['result']): string {\n const d = asDisplayRecord(result?.display);\n if (d?.content_length != null) {\n const parts = [`Received ${d.content_length} bytes`];\n if (d.duration_ms != null) parts.push(`in ${d.duration_ms}ms`);\n if (d.from_cache) parts.push('(cached)');\n return parts.join(' ');\n }\n\n const text = result?.summary?.trim() ?? '';\n if (!text) return '(done)';\n\n const match = text.match(RECEIVED_RE);\n if (match) {\n const line = match[0].split('\\n', 1)[0] ?? match[0];\n return text.length <= 400 ? text : `${line}\\n…`;\n }\n\n const { text: truncated, truncated: was } = truncateLines(text, MAX_BODY_LINES);\n return was ? `${truncated}\\n… 已截断` : truncated;\n}\n\nexport function WebFetchToolBody({\n result,\n bodyMode,\n onBodyModeChange,\n}: ToolDisplayProps) {\n if (result?.error) {\n return (\n <div className=\"lax-tool-body lax-tool-body--webfetch\">\n <div className=\"lax-tool-body__block\" data-variant=\"error\">\n <pre className=\"lax-tool-body__text\">{result.error.message}</pre>\n </div>\n </div>\n );\n }\n\n const bodyText = buildWebFetchBody(result);\n\n return (\n <div className=\"lax-tool-body lax-tool-body--webfetch\">\n <TruncatedContent\n text={bodyText}\n mode={bodyMode}\n maxLines={12}\n onExpand={() => onBodyModeChange?.('full')}\n />\n </div>\n );\n}\n","/**\n * WebSearchToolBody.tsx — WebSearch 工具正文\n *\n * 对齐参考:CLI widgets/tools/websearch/widget.py · CC WebSearchTool/UI.tsx\n */\nimport { asDisplayRecord, strField } from '../displayRecord';\nimport { truncateLines } from '../presentation/searchHelpers';\nimport { TruncatedContent } from '../presentation/TruncatedContent';\nimport type { ToolDisplayProps } from '../types';\n\nconst MAX_BODY_LINES = 15;\n\nfunction buildWebSearchBody(result: ToolDisplayProps['result']): string {\n const d = asDisplayRecord(result?.display);\n if (d?.total_hits != null) {\n const engine = strField(d, 'search_engine') || 'search';\n return `Web search (${engine}): ${d.total_hits} results`;\n }\n\n const text = result?.summary?.trim() ?? '';\n if (!text) return '(done)';\n\n const first = text.split('\\n', 1)[0]?.trim() ?? '';\n if (/^(web search|did |found )/i.test(first)) {\n return text.length < 300 ? text : `${first}\\n…`;\n }\n\n const { text: truncated, truncated: was } = truncateLines(text, MAX_BODY_LINES);\n return was ? `${truncated}\\n… 已截断` : truncated;\n}\n\nexport function WebSearchToolBody({\n result,\n bodyMode,\n onBodyModeChange,\n}: ToolDisplayProps) {\n if (result?.error) {\n return (\n <div className=\"lax-tool-body lax-tool-body--websearch\">\n <div className=\"lax-tool-body__block\" data-variant=\"error\">\n <pre className=\"lax-tool-body__text\">{result.error.message}</pre>\n </div>\n </div>\n );\n }\n\n const bodyText = buildWebSearchBody(result);\n\n return (\n <div className=\"lax-tool-body lax-tool-body--websearch\">\n <TruncatedContent\n text={bodyText}\n mode={bodyMode}\n maxLines={12}\n onExpand={() => onBodyModeChange?.('full')}\n />\n </div>\n );\n}\n","/**\n * WriteToolBody.tsx — write 工具正文(diff 或新建预览)\n *\n * 对齐参考:CLI widgets/tools/write/widget.py · CC FileWriteTool/UI.tsx\n */\nimport { asDisplayRecord, asInputRecord, strField } from '../displayRecord';\nimport {\n countLines,\n formatDiffFromStrings,\n WRITE_PREVIEW_LINES,\n} from '../presentation/diffHelpers';\nimport { DiffView } from '../presentation/DiffView';\nimport { TruncatedContent } from '../presentation/TruncatedContent';\nimport { displayPath } from '../presentation/paths';\nimport type { ToolDisplayProps } from '../types';\n\nfunction buildWriteBodyText(\n input: unknown,\n display: unknown,\n summary: string,\n): { kind: 'diff' | 'preview' | 'text'; text: string } {\n const d = asDisplayRecord(display);\n const inp = asInputRecord(input);\n const content = strField(inp, 'content');\n const path = displayPath(\n strField(d ?? {}, 'file_path') || strField(inp, 'file_path'),\n );\n const fileType = strField(d ?? {}, 'type');\n\n const original = d?.original_file;\n if (fileType === 'update' && original != null && content) {\n return {\n kind: 'diff',\n text: formatDiffFromStrings(String(original), content),\n };\n }\n\n const diffText = strField(d ?? {}, 'diff');\n if (diffText) {\n return { kind: 'diff', text: diffText };\n }\n\n const numLines =\n typeof d?.num_lines === 'number'\n ? d.num_lines\n : countLines(content);\n\n if (numLines === 0 && !content.trim()) {\n const trimmed = summary.trim();\n return { kind: 'text', text: trimmed || '(No content)' };\n }\n\n const lines = content.split('\\n');\n const preview = lines.slice(0, WRITE_PREVIEW_LINES).join('\\n');\n const remaining = numLines - WRITE_PREVIEW_LINES;\n const header = `Wrote ${numLines} lines to ${path || 'file'}`;\n const body =\n remaining > 0 ? `${header}\\n${preview}\\n… +${remaining} lines` : `${header}\\n${preview}`;\n\n return { kind: 'preview', text: body };\n}\n\nexport function WriteToolBody({\n input,\n result,\n bodyMode,\n onBodyModeChange,\n}: ToolDisplayProps) {\n if (result?.error) {\n return (\n <div className=\"lax-tool-body lax-tool-body--write\">\n <div className=\"lax-tool-body__block\" data-variant=\"error\">\n <pre className=\"lax-tool-body__text\">{result.error.message}</pre>\n </div>\n </div>\n );\n }\n\n const body = buildWriteBodyText(\n input,\n result?.display,\n result?.summary ?? '',\n );\n\n if (body.kind === 'diff') {\n return (\n <div className=\"lax-tool-body lax-tool-body--write\">\n <DiffView\n diff={body.text}\n mode={bodyMode}\n onExpand={() => onBodyModeChange?.('full')}\n />\n </div>\n );\n }\n\n return (\n <div className=\"lax-tool-body lax-tool-body--write\">\n <TruncatedContent\n text={body.text}\n mode={bodyMode}\n maxLines={WRITE_PREVIEW_LINES + 1}\n onExpand={() => onBodyModeChange?.('full')}\n />\n </div>\n );\n}\n","/**\r\n * registry.ts — 工具展示注册表\r\n */\r\nimport { AgentToolBody } from './agent/AgentToolBody';\r\nimport { AskUserQuestionToolBody } from './ask_user_question/AskUserQuestionToolBody';\r\nimport { BashToolBody } from './bash/BashToolBody';\r\nimport { EditToolBody } from './edit/EditToolBody';\r\nimport { GlobToolBody } from './glob/GlobToolBody';\r\nimport { GrepToolBody } from './grep/GrepToolBody';\r\nimport { ReadToolBody } from './read/ReadToolBody';\r\nimport { SkillToolBody } from './skill/SkillToolBody';\r\nimport { WebFetchToolBody } from './webfetch/WebFetchToolBody';\r\nimport { WebSearchToolBody } from './websearch/WebSearchToolBody';\r\nimport { WriteToolBody } from './write/WriteToolBody';\r\nimport {\r\n Agent,\r\n AskUserQuestion,\r\n Bash,\r\n Edit,\r\n Glob,\r\n Grep,\r\n Read,\r\n Skill,\r\n WebFetch,\r\n WebSearch,\r\n Write,\r\n} from './toolNames';\r\nimport type { ToolBodyComponent } from './types';\r\n\r\nexport class ToolDisplayRegistry {\r\n private readonly map = new Map<string, ToolBodyComponent>();\r\n\r\n register(toolName: string, body: ToolBodyComponent): this {\r\n this.map.set(toolName, body);\r\n return this;\r\n }\r\n\r\n resolve(toolName: string): ToolBodyComponent | undefined {\r\n return this.map.get(toolName);\r\n }\r\n\r\n static default(): ToolDisplayRegistry {\r\n return createDefaultToolRegistry();\r\n }\r\n}\r\n\r\n/** 默认 registry:CC TOOL_NAME 单键,与 SDK registry_names.py 对齐。 */\r\nexport function createDefaultToolRegistry(): ToolDisplayRegistry {\r\n return new ToolDisplayRegistry()\r\n .register(Read, ReadToolBody)\r\n .register(Grep, GrepToolBody)\r\n .register(Glob, GlobToolBody)\r\n .register(Edit, EditToolBody)\r\n .register(Write, WriteToolBody)\r\n .register(Bash, BashToolBody)\r\n .register(Agent, AgentToolBody)\r\n .register(Skill, SkillToolBody)\r\n .register(AskUserQuestion, AskUserQuestionToolBody)\r\n .register(WebSearch, WebSearchToolBody)\r\n .register(WebFetch, WebFetchToolBody);\r\n}\r\n"],"mappings":"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","names":["truncatePreview","truncated","was","formatSubagentProgressLine","truncatePreview","jsx","jsxs","jsx","jsxs","jsx","text","jsx","jsxs","jsx","jsx","summary","jsx","summary","jsx","jsxs","jsx","jsx","MAX_BODY_LINES","jsx","MAX_BODY_LINES","jsx"]}
package/dist/index.d.ts CHANGED
@@ -78,7 +78,7 @@ interface WorkflowScaleOptions {
78
78
  completedStagePageSize: number;
79
79
  /** P2:completed 且未 pin 的 loop 树移出内存,保留摘要 */
80
80
  evictCompletedLoops: boolean;
81
- /** P4running 容器仅 active 自动展开 AgentLoopView */
81
+ /** P4:历史选项;折叠不变式不再因 non-active 隐藏 running 容器(见 workflow-display-rules §8) */
82
82
  onlyExpandActiveRunning: boolean;
83
83
  /**
84
84
  * P1:已弃用 — parallel item shell 不再使用虚拟滚动(最大并行跨度仅 4)。
@@ -114,9 +114,11 @@ interface WorkflowSessionProps {
114
114
  workflowScale?: Partial<WorkflowScaleOptions>;
115
115
  /** P2:展开已淘汰 loop 时由宿主 replay 事件 */
116
116
  onRequestLoopReplay?: WorkflowLoopReplayHandler;
117
+ /** SSE 流正常结束(传输 resolve);与 status=done 互补,供宿主解锁 loading */
118
+ onStreamComplete?: () => void;
117
119
  children?: ReactNode;
118
120
  }
119
- declare function WorkflowSession({ source, initialEvents, registry, tierOverrides, onError, interactionBus, toolDisplayRegistry, defaultBodyMode, permissionUiMode, markdownRenderer, displayMode, verbose, exploreFullscreenBash, memoryDir, workspaceRoot, virtualized, virtualizeThreshold, groupParallelTools, workflowScale, onRequestLoopReplay, children, }: WorkflowSessionProps): react_jsx_runtime.JSX.Element;
121
+ declare function WorkflowSession({ source, initialEvents, registry, tierOverrides, onError, interactionBus, toolDisplayRegistry, defaultBodyMode, permissionUiMode, markdownRenderer, displayMode, verbose, exploreFullscreenBash, memoryDir, workspaceRoot, virtualized, virtualizeThreshold, groupParallelTools, workflowScale, onRequestLoopReplay, onStreamComplete, children, }: WorkflowSessionProps): react_jsx_runtime.JSX.Element;
120
122
 
121
123
  declare const WorkflowScaleContext: react.Context<WorkflowScaleOptions>;
122
124
 
@@ -223,7 +225,7 @@ interface WorkflowStageListPartition {
223
225
  * done 按 maxVisibleDoneCount 分页展示(默认最近 completedStagePageSize 条)。
224
226
  * maxVisibleDoneCount 由 WorkflowStageListPanel 的 "Show N more" 逐页递增。
225
227
  */
226
- declare function partitionWorkflowStages(stages: WorkflowContainerRuntimeNode[], maxVisibleDoneCount: number): WorkflowStageListPartition;
228
+ declare function partitionWorkflowStages(stages: WorkflowContainerRuntimeNode[], maxVisibleDoneCount: number, containersById?: Record<string, WorkflowContainerRuntimeNode>): WorkflowStageListPartition;
227
229
 
228
230
  /**
229
231
  * workflowSession.ts — Workflow 会话顶层状态
@@ -327,6 +329,8 @@ interface WorkflowSessionStoreState {
327
329
  applyEvents: (events: LangchainAgentEvent[]) => void;
328
330
  reset: () => void;
329
331
  markAsError: (error?: Error) => void;
332
+ /** SSE 正常结束:推断 done 并收口 running loop(嵌套 parallel 缺 workflow-end 兜底) */
333
+ markStreamComplete: () => void;
330
334
  /** P2:展开 done stage 时 pin,避免淘汰 */
331
335
  pinLoopSession: (loopSessionId: string) => void;
332
336
  /** P2:宿主 replay 后灌入 loop 树(同步;测试与小批量) */
@@ -595,6 +599,7 @@ declare class ExploreCollapseAccumulator {
595
599
  private breaksGroup;
596
600
  private waitingPermission;
597
601
  private toolKind;
602
+ private absorbHookEntry;
598
603
  private absorbToolEntry;
599
604
  private groupCounts;
600
605
  private resolveShellProgressSuffix;
@@ -674,11 +679,6 @@ declare function buildSystemEventCanonical(options: {
674
679
  timestamp?: number;
675
680
  }): CanonicalNodeRef;
676
681
 
677
- /**
678
- * systemSummaryText.ts — system_summary 摘要文案
679
- *
680
- * 对齐 CC collapseHookSummaries / CLI system_summary.py 感官。
681
- */
682
682
  declare function formatHookFinishedSummary(data: Record<string, unknown>): string;
683
683
 
684
684
  /**
@@ -989,7 +989,6 @@ interface AgentxMetaFrame {
989
989
  started_at?: number;
990
990
  application_kind?: ApplicationKind;
991
991
  }
992
- /** 手动重连时追加 resume 查询参数(EventSource 无法设 Last-Event-ID 请求头)。 */
993
992
  declare function buildResumeStreamUrl(baseUrl: string, lastEventId: string | null | undefined, queryParam?: string): string;
994
993
  declare function createAgentxSseSource(options: AgentxSseSourceOptions): Source;
995
994
  /** 测试/Story 用:内存事件源 */
@@ -1094,6 +1093,15 @@ declare function filterAgentLoopReplayEvents<T extends {
1094
1093
  event_type: string;
1095
1094
  }>(events: T[]): T[];
1096
1095
 
1096
+ /**
1097
+ * loopSessionUtils.ts — Workflow loop session_id 推导(对齐 SDK WorkflowSessionIdPolicy)
1098
+ *
1099
+ * loop_session_id = `{workflow_id}-{task_key}`
1100
+ */
1101
+
1102
+ /** agent 事件缺 session_id 时,从 workflow_id (或 workflow_path 兜底) + scope key 推导。 */
1103
+ declare function deriveLoopSessionIdFromAgentEvent(event: LangchainAgentEvent): string | null;
1104
+
1097
1105
  /**
1098
1106
  * 职责:事件分级类型(V2-A classify 层公共契约)。
1099
1107
  * 链路位置:classify.ts → reducer;AgentSession tierOverrides 传入。
@@ -1122,4 +1130,4 @@ interface ClassifyContext {
1122
1130
  declare function resolveEventTier(eventType: string, overrides?: TierOverrides): EventTier;
1123
1131
  declare function classifyEvent(event: LangchainAgentEvent, ctx: ClassifyContext, overrides?: TierOverrides, eventIndex?: number): ClassifiedEvent;
1124
1132
 
1125
- export { Agent, AgentLoopView, type AgentLoopViewProps, AgentSession, type AgentSessionProps, type AgentxMetaFrame, type AgentxSseSourceOptions, type ApplicationKind, ApplicationKindMismatchError, AskUserQuestion, Bash, CanonicalNodeRef, type ClassifiedEvent, type ClassifyContext, CollapseKind, CollapsedExploreNode, type CollapsedExploreNodeProps, DEFAULT_WORKFLOW_SCALE_OPTIONS, type DiagramFitLayout, DiagramZoomShell, type DiagramZoomShellProps, DiagramZoomView, type DiagramZoomViewProps, DisplayMode, EXPECTED_PROTOCOL_VERSION, Edit, ErrorCard, EventTier, ExploreCollapseAccumulator, GROUPABLE_TOOL_NAMES, Glob, Grep, GroupedToolUseAccumulator, type HydrateLoopSessionAsyncOptions, InteractionBus, LangchainAgentEvent, MIN_HINT_DISPLAY_MS, MarkdownRenderer, MermaidDiagram, type MermaidDiagramProps, type MermaidInitOptions, type MermaidThemeName, MissingApplicationKindError, NodeRegistry, PermissionCard, PermissionUiMode, PlantUMLBlock, type PlantUMLBlockProps, PlantUMLDiagram, type PlantUMLDiagramProps, type ProjectedTimelineItem, ProjectionContext, DisplayMode as ProjectionDisplayMode, Read, ReasoningBubble, type ReduceOptions, ReducerError, RenderableEntry, RenderableTimelineProjector, type ReplayOptions, type ReplaySourceOptions, RichMarkdown, type RichMarkdownProps, SHELL_PROGRESS_MIN_ELAPSED_SECONDS, SessionNode, SessionNodeKind, SessionStatus, SessionTree, Skill, Source, SourceEventContext, Spinner, type SpinnerProps, type SseTransportFailureKind, SseTransportTerminalError, StepCard, SubAgentBlock, SystemSummaryAccumulator, SystemSummaryNode, Task, TaskList, TaskListFooter, TextBubble, TierOverrides, Timeline, TimelineItem, ToolBodyMode, ToolCallCard, ToolDisplayRegistry, ToolProjectionClassifier, UnknownCard, WORKFLOW_STRUCTURE_EVENT_PREFIXES, WORKFLOW_STRUCTURE_EVENT_TYPES, WebFetch, WebSearch, WorkflowChrome, type WorkflowChromeProps, type WorkflowLoopReplayHandler, WorkflowLoopReplayProvider, type WorkflowProgressState, WorkflowScaleContext, type WorkflowScaleOptions, type WorkflowScopeFrame, WorkflowSession, type WorkflowSessionProps, type WorkflowSessionState, type WorkflowSessionStore, type WorkflowSessionStoreOptions, type WorkflowSessionStoreState, type WorkflowStageProgress, WorkflowTaskListFooter, Write, buildCanonicalFromTree, buildRelevantMemoriesCanonical, buildResumeStreamUrl, buildSystemEventCanonical, buildTimelineEntries, classifyEvent, commandAsHint, computeViewportFitTransform, configureMermaid, configurePlantumlServer, createAgentxSseSource, createDefaultRegistry, createEmptyWorkflowSessionState, createMockSource, createReplaySource, createWorkflowSessionStore, entryKey, filterAgentLoopReplayEvents, fixDiagramSvg, formatAgentTitle, formatExploreSummaryText, formatHookFinishedSummary, formatShellProgressSuffix, formatTaskFooterLabel, getChildIds, getMainStageIds, isAgentLoopReplayEventType, isGitOperationCommand, isGroupableToolName, isMcpToolName, isWorkflowStructureEventType, iterMountCandidates, partitionWorkflowStages, projectCanonical, projectTimeline, reduceAgentLoopEvent, reduceEvents, reduceTree, reduceWorkflowEvents, reduceWorkflowSession, replayEvents, replayTree, resolveEventTier, resolveResponseId, resolveShellProgressFromPayload, shouldShowTaskListFooter, streamChunk, useChildren, useInteractionBus, useInternalErrors, useMinDisplayTime, useNode, useNodeTyped, useProjectedTimeline, useReplayTree, useSessionMeta, useSessionStatus, useTimeline, useWorkflowSessionStatus, useWorkflowSessionStoreApi };
1133
+ export { Agent, AgentLoopView, type AgentLoopViewProps, AgentSession, type AgentSessionProps, type AgentxMetaFrame, type AgentxSseSourceOptions, type ApplicationKind, ApplicationKindMismatchError, AskUserQuestion, Bash, CanonicalNodeRef, type ClassifiedEvent, type ClassifyContext, CollapseKind, CollapsedExploreNode, type CollapsedExploreNodeProps, DEFAULT_WORKFLOW_SCALE_OPTIONS, type DiagramFitLayout, DiagramZoomShell, type DiagramZoomShellProps, DiagramZoomView, type DiagramZoomViewProps, DisplayMode, EXPECTED_PROTOCOL_VERSION, Edit, ErrorCard, EventTier, ExploreCollapseAccumulator, GROUPABLE_TOOL_NAMES, Glob, Grep, GroupedToolUseAccumulator, type HydrateLoopSessionAsyncOptions, InteractionBus, LangchainAgentEvent, MIN_HINT_DISPLAY_MS, MarkdownRenderer, MermaidDiagram, type MermaidDiagramProps, type MermaidInitOptions, type MermaidThemeName, MissingApplicationKindError, NodeRegistry, PermissionCard, PermissionUiMode, PlantUMLBlock, type PlantUMLBlockProps, PlantUMLDiagram, type PlantUMLDiagramProps, type ProjectedTimelineItem, ProjectionContext, DisplayMode as ProjectionDisplayMode, Read, ReasoningBubble, type ReduceOptions, ReducerError, RenderableEntry, RenderableTimelineProjector, type ReplayOptions, type ReplaySourceOptions, RichMarkdown, type RichMarkdownProps, SHELL_PROGRESS_MIN_ELAPSED_SECONDS, SessionNode, SessionNodeKind, SessionStatus, SessionTree, Skill, Source, SourceEventContext, Spinner, type SpinnerProps, type SseTransportFailureKind, SseTransportTerminalError, StepCard, SubAgentBlock, SystemSummaryAccumulator, SystemSummaryNode, Task, TaskList, TaskListFooter, TextBubble, TierOverrides, Timeline, TimelineItem, ToolBodyMode, ToolCallCard, ToolDisplayRegistry, ToolProjectionClassifier, UnknownCard, WORKFLOW_STRUCTURE_EVENT_PREFIXES, WORKFLOW_STRUCTURE_EVENT_TYPES, WebFetch, WebSearch, WorkflowChrome, type WorkflowChromeProps, type WorkflowLoopReplayHandler, WorkflowLoopReplayProvider, type WorkflowProgressState, WorkflowScaleContext, type WorkflowScaleOptions, type WorkflowScopeFrame, WorkflowSession, type WorkflowSessionProps, type WorkflowSessionState, type WorkflowSessionStore, type WorkflowSessionStoreOptions, type WorkflowSessionStoreState, type WorkflowStageProgress, WorkflowTaskListFooter, Write, buildCanonicalFromTree, buildRelevantMemoriesCanonical, buildResumeStreamUrl, buildSystemEventCanonical, buildTimelineEntries, classifyEvent, commandAsHint, computeViewportFitTransform, configureMermaid, configurePlantumlServer, createAgentxSseSource, createDefaultRegistry, createEmptyWorkflowSessionState, createMockSource, createReplaySource, createWorkflowSessionStore, deriveLoopSessionIdFromAgentEvent, entryKey, filterAgentLoopReplayEvents, fixDiagramSvg, formatAgentTitle, formatExploreSummaryText, formatHookFinishedSummary, formatShellProgressSuffix, formatTaskFooterLabel, getChildIds, getMainStageIds, isAgentLoopReplayEventType, isGitOperationCommand, isGroupableToolName, isMcpToolName, isWorkflowStructureEventType, iterMountCandidates, partitionWorkflowStages, projectCanonical, projectTimeline, reduceAgentLoopEvent, reduceEvents, reduceTree, reduceWorkflowEvents, reduceWorkflowSession, replayEvents, replayTree, resolveEventTier, resolveResponseId, resolveShellProgressFromPayload, shouldShowTaskListFooter, streamChunk, useChildren, useInteractionBus, useInternalErrors, useMinDisplayTime, useNode, useNodeTyped, useProjectedTimeline, useReplayTree, useSessionMeta, useSessionStatus, useTimeline, useWorkflowSessionStatus, useWorkflowSessionStoreApi };