langchain_agentx_stream_ui 0.6.4 → 0.7.0

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.
Files changed (37) hide show
  1. package/dist/{AskUserQuestionToolBody-J8MqSUEs.d.ts → AskUserQuestionToolBody-C6J742a2.d.ts} +2 -2
  2. package/dist/{MarkdownBlock-DeICJUtu.d.ts → MarkdownBlock-B_wNhCB4.d.ts} +1 -1
  3. package/dist/{chunk-GBY5DJ7L.js → chunk-4RIOBLGB.js} +1 -1
  4. package/dist/chunk-4RIOBLGB.js.map +1 -0
  5. package/dist/{chunk-YHCK76OU.js → chunk-7TBPTIAP.js} +78 -37
  6. package/dist/chunk-7TBPTIAP.js.map +1 -0
  7. package/dist/{chunk-6Z4ZF36Z.js → chunk-DP7V33X7.js} +1 -1
  8. package/dist/chunk-DP7V33X7.js.map +1 -0
  9. package/dist/{chunk-O5GERXTY.js → chunk-EFJMU4WW.js} +213 -23
  10. package/dist/chunk-EFJMU4WW.js.map +1 -0
  11. package/dist/{chunk-GYFC2DI7.js → chunk-GLUQUP3A.js} +218 -5
  12. package/dist/chunk-GLUQUP3A.js.map +1 -0
  13. package/dist/{chunk-5XELRP3S.js → chunk-OV6UUIA3.js} +4 -4
  14. package/dist/chunk-OV6UUIA3.js.map +1 -0
  15. package/dist/default.css +16 -0
  16. package/dist/index.d.ts +36 -14
  17. package/dist/index.js +221 -18
  18. package/dist/index.js.map +1 -1
  19. package/dist/{multi-session-4GMo1sLl.d.ts → multi-session-DhTXvNpi.d.ts} +22 -3
  20. package/dist/multi-session.d.ts +4 -4
  21. package/dist/multi-session.js +6 -6
  22. package/dist/{nodes-7_0rCAc4.d.ts → nodes-MpVB9C5d.d.ts} +7 -1
  23. package/dist/{sessionViewOptions-EIBugOkf.d.ts → sessionViewOptions-DeTrGjRM.d.ts} +1 -1
  24. package/dist/tools-presentation.d.ts +3 -3
  25. package/dist/tools-presentation.js +2 -2
  26. package/dist/tools.d.ts +5 -5
  27. package/dist/tools.js +4 -4
  28. package/dist/{types-DAkw2VOv.d.ts → types-SVtInovH.d.ts} +1 -1
  29. package/dist/virtual.d.ts +1 -1
  30. package/dist/virtual.js +3 -3
  31. package/package.json +1 -1
  32. package/dist/chunk-5XELRP3S.js.map +0 -1
  33. package/dist/chunk-6Z4ZF36Z.js.map +0 -1
  34. package/dist/chunk-GBY5DJ7L.js.map +0 -1
  35. package/dist/chunk-GYFC2DI7.js.map +0 -1
  36. package/dist/chunk-O5GERXTY.js.map +0 -1
  37. package/dist/chunk-YHCK76OU.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/view/tools/ask_user_question/formatAskUserQuestionTitle.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/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":["/**\n * formatAskUserQuestionTitle.ts — AskUserQuestion 工具标题\n *\n * 对齐参考:CLI widgets/tools/ask_user_question/widget.py format_title\n */\nimport { asDisplayRecord, asInputRecord, numField } from '../displayRecord';\nimport { formatAskUserQuestionsPreview } from '../presentation/askUserHelpers';\nimport { truncatePreview } from '../presentation/textHelpers';\n\nfunction firstQuestion(\n display: Record<string, unknown> | null,\n input: Record<string, unknown>,\n): { header: string; question: string } {\n const items = display?.questions;\n if (Array.isArray(items) && items.length > 0) {\n const first = items[0];\n if (first != null && typeof first === 'object') {\n const row = first as Record<string, unknown>;\n return {\n header: String(row.header ?? '').trim(),\n question: String(row.question ?? '').trim(),\n };\n }\n }\n\n const questions = input.questions;\n if (Array.isArray(questions) && questions.length > 0) {\n const first = questions[0];\n if (first != null && typeof first === 'object') {\n const row = first as Record<string, unknown>;\n return {\n header: String(row.header ?? '').trim(),\n question: String(row.question ?? '').trim(),\n };\n }\n }\n\n return { header: '', question: '' };\n}\n\nexport function formatAskUserQuestionTitle(\n input: unknown,\n display: unknown,\n _summary?: string | null,\n): string {\n const d = asDisplayRecord(display);\n const inp = asInputRecord(input);\n const { header, question } = firstQuestion(d, inp);\n\n if (question) {\n const label = header ? `[${header}] ${question}` : question;\n return truncatePreview(label, 100);\n }\n\n const answered = numField(d ?? {}, 'answered_count');\n if (answered != null) return `Ask user (${answered} answered)`;\n\n return 'Ask user';\n}\n\nexport { formatAskUserQuestionsPreview };\n","/**\n * formatGlobTitle.ts — glob 工具标题\n *\n * 对齐参考:CLI widgets/tools/glob/widget.py format_title\n */\nimport { formatPatternTitle } from '../presentation/searchHelpers';\nimport { asDisplayRecord, asInputRecord, numField, strField } from '../displayRecord';\n\nexport function formatGlobTitle(\n input: unknown,\n display: unknown,\n _summary?: string | null,\n): string {\n const d = asDisplayRecord(display);\n const inp = asInputRecord(input);\n const pattern = strField(d ?? {}, 'pattern') || strField(inp, 'pattern');\n\n if (!pattern) return 'Search';\n\n const path = strField(inp, 'path') || undefined;\n const suffix = formatPatternTitle(pattern, path);\n const numFiles = numField(d ?? {}, 'num_files');\n const countHint = numFiles != null ? ` · ${numFiles} files` : '';\n\n return `Search(${suffix}${countHint})`;\n}\n","/**\n * formatGrepTitle.ts — grep 工具标题\n *\n * 对齐参考:CLI widgets/tools/grep/widget.py format_title\n */\nimport { formatPatternTitle } from '../presentation/searchHelpers';\nimport { asDisplayRecord, asInputRecord, numField, strField } from '../displayRecord';\n\nexport function formatGrepTitle(\n input: unknown,\n display: unknown,\n _summary?: string | null,\n): string {\n const d = asDisplayRecord(display);\n const inp = asInputRecord(input);\n const pattern = strField(d ?? {}, 'pattern') || strField(inp, 'pattern');\n\n if (!pattern) return 'Search';\n\n const path = strField(inp, 'path') || undefined;\n const suffix = formatPatternTitle(pattern, path);\n const numMatches = numField(d ?? {}, 'num_matches');\n const countHint = numMatches != null ? ` · ${numMatches} matches` : '';\n\n return `Search(${suffix}${countHint})`;\n}\n","/**\n * formatReadTitle.ts — Read 工具标题\n *\n * 对齐参考:CLI widgets/tools/read/widget.py format_title\n */\nimport { displayPath } from '../presentation/paths';\nimport { asDisplayRecord, asInputRecord, numField, strField } from '../displayRecord';\n\nconst LINES_RANGE_RE = /lines (\\d+)-(\\d+) of (\\d+)/;\nconst READ_LINES_RE = /Read (\\d+) lines from/;\n\nfunction titleSuffixFromDisplay(display: unknown): string {\n const d = asDisplayRecord(display);\n if (!d) return '';\n\n if (d.type === 'text') {\n const start = numField(d, 'line_start');\n const end = numField(d, 'line_end');\n if (start != null && end != null) {\n return ` · lines ${start}-${end}`;\n }\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 ` · pages ${ps}-${pe}`;\n }\n }\n\n return '';\n}\n\nfunction titleSuffixFromSummary(summary: string, input: unknown): string {\n const matchRange = summary.match(LINES_RANGE_RE);\n if (matchRange) {\n return ` · lines ${matchRange[1]}-${matchRange[2]}`;\n }\n\n const inp = asInputRecord(input);\n const offset = numField(inp, 'offset');\n const limit = numField(inp, 'limit');\n if (offset != null && limit != null) {\n return ` · lines ${offset}-${offset + limit - 1}`;\n }\n\n const matchLines = summary.match(READ_LINES_RE);\n if (matchLines) {\n return ` · ${matchLines[1]} lines`;\n }\n\n return '';\n}\n\nexport function formatReadTitle(input: unknown, display: unknown, summary?: string | null): string {\n const d = asDisplayRecord(display);\n const inp = asInputRecord(input);\n const path = displayPath(\n strField(d ?? {}, 'file_path') ||\n strField(inp, 'file_path') ||\n strField(inp, 'path'),\n );\n\n const suffix =\n titleSuffixFromDisplay(display) ||\n (summary ? titleSuffixFromSummary(summary, input) : '');\n\n if (!path) {\n return suffix ? `Read(${suffix.trim()})` : 'Read';\n }\n\n return `Read(${path}${suffix})`;\n}\n","/**\n * formatSkillTitle.ts — skill 工具标题\n *\n * 对齐参考:CLI widgets/tools/skill/widget.py format_title\n */\nimport { asDisplayRecord, asInputRecord, strField } from '../displayRecord';\n\nexport function formatSkillTitle(\n input: unknown,\n display: unknown,\n _summary?: string | null,\n): string {\n const d = asDisplayRecord(display);\n const inp = asInputRecord(input);\n const name = strField(d ?? {}, 'skill_name') || strField(inp, 'skill_name');\n if (!name) return 'Skill';\n\n if (d?.source === 'commands_DEPRECATED') {\n return `/${name}`;\n }\n return name;\n}\n","/**\n * formatWebFetchTitle.ts — WebFetch 工具标题\n *\n * 对齐参考:CLI widgets/tools/webfetch/widget.py format_title\n */\nimport { asDisplayRecord, asInputRecord, numField, strField } from '../displayRecord';\nimport { truncatePreview } from '../presentation/textHelpers';\n\nexport function formatWebFetchTitle(\n input: unknown,\n display: unknown,\n _summary?: string | null,\n): string {\n const d = asDisplayRecord(display);\n const inp = asInputRecord(input);\n const url = strField(d ?? {}, 'url') || strField(inp, 'url');\n if (!url) return 'Fetch';\n\n const code = numField(d ?? {}, 'http_code');\n const title =\n code != null ? `${url} · HTTP ${code}` : truncatePreview(url, 100);\n return `Fetch(${title})`;\n}\n","/**\n * formatWebSearchTitle.ts — WebSearch 工具标题\n *\n * 对齐参考:CLI widgets/tools/websearch/widget.py format_title\n */\nimport { asDisplayRecord, asInputRecord, numField, strField } from '../displayRecord';\nimport { truncatePreview } from '../presentation/textHelpers';\n\nexport function formatWebSearchTitle(\n input: unknown,\n display: unknown,\n _summary?: string | null,\n): string {\n const d = asDisplayRecord(display);\n const inp = asInputRecord(input);\n const query = strField(d ?? {}, 'query') || strField(inp, 'query');\n if (!query) return 'Web Search';\n\n let queryPart = `\"${truncatePreview(query, 100)}\"`;\n const hits = numField(d ?? {}, 'total_hits');\n if (hits != null) queryPart = `${queryPart} · ${hits} hits`;\n\n return `Web Search(${queryPart})`;\n}\n","/**\n * formatToolTitle.ts — 工具卡片标题格式化\n */\nimport { formatAgentTitle } from './presentation/agentHelpers';\nimport { formatAskUserQuestionTitle } from './ask_user_question/formatAskUserQuestionTitle';\nimport { formatBashTitle } from './presentation/bashHelpers';\nimport { formatEditTitle } from './edit/formatEditTitle';\nimport { formatGlobTitle } from './glob/formatGlobTitle';\nimport { formatGrepTitle } from './grep/formatGrepTitle';\nimport { formatReadTitle } from './read/formatReadTitle';\nimport { formatSkillTitle } from './skill/formatSkillTitle';\nimport { formatWebFetchTitle } from './webfetch/formatWebFetchTitle';\nimport { formatWebSearchTitle } from './websearch/formatWebSearchTitle';\nimport { formatWriteTitle } from './write/formatWriteTitle';\nimport {\n Agent,\n AskUserQuestion,\n Bash,\n Edit,\n Glob,\n Grep,\n Read,\n Skill,\n WebFetch,\n WebSearch,\n Write,\n} from './toolNames';\n\ntype TitleFormatter = (\n input: unknown,\n display: unknown,\n summary?: string | null,\n meta?: unknown,\n) => string;\n\nconst TITLE_FORMATTERS: Record<string, TitleFormatter> = {\n [Read]: formatReadTitle,\n [Grep]: formatGrepTitle,\n [Glob]: formatGlobTitle,\n [Edit]: formatEditTitle,\n [Write]: formatWriteTitle,\n [Bash]: formatBashTitle,\n [Agent]: formatAgentTitle,\n [Skill]: formatSkillTitle,\n [WebSearch]: formatWebSearchTitle,\n [WebFetch]: formatWebFetchTitle,\n [AskUserQuestion]: formatAskUserQuestionTitle,\n};\n\nexport function formatToolTitle(\n toolName: string,\n input: unknown,\n display: unknown,\n summary?: string | null,\n meta?: unknown,\n): string {\n const formatter = TITLE_FORMATTERS[toolName];\n if (formatter) {\n return formatter(input, display, summary, meta);\n }\n return toolName;\n}\n","/**\n * DefaultToolBody.tsx — 未注册工具回退 Body\n *\n * 职责:\n * summary + display JSON 预览(≥ V2);markdown/text 走 TruncatedContent。\n *\n * 链路位置:\n * resolveToolBody 最终回退。\n *\n * 当前裁剪范围:\n * 不渲染 blocks 主视图(折叠区保留在 ToolCallCard details)。\n *\n * 对齐参考:\n * CLI widgets/tools/base.py BaseToolWidget · V2 ToolCallCard JSON pre\n */\nimport { ToolResultHints } from './presentation/ToolResultHints';\nimport { TruncatedContent } from './presentation/TruncatedContent';\nimport type { ToolDisplayProps } from './types';\n\nfunction formatDisplayJson(display: unknown): string {\n if (display == null) return '';\n if (typeof display === 'string') return display;\n try {\n return JSON.stringify(display, null, 2);\n } catch {\n return String(display);\n }\n}\n\nfunction extractTextContent(display: unknown): string | null {\n if (display == null) return null;\n if (typeof display === 'string') return display;\n if (typeof display === 'object') {\n const record = display as { content?: unknown; text?: unknown };\n if (typeof record.content === 'string') return record.content;\n if (typeof record.text === 'string') return record.text;\n }\n return null;\n}\n\nexport function DefaultToolBody({\n result,\n bodyMode,\n onBodyModeChange,\n}: ToolDisplayProps) {\n const summary = result?.summary;\n const displayBody = result?.display ?? null;\n const textContent = extractTextContent(displayBody);\n const jsonBody = textContent ?? formatDisplayJson(displayBody);\n\n return (\n <div className=\"lax-tool-body lax-tool-body--default\">\n {summary ? (\n <div className=\"lax-tool-card__summary\">{summary}</div>\n ) : null}\n\n {displayBody != null && displayBody !== '' && jsonBody ? (\n <div className=\"lax-tool-card__display\">\n {textContent != null ? (\n <TruncatedContent\n text={textContent}\n mode={bodyMode}\n onExpand={() => onBodyModeChange?.('full')}\n />\n ) : (\n <pre className=\"lax-tool-card__display-body\">{jsonBody}</pre>\n )}\n </div>\n ) : null}\n\n {result?.truncated ? (\n <div className=\"lax-tool-card__truncated\">结果已截断</div>\n ) : null}\n\n {result?.overflow_file ? (\n <div className=\"lax-tool-card__overflow\">\n 完整输出:\n <code>{result.overflow_file}</code>\n </div>\n ) : null}\n\n <ToolResultHints hints={result?.hints} />\n </div>\n );\n}\n","/**\n * resolveToolBody.ts — 工具 Body 路由纯函数\n *\n * 职责:\n * registry → display.type → DefaultToolBody(精确 tool_name 匹配,无 alias)。\n *\n * 链路位置:\n * ToolCallCard render。\n *\n * 当前裁剪范围:\n * T0 display.type 二级路由表为空;T1+ 注册专用 Widget 与 kind router。\n *\n * 对齐参考:\n * CLI widgets/tools/__init__.py resolve_tool_widget\n */\nimport { DefaultToolBody } from './DefaultToolBody';\nimport type { ToolDisplayRegistry } from './registry';\nimport type { ToolBodyComponent } from './types';\n\n/** display.type → Body;T0 空表,T1+ 填充。 */\nconst DISPLAY_KIND_ROUTER = new Map<string, ToolBodyComponent>();\n\nfunction getDisplayType(display: unknown): string | undefined {\n if (display == null || typeof display !== 'object') return undefined;\n const type = (display as { type?: unknown }).type;\n return typeof type === 'string' ? type : undefined;\n}\n\nexport function resolveToolBody(\n toolName: string,\n display: unknown,\n registry: ToolDisplayRegistry,\n): ToolBodyComponent {\n const byName = registry.resolve(toolName);\n if (byName) return byName;\n\n const displayType = getDisplayType(display);\n if (displayType) {\n const byKind = DISPLAY_KIND_ROUTER.get(displayType);\n if (byKind) return byKind;\n }\n\n return DefaultToolBody;\n}\n\n/** 测试 / 扩展用:注册 display.type 路由。 */\nexport function registerDisplayKind(\n displayType: string,\n body: ToolBodyComponent,\n): void {\n DISPLAY_KIND_ROUTER.set(displayType, body);\n}\n\n/** 测试用:清空 display kind 路由。 */\nexport function clearDisplayKindRouter(): void {\n DISPLAY_KIND_ROUTER.clear();\n}\n","/**\n * 职责:人类回写薄层 API;PermissionNode 触发,业务实现 HTTP 回写。\n * 链路位置:AgentSession interactionBus prop → PermissionNode 按钮。\n * 当前裁剪范围:permission resolve;不含 HITL 表单协议。\n */\n\nexport interface PermissionResolvePayload {\n requestId: string;\n allow: boolean;\n message?: string;\n}\n\nexport interface InteractionBus {\n resolvePermission: (payload: PermissionResolvePayload) => void | Promise<void>;\n}\n\nexport interface InteractionBusHandlers {\n onPermissionResolve?: (payload: PermissionResolvePayload) => void | Promise<void>;\n}\n\nconst noopBus: InteractionBus = {\n resolvePermission() {\n if (import.meta.env?.DEV) {\n console.warn('[langchain_agentx_stream_ui] resolvePermission without InteractionBus');\n }\n },\n};\n\nexport function createInteractionBus(handlers: InteractionBusHandlers = {}): InteractionBus {\n return {\n resolvePermission(payload) {\n return handlers.onPermissionResolve?.(payload);\n },\n };\n}\n\nexport function getNoopInteractionBus(): InteractionBus {\n return noopBus;\n}\n","/**\n * 职责:向 PermissionNode 注入 InteractionBus。\n * 链路位置:AgentSession / MultiAgentSession Provider。\n * 当前裁剪范围:单 bus;多会话共用同一 bus(业务按 requestId 路由)。\n */\nimport { createContext, useContext } from 'react';\n\nimport type { InteractionBus } from '../interaction/InteractionBus';\nimport { getNoopInteractionBus } from '../interaction/InteractionBus';\n\nexport const InteractionBusContext = createContext<InteractionBus>(getNoopInteractionBus());\n\nexport function useInteractionBus(): InteractionBus {\n return useContext(InteractionBusContext);\n}\n","/**\n * ToolPermissionWait.tsx — ToolCallShell 内嵌 permission 等待态(T4.6)\n *\n * 对齐参考:CC AssistantToolUseMessage「Waiting for permission…」分支\n */\nimport { useState } from 'react';\n\nimport { useInteractionBus } from '../../core/context/InteractionContext';\nimport type { PermissionNode } from '../../types/nodes';\nimport type { PermissionUiMode } from '../sessionViewOptions';\n\nexport interface ToolPermissionWaitProps {\n permission: PermissionNode;\n mode: PermissionUiMode;\n}\n\nexport function ToolPermissionWait({ permission, mode }: ToolPermissionWaitProps) {\n const bus = useInteractionBus();\n const [resolvedLocally, setResolvedLocally] = useState(false);\n\n if (permission.status !== 'pending' || resolvedLocally) return null;\n\n const showActions = mode === 'inline' || mode === 'both';\n\n const onAllow = () => {\n void bus.resolvePermission({ requestId: permission.requestId, allow: true });\n setResolvedLocally(true);\n };\n\n const onDeny = () => {\n void bus.resolvePermission({ requestId: permission.requestId, allow: false });\n setResolvedLocally(true);\n };\n\n return (\n <div className=\"lax-tool-shell__permission-wait\" role=\"status\">\n <div className=\"lax-tool-shell__permission-wait-text\">\n Waiting for permission…\n </div>\n {permission.message ? (\n <div className=\"lax-tool-shell__permission-wait-detail\">{permission.message}</div>\n ) : null}\n {showActions ? (\n <div className=\"lax-tool-shell__permission-actions\">\n <button type=\"button\" className=\"lax-permission-card__allow\" onClick={onAllow}>\n Allow\n </button>\n <button type=\"button\" className=\"lax-permission-card__deny\" onClick={onDeny}>\n Deny\n </button>\n </div>\n ) : null}\n </div>\n );\n}\n","/**\n * ToolCallShell.tsx — 工具卡片外壳\n *\n * 职责:\n * 状态圆点、标题、progress、error 边框;不含工具语义。\n *\n * 链路位置:\n * ToolCallCard 外层布局。\n *\n * 当前裁剪范围:\n * T4.6 内嵌 permission 等待态;Grouped 紧凑布局 variant。\n *\n * 对齐参考:\n * CLI base.py 状态圆点 · CC AssistantToolUseMessage.tsx 外层 Box\n */\nimport type { ReactNode } from 'react';\n\nimport type { ToolCallNode } from '../../types/nodes';\nimport type { PermissionNode } from '../../types/nodes';\nimport type { PermissionUiMode } from '../sessionViewOptions';\nimport { ToolPermissionWait } from './ToolPermissionWait';\n\nexport interface ToolCallShellProps {\n status: ToolCallNode['status'];\n title: string;\n progress?: ToolCallNode['progress'];\n errorMessage?: string | null;\n layout?: 'default' | 'grouped';\n permissionWait?: PermissionNode;\n permissionUiMode?: PermissionUiMode;\n children?: ReactNode;\n}\n\nexport function ToolCallShell({\n status,\n title,\n progress,\n errorMessage,\n layout = 'default',\n permissionWait,\n permissionUiMode = 'standalone',\n children,\n}: ToolCallShellProps) {\n const bare = !title.trim();\n const waitingForPermission =\n permissionWait &&\n permissionUiMode !== 'standalone' &&\n (status === 'running' || status === 'failed');\n\n return (\n <div\n className={[\n 'lax-tool-card',\n 'lax-tool-shell',\n bare ? 'lax-tool-shell--bare' : '',\n layout === 'grouped' ? 'lax-tool-shell--grouped' : '',\n waitingForPermission ? 'lax-tool-shell--permission-wait' : '',\n ]\n .filter(Boolean)\n .join(' ')}\n data-status={status}\n data-error-kind={\n errorMessage ? 'error' : waitingForPermission ? 'permission' : undefined\n }\n >\n {!bare ? (\n <div className=\"lax-tool-shell__header lax-tool-card__header\">\n <span\n className=\"lax-tool-shell__status-dot lax-tool-card__status-dot\"\n data-status={status}\n aria-hidden\n >\n ●{' '}\n </span>\n <span className=\"lax-tool-shell__title lax-tool-card__name\">{title}</span>\n </div>\n ) : null}\n\n {progress ? (\n <div className=\"lax-tool-shell__progress lax-tool-card__progress\">\n {progress.message ?? `${progress.current}/${progress.total}`}\n </div>\n ) : null}\n\n {waitingForPermission && permissionWait ? (\n <ToolPermissionWait permission={permissionWait} mode={permissionUiMode} />\n ) : null}\n\n {children}\n\n {errorMessage && status === 'failed' ? (\n <div className=\"lax-tool-card__error\" role=\"alert\">\n {errorMessage}\n </div>\n ) : null}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,SAAS,cACP,SACA,OACsC;AACtC,QAAM,QAAQ,SAAS;AACvB,MAAI,MAAM,QAAQ,KAAK,KAAK,MAAM,SAAS,GAAG;AAC5C,UAAM,QAAQ,MAAM,CAAC;AACrB,QAAI,SAAS,QAAQ,OAAO,UAAU,UAAU;AAC9C,YAAM,MAAM;AACZ,aAAO;AAAA,QACL,QAAQ,OAAO,IAAI,UAAU,EAAE,EAAE,KAAK;AAAA,QACtC,UAAU,OAAO,IAAI,YAAY,EAAE,EAAE,KAAK;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AAEA,QAAM,YAAY,MAAM;AACxB,MAAI,MAAM,QAAQ,SAAS,KAAK,UAAU,SAAS,GAAG;AACpD,UAAM,QAAQ,UAAU,CAAC;AACzB,QAAI,SAAS,QAAQ,OAAO,UAAU,UAAU;AAC9C,YAAM,MAAM;AACZ,aAAO;AAAA,QACL,QAAQ,OAAO,IAAI,UAAU,EAAE,EAAE,KAAK;AAAA,QACtC,UAAU,OAAO,IAAI,YAAY,EAAE,EAAE,KAAK;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,QAAQ,IAAI,UAAU,GAAG;AACpC;AAEO,SAAS,2BACd,OACA,SACA,UACQ;AACR,QAAM,IAAI,gBAAgB,OAAO;AACjC,QAAM,MAAM,cAAc,KAAK;AAC/B,QAAM,EAAE,QAAQ,SAAS,IAAI,cAAc,GAAG,GAAG;AAEjD,MAAI,UAAU;AACZ,UAAM,QAAQ,SAAS,IAAI,MAAM,KAAK,QAAQ,KAAK;AACnD,WAAO,gBAAgB,OAAO,GAAG;AAAA,EACnC;AAEA,QAAM,WAAW,SAAS,KAAK,CAAC,GAAG,gBAAgB;AACnD,MAAI,YAAY,KAAM,QAAO,aAAa,QAAQ;AAElD,SAAO;AACT;;;AClDO,SAAS,gBACd,OACA,SACA,UACQ;AACR,QAAM,IAAI,gBAAgB,OAAO;AACjC,QAAM,MAAM,cAAc,KAAK;AAC/B,QAAM,UAAU,SAAS,KAAK,CAAC,GAAG,SAAS,KAAK,SAAS,KAAK,SAAS;AAEvE,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,OAAO,SAAS,KAAK,MAAM,KAAK;AACtC,QAAM,SAAS,mBAAmB,SAAS,IAAI;AAC/C,QAAM,WAAW,SAAS,KAAK,CAAC,GAAG,WAAW;AAC9C,QAAM,YAAY,YAAY,OAAO,SAAM,QAAQ,WAAW;AAE9D,SAAO,UAAU,MAAM,GAAG,SAAS;AACrC;;;ACjBO,SAAS,gBACd,OACA,SACA,UACQ;AACR,QAAM,IAAI,gBAAgB,OAAO;AACjC,QAAM,MAAM,cAAc,KAAK;AAC/B,QAAM,UAAU,SAAS,KAAK,CAAC,GAAG,SAAS,KAAK,SAAS,KAAK,SAAS;AAEvE,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,OAAO,SAAS,KAAK,MAAM,KAAK;AACtC,QAAM,SAAS,mBAAmB,SAAS,IAAI;AAC/C,QAAM,aAAa,SAAS,KAAK,CAAC,GAAG,aAAa;AAClD,QAAM,YAAY,cAAc,OAAO,SAAM,UAAU,aAAa;AAEpE,SAAO,UAAU,MAAM,GAAG,SAAS;AACrC;;;ACjBA,IAAM,iBAAiB;AACvB,IAAM,gBAAgB;AAEtB,SAAS,uBAAuB,SAA0B;AACxD,QAAM,IAAI,gBAAgB,OAAO;AACjC,MAAI,CAAC,EAAG,QAAO;AAEf,MAAI,EAAE,SAAS,QAAQ;AACrB,UAAM,QAAQ,SAAS,GAAG,YAAY;AACtC,UAAM,MAAM,SAAS,GAAG,UAAU;AAClC,QAAI,SAAS,QAAQ,OAAO,MAAM;AAChC,aAAO,eAAY,KAAK,IAAI,GAAG;AAAA,IACjC;AAAA,EACF;AAEA,MAAI,EAAE,SAAS,OAAO;AACpB,UAAM,KAAK,SAAS,GAAG,YAAY;AACnC,UAAM,KAAK,SAAS,GAAG,UAAU;AACjC,QAAI,MAAM,QAAQ,MAAM,MAAM;AAC5B,aAAO,eAAY,EAAE,IAAI,EAAE;AAAA,IAC7B;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,uBAAuB,SAAiB,OAAwB;AACvE,QAAM,aAAa,QAAQ,MAAM,cAAc;AAC/C,MAAI,YAAY;AACd,WAAO,eAAY,WAAW,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC;AAAA,EACnD;AAEA,QAAM,MAAM,cAAc,KAAK;AAC/B,QAAM,SAAS,SAAS,KAAK,QAAQ;AACrC,QAAM,QAAQ,SAAS,KAAK,OAAO;AACnC,MAAI,UAAU,QAAQ,SAAS,MAAM;AACnC,WAAO,eAAY,MAAM,IAAI,SAAS,QAAQ,CAAC;AAAA,EACjD;AAEA,QAAM,aAAa,QAAQ,MAAM,aAAa;AAC9C,MAAI,YAAY;AACd,WAAO,SAAM,WAAW,CAAC,CAAC;AAAA,EAC5B;AAEA,SAAO;AACT;AAEO,SAAS,gBAAgB,OAAgB,SAAkB,SAAiC;AACjG,QAAM,IAAI,gBAAgB,OAAO;AACjC,QAAM,MAAM,cAAc,KAAK;AAC/B,QAAM,OAAO;AAAA,IACX,SAAS,KAAK,CAAC,GAAG,WAAW,KAC3B,SAAS,KAAK,WAAW,KACzB,SAAS,KAAK,MAAM;AAAA,EACxB;AAEA,QAAM,SACJ,uBAAuB,OAAO,MAC7B,UAAU,uBAAuB,SAAS,KAAK,IAAI;AAEtD,MAAI,CAAC,MAAM;AACT,WAAO,SAAS,QAAQ,OAAO,KAAK,CAAC,MAAM;AAAA,EAC7C;AAEA,SAAO,QAAQ,IAAI,GAAG,MAAM;AAC9B;;;AClEO,SAAS,iBACd,OACA,SACA,UACQ;AACR,QAAM,IAAI,gBAAgB,OAAO;AACjC,QAAM,MAAM,cAAc,KAAK;AAC/B,QAAM,OAAO,SAAS,KAAK,CAAC,GAAG,YAAY,KAAK,SAAS,KAAK,YAAY;AAC1E,MAAI,CAAC,KAAM,QAAO;AAElB,MAAI,GAAG,WAAW,uBAAuB;AACvC,WAAO,IAAI,IAAI;AAAA,EACjB;AACA,SAAO;AACT;;;ACbO,SAAS,oBACd,OACA,SACA,UACQ;AACR,QAAM,IAAI,gBAAgB,OAAO;AACjC,QAAM,MAAM,cAAc,KAAK;AAC/B,QAAM,MAAM,SAAS,KAAK,CAAC,GAAG,KAAK,KAAK,SAAS,KAAK,KAAK;AAC3D,MAAI,CAAC,IAAK,QAAO;AAEjB,QAAM,OAAO,SAAS,KAAK,CAAC,GAAG,WAAW;AAC1C,QAAM,QACJ,QAAQ,OAAO,GAAG,GAAG,cAAW,IAAI,KAAK,gBAAgB,KAAK,GAAG;AACnE,SAAO,SAAS,KAAK;AACvB;;;ACdO,SAAS,qBACd,OACA,SACA,UACQ;AACR,QAAM,IAAI,gBAAgB,OAAO;AACjC,QAAM,MAAM,cAAc,KAAK;AAC/B,QAAM,QAAQ,SAAS,KAAK,CAAC,GAAG,OAAO,KAAK,SAAS,KAAK,OAAO;AACjE,MAAI,CAAC,MAAO,QAAO;AAEnB,MAAI,YAAY,IAAI,gBAAgB,OAAO,GAAG,CAAC;AAC/C,QAAM,OAAO,SAAS,KAAK,CAAC,GAAG,YAAY;AAC3C,MAAI,QAAQ,KAAM,aAAY,GAAG,SAAS,SAAM,IAAI;AAEpD,SAAO,cAAc,SAAS;AAChC;;;ACYA,IAAM,mBAAmD;AAAA,EACvD,CAAC,IAAI,GAAG;AAAA,EACR,CAAC,IAAI,GAAG;AAAA,EACR,CAAC,IAAI,GAAG;AAAA,EACR,CAAC,IAAI,GAAG;AAAA,EACR,CAAC,KAAK,GAAG;AAAA,EACT,CAAC,IAAI,GAAG;AAAA,EACR,CAAC,KAAK,GAAG;AAAA,EACT,CAAC,KAAK,GAAG;AAAA,EACT,CAAC,SAAS,GAAG;AAAA,EACb,CAAC,QAAQ,GAAG;AAAA,EACZ,CAAC,eAAe,GAAG;AACrB;AAEO,SAAS,gBACd,UACA,OACA,SACA,SACA,MACQ;AACR,QAAM,YAAY,iBAAiB,QAAQ;AAC3C,MAAI,WAAW;AACb,WAAO,UAAU,OAAO,SAAS,SAAS,IAAI;AAAA,EAChD;AACA,SAAO;AACT;;;ACRQ,cAsBA,YAtBA;AAlCR,SAAS,kBAAkB,SAA0B;AACnD,MAAI,WAAW,KAAM,QAAO;AAC5B,MAAI,OAAO,YAAY,SAAU,QAAO;AACxC,MAAI;AACF,WAAO,KAAK,UAAU,SAAS,MAAM,CAAC;AAAA,EACxC,QAAQ;AACN,WAAO,OAAO,OAAO;AAAA,EACvB;AACF;AAEA,SAAS,mBAAmB,SAAiC;AAC3D,MAAI,WAAW,KAAM,QAAO;AAC5B,MAAI,OAAO,YAAY,SAAU,QAAO;AACxC,MAAI,OAAO,YAAY,UAAU;AAC/B,UAAM,SAAS;AACf,QAAI,OAAO,OAAO,YAAY,SAAU,QAAO,OAAO;AACtD,QAAI,OAAO,OAAO,SAAS,SAAU,QAAO,OAAO;AAAA,EACrD;AACA,SAAO;AACT;AAEO,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AACF,GAAqB;AACnB,QAAM,UAAU,QAAQ;AACxB,QAAM,cAAc,QAAQ,WAAW;AACvC,QAAM,cAAc,mBAAmB,WAAW;AAClD,QAAM,WAAW,eAAe,kBAAkB,WAAW;AAE7D,SACE,qBAAC,SAAI,WAAU,wCACZ;AAAA,cACC,oBAAC,SAAI,WAAU,0BAA0B,mBAAQ,IAC/C;AAAA,IAEH,eAAe,QAAQ,gBAAgB,MAAM,WAC5C,oBAAC,SAAI,WAAU,0BACZ,yBAAe,OACd;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU,MAAM,mBAAmB,MAAM;AAAA;AAAA,IAC3C,IAEA,oBAAC,SAAI,WAAU,+BAA+B,oBAAS,GAE3D,IACE;AAAA,IAEH,QAAQ,YACP,oBAAC,SAAI,WAAU,4BAA2B,4CAAK,IAC7C;AAAA,IAEH,QAAQ,gBACP,qBAAC,SAAI,WAAU,2BAA0B;AAAA;AAAA,MAEvC,oBAAC,UAAM,iBAAO,eAAc;AAAA,OAC9B,IACE;AAAA,IAEJ,oBAAC,mBAAgB,OAAO,QAAQ,OAAO;AAAA,KACzC;AAEJ;;;AChEA,IAAM,sBAAsB,oBAAI,IAA+B;AAE/D,SAAS,eAAe,SAAsC;AAC5D,MAAI,WAAW,QAAQ,OAAO,YAAY,SAAU,QAAO;AAC3D,QAAM,OAAQ,QAA+B;AAC7C,SAAO,OAAO,SAAS,WAAW,OAAO;AAC3C;AAEO,SAAS,gBACd,UACA,SACA,UACmB;AACnB,QAAM,SAAS,SAAS,QAAQ,QAAQ;AACxC,MAAI,OAAQ,QAAO;AAEnB,QAAM,cAAc,eAAe,OAAO;AAC1C,MAAI,aAAa;AACf,UAAM,SAAS,oBAAoB,IAAI,WAAW;AAClD,QAAI,OAAQ,QAAO;AAAA,EACrB;AAEA,SAAO;AACT;;;ACvBA,IAAM,UAA0B;AAAA,EAC9B,oBAAoB;AAClB,QAAI,YAAY,KAAK,KAAK;AACxB,cAAQ,KAAK,uEAAuE;AAAA,IACtF;AAAA,EACF;AACF;AAEO,SAAS,qBAAqB,WAAmC,CAAC,GAAmB;AAC1F,SAAO;AAAA,IACL,kBAAkB,SAAS;AACzB,aAAO,SAAS,sBAAsB,OAAO;AAAA,IAC/C;AAAA,EACF;AACF;AAEO,SAAS,wBAAwC;AACtD,SAAO;AACT;;;ACjCA,SAAS,eAAe,kBAAkB;AAKnC,IAAM,wBAAwB,cAA8B,sBAAsB,CAAC;AAEnF,SAAS,oBAAoC;AAClD,SAAO,WAAW,qBAAqB;AACzC;;;ACTA,SAAS,gBAAgB;AA+BnB,gBAAAA,MAOE,QAAAC,aAPF;AApBC,SAAS,mBAAmB,EAAE,YAAY,KAAK,GAA4B;AAChF,QAAM,MAAM,kBAAkB;AAC9B,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,SAAS,KAAK;AAE5D,MAAI,WAAW,WAAW,aAAa,gBAAiB,QAAO;AAE/D,QAAM,cAAc,SAAS,YAAY,SAAS;AAElD,QAAM,UAAU,MAAM;AACpB,SAAK,IAAI,kBAAkB,EAAE,WAAW,WAAW,WAAW,OAAO,KAAK,CAAC;AAC3E,uBAAmB,IAAI;AAAA,EACzB;AAEA,QAAM,SAAS,MAAM;AACnB,SAAK,IAAI,kBAAkB,EAAE,WAAW,WAAW,WAAW,OAAO,MAAM,CAAC;AAC5E,uBAAmB,IAAI;AAAA,EACzB;AAEA,SACE,gBAAAA,MAAC,SAAI,WAAU,mCAAkC,MAAK,UACpD;AAAA,oBAAAD,KAAC,SAAI,WAAU,wCAAuC,0CAEtD;AAAA,IACC,WAAW,UACV,gBAAAA,KAAC,SAAI,WAAU,0CAA0C,qBAAW,SAAQ,IAC1E;AAAA,IACH,cACC,gBAAAC,MAAC,SAAI,WAAU,sCACb;AAAA,sBAAAD,KAAC,YAAO,MAAK,UAAS,WAAU,8BAA6B,SAAS,SAAS,mBAE/E;AAAA,MACA,gBAAAA,KAAC,YAAO,MAAK,UAAS,WAAU,6BAA4B,SAAS,QAAQ,kBAE7E;AAAA,OACF,IACE;AAAA,KACN;AAEJ;;;ACaU,SAOA,OAAAE,MAPA,QAAAC,aAAA;AAlCH,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA,mBAAmB;AAAA,EACnB;AACF,GAAuB;AACrB,QAAM,OAAO,CAAC,MAAM,KAAK;AACzB,QAAM,uBACJ,kBACA,qBAAqB,iBACpB,WAAW,aAAa,WAAW;AAEtC,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA,OAAO,yBAAyB;AAAA,QAChC,WAAW,YAAY,4BAA4B;AAAA,QACnD,uBAAuB,oCAAoC;AAAA,MAC7D,EACG,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,MACX,eAAa;AAAA,MACb,mBACE,eAAe,UAAU,uBAAuB,eAAe;AAAA,MAGhE;AAAA,SAAC,OACA,gBAAAA,MAAC,SAAI,WAAU,gDACb;AAAA,0BAAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,eAAa;AAAA,cACb,eAAW;AAAA,cACZ;AAAA;AAAA,gBACG;AAAA;AAAA;AAAA,UACJ;AAAA,UACA,gBAAAD,KAAC,UAAK,WAAU,6CAA6C,iBAAM;AAAA,WACrE,IACE;AAAA,QAEH,WACC,gBAAAA,KAAC,SAAI,WAAU,oDACZ,mBAAS,WAAW,GAAG,SAAS,OAAO,IAAI,SAAS,KAAK,IAC5D,IACE;AAAA,QAEH,wBAAwB,iBACvB,gBAAAA,KAAC,sBAAmB,YAAY,gBAAgB,MAAM,kBAAkB,IACtE;AAAA,QAEH;AAAA,QAEA,gBAAgB,WAAW,WAC1B,gBAAAA,KAAC,SAAI,WAAU,wBAAuB,MAAK,SACxC,wBACH,IACE;AAAA;AAAA;AAAA,EACN;AAEJ;","names":["jsx","jsxs","jsx","jsxs"]}
package/dist/default.css CHANGED
@@ -370,6 +370,10 @@
370
370
  color: var(--lax-color-error);
371
371
  }
372
372
 
373
+ .lax-tool-card__status-dot[data-status='cancelled'] {
374
+ color: var(--lax-muted);
375
+ }
376
+
373
377
  @keyframes lax-pulse {
374
378
  0%,
375
379
  100% {
@@ -1640,6 +1644,18 @@
1640
1644
  font-weight: 500;
1641
1645
  }
1642
1646
 
1647
+ /* D43 P-UI-1:用户取消 / hook_stopped — 非红条 alert */
1648
+ .lax-error-card--interrupt .lax-error-card__message {
1649
+ color: var(--lax-muted);
1650
+ font-weight: 500;
1651
+ }
1652
+
1653
+ .lax-error-card--interrupt .lax-error-card__type {
1654
+ color: var(--lax-muted);
1655
+ font-size: 0.8125rem;
1656
+ opacity: 0.85;
1657
+ }
1658
+
1643
1659
  /* ============================================================================
1644
1660
  未知卡片
1645
1661
  ============================================================================ */
package/dist/index.d.ts CHANGED
@@ -1,18 +1,18 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as react from 'react';
3
3
  import { ReactNode, PointerEventHandler } from 'react';
4
- import { W as WorkflowAuthoritySnapshot, u as Source, L as LangchainAgentEvent, N as NodeRegistry, z as TierOverrides, I as InteractionBus, M as MarkdownRenderer, a as AskDisplaySnapshot, s as SessionTree, H as WorkflowDisplayProjection, G as WorkflowContainerTreeState, Q as WorkflowSessionState, F as WorkflowContainerRuntimeNode, v as SourceEventContext, J as WorkflowDisplayProjectionStatus, T as Task, x as TaskPhase, o as SessionStatus, R as ReducerError, B as WorkflowAuthorityStatus, r as SessionStoreState, t as SessionTreeSnapshot, E as EventTier } from './multi-session-4GMo1sLl.js';
5
- export { A as AskCoalescedBlock, b as AskDisplaySnapshotMetadata, c as AskSnapshotProjectionStatus, C as CommonFields, D as DEFAULT_EVENT_TIERS, d as EventType, e as InteractionBusHandlers, f as MarkdownRendererProps, g as MultiAgentSession, h as MultiAgentSessionProps, i as MultiSessionSourceConfig, j as MultiSessionStore, k as MultiSessionStoreOptions, l as MultiSessionStoreState, m as NodeWidget, n as NodeWidgetProps, P as PermissionResolvePayload, S as SessionSlice, p as SessionStore, q as SessionStoreOptions, w as SourceHandler, y as TaskStatus, K as WorkflowProgressState, O as WorkflowScopeFrame, U as WorkflowStageProgress, V as WorkflowTerminalKind, X as createActiveSessionBridge, Y as createEmptyTree, Z as createEmptyWorkflowSessionState, _ as createInteractionBus, $ as createMultiSessionStore, a0 as createSessionStore, a1 as getNoopInteractionBus, a2 as useActiveSession, a3 as useSessionIds } from './multi-session-4GMo1sLl.js';
6
- import { T as ToolDisplayRegistry, P as PermissionUiMode, b as DisplayMode, c as ProjectionContext, R as RenderableEntry, C as CanonicalNodeRef } from './sessionViewOptions-EIBugOkf.js';
7
- export { a as CollapsedExplorePayload, D as DEFAULT_SESSION_VIEW_OPTIONS, S as SessionViewOptions, d as ToolUseSnapshot, e as buildProjectionContext, f as buildProjectionViewContext, g as createDefaultToolRegistry, h as createProjectionContext, r as resolveEffectiveToolBodyMode, s as shouldApplyGrouping, i as shouldShowExploreDetail } from './sessionViewOptions-EIBugOkf.js';
8
- import { a as ToolBodyMode } from './types-DAkw2VOv.js';
9
- export { T as ToolBodyComponent, b as ToolDisplayProps } from './types-DAkw2VOv.js';
4
+ import { W as WorkflowAuthoritySnapshot, u as Source, L as LangchainAgentEvent, N as NodeRegistry, z as TierOverrides, I as InteractionBus, M as MarkdownRenderer, a as AskDisplaySnapshot, s as SessionTree, H as WorkflowDisplayProjection, G as WorkflowContainerTreeState, Q as WorkflowSessionState, F as WorkflowContainerRuntimeNode, v as SourceEventContext, J as WorkflowDisplayProjectionStatus, T as Task, x as TaskPhase, o as SessionStatus, R as ReducerError, B as WorkflowAuthorityStatus, r as SessionStoreState, t as SessionTreeSnapshot, E as EventTier } from './multi-session-DhTXvNpi.js';
5
+ export { A as AskCoalescedBlock, b as AskDisplaySnapshotMetadata, c as AskSnapshotProjectionStatus, C as CommonFields, D as DEFAULT_EVENT_TIERS, d as EventType, e as InteractionBusHandlers, f as MarkdownRendererProps, g as MultiAgentSession, h as MultiAgentSessionProps, i as MultiSessionSourceConfig, j as MultiSessionStore, k as MultiSessionStoreOptions, l as MultiSessionStoreState, m as NodeWidget, n as NodeWidgetProps, P as PermissionResolvePayload, S as SessionSlice, p as SessionStore, q as SessionStoreOptions, w as SourceHandler, y as TaskStatus, K as WorkflowProgressState, O as WorkflowScopeFrame, U as WorkflowStageProgress, V as WorkflowTerminalKind, X as createActiveSessionBridge, Y as createEmptyTree, Z as createEmptyWorkflowSessionState, _ as createInteractionBus, $ as createMultiSessionStore, a0 as createSessionStore, a1 as getNoopInteractionBus, a2 as useActiveSession, a3 as useSessionIds } from './multi-session-DhTXvNpi.js';
6
+ import { T as ToolDisplayRegistry, P as PermissionUiMode, b as DisplayMode, c as ProjectionContext, R as RenderableEntry, C as CanonicalNodeRef } from './sessionViewOptions-DeTrGjRM.js';
7
+ export { a as CollapsedExplorePayload, D as DEFAULT_SESSION_VIEW_OPTIONS, S as SessionViewOptions, d as ToolUseSnapshot, e as buildProjectionContext, f as buildProjectionViewContext, g as createDefaultToolRegistry, h as createProjectionContext, r as resolveEffectiveToolBodyMode, s as shouldApplyGrouping, i as shouldShowExploreDetail } from './sessionViewOptions-DeTrGjRM.js';
8
+ import { a as ToolBodyMode } from './types-SVtInovH.js';
9
+ export { T as ToolBodyComponent, b as ToolDisplayProps } from './types-SVtInovH.js';
10
10
  import { StoreApi } from 'zustand/vanilla';
11
11
  export { DEFAULT_ESTIMATE_SIZE, DEFAULT_VIRTUALIZE_THRESHOLD, SessionTimeline, SessionTimelineProps, VirtualTimeline, VirtualTimelineProps } from './virtual.js';
12
- export { A as AgentToolBody, a as AskUserQuestionToolBody, B as BashToolBody, D as DefaultToolBody, E as EditToolBody, G as GlobToolBody, b as GrepToolBody, R as ReadToolBody, S as SkillToolBody, W as WebFetchToolBody, c as WebSearchToolBody, d as WriteToolBody, f as formatToolTitle, r as resolveToolBody } from './AskUserQuestionToolBody-J8MqSUEs.js';
13
- import { S as SessionNode, a as SessionNodeKind } from './nodes-7_0rCAc4.js';
14
- export { E as ErrorNode, N as NodeDetail, P as PermissionNode, R as ReasoningNode, b as StepDetail, c as StepNode, d as SubAgentNode, T as TextNode, h as ToolCallNode, U as UnknownNode } from './nodes-7_0rCAc4.js';
15
- export { B as BodyBlock, a as BodyBlockList, D as DiffView, M as MAX_PREVIEW_LINES, b as MarkdownBlock, T as TruncatedContent, c as buildBashBodyBlocks, d as displayPath, f as formatDiffFromStrings, e as formatPatternTitle, g as formatSearchResultBody, h as formatTimeoutFooter, p as parseDiffText, t as truncateCommand } from './MarkdownBlock-DeICJUtu.js';
12
+ export { A as AgentToolBody, a as AskUserQuestionToolBody, B as BashToolBody, D as DefaultToolBody, E as EditToolBody, G as GlobToolBody, b as GrepToolBody, R as ReadToolBody, S as SkillToolBody, W as WebFetchToolBody, c as WebSearchToolBody, d as WriteToolBody, f as formatToolTitle, r as resolveToolBody } from './AskUserQuestionToolBody-C6J742a2.js';
13
+ import { S as SessionNode, a as SessionNodeKind } from './nodes-MpVB9C5d.js';
14
+ export { E as ErrorNode, N as NodeDetail, P as PermissionNode, R as ReasoningNode, b as StepDetail, c as StepNode, d as SubAgentNode, T as TextNode, h as ToolCallNode, U as UnknownNode } from './nodes-MpVB9C5d.js';
15
+ export { B as BodyBlock, a as BodyBlockList, D as DiffView, M as MAX_PREVIEW_LINES, b as MarkdownBlock, T as TruncatedContent, c as buildBashBodyBlocks, d as displayPath, f as formatDiffFromStrings, e as formatPatternTitle, g as formatSearchResultBody, h as formatTimeoutFooter, p as parseDiffText, t as truncateCommand } from './MarkdownBlock-B_wNhCB4.js';
16
16
 
17
17
  /** Workflow 大规模编排 UI 缩放选项(P1–P4 · D40 O1–O4 · D41 P-UX) */
18
18
  type DeferEvictionUntil = 'immediate' | 'run-idle' | 'host-reset';
@@ -1185,6 +1185,7 @@ declare function useSessionMeta(): {
1185
1185
  lastEventId: string | null;
1186
1186
  displayTruncated?: boolean;
1187
1187
  displayTruncatedDropped?: number;
1188
+ taskNotificationClosedIds?: Record<string, true>;
1188
1189
  };
1189
1190
  /** D38 P4:AgentSession authority 快照(无绑定时为 null) */
1190
1191
  declare function useAgentAuthority(): WorkflowAuthoritySnapshot | null;
@@ -1244,7 +1245,7 @@ declare function isAuthorityTerminal(state: WorkflowSessionState): boolean;
1244
1245
  /** 全局 workflow spinner:authority 非 terminal 时保持(含 projection 已 done 的 T2)。 */
1245
1246
  declare function shouldShowGlobalSpinner(state: WorkflowSessionState): boolean;
1246
1247
  interface WorkflowBannerDescriptor {
1247
- kind: 'none' | 'authority_error' | 'partial_success' | 'forced_closeout' | 'projection_degraded' | 'loop_display_truncated' | 'snapshot_unavailable' | 'awaiting_authority' | 'sync_failed';
1248
+ kind: 'none' | 'authority_error' | 'canceled' | 'partial_success' | 'forced_closeout' | 'projection_degraded' | 'loop_display_truncated' | 'snapshot_unavailable' | 'awaiting_authority' | 'sync_failed';
1248
1249
  message: string;
1249
1250
  }
1250
1251
  /** D36 §00.1 Banner 优先级栈(高→低)— 返回最高优先级一条。 */
@@ -1254,17 +1255,38 @@ declare function getDisplayProjectionStatus(state: WorkflowSessionState): Workfl
1254
1255
  declare function applyAuthoritySnapshotToState(state: WorkflowSessionState, snapshot: WorkflowAuthoritySnapshot): WorkflowSessionState;
1255
1256
 
1256
1257
  /**
1257
- * agentAuthoritySelectors.ts — AgentSession authority / spinner 读法(D38 P4)
1258
+ * agentAuthoritySelectors.ts — AgentSession authority / spinner 读法(D38 P4 · D43 P-UI-4)
1258
1259
  *
1259
- * 职责:authority 绑定时 Spinner phase 读 REST 快照,非 SSE reducer status。
1260
+ * 职责:authority 绑定时 Spinner / 输入锁定读 REST 快照,非 SSE reducer status。
1260
1261
  */
1261
1262
 
1262
1263
  declare function shouldShowAgentSpinner(state: SessionStoreState): boolean;
1264
+ /**
1265
+ * D43 P-UI-4:输入区是否应保持锁定(宿主应对齐此读法)。
1266
+ * authority 绑定时:仅 terminal 解锁;Interrupted / finish 不得单独解锁(P-DISP)。
1267
+ */
1268
+ declare function isAgentInputLocked(state: SessionStoreState): boolean;
1263
1269
  type AgentAuthorityMetadata = WorkflowAuthoritySnapshot['metadata'] & {
1264
1270
  projection_status?: 'complete' | 'degraded' | 'running';
1265
1271
  projection_dropped_count?: number;
1266
1272
  };
1267
1273
 
1274
+ /**
1275
+ * 职责:authority=canceled 时兜底收口 SessionTree 僵尸 running 点(D43 P-UI-4),
1276
+ * 并 remap 已写入的取消哨兵 tool-error 为 soft(层 C · D-HOST · CC 双轨)。
1277
+ * 链路位置:SessionStore / WorkflowSessionStore.applyAuthoritySnapshot。
1278
+ * 当前裁剪范围:仅 canceled;不写 authority;不吞真 boom。
1279
+ */
1280
+
1281
+ /**
1282
+ * authority → canceled 时:running tool 收口为 cancelled(soft),
1283
+ * 并对已 failed 且为取消哨兵的节点改写 soft;真 boom 保持 failed。
1284
+ *
1285
+ * running 收口对齐 CC createToolResultStopMessage → canceled 轨;
1286
+ * 已有 Abort 哨兵保持 rejected 轨。
1287
+ */
1288
+ declare function finalizeSessionTreeOnAuthorityCanceled(tree: SessionTree, endedAtMs?: number): SessionTree;
1289
+
1268
1290
  /** 与 backend/langchain_agentx_stream_ui_backend/task_sync/multi_sse_bridge.py 对齐 */
1269
1291
  declare const WORKFLOW_STRUCTURE_EVENT_PREFIXES: readonly string[];
1270
1292
  /** 显式 SSOT(文档/契约测试);新增结构类型应同时满足前缀规则或补入此集合 */
@@ -1373,4 +1395,4 @@ interface ClassifyContext {
1373
1395
  declare function resolveEventTier(eventType: string, overrides?: TierOverrides): EventTier;
1374
1396
  declare function classifyEvent(event: LangchainAgentEvent, ctx: ClassifyContext, overrides?: TierOverrides, eventIndex?: number): ClassifiedEvent;
1375
1397
 
1376
- export { Agent, type AgentAuthorityMetadata, type WorkflowAuthoritySource as AgentAuthoritySource, AgentLoopView, type AgentLoopViewProps, AgentSession, AgentSessionBanners, type AgentSessionBannersProps, type AgentSessionProps, type AgentxMetaFrame, type AgentxSseSourceOptions, type ApplicationKind, ApplicationKindMismatchError, AskDisplaySnapshot, AskUserQuestion, AuthorityPollFatalError, BOUNDED_DEFAULTS, Bash, CanonicalNodeRef, type ClassifiedEvent, type ClassifyContext, CollapseKind, CollapsedExploreNode, type CollapsedExploreNodeProps, DEFAULT_WORKFLOW_SCALE_OPTIONS, DEMO_WORKFLOW_SCALE, type DeferEvictionUntil, type DiagramFitLayout, DiagramZoomShell, type DiagramZoomShellProps, DiagramZoomView, type DiagramZoomViewProps, DisplayMode, EXPECTED_PROTOCOL_VERSION, Edit, ErrorCard, EventTier, type EvictionDeferContext, ExploreCollapseAccumulator, GROUPABLE_TOOL_NAMES, Glob, Grep, GroupedToolUseAccumulator, type HydrateAskSnapshotState, type HydrateLoopSessionAsyncOptions, type HydrateWorkflowSnapshotOptions, InteractionBus, LangchainAgentEvent, MIN_HINT_DISPLAY_MS, MarkdownRenderer, MermaidDiagram, type MermaidDiagramProps, type MermaidInitOptions, type MermaidThemeName, MissingApplicationKindError, type MockAuthoritySourceOptions, NodeRegistry, PROFILE_PRESETS, PermissionCard, PermissionUiMode, PlantUMLBlock, type PlantUMLBlockProps, PlantUMLDiagram, type PlantUMLDiagramProps, type PollingAuthoritySourceOptions, type ProjectedTimelineItem, ProjectionContext, DisplayMode as ProjectionDisplayMode, Read, ReasoningBubble, ReconnectBudget, type ReduceOptions, ReducerError, RenderableEntry, RenderableTimelineProjector, type ReplayOptions, type ReplaySourceOptions, RichMarkdown, type RichMarkdownProps, SCALE_WORKFLOW_SCALE, SHELL_PROGRESS_MIN_ELAPSED_SECONDS, SessionNode, SessionNodeKind, SessionStatus, SessionStoreState, SessionTree, SessionTreeSnapshot, Skill, Source, SourceEventContext, Spinner, type SpinnerProps, type SseReconnectMode, type SseReconnectPolicy, type SseReplayMode, type SseTerminalPolicy, type SseTransportFailureKind, type SseTransportPolicy, type SseTransportPolicyOverride, type SseTransportProfile, 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, WorkflowAuthoritySnapshot, type WorkflowAuthoritySource, WorkflowAuthorityStatus, type WorkflowBannerDescriptor, WorkflowChrome, type WorkflowChromeProps, type WorkflowCoalescedBlock, WorkflowDisplayProjection, WorkflowDisplayProjectionStatus, type WorkflowDisplaySnapshot, type WorkflowDisplaySnapshotMetadata, WorkflowScaleContext, type WorkflowScaleOptions, WorkflowSession, type WorkflowSessionProps, WorkflowSessionState, type WorkflowSessionStore, type WorkflowSessionStoreOptions, type WorkflowSessionStoreState, type WorkflowSnapshotProjectionStatus, WorkflowTaskListFooter, Write, applyAuthoritySnapshotToState, buildCanonicalFromTree, buildRelevantMemoriesCanonical, buildResumeStreamUrl, buildSystemEventCanonical, buildTimelineEntries, classifyEvent, commandAsHint, computeViewportFitTransform, configureMermaid, configurePlantumlServer, createAgentxSseSource, createControllableAuthoritySource, createDefaultRegistry, createDoneAuthoritySource, createMockAuthoritySource, createMockSource, createPollingAuthoritySource, createReplaySource, createRunningAuthoritySource, createWorkflowSessionStore, deriveLoopSessionIdFromAgentEvent, entryKey, filterAgentLoopReplayEvents, finalizeWorkflowDisplayOnStreamEnded, fixDiagramSvg, formatAgentTitle, formatExploreSummaryText, formatHookFinishedSummary, formatShellProgressSuffix, formatTaskFooterLabel, getChildIds, getDisplayProjectionStatus, getMainStageIds, hydrateAskFromSnapshot, hydrateWorkflowFromSnapshot, isAgentLoopReplayEventType, isAtOrBeforeProjectionCursor, isAuthorityTerminal, isAuthorityTerminalStatus, isFatalAuthorityPollStatus, isGitOperationCommand, isGroupableToolName, isMcpToolName, isSseStreamTerminalEvent, isWorkflowStructureEventType, iterMountCandidates, partitionWorkflowStages, projectCanonical, projectTimeline, reduceAgentLoopEvent, reduceEvents, reduceTree, reduceWorkflowEvents, reduceWorkflowSession, replayEvents, replayTree, resolveEventTier, resolveResponseId, resolveShellProgressFromPayload, resolveSseTransportPolicy, resolveWorkflowBanner, resolveWorkflowScale, sessionTreeSnapshotToTree, shouldDeferEviction, shouldShowAgentSpinner, shouldShowGlobalSpinner, shouldShowTaskListFooter, streamChunk, useAgentAuthority, useAgentAuthoritySubscribeFailed, useChildren, useInteractionBus, useInternalErrors, useMinDisplayTime, useNode, useNodeTyped, useProjectedTimeline, useReplayTree, useSessionMeta, useSessionStatus, useTimeline, useWorkflowSessionStatus, useWorkflowSessionStoreApi };
1398
+ export { Agent, type AgentAuthorityMetadata, type WorkflowAuthoritySource as AgentAuthoritySource, AgentLoopView, type AgentLoopViewProps, AgentSession, AgentSessionBanners, type AgentSessionBannersProps, type AgentSessionProps, type AgentxMetaFrame, type AgentxSseSourceOptions, type ApplicationKind, ApplicationKindMismatchError, AskDisplaySnapshot, AskUserQuestion, AuthorityPollFatalError, BOUNDED_DEFAULTS, Bash, CanonicalNodeRef, type ClassifiedEvent, type ClassifyContext, CollapseKind, CollapsedExploreNode, type CollapsedExploreNodeProps, DEFAULT_WORKFLOW_SCALE_OPTIONS, DEMO_WORKFLOW_SCALE, type DeferEvictionUntil, type DiagramFitLayout, DiagramZoomShell, type DiagramZoomShellProps, DiagramZoomView, type DiagramZoomViewProps, DisplayMode, EXPECTED_PROTOCOL_VERSION, Edit, ErrorCard, EventTier, type EvictionDeferContext, ExploreCollapseAccumulator, GROUPABLE_TOOL_NAMES, Glob, Grep, GroupedToolUseAccumulator, type HydrateAskSnapshotState, type HydrateLoopSessionAsyncOptions, type HydrateWorkflowSnapshotOptions, InteractionBus, LangchainAgentEvent, MIN_HINT_DISPLAY_MS, MarkdownRenderer, MermaidDiagram, type MermaidDiagramProps, type MermaidInitOptions, type MermaidThemeName, MissingApplicationKindError, type MockAuthoritySourceOptions, NodeRegistry, PROFILE_PRESETS, PermissionCard, PermissionUiMode, PlantUMLBlock, type PlantUMLBlockProps, PlantUMLDiagram, type PlantUMLDiagramProps, type PollingAuthoritySourceOptions, type ProjectedTimelineItem, ProjectionContext, DisplayMode as ProjectionDisplayMode, Read, ReasoningBubble, ReconnectBudget, type ReduceOptions, ReducerError, RenderableEntry, RenderableTimelineProjector, type ReplayOptions, type ReplaySourceOptions, RichMarkdown, type RichMarkdownProps, SCALE_WORKFLOW_SCALE, SHELL_PROGRESS_MIN_ELAPSED_SECONDS, SessionNode, SessionNodeKind, SessionStatus, SessionStoreState, SessionTree, SessionTreeSnapshot, Skill, Source, SourceEventContext, Spinner, type SpinnerProps, type SseReconnectMode, type SseReconnectPolicy, type SseReplayMode, type SseTerminalPolicy, type SseTransportFailureKind, type SseTransportPolicy, type SseTransportPolicyOverride, type SseTransportProfile, 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, WorkflowAuthoritySnapshot, type WorkflowAuthoritySource, WorkflowAuthorityStatus, type WorkflowBannerDescriptor, WorkflowChrome, type WorkflowChromeProps, type WorkflowCoalescedBlock, WorkflowDisplayProjection, WorkflowDisplayProjectionStatus, type WorkflowDisplaySnapshot, type WorkflowDisplaySnapshotMetadata, WorkflowScaleContext, type WorkflowScaleOptions, WorkflowSession, type WorkflowSessionProps, WorkflowSessionState, type WorkflowSessionStore, type WorkflowSessionStoreOptions, type WorkflowSessionStoreState, type WorkflowSnapshotProjectionStatus, WorkflowTaskListFooter, Write, applyAuthoritySnapshotToState, buildCanonicalFromTree, buildRelevantMemoriesCanonical, buildResumeStreamUrl, buildSystemEventCanonical, buildTimelineEntries, classifyEvent, commandAsHint, computeViewportFitTransform, configureMermaid, configurePlantumlServer, createAgentxSseSource, createControllableAuthoritySource, createDefaultRegistry, createDoneAuthoritySource, createMockAuthoritySource, createMockSource, createPollingAuthoritySource, createReplaySource, createRunningAuthoritySource, createWorkflowSessionStore, deriveLoopSessionIdFromAgentEvent, entryKey, filterAgentLoopReplayEvents, finalizeSessionTreeOnAuthorityCanceled, finalizeWorkflowDisplayOnStreamEnded, fixDiagramSvg, formatAgentTitle, formatExploreSummaryText, formatHookFinishedSummary, formatShellProgressSuffix, formatTaskFooterLabel, getChildIds, getDisplayProjectionStatus, getMainStageIds, hydrateAskFromSnapshot, hydrateWorkflowFromSnapshot, isAgentInputLocked, isAgentLoopReplayEventType, isAtOrBeforeProjectionCursor, isAuthorityTerminal, isAuthorityTerminalStatus, isFatalAuthorityPollStatus, isGitOperationCommand, isGroupableToolName, isMcpToolName, isSseStreamTerminalEvent, isWorkflowStructureEventType, iterMountCandidates, partitionWorkflowStages, projectCanonical, projectTimeline, reduceAgentLoopEvent, reduceEvents, reduceTree, reduceWorkflowEvents, reduceWorkflowSession, replayEvents, replayTree, resolveEventTier, resolveResponseId, resolveShellProgressFromPayload, resolveSseTransportPolicy, resolveWorkflowBanner, resolveWorkflowScale, sessionTreeSnapshotToTree, shouldDeferEviction, shouldShowAgentSpinner, shouldShowGlobalSpinner, shouldShowTaskListFooter, streamChunk, useAgentAuthority, useAgentAuthoritySubscribeFailed, useChildren, useInteractionBus, useInternalErrors, useMinDisplayTime, useNode, useNodeTyped, useProjectedTimeline, useReplayTree, useSessionMeta, useSessionStatus, useTimeline, useWorkflowSessionStatus, useWorkflowSessionStoreApi };
package/dist/index.js CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  fixDiagramSvg,
24
24
  markEventIdSeen,
25
25
  shouldSkipDuplicateEvent
26
- } from "./chunk-YHCK76OU.js";
26
+ } from "./chunk-7TBPTIAP.js";
27
27
  import {
28
28
  DefaultToolBody,
29
29
  InteractionBusContext,
@@ -32,8 +32,8 @@ import {
32
32
  getNoopInteractionBus,
33
33
  resolveToolBody,
34
34
  useInteractionBus
35
- } from "./chunk-5XELRP3S.js";
36
- import "./chunk-6Z4ZF36Z.js";
35
+ } from "./chunk-OV6UUIA3.js";
36
+ import "./chunk-DP7V33X7.js";
37
37
  import {
38
38
  CollapseKind,
39
39
  CollapsedExploreNode,
@@ -79,6 +79,7 @@ import {
79
79
  getChildIds,
80
80
  getDisplayProjectionStatus,
81
81
  getMainStageIds,
82
+ isAgentInputLocked,
82
83
  isAuthorityTerminal,
83
84
  isAuthorityTerminalStatus,
84
85
  isGitOperationCommand,
@@ -119,7 +120,7 @@ import {
119
120
  useSessionStatus,
120
121
  useSessionViewOptions,
121
122
  useTimeline
122
- } from "./chunk-O5GERXTY.js";
123
+ } from "./chunk-EFJMU4WW.js";
123
124
  import {
124
125
  AGENT_PROGRESS_GUTTER,
125
126
  AGENT_PROGRESS_INDENT,
@@ -146,10 +147,14 @@ import {
146
147
  WebSearchToolBody,
147
148
  Write,
148
149
  WriteToolBody,
150
+ classifyToolResultSoftKind,
149
151
  createDefaultToolRegistry,
150
152
  formatAgentTitle,
151
- formatExploreSummaryText
152
- } from "./chunk-GYFC2DI7.js";
153
+ formatExploreSummaryText,
154
+ isCancelToolResultError,
155
+ isToolResultCancelled,
156
+ resolveToolCancelDisplayText
157
+ } from "./chunk-GLUQUP3A.js";
153
158
  import {
154
159
  BodyBlockList,
155
160
  DiffView,
@@ -165,7 +170,7 @@ import {
165
170
  formatTimeoutFooter,
166
171
  parseDiffText,
167
172
  truncateCommand
168
- } from "./chunk-GBY5DJ7L.js";
173
+ } from "./chunk-4RIOBLGB.js";
169
174
 
170
175
  // src/view/AgentSession.tsx
171
176
  import { useEffect as useEffect3, useMemo, useRef as useRef3 } from "react";
@@ -990,6 +995,140 @@ function trimWorkflowLoopTreesSoft(state, options) {
990
995
  };
991
996
  }
992
997
 
998
+ // src/core/sessionTreeAuthorityFinalize.ts
999
+ function resolvePreservedErrorKind(meta) {
1000
+ if (meta != null && typeof meta === "object" && !Array.isArray(meta)) {
1001
+ const kind = meta.error_kind;
1002
+ if (kind === "aborted" || kind === "user_cancelled" || kind === "cancelled") {
1003
+ return kind;
1004
+ }
1005
+ }
1006
+ return "aborted";
1007
+ }
1008
+ function resolveSoftKindForRemap(result, fallback) {
1009
+ return classifyToolResultSoftKind(result) ?? fallback;
1010
+ }
1011
+ function finalizeSessionTreeOnAuthorityCanceled(tree, endedAtMs = Date.now()) {
1012
+ const byId = { ...tree.byId };
1013
+ let changed = false;
1014
+ for (const [id, node] of Object.entries(byId)) {
1015
+ if (!node) continue;
1016
+ if ((node.kind === "text" || node.kind === "reasoning") && node.status === "streaming") {
1017
+ byId[id] = { ...node, status: "done" };
1018
+ changed = true;
1019
+ continue;
1020
+ }
1021
+ if (node.kind === "error") {
1022
+ if (isCancelToolResultError(
1023
+ { message: node.message, type: node.errorType ?? void 0 },
1024
+ { error_type: node.errorType }
1025
+ ) && node.variant !== "interrupt") {
1026
+ byId[id] = {
1027
+ ...node,
1028
+ message: resolveToolCancelDisplayText("rejected"),
1029
+ errorType: "cancelled",
1030
+ variant: "interrupt"
1031
+ };
1032
+ changed = true;
1033
+ }
1034
+ continue;
1035
+ }
1036
+ if (node.kind !== "tool_call") continue;
1037
+ let next = node;
1038
+ const wasCancelResult = isToolResultCancelled(next.result);
1039
+ if (node.status === "running") {
1040
+ const softKind = "canceled";
1041
+ const soft = resolveToolCancelDisplayText(softKind);
1042
+ const prevMeta = typeof next.result?.meta === "object" && next.result.meta != null && !Array.isArray(next.result.meta) ? next.result.meta : {};
1043
+ next = {
1044
+ ...next,
1045
+ status: "cancelled",
1046
+ endedAt: node.endedAt ?? endedAtMs,
1047
+ result: {
1048
+ schema_version: next.result?.schema_version ?? "2",
1049
+ status: "error",
1050
+ summary: soft,
1051
+ payload: next.result?.payload ?? soft,
1052
+ blocks: next.result?.blocks ?? [],
1053
+ artifacts: next.result?.artifacts ?? [],
1054
+ hints: next.result?.hints ?? null,
1055
+ meta: {
1056
+ ...prevMeta,
1057
+ terminal_state: "cancelled",
1058
+ error_kind: "user_cancelled",
1059
+ cancel_ui_kind: softKind
1060
+ },
1061
+ error: { message: soft, type: "cancelled" },
1062
+ truncated: next.result?.truncated ?? false,
1063
+ overflow_file: next.result?.overflow_file ?? null
1064
+ }
1065
+ };
1066
+ changed = true;
1067
+ } else if (wasCancelResult && next.status !== "cancelled") {
1068
+ const softKind = resolveSoftKindForRemap(next.result, "rejected");
1069
+ const soft = resolveToolCancelDisplayText(softKind);
1070
+ const prevMeta = typeof next.result?.meta === "object" && next.result.meta != null && !Array.isArray(next.result.meta) ? next.result.meta : {};
1071
+ const errorKind = resolvePreservedErrorKind(prevMeta);
1072
+ next = {
1073
+ ...next,
1074
+ status: "cancelled",
1075
+ result: {
1076
+ ...next.result,
1077
+ summary: soft,
1078
+ error: { message: soft, type: "cancelled" },
1079
+ meta: {
1080
+ ...prevMeta,
1081
+ terminal_state: "cancelled",
1082
+ error_kind: errorKind,
1083
+ cancel_ui_kind: softKind ?? (errorKind === "user_cancelled" ? "canceled" : "rejected")
1084
+ }
1085
+ }
1086
+ };
1087
+ changed = true;
1088
+ }
1089
+ if (next.subagentSessions) {
1090
+ const sessions = { ...next.subagentSessions };
1091
+ let sessChanged = false;
1092
+ for (const [agentId, marker] of Object.entries(sessions)) {
1093
+ if (marker.status === "running") {
1094
+ sessions[agentId] = {
1095
+ ...marker,
1096
+ status: "done",
1097
+ endedAt: endedAtMs
1098
+ };
1099
+ sessChanged = true;
1100
+ }
1101
+ }
1102
+ if (sessChanged) {
1103
+ next = { ...next, subagentSessions: sessions };
1104
+ changed = true;
1105
+ }
1106
+ }
1107
+ if (next.subagentProgress?.some((e) => e.status === "running")) {
1108
+ next = {
1109
+ ...next,
1110
+ subagentProgress: next.subagentProgress.map(
1111
+ (entry) => entry.status === "running" ? { ...entry, status: "error" } : entry
1112
+ )
1113
+ };
1114
+ changed = true;
1115
+ }
1116
+ if (next !== node) {
1117
+ byId[id] = next;
1118
+ }
1119
+ }
1120
+ if (!changed) {
1121
+ return tree;
1122
+ }
1123
+ return {
1124
+ ...tree,
1125
+ byId,
1126
+ activeRoundId: null,
1127
+ // 展示树终态;不升格 / 不写 REST authority(P-AUTH)
1128
+ status: tree.status === "done" || tree.status === "done_with_warning" ? tree.status : "error"
1129
+ };
1130
+ }
1131
+
993
1132
  // src/core/store.ts
994
1133
  function safeReduce(tree, event, eventIndex, options) {
995
1134
  try {
@@ -1059,7 +1198,12 @@ function createSessionStore(initialTree = createEmptyTree(), storeOptions) {
1059
1198
  set({ tree, eventCount });
1060
1199
  },
1061
1200
  applyAuthoritySnapshot(snapshot) {
1062
- set({ authority: snapshot });
1201
+ const current = get();
1202
+ let tree = current.tree;
1203
+ if (snapshot.status === "canceled") {
1204
+ tree = finalizeSessionTreeOnAuthorityCanceled(tree);
1205
+ }
1206
+ set({ authority: snapshot, tree });
1063
1207
  },
1064
1208
  setAuthoritySubscribeFailed(failed) {
1065
1209
  set({ authoritySubscribeFailed: failed });
@@ -3383,6 +3527,38 @@ function safeReduceWorkflow(state, event, eventIndex, options) {
3383
3527
  };
3384
3528
  }
3385
3529
  }
3530
+ function finalizeWorkflowContainersOnAuthorityCanceled(state) {
3531
+ const containersById = {
3532
+ ...state.containerTree.containersById
3533
+ };
3534
+ let changed = false;
3535
+ for (const [id, node] of Object.entries(containersById)) {
3536
+ if (node.status !== "running" && node.status !== "pending") {
3537
+ continue;
3538
+ }
3539
+ const display = node.display ? { ...node.display, metrics_running: 0 } : node.display;
3540
+ containersById[id] = {
3541
+ ...node,
3542
+ status: "failed",
3543
+ is_open: false,
3544
+ display
3545
+ };
3546
+ changed = true;
3547
+ }
3548
+ if (!changed) {
3549
+ return state;
3550
+ }
3551
+ return {
3552
+ ...state,
3553
+ containerTree: {
3554
+ ...state.containerTree,
3555
+ containersById,
3556
+ activeContainerIds: state.containerTree.activeContainerIds.filter(
3557
+ (id) => containersById[id]?.is_open
3558
+ )
3559
+ }
3560
+ };
3561
+ }
3386
3562
  function finalizeWorkflowSessionOnStreamError(state, message, eventIndex, stack) {
3387
3563
  const containersById = {
3388
3564
  ...state.containerTree.containersById
@@ -3522,17 +3698,33 @@ function createWorkflowSessionStore(initialState = createEmptyWorkflowSessionSta
3522
3698
  }));
3523
3699
  },
3524
3700
  applyAuthoritySnapshot(snapshot) {
3525
- set((current) => ({
3526
- state: {
3527
- ...current.state,
3528
- authority: snapshot,
3529
- display: {
3530
- ...current.state.display,
3531
- awaitingAuthority: false,
3532
- authoritySyncFailed: false
3701
+ set((current) => {
3702
+ let nextState = current.state;
3703
+ if (snapshot.status === "canceled") {
3704
+ nextState = finalizeWorkflowContainersOnAuthorityCanceled(nextState);
3705
+ const nextLoops = {
3706
+ ...nextState.loopTreesBySessionId
3707
+ };
3708
+ for (const [loopSessionId, loopTree] of Object.entries(nextLoops)) {
3709
+ nextLoops[loopSessionId] = finalizeSessionTreeOnAuthorityCanceled(loopTree);
3533
3710
  }
3711
+ nextState = {
3712
+ ...nextState,
3713
+ loopTreesBySessionId: nextLoops
3714
+ };
3534
3715
  }
3535
- }));
3716
+ return {
3717
+ state: {
3718
+ ...nextState,
3719
+ authority: snapshot,
3720
+ display: {
3721
+ ...nextState.display,
3722
+ awaitingAuthority: false,
3723
+ authoritySyncFailed: false
3724
+ }
3725
+ }
3726
+ };
3727
+ });
3536
3728
  },
3537
3729
  setAwaitingAuthority(value) {
3538
3730
  set((current) => ({
@@ -5392,8 +5584,17 @@ function WorkflowSessionBanners({ state }) {
5392
5584
  if (banner.kind === "none" && display.projectionStatus !== "error" && display.projectionStatus !== "done_with_warning" && state.internalErrors.length === 0) {
5393
5585
  return null;
5394
5586
  }
5395
- const showTransportError = (display.projectionStatus === "error" || state.internalErrors.length > 0) && banner.kind !== "projection_degraded" && banner.kind !== "authority_error";
5587
+ const showTransportError = (display.projectionStatus === "error" || state.internalErrors.length > 0) && banner.kind !== "projection_degraded" && banner.kind !== "authority_error" && banner.kind !== "canceled";
5396
5588
  return /* @__PURE__ */ jsxs14(Fragment4, { children: [
5589
+ banner.kind === "canceled" ? /* @__PURE__ */ jsx17(
5590
+ "div",
5591
+ {
5592
+ className: "lax-workflow-banner lax-workflow-banner--canceled",
5593
+ "data-testid": "lax-workflow-canceled-banner",
5594
+ role: "status",
5595
+ children: banner.message
5596
+ }
5597
+ ) : null,
5397
5598
  banner.kind === "authority_error" ? /* @__PURE__ */ jsx17(
5398
5599
  "div",
5399
5600
  {
@@ -6138,6 +6339,7 @@ export {
6138
6339
  displayPath,
6139
6340
  entryKey,
6140
6341
  filterAgentLoopReplayEvents,
6342
+ finalizeSessionTreeOnAuthorityCanceled,
6141
6343
  finalizeWorkflowDisplayOnStreamEnded,
6142
6344
  fixDiagramSvg,
6143
6345
  formatAgentTitle,
@@ -6156,6 +6358,7 @@ export {
6156
6358
  getNoopInteractionBus,
6157
6359
  hydrateAskFromSnapshot,
6158
6360
  hydrateWorkflowFromSnapshot,
6361
+ isAgentInputLocked,
6159
6362
  isAgentLoopReplayEventType,
6160
6363
  isAtOrBeforeProjectionCursor,
6161
6364
  isAuthorityTerminal,