langchain_agentx_stream_ui 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +14 -13
- package/dist/index.js +34 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/view/AgentSession.tsx","../src/core/store.ts","../src/transport/applicationKind.ts","../src/transport/createAgentxSseSource.ts","../src/view/agentLoop/ScopedSessionStore.tsx","../src/view/agentLoop/AgentLoopView.tsx","../src/view/workflow/WorkflowSession.tsx","../src/core/context/WorkflowSessionContext.tsx","../src/core/context/WorkflowLoopReplayContext.tsx","../src/core/context/WorkflowScaleContext.tsx","../src/view/workflow/workflowScaleOptions.ts","../src/core/workflowSessionStore.ts","../src/types/workflowContainer.ts","../src/types/workflowSession.ts","../src/core/workflow/workflowLoopTreeUtils.ts","../src/types/workflowDisplay.ts","../src/core/workflow/workflowContainerProjector.ts","../src/core/workflow/loopSessionUtils.ts","../src/core/workflowStructureEvents.ts","../src/core/workflowReducer.ts","../src/core/workflow/stageDoneSummary.ts","../src/core/workflow/workflowLoopEviction.ts","../src/view/workflow/WorkflowChrome.tsx","../src/view/workflow/WorkflowAggregateContainer.tsx","../src/view/workflow/WorkflowContainerLine.tsx","../src/view/workflow/WorkflowExpandTrigger.tsx","../src/view/workflow/workflowContainerLineUtils.ts","../src/view/workflow/WorkflowParallelGroup.tsx","../src/core/workflow/workflowParallelGroupMetrics.ts","../src/view/workflow/WorkflowStageContainer.tsx","../src/core/workflow/loopTreeUtils.ts","../src/view/workflow/workflowStageDoneBody.tsx","../src/view/workflow/workflowStageListUtils.ts","../src/view/workflow/WorkflowRootContainer.tsx","../src/view/workflow/WorkflowRouteContainer.tsx","../src/view/workflow/WorkflowSubworkflowContainer.tsx","../src/view/workflow/WorkflowTaskListFooter.tsx","../src/view/workflow/workflowTaskListMerge.ts","../src/view/tools/groupParallelTools.ts","../src/view/nodes/SubAgentNode.tsx","../src/transport/createReplaySource.ts"],"sourcesContent":["/**\n * 职责:顶层容器,连接 Source → store → Timeline 渲染。\n * 链路位置:业务页面 <AgentSession source={...} /> 唯一入口。\n * 当前裁剪范围:单会话;initialEvents 支持 EventBuffer 快照续流(M3);reducer/transport 异常自吞。\n */\nimport { useEffect, useMemo, useRef, type ReactNode } from 'react';\n\nimport { createSessionStore } from '../core/store';\nimport { replayEvents } from '../core/replay';\nimport {\n SessionStoreContext,\n NodeRegistryContext,\n ToolDisplayOptionsContext,\n SessionViewOptionsContext,\n} from '../core/context/SessionContext';\nimport type { Source } from '../transport/types';\nimport { SseTransportTerminalError } from '../transport/createAgentxSseSource';\nimport type { LangchainAgentEvent, TierOverrides } from '../types/events';\nimport type { ReducerError } from '../types/tree';\nimport { createDefaultRegistry } from './defaultRegistry';\nimport type { NodeRegistry } from './NodeRegistry';\nimport { AgentLoopView } from './agentLoop/AgentLoopView';\nimport { InteractionBusContext } from '../core/context/InteractionContext';\nimport type { InteractionBus } from '../core/interaction/InteractionBus';\nimport { getNoopInteractionBus } from '../core/interaction/InteractionBus';\nimport { useInternalErrors, useSessionStatus } from '../core/hooks';\nimport type { MarkdownRenderer } from '../core/context/MarkdownRendererContext';\nimport { MarkdownRendererContext } from '../core/context/MarkdownRendererContext';\nimport {\n createDefaultToolRegistry,\n type ToolDisplayRegistry,\n} from './tools/registry';\nimport type { ToolBodyMode } from './tools/types';\nimport type { PermissionUiMode, DisplayMode } from './sessionViewOptions';\nimport { DEFAULT_SESSION_VIEW_OPTIONS } from './sessionViewOptions';\n\nexport interface AgentSessionProps {\n source: Source;\n /** 挂载时先 replay 预灌树(含 EventBuffer ingest 快照),再接 source 续流 */\n initialEvents?: LangchainAgentEvent[];\n registry?: NodeRegistry;\n tierOverrides?: TierOverrides;\n onError?: (error: Error) => void;\n autoReconnect?: boolean;\n debug?: boolean;\n /** 为 true 且主舞台节点数超过阈值时使用 VirtualTimeline(V2-E) */\n virtualized?: boolean;\n virtualizeThreshold?: number;\n /** 权限回写薄层;PermissionCard 触发 onPermissionResolve(V2-D) */\n interactionBus?: InteractionBus;\n /** 按工具名注册 Body 组件(V3-T0) */\n toolDisplayRegistry?: ToolDisplayRegistry;\n /** 工具正文默认 preview / full(V3-T0) */\n defaultBodyMode?: ToolBodyMode;\n /** @deprecated Phase 4 起由 projection GroupedToolUseAccumulator 自动分组;保留 prop 兼容 */\n groupParallelTools?: boolean;\n /** 权限 UI:standalone | inline | both(V3-T4.6);后台 bypass 时通常无 pending */\n permissionUiMode?: PermissionUiMode;\n /** 富 Markdown 渲染(simple demo 可注入 react-markdown + mermaid) */\n markdownRenderer?: MarkdownRenderer;\n /** 对齐 CLI display mode(normal / brief_only / transcript) */\n displayMode?: DisplayMode;\n /** 对齐 CC verbose;为 true 时跳过分组并展开 explore detail */\n verbose?: boolean;\n exploreFullscreenBash?: boolean;\n memoryDir?: string | null;\n workspaceRoot?: string | null;\n children?: ReactNode;\n}\n\nfunction DebugPanel() {\n const status = useSessionStatus();\n const errors = useInternalErrors();\n if (errors.length === 0) return null;\n return (\n <div className=\"lax-debug-panel\" data-testid=\"lax-debug-panel\">\n <div>status: {status}</div>\n <ul>\n {errors.map((err: ReducerError, i: number) => (\n <li key={`${err.eventIndex}-${i}`}>\n [{err.eventType}] {err.message}\n </li>\n ))}\n </ul>\n </div>\n );\n}\n\nexport function AgentSession({\n source,\n initialEvents,\n registry,\n tierOverrides: _tierOverrides,\n onError,\n autoReconnect: _autoReconnect,\n debug = false,\n virtualized = false,\n virtualizeThreshold,\n interactionBus,\n toolDisplayRegistry,\n defaultBodyMode = 'preview',\n groupParallelTools = false,\n permissionUiMode = 'standalone',\n markdownRenderer,\n displayMode = 'normal',\n verbose = false,\n exploreFullscreenBash = true,\n memoryDir = null,\n workspaceRoot = null,\n children,\n}: AgentSessionProps) {\n const storeRef = useRef<ReturnType<typeof createSessionStore> | null>(null);\n if (storeRef.current === null) {\n const replayOpts = {\n tierOverrides: _tierOverrides,\n collectDebug: debug,\n };\n const initialTree =\n initialEvents && initialEvents.length > 0\n ? replayEvents(initialEvents, replayOpts)\n : undefined;\n storeRef.current = createSessionStore(initialTree, {\n tierOverrides: _tierOverrides,\n debug,\n initialEventCount: initialEvents?.length ?? 0,\n });\n }\n const registryRef = useMemo(() => registry ?? createDefaultRegistry(), [registry]);\n const busRef = useMemo(\n () => interactionBus ?? getNoopInteractionBus(),\n [interactionBus],\n );\n const toolDisplayRef = useMemo(\n () => ({\n registry: toolDisplayRegistry ?? createDefaultToolRegistry(),\n defaultBodyMode,\n }),\n [toolDisplayRegistry, defaultBodyMode],\n );\n const sessionViewRef = useMemo(\n () => ({\n ...DEFAULT_SESSION_VIEW_OPTIONS,\n groupParallelTools,\n permissionUiMode,\n verboseReasoning: debug,\n displayMode,\n verbose,\n exploreFullscreenBash,\n memoryDir,\n workspaceRoot,\n }),\n [\n groupParallelTools,\n permissionUiMode,\n debug,\n displayMode,\n verbose,\n exploreFullscreenBash,\n memoryDir,\n workspaceRoot,\n ],\n );\n\n useEffect(() => {\n const store = storeRef.current!;\n const controller = new AbortController();\n\n void source.start((event, ctx) => {\n store.getState().applyEvent(event, ctx);\n }, controller.signal).catch((err: unknown) => {\n if (err instanceof SseTransportTerminalError) {\n const { tree } = store.getState();\n if (tree.status === 'running' || tree.status === 'connecting') {\n store.setState({ tree: { ...tree, status: 'error' } });\n }\n }\n });\n\n return () => {\n controller.abort();\n };\n }, [source, onError]);\n\n return (\n <SessionStoreContext.Provider value={storeRef.current!}>\n <InteractionBusContext.Provider value={busRef}>\n <NodeRegistryContext.Provider value={registryRef}>\n <MarkdownRendererContext.Provider value={markdownRenderer}>\n <ToolDisplayOptionsContext.Provider value={toolDisplayRef}>\n <SessionViewOptionsContext.Provider value={sessionViewRef}>\n <div className=\"lax-agent-session\" data-testid=\"lax-agent-session\">\n {children ?? (\n <AgentLoopView\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n />\n )}\n {debug ? <DebugPanel /> : null}\n </div>\n </SessionViewOptionsContext.Provider>\n </ToolDisplayOptionsContext.Provider>\n </MarkdownRendererContext.Provider>\n </NodeRegistryContext.Provider>\n </InteractionBusContext.Provider>\n </SessionStoreContext.Provider>\n );\n}\n","import { createStore, type StoreApi } from 'zustand/vanilla';\n\nimport { createEmptyTree, type ReducerError, type SessionTree } from '../types/tree';\nimport type { LangchainAgentEvent, TierOverrides } from '../types/events';\nimport { markEventIdSeen, shouldSkipDuplicateEvent } from './dedupe';\nimport { reduceTree, type ReduceOptions } from './reducer';\nimport type { SourceEventContext } from '../transport/types';\n\nexport interface SessionStoreOptions {\n tierOverrides?: TierOverrides;\n debug?: boolean;\n /** 预灌历史事件数;续流时保证 reducer eventIndex 连续 */\n initialEventCount?: number;\n /** 续传恢复:已见过的 SSE id,避免重叠帧重复建节点 */\n initialSeenEventIds?: Iterable<string>;\n}\n\nexport interface SessionStoreState {\n tree: SessionTree;\n eventCount: number;\n applyEvent: (event: LangchainAgentEvent, ctx?: SourceEventContext) => void;\n applyEvents: (events: LangchainAgentEvent[]) => void;\n reset: () => void;\n markAsError: (error?: Error) => void;\n}\n\nfunction safeReduce(\n tree: SessionTree,\n event: LangchainAgentEvent,\n eventIndex: number,\n options?: ReduceOptions,\n): { tree: SessionTree; error?: ReducerError } {\n try {\n return { tree: reduceTree(tree, event, eventIndex, options) };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n const stack = err instanceof Error ? err.stack : undefined;\n if (import.meta.env?.DEV) {\n console.error('[langchain_agentx_stream_ui] reducer error:', err);\n }\n return {\n tree: {\n ...tree,\n internalErrors: [\n ...tree.internalErrors,\n { eventIndex, eventType: event.event_type, message, stack },\n ],\n },\n };\n }\n}\n\nexport function createSessionStore(\n initialTree: SessionTree = createEmptyTree(),\n storeOptions?: SessionStoreOptions,\n): StoreApi<SessionStoreState> {\n const reduceOpts: ReduceOptions = {\n tierOverrides: storeOptions?.tierOverrides,\n collectDebug: storeOptions?.debug === true,\n };\n const initialEventCount = storeOptions?.initialEventCount ?? 0;\n const seenEventIds = new Set<string>(storeOptions?.initialSeenEventIds);\n return createStore<SessionStoreState>((set, get) => ({\n tree: initialTree,\n eventCount: initialEventCount,\n applyEvent(event, ctx) {\n const sseEventId = ctx?.sseEventId;\n if (shouldSkipDuplicateEvent(seenEventIds, sseEventId)) return;\n\n const { tree, eventCount } = get();\n const { tree: reduced } = safeReduce(tree, event, eventCount, reduceOpts);\n const nextTree: SessionTree =\n sseEventId\n ? {\n ...reduced,\n meta: { ...reduced.meta, lastEventId: sseEventId },\n }\n : reduced;\n markEventIdSeen(seenEventIds, sseEventId);\n set({ tree: nextTree, eventCount: eventCount + 1 });\n },\n applyEvents(events) {\n let { tree, eventCount } = get();\n for (const event of events) {\n const result = safeReduce(tree, event, eventCount, reduceOpts);\n tree = result.tree;\n eventCount += 1;\n }\n set({ tree, eventCount });\n },\n reset() {\n seenEventIds.clear();\n set({ tree: createEmptyTree(), eventCount: 0 });\n },\n markAsError(error?: Error) {\n const { tree } = get();\n set({\n tree: {\n ...tree,\n status: 'error',\n internalErrors: error\n ? [\n ...tree.internalErrors,\n {\n eventIndex: -1,\n eventType: 'sse_connection_failed',\n message: error.message,\n stack: error.stack,\n },\n ]\n : tree.internalErrors,\n },\n });\n },\n }));\n}\n\nexport type SessionStore = StoreApi<SessionStoreState>;\n","/**\n * applicationKind.ts — SSE meta application_kind 契约\n *\n * 职责:\n * 定义双轨 SSE 出口 kind 枚举与 mismatch 错误类型。\n *\n * 链路位置:\n * createAgentxSseSource meta 握手校验。\n *\n * 当前裁剪范围:\n * 仅 agent_session / workflow;无自动推断。\n */\nexport type ApplicationKind = 'agent_session' | 'workflow';\n\nexport class ApplicationKindMismatchError extends Error {\n readonly name = 'ApplicationKindMismatchError';\n readonly expected: ApplicationKind;\n readonly actual: string | undefined;\n\n constructor(expected: ApplicationKind, actual: string | undefined) {\n super(\n `application_kind mismatch: expected ${expected}, got ${actual ?? '(missing)'}`,\n );\n this.expected = expected;\n this.actual = actual;\n }\n}\n\nexport class MissingApplicationKindError extends Error {\n readonly name = 'MissingApplicationKindError';\n\n constructor() {\n super('application_kind missing in SSE meta frame');\n }\n}\n","/**\n * 职责:浏览器 EventSource 封装,解码 meta/agentx 命名帧并校验协议版本。\n * 链路位置:业务页面 createAgentxSseSource({ url }) → AgentSession source prop。\n *\n * 错误分层(对齐 claude-code SSETransport / Messages 管线):\n * - 传输 terminal:握手前/未 finish 断连 → reject(SseTransportTerminalError),不进 Timeline\n * - 传输 benign:finish/error 帧后的 EventSource.onerror → resolve\n * - 业务层:agentx event_type=error → reducer → ErrorNode(唯一用户可见错误文案)\n */\nimport type { LangchainAgentEvent } from '../types/events';\nimport type { Source, SourceHandler, SourceEventContext } from './types';\nimport type { ApplicationKind } from './applicationKind';\nimport {\n ApplicationKindMismatchError,\n MissingApplicationKindError,\n} from './applicationKind';\n\nexport const EXPECTED_PROTOCOL_VERSION = '1';\n\n/** 传输层 terminal 失败(须排查/fix);与 agentx error 帧(业务错误)分离。 */\nexport type SseTransportFailureKind = 'handshake_failed' | 'premature_close';\n\nexport class SseTransportTerminalError extends Error {\n readonly kind: SseTransportFailureKind;\n\n constructor(kind: SseTransportFailureKind, message: string) {\n super(message);\n this.name = 'SseTransportTerminalError';\n this.kind = kind;\n }\n}\n\nexport interface AgentxSseSourceOptions {\n url: string;\n autoReconnect?: boolean;\n reconnectDelayMs?: number;\n /** 每收到 agentx 帧 SSE id 时回调(含续传重叠 id) */\n onLastEventId?: (id: string) => void;\n /** 测试注入:替换全局 EventSource */\n EventSourceImpl?: typeof EventSource;\n /** /chat 与 /workflow 必填:校验 meta.application_kind */\n expectedApplicationKind?: ApplicationKind;\n}\n\nexport interface AgentxMetaFrame {\n protocol_version: string;\n session_id?: string | null;\n started_at?: number;\n application_kind?: ApplicationKind;\n}\n\n/** 传输层 diagnostics;不驱动 UI(对齐 CC logForDiagnostics / warn+drop)。 */\nfunction transportLog(message: string, level: 'warn' | 'error' = 'warn'): void {\n const line = `[langchain_agentx_stream_ui] SSE transport: ${message}`;\n if (level === 'error') {\n console.error(line);\n } else {\n console.warn(line);\n }\n}\n\n/** 手动重连时追加 resume 查询参数(EventSource 无法设 Last-Event-ID 请求头)。 */\nexport function buildResumeStreamUrl(\n baseUrl: string,\n lastEventId: string | null | undefined,\n queryParam = 'last_event_id',\n): string {\n if (!lastEventId) return baseUrl;\n const sep = baseUrl.includes('?') ? '&' : '?';\n return `${baseUrl}${sep}${encodeURIComponent(queryParam)}=${encodeURIComponent(lastEventId)}`;\n}\n\nexport function createAgentxSseSource(options: AgentxSseSourceOptions): Source {\n const {\n url,\n autoReconnect = true,\n reconnectDelayMs = 1000,\n onLastEventId,\n EventSourceImpl = EventSource,\n expectedApplicationKind,\n } = options;\n\n return {\n start(handler: SourceHandler, signal: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n let es: EventSource | null = null;\n let handshakeOk = false;\n let lastEventId: string | null = null;\n let fatal = false;\n /** finish/error 帧后服务端关连接;EventSource.onerror 为预期行为,非 UI 错误。 */\n let streamTerminal = false;\n\n type BufferedDelta = {\n event: LangchainAgentEvent;\n ctx?: SourceEventContext;\n };\n let bufferedDelta: BufferedDelta | null = null;\n let flushTimer: ReturnType<typeof setTimeout> | null = null;\n\n const flushBufferedDelta = (): void => {\n if (flushTimer) {\n clearTimeout(flushTimer);\n flushTimer = null;\n }\n if (!bufferedDelta) return;\n handler(bufferedDelta.event, bufferedDelta.ctx);\n bufferedDelta = null;\n };\n\n const isBufferedDeltaEvent = (event: LangchainAgentEvent): boolean =>\n event.event_type === 'text-delta' || event.event_type === 'reasoning-delta';\n\n const mergeDeltaEvent = (\n prev: LangchainAgentEvent,\n next: LangchainAgentEvent,\n ): LangchainAgentEvent | null => {\n if (prev.event_type !== next.event_type) return null;\n if (prev.step_index !== next.step_index) return null;\n if (prev.tool_name !== next.tool_name) return null;\n if (prev.session_id !== next.session_id) return null;\n\n const prevData = prev.data as { delta?: string; text?: string; content?: string };\n const nextData = next.data as { delta?: string; text?: string; content?: string };\n\n const prevChunk = prevData.delta ?? prevData.text ?? prevData.content ?? '';\n const nextChunk = nextData.delta ?? nextData.text ?? nextData.content ?? '';\n\n return {\n ...next,\n data: {\n ...next.data,\n text: `${prevChunk}${nextChunk}`,\n },\n } as LangchainAgentEvent;\n };\n\n const cleanup = (): void => {\n es?.close();\n es = null;\n };\n\n const finish = (error?: Error): void => {\n flushBufferedDelta();\n cleanup();\n if (error) reject(error);\n else resolve();\n };\n\n const failHandshake = (error: Error): void => {\n fatal = true;\n transportLog(error.message, 'error');\n cleanup();\n finish(error);\n };\n\n const failPrematureClose = (): void => {\n const error = new SseTransportTerminalError(\n 'premature_close',\n 'SSE connection lost before stream finished',\n );\n transportLog(error.message, 'error');\n cleanup();\n finish(error);\n };\n\n const connect = (resumeFromId?: string | null): void => {\n if (signal.aborted || fatal) {\n finish();\n return;\n }\n\n const connectUrl =\n resumeFromId != null && resumeFromId !== ''\n ? buildResumeStreamUrl(url, resumeFromId)\n : url;\n\n es = new EventSourceImpl(connectUrl);\n handshakeOk = false;\n\n es.addEventListener('meta', (event: MessageEvent<string>) => {\n try {\n const meta = JSON.parse(event.data) as AgentxMetaFrame;\n if (meta.protocol_version !== EXPECTED_PROTOCOL_VERSION) {\n failHandshake(\n new Error(`Unsupported protocol_version: ${meta.protocol_version}`),\n );\n return;\n }\n if (expectedApplicationKind) {\n const actual = meta.application_kind;\n if (actual === undefined || actual === null) {\n failHandshake(new MissingApplicationKindError());\n return;\n }\n if (actual !== expectedApplicationKind) {\n failHandshake(\n new ApplicationKindMismatchError(expectedApplicationKind, actual),\n );\n return;\n }\n }\n handshakeOk = true;\n } catch (err) {\n const message =\n err instanceof Error ? err.message : 'Failed to decode meta frame';\n failHandshake(new Error(message));\n }\n });\n\n es.addEventListener('agentx', (event: MessageEvent<string>) => {\n if (!handshakeOk) {\n failHandshake(new Error('Received agentx frame before meta handshake'));\n return;\n }\n try {\n const agentEvent = JSON.parse(event.data) as LangchainAgentEvent;\n const sseEventId = event.lastEventId || undefined;\n if (sseEventId) {\n lastEventId = sseEventId;\n onLastEventId?.(sseEventId);\n }\n\n const ctx = sseEventId ? { sseEventId } : undefined;\n\n if (isBufferedDeltaEvent(agentEvent)) {\n if (bufferedDelta) {\n const merged = mergeDeltaEvent(bufferedDelta.event, agentEvent);\n if (merged) {\n bufferedDelta = { event: merged, ctx };\n } else {\n flushBufferedDelta();\n bufferedDelta = { event: agentEvent, ctx };\n }\n } else {\n bufferedDelta = { event: agentEvent, ctx };\n }\n\n if (!flushTimer) {\n flushTimer = setTimeout(() => {\n flushBufferedDelta();\n }, 16);\n }\n } else {\n flushBufferedDelta();\n handler(agentEvent, ctx);\n if (\n agentEvent.event_type === 'finish'\n || agentEvent.event_type === 'error'\n ) {\n streamTerminal = true;\n }\n }\n } catch (err) {\n const message =\n err instanceof Error\n ? err.message\n : 'Failed to decode agentx frame';\n transportLog(`Dropped agentx frame: ${message}`, 'warn');\n }\n });\n\n es.onerror = () => {\n flushBufferedDelta();\n // 已收到 finish/error 帧后的关连接:EventSource 规范行为,非故障。\n if (signal.aborted || fatal || streamTerminal) {\n cleanup();\n finish();\n return;\n }\n // 握手前断连(含 HTTP 4xx/5xx、CORS):EventSource 不提供 status,只能凭「尚无 meta」判定。\n if (!handshakeOk) {\n const error = new SseTransportTerminalError(\n 'handshake_failed',\n 'SSE connection failed before meta handshake',\n );\n transportLog(error.message, 'error');\n cleanup();\n finish(error);\n return;\n }\n if (autoReconnect) {\n cleanup();\n setTimeout(() => connect(lastEventId), reconnectDelayMs);\n return;\n }\n // 已握手但未收到 finish/error 就断连:真实传输中断,须 reject 供宿主感知。\n failPrematureClose();\n };\n };\n\n signal.addEventListener('abort', () => {\n flushBufferedDelta();\n fatal = true;\n finish();\n }, { once: true });\n\n connect();\n });\n },\n };\n}\n\n/** 测试/Story 用:内存事件源 */\nexport function createMockSource(events: LangchainAgentEvent[]): Source {\n return {\n async start(handler, signal) {\n for (const event of events) {\n if (signal.aborted) break;\n handler(event);\n }\n },\n };\n}\n","/**\n * ScopedSessionStore.tsx — 外部 SessionTree 注入 SessionStore 上下文\n *\n * 职责:\n * 让 AgentLoopView 在 workflow scoped 子树渲染时复用 Timeline 组件栈。\n *\n * 链路位置:\n * AgentLoopView(tree prop)→ ScopedSessionStoreProvider。\n *\n * 当前裁剪范围:\n * 只读同步 tree prop;不接收 live applyEvent(由父 workflow store 驱动)。\n */\nimport { useEffect, useRef, type ReactNode } from 'react';\n\nimport { SessionStoreContext } from '../../core/context/SessionContext';\nimport { createSessionStore } from '../../core/store';\nimport type { SessionTree } from '../../types/tree';\n\nexport function ScopedSessionStoreProvider({\n tree,\n children,\n}: {\n tree: SessionTree;\n children: ReactNode;\n}) {\n const storeRef = useRef(createSessionStore(tree, { initialEventCount: 1 }));\n useEffect(() => {\n storeRef.current.setState({ tree });\n }, [tree]);\n\n return (\n <SessionStoreContext.Provider value={storeRef.current}>\n {children}\n </SessionStoreContext.Provider>\n );\n}\n","/**\n * AgentLoopView.tsx — CC 主舞台(Timeline + Spinner + 可选 TaskListFooter)\n *\n * 职责:\n * /chat 与 /workflow 内 agent loop 区域共用投影与节点渲染。\n *\n * 链路位置:\n * AgentSession · WorkflowSession scoped loop。\n *\n * 当前裁剪范围:\n * workflow 页 showTaskListFooter=false(合并 Footer 在 P3)。\n */\nimport type { SessionTree } from '../../types/tree';\nimport { SessionTimeline } from '../SessionTimeline';\nimport { ScopedSessionStoreProvider } from './ScopedSessionStore';\n\nexport interface AgentLoopViewProps {\n /** 传入时使用隔离 store(workflow scoped);省略则使用上层 SessionStoreContext */\n tree?: SessionTree;\n showTaskListFooter?: boolean;\n virtualized?: boolean;\n virtualizeThreshold?: number;\n groupParallelTools?: boolean;\n}\n\nfunction AgentLoopViewBody({\n showTaskListFooter = true,\n virtualized,\n virtualizeThreshold,\n groupParallelTools,\n}: Omit<AgentLoopViewProps, 'tree'>) {\n return (\n <div className=\"lax-agent-loop-view\" data-testid=\"lax-agent-loop-view\">\n <SessionTimeline\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n showTaskListFooter={showTaskListFooter}\n />\n </div>\n );\n}\n\nexport function AgentLoopView({\n tree,\n showTaskListFooter = true,\n virtualized,\n virtualizeThreshold,\n groupParallelTools,\n}: AgentLoopViewProps) {\n if (tree) {\n return (\n <ScopedSessionStoreProvider tree={tree}>\n <AgentLoopViewBody\n showTaskListFooter={showTaskListFooter}\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n />\n </ScopedSessionStoreProvider>\n );\n }\n return (\n <AgentLoopViewBody\n showTaskListFooter={showTaskListFooter}\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n />\n );\n}\n","/**\n * WorkflowSession.tsx — /workflow 页顶层容器\n *\n * 职责:\n * WorkflowChrome + scoped AgentLoopView;workflow SSE Source 写入 workflow store。\n *\n * 链路位置:\n * Simple /workflow 页 · 业务 Workflow 演示。\n *\n * 当前裁剪范围:\n * 无 WorkflowTaskListFooter(P3);permission 与 AgentSession 同构 props 子集。\n */\nimport { useEffect, useMemo, useRef, type ReactNode } from 'react';\n\nimport { WorkflowSessionStoreContext } from '../../core/context/WorkflowSessionContext';\nimport { WorkflowLoopReplayProvider } from '../../core/context/WorkflowLoopReplayContext';\nimport type { WorkflowLoopReplayHandler } from '../../core/context/WorkflowLoopReplayContext';\nimport {\n WorkflowScaleContext,\n} from '../../core/context/WorkflowScaleContext';\nimport {\n DEFAULT_WORKFLOW_SCALE_OPTIONS,\n type WorkflowScaleOptions,\n} from './workflowScaleOptions';\nimport {\n NodeRegistryContext,\n ToolDisplayOptionsContext,\n SessionViewOptionsContext,\n} from '../../core/context/SessionContext';\nimport { InteractionBusContext } from '../../core/context/InteractionContext';\nimport { MarkdownRendererContext } from '../../core/context/MarkdownRendererContext';\nimport type { MarkdownRenderer } from '../../core/context/MarkdownRendererContext';\nimport { getNoopInteractionBus } from '../../core/interaction/InteractionBus';\nimport type { InteractionBus } from '../../core/interaction/InteractionBus';\nimport { createWorkflowSessionStore } from '../../core/workflowSessionStore';\nimport { reduceWorkflowEvents } from '../../core/workflowReducer';\nimport type { Source } from '../../transport/types';\nimport { SseTransportTerminalError } from '../../transport/createAgentxSseSource';\nimport type { LangchainAgentEvent, TierOverrides } from '../../types/events';\nimport { createDefaultRegistry } from '../defaultRegistry';\nimport type { NodeRegistry } from '../NodeRegistry';\nimport {\n createDefaultToolRegistry,\n type ToolDisplayRegistry,\n} from '../tools/registry';\nimport type { ToolBodyMode } from '../tools/types';\nimport type { DisplayMode, PermissionUiMode } from '../sessionViewOptions';\nimport { DEFAULT_SESSION_VIEW_OPTIONS } from '../sessionViewOptions';\nimport { WorkflowChrome } from './WorkflowChrome';\nimport { WorkflowTaskListFooter } from './WorkflowTaskListFooter';\nimport { useStore } from 'zustand';\nimport type { WorkflowSessionStoreState } from '../../core/workflowSessionStore';\n\nexport interface WorkflowSessionProps {\n source: Source;\n initialEvents?: LangchainAgentEvent[];\n registry?: NodeRegistry;\n tierOverrides?: TierOverrides;\n onError?: (error: Error) => void;\n interactionBus?: InteractionBus;\n toolDisplayRegistry?: ToolDisplayRegistry;\n defaultBodyMode?: ToolBodyMode;\n permissionUiMode?: PermissionUiMode;\n markdownRenderer?: MarkdownRenderer;\n displayMode?: DisplayMode;\n verbose?: boolean;\n exploreFullscreenBash?: boolean;\n memoryDir?: string | null;\n workspaceRoot?: string | null;\n virtualized?: boolean;\n virtualizeThreshold?: number;\n groupParallelTools?: boolean;\n /** P1–P4:大规模 workflow 缩放选项 */\n workflowScale?: Partial<WorkflowScaleOptions>;\n /** P2:展开已淘汰 loop 时由宿主 replay 事件 */\n onRequestLoopReplay?: WorkflowLoopReplayHandler;\n children?: ReactNode;\n}\n\nexport function WorkflowSession({\n source,\n initialEvents,\n registry,\n tierOverrides,\n onError,\n interactionBus,\n toolDisplayRegistry,\n defaultBodyMode = 'preview',\n permissionUiMode = 'standalone',\n markdownRenderer,\n displayMode = 'normal',\n verbose = false,\n exploreFullscreenBash = true,\n memoryDir = null,\n workspaceRoot = null,\n virtualized = false,\n virtualizeThreshold,\n groupParallelTools = false,\n workflowScale,\n onRequestLoopReplay,\n children,\n}: WorkflowSessionProps) {\n const storeRef = useRef<ReturnType<typeof createWorkflowSessionStore> | null>(null);\n if (storeRef.current === null) {\n const initialState =\n initialEvents && initialEvents.length > 0\n ? reduceWorkflowEvents(initialEvents, { tierOverrides })\n : undefined;\n storeRef.current = createWorkflowSessionStore(initialState, {\n tierOverrides,\n initialEventCount: initialEvents?.length ?? 0,\n evictCompletedLoops: workflowScale?.evictCompletedLoops\n ?? DEFAULT_WORKFLOW_SCALE_OPTIONS.evictCompletedLoops,\n maxHydratedCompletedLoops: workflowScale?.maxHydratedCompletedLoops\n ?? DEFAULT_WORKFLOW_SCALE_OPTIONS.maxHydratedCompletedLoops,\n });\n }\n\n const scaleOptions = useMemo(\n () => ({ ...DEFAULT_WORKFLOW_SCALE_OPTIONS, ...workflowScale }),\n [workflowScale],\n );\n\n const registryRef = useMemo(() => registry ?? createDefaultRegistry(), [registry]);\n const busRef = useMemo(\n () => interactionBus ?? getNoopInteractionBus(),\n [interactionBus],\n );\n const toolDisplayRef = useMemo(\n () => ({\n registry: toolDisplayRegistry ?? createDefaultToolRegistry(),\n defaultBodyMode,\n }),\n [toolDisplayRegistry, defaultBodyMode],\n );\n const sessionViewRef = useMemo(\n () => ({\n ...DEFAULT_SESSION_VIEW_OPTIONS,\n groupParallelTools,\n permissionUiMode,\n displayMode,\n verbose,\n exploreFullscreenBash,\n memoryDir,\n workspaceRoot,\n }),\n [\n groupParallelTools,\n permissionUiMode,\n displayMode,\n verbose,\n exploreFullscreenBash,\n memoryDir,\n workspaceRoot,\n ],\n );\n\n const containerTree = useStore(\n storeRef.current!,\n (s: WorkflowSessionStoreState) => s.state.containerTree,\n );\n const loopTreesBySessionId = useStore(\n storeRef.current!,\n (s: WorkflowSessionStoreState) => s.state.loopTreesBySessionId,\n );\n\n useEffect(() => {\n const store = storeRef.current!;\n const controller = new AbortController();\n\n void source.start((event, ctx) => {\n store.getState().applyEvent(event, ctx);\n }, controller.signal).catch((err: unknown) => {\n if (err instanceof SseTransportTerminalError) {\n const { state } = store.getState();\n if (state.status === 'running') {\n store.setState({ state: { ...state, status: 'error' } });\n }\n }\n });\n\n return () => {\n controller.abort();\n };\n }, [source, onError]);\n\n return (\n <WorkflowSessionStoreContext.Provider value={storeRef.current!}>\n <WorkflowScaleContext.Provider value={scaleOptions}>\n <WorkflowLoopReplayProvider onRequestLoopReplay={onRequestLoopReplay}>\n <InteractionBusContext.Provider value={busRef}>\n <NodeRegistryContext.Provider value={registryRef}>\n <MarkdownRendererContext.Provider value={markdownRenderer}>\n <ToolDisplayOptionsContext.Provider value={toolDisplayRef}>\n <SessionViewOptionsContext.Provider value={sessionViewRef}>\n <div\n className=\"lax-agent-session lax-workflow-session\"\n data-testid=\"lax-workflow-session\"\n >\n <WorkflowChrome\n containerTree={containerTree}\n loopTreesBySessionId={loopTreesBySessionId}\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n />\n <WorkflowTaskListFooter />\n {children}\n </div>\n </SessionViewOptionsContext.Provider>\n </ToolDisplayOptionsContext.Provider>\n </MarkdownRendererContext.Provider>\n </NodeRegistryContext.Provider>\n </InteractionBusContext.Provider>\n </WorkflowLoopReplayProvider>\n </WorkflowScaleContext.Provider>\n </WorkflowSessionStoreContext.Provider>\n );\n}\n","/**\n * WorkflowSessionContext.tsx — Workflow store React 上下文\n *\n * 职责:\n * 向 WorkflowSession 子树注入 workflowSessionStore。\n *\n * 链路位置:\n * WorkflowSession Provider。\n *\n * 当前裁剪范围:\n * 与 SessionStoreContext 平行,不混用。\n */\nimport { createContext, useContext } from 'react';\nimport { useStore } from 'zustand';\n\nimport type { SessionStatus } from '../../types/tree';\nimport type { WorkflowSessionStore } from '../workflowSessionStore';\n\nexport const WorkflowSessionStoreContext = createContext<WorkflowSessionStore | null>(null);\n\nexport function useWorkflowSessionStoreApi(): WorkflowSessionStore {\n const store = useContext(WorkflowSessionStoreContext);\n if (!store) {\n throw new Error('useWorkflowSessionStoreApi must be used within WorkflowSession');\n }\n return store;\n}\n\nexport function useWorkflowSessionStatus(): SessionStatus {\n const store = useWorkflowSessionStoreApi();\n return useStore(store, (s) => s.state.status);\n}\n","import { createContext, useContext, type ReactNode } from 'react';\n\n/** 宿主按需 replay 某 loopSessionId 的事件(P2 懒加载) */\nexport type WorkflowLoopReplayHandler = (loopSessionId: string) => void | Promise<void>;\n\nconst WorkflowLoopReplayContext = createContext<WorkflowLoopReplayHandler | undefined>(\n undefined,\n);\n\nexport function WorkflowLoopReplayProvider({\n onRequestLoopReplay,\n children,\n}: {\n onRequestLoopReplay?: WorkflowLoopReplayHandler;\n children: ReactNode;\n}) {\n return (\n <WorkflowLoopReplayContext.Provider value={onRequestLoopReplay}>\n {children}\n </WorkflowLoopReplayContext.Provider>\n );\n}\n\nexport function useWorkflowLoopReplayHandler(): WorkflowLoopReplayHandler | undefined {\n return useContext(WorkflowLoopReplayContext);\n}\n","import { createContext, useContext } from 'react';\n\nimport {\n DEFAULT_WORKFLOW_SCALE_OPTIONS,\n type WorkflowScaleOptions,\n} from '../../view/workflow/workflowScaleOptions';\n\nexport const WorkflowScaleContext = createContext<WorkflowScaleOptions>(\n DEFAULT_WORKFLOW_SCALE_OPTIONS,\n);\n\nexport function useWorkflowScaleOptions(): WorkflowScaleOptions {\n return useContext(WorkflowScaleContext);\n}\n","/** Workflow 大规模编排 UI 缩放选项(P1–P4) */\nexport interface WorkflowScaleOptions {\n /**\n * P1:已弃用 — stage 壳列表不再使用虚拟滚动。\n * 保留字段以保证向后兼容,工作流主链路不再读取此值。\n * @deprecated D25 Phase 1 移除 stage shell virtualization 后不再生效。\n */\n stageVirtualizeThreshold: number;\n /** P3:默认展示的 completed done stage 上限(running/failed/pending 始终展示) */\n completedStagePageSize: number;\n /** P2:completed 且未 pin 的 loop 树移出内存,保留摘要 */\n evictCompletedLoops: boolean;\n /** P4:running 容器仅 active 自动展开 AgentLoopView */\n onlyExpandActiveRunning: boolean;\n /**\n * P1:已弃用 — parallel item shell 不再使用虚拟滚动(最大并行跨度仅 4)。\n * 保留字段以保证向后兼容,工作流主链路不再读取此值。\n * @deprecated D25 Phase 1 移除 parallel item virtualization 后不再生效。\n */\n parallelItemVirtualizeThreshold: number;\n /** P2:completed hydrated loop 热缓存上限(默认 4,与最大并行跨度对齐) */\n maxHydratedCompletedLoops: number;\n}\n\nexport const DEFAULT_WORKFLOW_SCALE_OPTIONS: WorkflowScaleOptions = {\n stageVirtualizeThreshold: 40,\n completedStagePageSize: 25,\n evictCompletedLoops: true,\n onlyExpandActiveRunning: true,\n parallelItemVirtualizeThreshold: 40,\n maxHydratedCompletedLoops: 4,\n};\n","/**\n * workflowSessionStore.ts — Workflow 页 zustand store\n *\n * 职责:\n * Source 事件写入 WorkflowSessionState;与 SessionStore 平行隔离。\n *\n * 链路位置:\n * WorkflowSession Provider → applyEvent。\n *\n * 当前裁剪范围:\n * 无多会话 Tab;dedupe 与 SessionStore 同构。\n */\nimport { createStore, type StoreApi } from 'zustand/vanilla';\n\nimport type { LangchainAgentEvent, TierOverrides } from '../types/events';\nimport type { ReducerError, SessionTree } from '../types/tree';\nimport {\n createEmptyWorkflowSessionState,\n type WorkflowSessionState,\n} from '../types/workflowSession';\nimport { markEventIdSeen, shouldSkipDuplicateEvent } from './dedupe';\nimport { createEmptyTree, type ReduceOptions, reduceTree } from './reducer';\nimport { reduceWorkflowSession } from './workflowReducer';\nimport {\n evictInactiveLoopTrees,\n evictCompletedLoopOverflow,\n touchCompletedLoopSession,\n} from './workflow/workflowLoopEviction';\nimport type { SourceEventContext } from '../transport/types';\n\nexport interface WorkflowSessionStoreOptions {\n tierOverrides?: TierOverrides;\n initialEventCount?: number;\n initialSeenEventIds?: Iterable<string>;\n /** P2:completed loop 树内存淘汰(默认 true) */\n evictCompletedLoops?: boolean;\n /** P2:completed hydrated loop 热缓存上限(默认 4) */\n maxHydratedCompletedLoops?: number;\n}\n\nexport interface WorkflowSessionStoreState {\n state: WorkflowSessionState;\n eventCount: number;\n applyEvent: (event: LangchainAgentEvent, ctx?: SourceEventContext) => void;\n applyEvents: (events: LangchainAgentEvent[]) => void;\n reset: () => void;\n markAsError: (error?: Error) => void;\n /** P2:展开 done stage 时 pin,避免淘汰 */\n pinLoopSession: (loopSessionId: string) => void;\n /** P2:宿主 replay 后灌入 loop 树 */\n hydrateLoopSession: (loopSessionId: string, events: LangchainAgentEvent[]) => void;\n}\n\nfunction safeReduceWorkflow(\n state: WorkflowSessionState,\n event: LangchainAgentEvent,\n eventIndex: number,\n options?: ReduceOptions,\n): { state: WorkflowSessionState; error?: ReducerError } {\n try {\n return { state: reduceWorkflowSession(state, event, eventIndex, options) };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n const stack = err instanceof Error ? err.stack : undefined;\n if (import.meta.env?.DEV) {\n console.error('[langchain_agentx_stream_ui] workflow reducer error:', err);\n }\n return {\n state: {\n ...state,\n internalErrors: [\n ...state.internalErrors,\n { eventIndex, eventType: event.event_type, message, stack },\n ],\n },\n };\n }\n}\n\nexport type WorkflowSessionStore = StoreApi<WorkflowSessionStoreState>;\n\nexport function createWorkflowSessionStore(\n initialState: WorkflowSessionState = createEmptyWorkflowSessionState(),\n storeOptions?: WorkflowSessionStoreOptions,\n): WorkflowSessionStore {\n const reduceOpts: ReduceOptions = {\n tierOverrides: storeOptions?.tierOverrides,\n };\n const initialEventCount = storeOptions?.initialEventCount ?? 0;\n const seenEventIds = new Set<string>(storeOptions?.initialSeenEventIds);\n const evictCompletedLoops = storeOptions?.evictCompletedLoops ?? true;\n const maxHydratedCompletedLoops = storeOptions?.maxHydratedCompletedLoops ?? 4;\n const pinnedLoopSessionIds: Record<string, true> = {};\n\n const finalizeState = (reduced: WorkflowSessionState): WorkflowSessionState => {\n if (!evictCompletedLoops) return reduced;\n return evictInactiveLoopTrees(reduced, pinnedLoopSessionIds);\n };\n\n return createStore<WorkflowSessionStoreState>((set, get) => ({\n state: initialState,\n eventCount: initialEventCount,\n applyEvent(event, ctx) {\n const sseEventId = ctx?.sseEventId;\n if (shouldSkipDuplicateEvent(seenEventIds, sseEventId)) return;\n\n const { state, eventCount } = get();\n const { state: reduced } = safeReduceWorkflow(state, event, eventCount, reduceOpts);\n const evicted = finalizeState(reduced);\n const nextMeta =\n sseEventId\n ? { ...evicted.meta, lastEventId: sseEventId }\n : evicted.meta;\n markEventIdSeen(seenEventIds, sseEventId);\n set({\n state: {\n ...evicted,\n meta: nextMeta,\n status: evicted.status === 'connecting' ? 'running' : evicted.status,\n },\n eventCount: eventCount + 1,\n });\n },\n applyEvents(events) {\n for (const event of events) {\n get().applyEvent(event);\n }\n },\n reset() {\n seenEventIds.clear();\n set({\n state: createEmptyWorkflowSessionState(),\n eventCount: 0,\n });\n },\n markAsError(error) {\n const { state } = get();\n const message = error?.message ?? 'Workflow stream error';\n set({\n state: {\n ...state,\n status: 'error',\n internalErrors: [\n ...state.internalErrors,\n {\n eventIndex: get().eventCount,\n eventType: 'stream-error',\n message,\n stack: error?.stack,\n },\n ],\n },\n });\n },\n /**\n * P2:将 completed loop 加入 LRU 热缓存并淘汰溢出。\n * running 保护由 collectProtectedLoopSessionIds 按状态自动覆盖,不再依赖永久 pin。\n */\n pinLoopSession(loopSessionId) {\n set((current) => {\n let next = touchCompletedLoopSession(current.state, loopSessionId);\n next = evictCompletedLoopOverflow(next, maxHydratedCompletedLoops);\n next = finalizeState(next);\n return { state: next };\n });\n },\n /**\n * P2:宿主 replay 后灌入 loop 树,touch LRU 并淘汰溢出。\n * completed loop 受 hotCompletedLoopSessionIds 保护,不再永久 pin。\n */\n hydrateLoopSession(loopSessionId, events) {\n const { state, eventCount } = get();\n let tree: SessionTree =\n state.loopTreesBySessionId[loopSessionId] ?? createEmptyTree();\n let idx = eventCount;\n for (const event of events) {\n tree = reduceTree(tree, event, idx, reduceOpts);\n idx += 1;\n }\n set((current) => {\n let next: WorkflowSessionState = {\n ...current.state,\n loopTreesBySessionId: {\n ...current.state.loopTreesBySessionId,\n [loopSessionId]: tree,\n },\n };\n next = touchCompletedLoopSession(next, loopSessionId);\n next = evictCompletedLoopOverflow(next, maxHydratedCompletedLoops);\n next = finalizeState(next);\n return { state: next };\n });\n },\n }));\n}\n","/**\n * workflowContainer.ts — Workflow 容器树投影类型\n *\n * 职责:\n * 容器节点、正文块、快照;对齐 SDK workflow_container_projector。\n *\n * 链路位置:\n * workflowContainerProjector → workflowReducer(P1+)→ WorkflowChrome(P2+)。\n *\n * 当前裁剪范围:\n * 不含 React 视图 props;仅投影层 state。\n */\n\nimport type { WorkflowDisplayPayload } from './workflowDisplay';\n\nexport type WorkflowContainerScope =\n | 'workflow'\n | 'stage'\n | 'item'\n | 'branch'\n | 'aggregate'\n | 'subworkflow';\n\nexport type WorkflowContainerStatus =\n | 'pending'\n | 'running'\n | 'completed'\n | 'failed'\n | 'skipped'\n | 'cancelled'\n | 'blocked'\n | 'retrying';\n\nexport type ContentBlockKind = 'reasoning' | 'text' | 'tool';\n\nexport interface WorkflowContentBlock {\n kind: ContentBlockKind;\n preview: string;\n tool_name: string | null;\n}\n\nexport interface WorkflowContainerNode {\n container_id: string;\n scope: WorkflowContainerScope;\n workflow_path: string;\n workflow_depth: number;\n scope_key: string;\n title: string;\n subtitle: string;\n status: WorkflowContainerStatus;\n pattern: string;\n parent_container_id: string | null;\n display: WorkflowDisplayPayload | null;\n content_blocks: WorkflowContentBlock[];\n is_open: boolean;\n}\n\nexport interface WorkflowContainerTreeSnapshot {\n root_container_ids: string[];\n containers: Record<string, WorkflowContainerNode>;\n active_container_ids: string[];\n}\n\n/** reducer 运行时节点:投影字段 + loop 绑定(P1) */\nexport interface WorkflowContainerRuntimeNode extends WorkflowContainerNode {\n loopSessionId: string | null;\n}\n\n/** WorkflowSession 容器树 state(P1+) */\nexport interface WorkflowContainerTreeState {\n rootContainerIds: string[];\n activeContainerIds: string[];\n containersById: Record<string, WorkflowContainerRuntimeNode>;\n}\n\nexport function createEmptyWorkflowContainerTreeState(): WorkflowContainerTreeState {\n return {\n rootContainerIds: [],\n activeContainerIds: [],\n containersById: {},\n };\n}\n\nexport function containerTreeToSnapshot(\n tree: WorkflowContainerTreeState,\n): WorkflowContainerTreeSnapshot {\n const containers: Record<string, WorkflowContainerNode> = {};\n for (const [id, node] of Object.entries(tree.containersById)) {\n const { loopSessionId: _loop, ...projection } = node;\n containers[id] = projection;\n }\n return {\n root_container_ids: [...tree.rootContainerIds],\n active_container_ids: [...tree.activeContainerIds],\n containers,\n };\n}\n\nexport type ContainerAction = 'open' | 'close' | 'append-content';\n\n/** SDK fixture expected.containers 子集(契约对照) */\nexport interface WorkflowContainerExpectedNode {\n title: string;\n subtitle: string;\n status: WorkflowContainerStatus;\n scope: WorkflowContainerScope;\n parent_container_id: string | null;\n content_blocks: WorkflowContentBlock[];\n}\n\nexport interface SdkContainerFixtureExpected {\n root_container_ids: string[];\n active_container_ids: string[];\n containers: Record<string, WorkflowContainerExpectedNode>;\n cli_tree_contains?: string[];\n}\n\nexport interface SdkContainerFixture {\n scenario: string;\n description?: string;\n events: Array<{\n event_type: string;\n data: Record<string, unknown>;\n step_index?: number | null;\n tool_name?: string | null;\n session_id?: string | null;\n timestamp?: number;\n }>;\n expected: SdkContainerFixtureExpected;\n}\n","/**\n * workflowSession.ts — Workflow 会话顶层状态\n *\n * 职责:\n * 定义 /workflow 页专用 WorkflowSessionState(与 /chat SessionTree 隔离)。\n *\n * 链路位置:\n * workflowReducer → workflowSessionStore → WorkflowSession / WorkflowChrome。\n *\n * 当前裁剪范围:\n * 不含合并 TaskListFooter(P3);parallel 结构仅基础字段。\n */\nimport type { SessionStatus, ReducerError, SessionTree } from './tree';\nimport {\n createEmptyWorkflowContainerTreeState,\n type WorkflowContainerTreeState,\n} from './workflowContainer';\n\n/** P2:stage 完成摘要缓存(loop 树淘汰后仍显示 teaser) */\nexport interface CachedStageDoneSummary {\n label: string;\n teaser: string;\n extraLines: number;\n}\n\nexport type WorkflowRunStatus = 'running' | 'done' | 'error';\n\nexport interface WorkflowStageProgress {\n stageKey: string;\n stageIndex: number;\n stageTotal?: number;\n status: 'pending' | 'running' | 'done' | 'failed';\n error?: string;\n}\n\nexport interface ParallelItemProgress {\n itemKey: string;\n itemIndex: number;\n itemTotal?: number;\n status: 'pending' | 'running' | 'done' | 'failed';\n loopSessionId: string | null;\n error?: string;\n}\n\nexport interface WorkflowProgressState {\n workflowId: string | null;\n workflowPath: string | null;\n status: WorkflowRunStatus;\n stages: WorkflowStageProgress[];\n parallelItems: Record<string, ParallelItemProgress>;\n}\n\nexport type WorkflowScopeKind = 'stage' | 'parallel-item' | 'subworkflow';\n\nexport interface WorkflowScopeFrame {\n kind: WorkflowScopeKind;\n key: string;\n loopSessionId: string | null;\n}\n\nexport interface WorkflowSessionState {\n status: SessionStatus;\n meta: {\n workflowRunId: string | null;\n startedAt: number | null;\n lastEventId: string | null;\n };\n /** SDK 容器树投影 + loopSessionId 绑定(P1 主模型) */\n containerTree: WorkflowContainerTreeState;\n /** 过渡期 dual-write;P2+ UI 逐步改读 containerTree */\n workflowProgress: WorkflowProgressState;\n loopTreesBySessionId: Record<string, SessionTree>;\n /** P2:container_id → done 摘要(loop 淘汰后) */\n stageDoneSummariesByContainerId: Record<string, CachedStageDoneSummary>;\n /** P2:completed hydrated loop LRU 热缓存(最近使用在数组尾部) */\n hotCompletedLoopSessionIds: string[];\n activeLoopSessionId: string | null;\n /** @deprecated P1 起由 containerTree.activeContainerIds 替代 */\n openScopeStack: WorkflowScopeFrame[];\n internalErrors: ReducerError[];\n}\n\nexport function createEmptyWorkflowProgress(): WorkflowProgressState {\n return {\n workflowId: null,\n workflowPath: null,\n status: 'running',\n stages: [],\n parallelItems: {},\n };\n}\n\nexport function createEmptyWorkflowSessionState(): WorkflowSessionState {\n return {\n status: 'connecting',\n meta: { workflowRunId: null, startedAt: null, lastEventId: null },\n containerTree: createEmptyWorkflowContainerTreeState(),\n workflowProgress: createEmptyWorkflowProgress(),\n loopTreesBySessionId: {},\n stageDoneSummariesByContainerId: {},\n hotCompletedLoopSessionIds: [],\n activeLoopSessionId: null,\n openScopeStack: [],\n internalErrors: [],\n };\n}\n","/**\n * workflowLoopTreeUtils.ts — Workflow scoped loop 占位树(仅 workflow 引用)\n *\n * 职责:stage running 且尚无 loop 内容时,为 AgentLoopView / Spinner 提供 startedAt。\n * 不修改 createEmptyTree 默认,避免影响 AgentSession /chat 显示。\n */\nimport { createEmptyTree, type SessionTree } from '../../types/tree';\n\n/** Workflow loop 运行占位:status running + startedAt(Spinner 门禁)。 */\nexport function createWorkflowRunningLoopTree(seedMs: number = Date.now()): SessionTree {\n const tree = createEmptyTree();\n tree.status = 'running';\n tree.meta.startedAt = seedMs;\n return tree;\n}\n","/**\n * workflowDisplay.ts — SDK WorkflowDisplayPayload 契约(TS)\n *\n * 职责:\n * 对齐 langchain_agentx WorkflowDisplayPayload;结构事件 data.display 类型。\n *\n * 链路位置:\n * workflowContainerProjector → WorkflowChrome(P2+)。\n *\n * 当前裁剪范围:\n * 只读消费;不计算 display(由 SDK enricher 注入)。\n */\n\nexport type WorkflowDisplayScope =\n | 'workflow'\n | 'stage'\n | 'item'\n | 'branch'\n | 'aggregate'\n | 'subworkflow';\n\nexport type WorkflowDisplayStatus =\n | 'pending'\n | 'running'\n | 'completed'\n | 'failed'\n | 'skipped'\n | 'cancelled'\n | 'blocked'\n | 'retrying';\n\n/** 对齐 SDK display_resolver.WorkflowDisplayPayload */\nexport interface WorkflowDisplayPayload {\n version?: number;\n scope?: WorkflowDisplayScope;\n title?: string;\n description?: string;\n workflow_title?: string;\n workflow_description?: string;\n parent_title?: string;\n breadcrumb?: string[];\n progress_current?: number;\n progress_total?: number;\n progress_label?: string;\n progress_indeterminate?: boolean;\n status?: WorkflowDisplayStatus;\n status_reason?: string;\n icon?: string;\n item_index?: number;\n item_total?: number;\n metrics_completed?: number;\n metrics_running?: number;\n metrics_failed?: number;\n metrics_total?: number;\n decision_label?: string;\n pattern?: string;\n debug_key?: string;\n}\n\nexport function readDisplayPayload(data: Record<string, unknown>): WorkflowDisplayPayload | null {\n const display = data.display;\n if (display != null && typeof display === 'object' && !Array.isArray(display)) {\n return display as WorkflowDisplayPayload;\n }\n return null;\n}\n","/**\n * workflowContainerProjector.ts — LangchainAgentEvent → 容器树投影\n *\n * 职责:\n * 对齐 SDK workflow_container_projector;维护 active set;正文路由。\n *\n * 链路位置:\n * workflowReducer(P1)← consume LangchainAgentEvent;fixture 单测 SSOT。\n *\n * 当前裁剪范围:\n * 仅投影层;不负责 React 渲染或 loop tree reduceTree。\n */\nimport type { LangchainAgentEvent } from '../../types/events';\nimport { readDisplayPayload } from '../../types/workflowDisplay';\nimport type {\n ContainerAction,\n WorkflowContainerNode,\n WorkflowContainerScope,\n WorkflowContainerStatus,\n WorkflowContainerTreeSnapshot,\n WorkflowContentBlock,\n} from '../../types/workflowContainer';\n\nconst OPEN_EVENT_TYPES = new Set<string>([\n 'workflow-start',\n 'subworkflow-start',\n 'stage-start',\n 'parallel-item-start',\n 'parallel-aggregate-start',\n 'route-branch-start',\n]);\n\nconst CLOSE_EVENT_TYPES = new Set<string>([\n 'workflow-end',\n 'workflow-failed',\n 'subworkflow-end',\n 'stage-done',\n 'stage-failed',\n 'parallel-item-done',\n 'parallel-item-failed',\n 'parallel-aggregate-done',\n 'parallel-aggregate-failed',\n 'route-branch-done',\n 'route-branch-failed',\n]);\n\nconst EVENT_TYPE_TO_SCOPE: Record<string, WorkflowContainerScope> = {\n 'workflow-start': 'workflow',\n 'workflow-end': 'workflow',\n 'workflow-failed': 'workflow',\n 'subworkflow-start': 'subworkflow',\n 'subworkflow-end': 'subworkflow',\n 'stage-start': 'stage',\n 'stage-done': 'stage',\n 'stage-failed': 'stage',\n 'parallel-item-start': 'item',\n 'parallel-item-done': 'item',\n 'parallel-item-failed': 'item',\n 'parallel-aggregate-start': 'aggregate',\n 'parallel-aggregate-done': 'aggregate',\n 'parallel-aggregate-failed': 'aggregate',\n 'route-branch-start': 'branch',\n 'route-branch-done': 'branch',\n 'route-branch-failed': 'branch',\n};\n\nconst CONTENT_EVENT_TYPES = new Set<string>([\n 'reasoning-start',\n 'reasoning-delta',\n 'reasoning-end',\n 'text-start',\n 'text-delta',\n 'text-end',\n 'tool-input',\n 'tool-input-start',\n 'tool-input-delta',\n 'tool-call',\n 'tool-result',\n 'tool-error',\n 'tool-progress',\n]);\n\nconst SCOPE_PRIORITY: Record<WorkflowContainerScope, number> = {\n workflow: 0,\n subworkflow: 1,\n aggregate: 2,\n stage: 3,\n item: 3,\n branch: 3,\n};\n\nconst FAILED_CLOSE_TYPES = new Set<string>([\n 'workflow-failed',\n 'stage-failed',\n 'parallel-item-failed',\n 'parallel-aggregate-failed',\n 'route-branch-failed',\n]);\n\nexport function buildContainerId(\n workflowPath: string,\n scope: WorkflowContainerScope,\n scopeKey: string,\n): string {\n return `${workflowPath}|${scope}:${scopeKey}`;\n}\n\nfunction readString(data: Record<string, unknown>, key: string): string | undefined {\n const value = data[key];\n return typeof value === 'string' ? value : undefined;\n}\n\nexport function resolveScopeKey(eventType: string, data: Record<string, unknown>): string {\n if (\n eventType === 'workflow-start'\n || eventType === 'workflow-end'\n || eventType === 'workflow-failed'\n ) {\n const workflowId = readString(data, 'workflow_id');\n if (workflowId) return workflowId;\n return readString(data, 'workflow_path') ?? 'workflow';\n }\n\n if (eventType === 'subworkflow-start' || eventType === 'subworkflow-end') {\n return readString(data, 'child_workflow_id') ?? 'subworkflow';\n }\n\n if (\n eventType === 'stage-start'\n || eventType === 'stage-done'\n || eventType === 'stage-failed'\n ) {\n const stageKey = readString(data, 'stage_key');\n if (stageKey) return stageKey;\n const stageIndex = data.stage_index;\n return typeof stageIndex === 'number' ? String(stageIndex) : 'stage';\n }\n\n if (\n eventType === 'parallel-item-start'\n || eventType === 'parallel-item-done'\n || eventType === 'parallel-item-failed'\n ) {\n const itemKey = readString(data, 'item_key');\n if (itemKey) return itemKey;\n const itemIndex = data.item_index;\n return typeof itemIndex === 'number' ? String(itemIndex) : 'item';\n }\n\n if (\n eventType === 'parallel-aggregate-start'\n || eventType === 'parallel-aggregate-done'\n || eventType === 'parallel-aggregate-failed'\n ) {\n return readString(data, 'aggregate_key') ?? 'aggregate';\n }\n\n if (\n eventType === 'route-branch-start'\n || eventType === 'route-branch-done'\n || eventType === 'route-branch-failed'\n ) {\n return readString(data, 'branch_key') ?? readString(data, 'branch_node') ?? 'branch';\n }\n\n const display = readDisplayPayload(data);\n if (display?.debug_key) return display.debug_key;\n\n return 'unknown';\n}\n\nfunction displayStatus(\n data: Record<string, unknown>,\n fallback: WorkflowContainerStatus,\n): WorkflowContainerStatus {\n const display = readDisplayPayload(data);\n if (display?.status) return display.status;\n return fallback;\n}\n\nfunction closeStatus(eventType: string): WorkflowContainerStatus {\n return FAILED_CLOSE_TYPES.has(eventType) ? 'failed' : 'completed';\n}\n\nfunction readPreview(data: Record<string, unknown>, ...keys: string[]): string {\n for (const key of keys) {\n const value = data[key];\n if (typeof value === 'string') return value;\n }\n return '';\n}\n\nfunction contentBlockFromEvent(event: LangchainAgentEvent): WorkflowContentBlock | null {\n const { event_type: eventType } = event;\n const payload = (event.data ?? {}) as Record<string, unknown>;\n\n if (\n eventType === 'reasoning-start'\n || eventType === 'reasoning-delta'\n || eventType === 'reasoning-end'\n ) {\n let preview = readPreview(payload, 'delta', 'text', 'reasoning');\n if (!preview && eventType === 'reasoning-start') preview = 'Thinking…';\n return { kind: 'reasoning', preview, tool_name: null };\n }\n\n if (\n eventType === 'text-start'\n || eventType === 'text-delta'\n || eventType === 'text-end'\n ) {\n const preview = readPreview(payload, 'delta', 'text');\n return { kind: 'text', preview, tool_name: null };\n }\n\n if (CONTENT_EVENT_TYPES.has(eventType)) {\n const toolName = event.tool_name ?? readString(payload, 'tool_name');\n const preview =\n readPreview(payload, 'summary', 'output', 'input', 'delta')\n || toolName\n || eventType;\n return {\n kind: 'tool',\n preview,\n tool_name: toolName ?? null,\n };\n }\n\n return null;\n}\n\nexport function resolveContentScopeKey(data: Record<string, unknown>): string | null {\n for (const keyName of ['stage_key', 'item_key', 'branch_key', 'debug_key'] as const) {\n const value = readString(data, keyName);\n if (value) return value;\n }\n const display = readDisplayPayload(data);\n return display?.debug_key ?? null;\n}\n\n/** 按容器身份索引的活跃集(并发 item 不依赖 LIFO 单栈) */\nexport class WorkflowContainerActiveSet {\n private readonly openOrder: string[] = [];\n private readonly nodes: Record<string, WorkflowContainerNode> = {};\n\n restoreNode(node: WorkflowContainerNode): void {\n this.nodes[node.container_id] = { ...node };\n if (node.is_open && !this.openOrder.includes(node.container_id)) {\n this.openOrder.push(node.container_id);\n }\n }\n\n open(node: WorkflowContainerNode): void {\n this.nodes[node.container_id] = node;\n if (!this.openOrder.includes(node.container_id)) {\n this.openOrder.push(node.container_id);\n }\n }\n\n close(containerId: string, status: WorkflowContainerStatus): void {\n const node = this.nodes[containerId];\n if (!node) return;\n node.status = status;\n node.is_open = false;\n const idx = this.openOrder.indexOf(containerId);\n if (idx !== -1) this.openOrder.splice(idx, 1);\n }\n\n get activeIds(): string[] {\n return [...this.openOrder];\n }\n\n getNode(containerId: string): WorkflowContainerNode | undefined {\n return this.nodes[containerId];\n }\n\n get nodesById(): Record<string, WorkflowContainerNode> {\n return this.nodes;\n }\n\n rankContainer(containerId: string): [number, number, number, number] {\n const node = this.nodes[containerId];\n if (!node) return [-1, -1, -1, -1];\n const openIndex = this.openOrder.indexOf(containerId);\n const scopePriority = SCOPE_PRIORITY[node.scope] ?? 0;\n return [node.workflow_depth, scopePriority, node.workflow_path.length, openIndex];\n }\n\n deepestActive(): string | null {\n if (this.openOrder.length === 0) return null;\n return this.openOrder.reduce((best, cid) =>\n this.compareRank(cid, best) > 0 ? cid : best,\n );\n }\n\n resolveContentTarget(workflowPath: string | null, scopeKey: string | null): string | null {\n if (scopeKey) {\n for (let i = this.openOrder.length - 1; i >= 0; i -= 1) {\n const containerId = this.openOrder[i]!;\n const node = this.nodes[containerId]!;\n if (node.scope_key === scopeKey && node.is_open) {\n if (workflowPath === null || node.workflow_path === workflowPath) {\n return containerId;\n }\n }\n }\n }\n\n if (workflowPath) {\n const candidates = this.openOrder.filter((cid) => {\n const node = this.nodes[cid]!;\n if (!node.is_open) return false;\n return (\n node.workflow_path === workflowPath\n || workflowPath.startsWith(`${node.workflow_path}>`)\n );\n });\n if (candidates.length > 0) {\n return candidates.reduce((best, cid) =>\n this.compareRank(cid, best) > 0 ? cid : best,\n );\n }\n }\n\n return this.deepestActive();\n }\n\n closeDescendantsOfPath(workflowPath: string, status: WorkflowContainerStatus): void {\n const toClose = this.openOrder.filter((cid) => {\n const node = this.nodes[cid]!;\n return (\n node.workflow_path === workflowPath\n || node.workflow_path.startsWith(`${workflowPath}>`)\n );\n });\n for (const containerId of toClose) {\n this.close(containerId, status);\n }\n }\n\n private compareRank(a: string, b: string): number {\n const ra = this.rankContainer(a);\n const rb = this.rankContainer(b);\n for (let i = 0; i < ra.length; i += 1) {\n if (ra[i]! > rb[i]!) return 1;\n if (ra[i]! < rb[i]!) return -1;\n }\n return 0;\n }\n\n /** 供 StateMachine 比较容器深度 rank */\n compareContainerRank(a: string, b: string): number {\n return this.compareRank(a, b);\n }\n}\n\n/** 事件 → 容器状态机(对齐 SDK reference) */\nexport class WorkflowContainerStateMachine {\n private readonly active = new WorkflowContainerActiveSet();\n private readonly rootIds: string[] = [];\n private suppressContentContainerIds: ReadonlySet<string> = new Set();\n\n get activeSet(): WorkflowContainerActiveSet {\n return this.active;\n }\n\n setSuppressContentContainerIds(ids: ReadonlySet<string>): void {\n this.suppressContentContainerIds = ids;\n }\n\n rehydrate(snapshot: WorkflowContainerTreeSnapshot): void {\n this.rootIds.length = 0;\n this.rootIds.push(...snapshot.root_container_ids);\n for (const node of Object.values(snapshot.containers)) {\n this.active.restoreNode(node);\n }\n }\n\n apply(event: LangchainAgentEvent): ContainerAction | null {\n const eventType = event.event_type;\n const data = (event.data ?? {}) as Record<string, unknown>;\n\n if (OPEN_EVENT_TYPES.has(eventType)) {\n this.openContainer(eventType, data);\n return 'open';\n }\n\n if (CLOSE_EVENT_TYPES.has(eventType)) {\n this.closeContainer(eventType, data);\n return 'close';\n }\n\n if (CONTENT_EVENT_TYPES.has(eventType)) {\n this.appendContent(event);\n return 'append-content';\n }\n\n return null;\n }\n\n snapshot(): WorkflowContainerTreeSnapshot {\n return {\n root_container_ids: [...this.rootIds],\n containers: { ...this.active.nodesById },\n active_container_ids: this.active.activeIds,\n };\n }\n\n private openContainer(eventType: string, data: Record<string, unknown>): void {\n const scope = EVENT_TYPE_TO_SCOPE[eventType];\n if (!scope) return;\n\n const workflowPath = readString(data, 'workflow_path') ?? '';\n const workflowDepth =\n typeof data.workflow_depth === 'number' ? data.workflow_depth : 0;\n const scopeKey = resolveScopeKey(eventType, data);\n const containerId = buildContainerId(workflowPath, scope, scopeKey);\n\n const display = readDisplayPayload(data);\n const title = display?.title ?? scopeKey;\n const subtitle = display?.description ?? '';\n const pattern = display?.pattern ?? '';\n const status = displayStatus(data, 'running');\n const parentId = this.resolveParentId(workflowPath, scope);\n\n const node: WorkflowContainerNode = {\n container_id: containerId,\n scope,\n workflow_path: workflowPath,\n workflow_depth: workflowDepth,\n scope_key: scopeKey,\n title,\n subtitle,\n status,\n pattern,\n parent_container_id: parentId,\n display,\n content_blocks: [],\n is_open: true,\n };\n\n this.active.open(node);\n if (scope === 'workflow' && !this.rootIds.includes(containerId)) {\n this.rootIds.push(containerId);\n }\n }\n\n private closeContainer(eventType: string, data: Record<string, unknown>): void {\n const scope = EVENT_TYPE_TO_SCOPE[eventType];\n if (!scope) return;\n\n const workflowPath = readString(data, 'workflow_path') ?? '';\n const scopeKey = resolveScopeKey(eventType, data);\n const containerId = buildContainerId(workflowPath, scope, scopeKey);\n const status = displayStatus(data, closeStatus(eventType));\n\n this.active.close(containerId, status);\n if (scope === 'workflow') {\n this.active.closeDescendantsOfPath(workflowPath, status);\n }\n }\n\n private appendContent(event: LangchainAgentEvent): void {\n const data = (event.data ?? {}) as Record<string, unknown>;\n const workflowPath = readString(data, 'workflow_path') ?? null;\n const scopeKey = resolveContentScopeKey(data);\n\n const targetId = this.active.resolveContentTarget(workflowPath, scopeKey);\n if (!targetId) return;\n if (this.suppressContentContainerIds.has(targetId)) return;\n\n const block = contentBlockFromEvent(event);\n if (!block) return;\n\n const node = this.active.getNode(targetId);\n if (!node) return;\n\n const last = node.content_blocks[node.content_blocks.length - 1];\n if (\n last\n && last.kind === block.kind\n && (block.kind === 'reasoning' || block.kind === 'text')\n ) {\n if (block.preview) {\n if (block.kind === 'reasoning' && last.preview === 'Thinking…') {\n last.preview = block.preview;\n } else {\n last.preview = `${last.preview}${block.preview}`;\n }\n }\n return;\n }\n\n node.content_blocks.push(block);\n }\n\n private resolveParentId(\n workflowPath: string,\n scope: WorkflowContainerScope,\n ): string | null {\n if (scope === 'workflow') return null;\n\n const openNodes = this.active.activeIds\n .map((cid) => this.active.getNode(cid)!)\n .filter((node) => node.is_open);\n\n if (openNodes.length === 0) return null;\n\n const prefixCandidates = openNodes.filter(\n (node) =>\n workflowPath === node.workflow_path\n || workflowPath.startsWith(`${node.workflow_path}>`),\n );\n\n if (prefixCandidates.length > 0) {\n const parent = prefixCandidates.reduce((best, node) =>\n this.active.compareContainerRank(node.container_id, best.container_id) > 0\n ? node\n : best,\n );\n if (parent.workflow_path === workflowPath && parent.scope === 'workflow') {\n return parent.container_id;\n }\n if (workflowPath.startsWith(`${parent.workflow_path}>`)) {\n return parent.container_id;\n }\n if (parent.workflow_path === workflowPath && parent.scope !== scope) {\n return parent.container_id;\n }\n }\n\n const workflowCandidates = openNodes.filter((node) => node.scope === 'workflow');\n if (workflowCandidates.length > 0) {\n return workflowCandidates.reduce((best, node) =>\n this.active.compareContainerRank(node.container_id, best.container_id) > 0\n ? node\n : best,\n ).container_id;\n }\n\n return openNodes.reduce((best, node) =>\n this.active.compareContainerRank(node.container_id, best.container_id) > 0\n ? node\n : best,\n ).container_id;\n }\n}\n\n/** LangchainAgentEvent 流 → 容器树快照 */\nexport class WorkflowContainerTreeProjector {\n private readonly machine = new WorkflowContainerStateMachine();\n\n rehydrate(snapshot: WorkflowContainerTreeSnapshot): void {\n this.machine.rehydrate(snapshot);\n }\n\n setSuppressContentContainerIds(ids: ReadonlySet<string>): void {\n this.machine.setSuppressContentContainerIds(ids);\n }\n\n consume(event: LangchainAgentEvent): ContainerAction | null {\n return this.machine.apply(event);\n }\n\n consumeAll(events: LangchainAgentEvent[]): WorkflowContainerTreeSnapshot {\n for (const event of events) {\n this.consume(event);\n }\n return this.snapshot();\n }\n\n snapshot(): WorkflowContainerTreeSnapshot {\n return this.machine.snapshot();\n }\n}\n\n/** 纯函数:快照 + 单事件 → 新快照(供 workflowReducer 双轨归约) */\nexport interface ReduceContainerSnapshotOptions {\n /** 已绑定 loop 的容器不再写入 content_blocks(过程层走 AgentLoopView) */\n suppressContentContainerIds?: ReadonlySet<string>;\n}\n\nexport function reduceContainerSnapshot(\n snapshot: WorkflowContainerTreeSnapshot,\n event: LangchainAgentEvent,\n options?: ReduceContainerSnapshotOptions,\n): WorkflowContainerTreeSnapshot {\n const projector = new WorkflowContainerTreeProjector();\n projector.rehydrate(snapshot);\n if (options?.suppressContentContainerIds?.size) {\n projector.setSuppressContentContainerIds(options.suppressContentContainerIds);\n }\n projector.consume(event);\n return projector.snapshot();\n}\n\n/** 从 open 容器集解析 agent 正文路由目标 */\nexport function resolveContentTargetFromSnapshot(\n snapshot: WorkflowContainerTreeSnapshot,\n workflowPath: string | null,\n scopeKey: string | null,\n): string | null {\n const active = new WorkflowContainerActiveSet();\n for (const containerId of snapshot.active_container_ids) {\n const node = snapshot.containers[containerId];\n if (node?.is_open) active.restoreNode(node);\n }\n return active.resolveContentTarget(workflowPath, scopeKey);\n}\n\n/** 投影快照合并 loopSessionId(projector 不管理 loop 绑定) */\nexport function mergeRuntimeContainerNodes(\n prev: Record<string, { loopSessionId: string | null }>,\n snapshot: WorkflowContainerTreeSnapshot,\n): Record<\n string,\n WorkflowContainerNode & { loopSessionId: string | null }\n> {\n const out: Record<string, WorkflowContainerNode & { loopSessionId: string | null }> = {};\n for (const [containerId, node] of Object.entries(snapshot.containers)) {\n out[containerId] = {\n ...node,\n loopSessionId: prev[containerId]?.loopSessionId ?? null,\n };\n }\n return out;\n}\n\n/** 序列化为 SDK fixture expected 对照结构 */\nexport function snapshotToExpectedFormat(\n snapshot: WorkflowContainerTreeSnapshot,\n): {\n root_container_ids: string[];\n active_container_ids: string[];\n containers: Record<\n string,\n {\n title: string;\n subtitle: string;\n status: WorkflowContainerStatus;\n scope: WorkflowContainerScope;\n parent_container_id: string | null;\n content_blocks: WorkflowContentBlock[];\n }\n >;\n} {\n const containers: Record<\n string,\n {\n title: string;\n subtitle: string;\n status: WorkflowContainerStatus;\n scope: WorkflowContainerScope;\n parent_container_id: string | null;\n content_blocks: WorkflowContentBlock[];\n }\n > = {};\n\n for (const [cid, node] of Object.entries(snapshot.containers)) {\n containers[cid] = {\n title: node.title,\n subtitle: node.subtitle,\n status: node.status,\n scope: node.scope,\n parent_container_id: node.parent_container_id,\n content_blocks: node.content_blocks.map((b) => ({\n kind: b.kind,\n preview: b.preview,\n tool_name: b.tool_name,\n })),\n };\n }\n\n return {\n root_container_ids: snapshot.root_container_ids,\n active_container_ids: snapshot.active_container_ids,\n containers,\n };\n}\n\nexport type {\n WorkflowContainerNode,\n WorkflowContainerTreeSnapshot,\n WorkflowContentBlock,\n ContainerAction,\n};\n","/**\n * loopSessionUtils.ts — Workflow loop session_id 推导(对齐 SDK WorkflowSessionIdPolicy)\n *\n * loop_session_id = `{workflow_id}-{task_key}`\n */\nimport type { LangchainAgentEvent } from '../../types/events';\nimport type { WorkflowContainerScope } from '../../types/workflowContainer';\nimport { resolveScopeKey } from './workflowContainerProjector';\n\nfunction readString(data: Record<string, unknown>, key: string): string | undefined {\n const value = data[key];\n return typeof value === 'string' ? value : undefined;\n}\n\n/** 会在其内运行 Agent loop 的结构 open 事件 → 容器 scope */\nconst LOOP_TASK_OPEN_SCOPES: Partial<Record<string, WorkflowContainerScope>> = {\n 'stage-start': 'stage',\n 'parallel-item-start': 'item',\n 'route-branch-start': 'branch',\n};\n\nexport function buildLoopSessionId(workflowId: string, taskKey: string): string {\n return `${workflowId}-${taskKey}`;\n}\n\n/** stage-start / parallel-item-start 等 open 事件预绑定 loop session。 */\nexport function deriveLoopSessionIdFromStructureOpen(\n event: LangchainAgentEvent,\n): string | null {\n if (!LOOP_TASK_OPEN_SCOPES[event.event_type]) return null;\n\n const data = (event.data ?? {}) as Record<string, unknown>;\n const workflowId = readString(data, 'workflow_id');\n if (!workflowId) return null;\n\n const taskKey = resolveScopeKey(event.event_type, data);\n if (!taskKey || taskKey === 'unknown') return null;\n\n return buildLoopSessionId(workflowId, taskKey);\n}\n\n/** agent 事件缺 session_id 时,从 workflow_id (或 workflow_path 兜底) + scope key 推导。 */\nexport function deriveLoopSessionIdFromAgentEvent(\n event: LangchainAgentEvent,\n): string | null {\n const data = (event.data ?? {}) as Record<string, unknown>;\n // 真捕获里 content 事件没有 workflow_id;但 SDK 容器投影 fixture 用 workflow_path。\n // 两者在根 workflow 上等价,所以允许 workflow_path 兜底(不破坏 D24,因为\n // workflow_id 永远优先;只是为了兼容用 workflow_path 命名 root 的 fixture)。\n const workflowId =\n readString(data, 'workflow_id') ?? readString(data, 'workflow_path');\n if (!workflowId) return null;\n\n const taskKey =\n readString(data, 'stage_key')\n ?? readString(data, 'item_key')\n ?? readString(data, 'branch_key');\n if (!taskKey) return null;\n\n return buildLoopSessionId(workflowId, taskKey);\n}\n\nexport function isLoopTaskStructureOpenEvent(eventType: string): boolean {\n return eventType in LOOP_TASK_OPEN_SCOPES;\n}\n\nexport function loopTaskScopeForStructureOpen(\n eventType: string,\n): WorkflowContainerScope | undefined {\n return LOOP_TASK_OPEN_SCOPES[eventType];\n}\n","/**\n * workflowStructureEvents.ts — Workflow 结构事件类型守卫\n *\n * 职责:\n * 区分 workflow 编排结构 event_type 与 agent loop 事件。\n *\n * 链路位置:\n * workflowReducer 路由 · Source application_kind 守卫(并行契约)。\n *\n * 当前裁剪范围:\n * 与 backend WORKFLOW_STRUCTURE_EVENT_TYPES 对齐;不进 tier-1 白名单。\n */\nexport const WORKFLOW_STRUCTURE_EVENT_TYPES: ReadonlySet<string> = new Set([\n 'workflow-start',\n 'workflow-end',\n 'workflow-failed',\n 'subworkflow-start',\n 'subworkflow-end',\n 'stage-start',\n 'stage-done',\n 'stage-failed',\n 'parallel-item-start',\n 'parallel-item-done',\n 'parallel-item-failed',\n 'parallel-aggregate-start',\n 'parallel-aggregate-done',\n 'parallel-aggregate-failed',\n 'route-branch-start',\n 'route-branch-done',\n 'route-branch-failed',\n]);\n\nexport function isWorkflowStructureEventType(eventType: string): boolean {\n return WORKFLOW_STRUCTURE_EVENT_TYPES.has(eventType);\n}\n","/**\n * workflowReducer.ts — WorkflowSession 容器树 + agent loop 双轨归约\n *\n * 职责:\n * 结构事件经 WorkflowContainerTreeProjector 更新 containerTree;\n * agent 事件 bind loopSessionId 并写入 loopTreesBySessionId。\n *\n * 链路位置:\n * workflowSessionStore.applyEvent → reduceWorkflowSession。\n *\n * 当前裁剪范围:\n * workflowProgress 为过渡期 dual-write;P2+ UI 改读 containerTree。\n */\nimport type { LangchainAgentEvent } from '../types/events';\nimport { createWorkflowRunningLoopTree } from './workflow/workflowLoopTreeUtils';\nimport type {\n WorkflowContainerRuntimeNode,\n WorkflowContainerStatus,\n WorkflowContainerTreeState,\n} from '../types/workflowContainer';\nimport { containerTreeToSnapshot } from '../types/workflowContainer';\nimport type {\n WorkflowSessionState,\n WorkflowStageProgress,\n ParallelItemProgress,\n WorkflowRunStatus,\n WorkflowProgressState,\n} from '../types/workflowSession';\nimport { createEmptyWorkflowSessionState } from '../types/workflowSession';\nimport {\n buildContainerId,\n mergeRuntimeContainerNodes,\n reduceContainerSnapshot,\n resolveContentScopeKey,\n resolveContentTargetFromSnapshot,\n resolveScopeKey,\n} from './workflow/workflowContainerProjector';\nimport {\n deriveLoopSessionIdFromAgentEvent,\n deriveLoopSessionIdFromStructureOpen,\n loopTaskScopeForStructureOpen,\n} from './workflow/loopSessionUtils';\nimport { isWorkflowStructureEventType } from './workflowStructureEvents';\nimport { reduceTree, type ReduceOptions } from './reducer';\n\nfunction readString(data: Record<string, unknown>, key: string): string | undefined {\n const value = data[key];\n return typeof value === 'string' ? value : undefined;\n}\n\nfunction mapContainerStatusToProgressStatus(\n status: WorkflowContainerStatus,\n): WorkflowStageProgress['status'] {\n switch (status) {\n case 'completed':\n return 'done';\n case 'failed':\n return 'failed';\n case 'running':\n return 'running';\n default:\n return 'pending';\n }\n}\n\nfunction syncWorkflowProgressFromContainerTree(\n tree: WorkflowContainerTreeState,\n prev: WorkflowProgressState,\n): WorkflowProgressState {\n const workflowNodes = Object.values(tree.containersById).filter((n) => n.scope === 'workflow');\n const rootWorkflow =\n workflowNodes.find((n) => tree.rootContainerIds.includes(n.container_id)) ?? workflowNodes[0];\n\n const stages: WorkflowStageProgress[] = Object.values(tree.containersById)\n .filter((n) => n.scope === 'stage')\n .sort((a, b) => {\n const ai = a.display?.progress_current ?? 0;\n const bi = b.display?.progress_current ?? 0;\n if (ai !== bi) return ai - bi;\n return a.scope_key.localeCompare(b.scope_key);\n })\n .map((node, index) => ({\n stageKey: node.scope_key,\n stageIndex: node.display?.progress_current ?? index,\n stageTotal: node.display?.progress_total,\n status: mapContainerStatusToProgressStatus(node.status),\n error: node.display?.status_reason,\n }));\n\n const parallelItems: Record<string, ParallelItemProgress> = {};\n for (const node of Object.values(tree.containersById)) {\n if (node.scope !== 'item') continue;\n parallelItems[node.scope_key] = {\n itemKey: node.scope_key,\n itemIndex: node.display?.item_index ?? 0,\n itemTotal: node.display?.item_total,\n status: mapContainerStatusToProgressStatus(node.status),\n loopSessionId: node.loopSessionId,\n error: node.display?.status_reason,\n };\n }\n\n let runStatus: WorkflowRunStatus = prev.status;\n if (rootWorkflow) {\n if (rootWorkflow.status === 'completed') runStatus = 'done';\n else if (rootWorkflow.status === 'failed') runStatus = 'error';\n else runStatus = 'running';\n }\n\n return {\n workflowId: rootWorkflow?.scope_key ?? prev.workflowId,\n workflowPath: rootWorkflow?.workflow_path ?? prev.workflowPath,\n status: runStatus,\n stages,\n parallelItems,\n };\n}\n\nfunction loopBoundContainerIds(\n containersById: Record<string, WorkflowContainerRuntimeNode>,\n): Set<string> {\n const ids = new Set<string>();\n for (const [containerId, node] of Object.entries(containersById)) {\n if (node.loopSessionId) ids.add(containerId);\n }\n return ids;\n}\n\nfunction applyStructureToContainerTree(\n tree: WorkflowContainerTreeState,\n event: LangchainAgentEvent,\n): WorkflowContainerTreeState {\n const snapshot = reduceContainerSnapshot(containerTreeToSnapshot(tree), event, {\n suppressContentContainerIds: loopBoundContainerIds(tree.containersById),\n });\n let containersById = mergeRuntimeContainerNodes(tree.containersById, snapshot);\n containersById = enrichWorkflowRootFromStages(\n containersById,\n snapshot.root_container_ids,\n );\n return {\n rootContainerIds: snapshot.root_container_ids,\n activeContainerIds: snapshot.active_container_ids,\n containersById,\n };\n}\n\n/** stage-start 等 open 事件:预绑定 loopSessionId + 清空 content_blocks(D24 过程层 SSOT)。 */\nfunction prebindLoopSessionFromStructureOpen(\n tree: WorkflowContainerTreeState,\n event: LangchainAgentEvent,\n): WorkflowContainerTreeState {\n const loopSessionId = deriveLoopSessionIdFromStructureOpen(event);\n const scope = loopTaskScopeForStructureOpen(event.event_type);\n if (!loopSessionId || !scope) return tree;\n\n const data = (event.data ?? {}) as Record<string, unknown>;\n const workflowPath = readString(data, 'workflow_path') ?? '';\n const scopeKey = resolveScopeKey(event.event_type, data);\n const containerId = buildContainerId(workflowPath, scope, scopeKey);\n\n const node = tree.containersById[containerId];\n if (!node) return tree;\n if (node.loopSessionId === loopSessionId && node.content_blocks.length === 0) {\n return tree;\n }\n\n return {\n ...tree,\n containersById: {\n ...tree.containersById,\n [containerId]: {\n ...node,\n loopSessionId,\n content_blocks: [],\n },\n },\n };\n}\n\n/** workflow display 缺 pattern/progress 时从 stage 子节点推导(对齐 D24 根行 meta)。 */\nfunction enrichWorkflowRootFromStages(\n containersById: Record<string, WorkflowContainerRuntimeNode>,\n rootContainerIds: string[],\n): Record<string, WorkflowContainerRuntimeNode> {\n const rootId = rootContainerIds[0];\n if (!rootId) return containersById;\n\n const root = containersById[rootId];\n if (!root || root.scope !== 'workflow') return containersById;\n\n const stages = Object.values(containersById).filter(\n (node) =>\n node.scope === 'stage'\n && node.workflow_path === root.workflow_path\n && node.workflow_depth === root.workflow_depth,\n );\n if (stages.length === 0) return containersById;\n\n const pattern =\n root.pattern\n || root.display?.pattern\n || stages.find((s) => s.pattern)?.pattern\n || stages.find((s) => s.display?.pattern)?.display?.pattern\n || 'chaining';\n\n const inferredTotal = stages.reduce(\n (max, s) => Math.max(max, s.display?.progress_total ?? 0),\n 0,\n );\n const progressTotal =\n root.display?.progress_total ?? (inferredTotal > 0 ? inferredTotal : stages.length);\n\n const settled = stages.filter(\n (s) => s.status === 'completed' || s.status === 'failed',\n ).length;\n const progressCurrent =\n root.status === 'completed' || root.status === 'failed'\n ? progressTotal\n : Math.max(root.display?.progress_current ?? 0, settled);\n\n if (\n root.pattern === pattern\n && root.display?.pattern === pattern\n && root.display?.progress_total === progressTotal\n && root.display?.progress_current === progressCurrent\n ) {\n return containersById;\n }\n\n const display = root.display\n ? {\n ...root.display,\n pattern,\n progress_total: progressTotal,\n progress_current: progressCurrent,\n }\n : root.display;\n\n return {\n ...containersById,\n [rootId]: {\n ...root,\n pattern,\n display,\n },\n };\n}\n\nfunction findContainerByLoopSession(\n tree: WorkflowContainerTreeState,\n loopSessionId: string,\n): string | null {\n for (const [containerId, node] of Object.entries(tree.containersById)) {\n if (node.loopSessionId === loopSessionId) return containerId;\n }\n return null;\n}\n\nconst WORKFLOW_DEFAULT_LOOP_SESSION_ID = 'workflow-loop-default';\n\n/** Agent loop 事件 session_id;缺省时从 workflow_id + task_key 推导,最后才 fallback。 */\nfunction resolveAgentLoopSessionId(event: LangchainAgentEvent): string | null {\n if (event.session_id) return event.session_id;\n if (isWorkflowStructureEventType(event.event_type)) return null;\n if (event.event_type === 'task-list-snapshot') return null;\n\n const derived = deriveLoopSessionIdFromAgentEvent(event);\n if (derived) return derived;\n\n return WORKFLOW_DEFAULT_LOOP_SESSION_ID;\n}\n\nfunction bindLoopSessionToContainerTree(\n tree: WorkflowContainerTreeState,\n event: LangchainAgentEvent,\n): WorkflowContainerTreeState {\n const sessionId = resolveAgentLoopSessionId(event);\n if (!sessionId) return tree;\n\n if (findContainerByLoopSession(tree, sessionId)) return tree;\n\n const data = (event.data ?? {}) as Record<string, unknown>;\n const workflowPath = readString(data, 'workflow_path') ?? null;\n const scopeKey = resolveContentScopeKey(data);\n\n let targetId: string | null = null;\n\n if (scopeKey) {\n targetId = resolveContentTargetFromSnapshot(\n containerTreeToSnapshot(tree),\n workflowPath,\n scopeKey,\n );\n }\n\n if (!targetId) {\n for (const containerId of tree.activeContainerIds) {\n const node = tree.containersById[containerId];\n if (\n (node?.scope === 'item' || node?.scope === 'stage')\n && !node.loopSessionId\n ) {\n targetId = containerId;\n break;\n }\n }\n }\n\n if (!targetId) {\n targetId = resolveContentTargetFromSnapshot(\n containerTreeToSnapshot(tree),\n workflowPath,\n null,\n );\n }\n\n if (!targetId) return tree;\n\n const node = tree.containersById[targetId];\n if (!node || node.loopSessionId) return tree;\n\n // D24 §8.2: 只有 stage / item / branch 才承载 agent loop;aggregate / route-decision /\n // workflow 等聚合性 scope 不应被绑定 loopSessionId(否则会被 suppressContentContainerIds\n // 抹掉 content_blocks,aggregate 的 waiting teaser、route 的 decision 都会失效)。\n if (node.scope !== 'stage' && node.scope !== 'item' && node.scope !== 'branch') {\n return tree;\n }\n\n return {\n ...tree,\n containersById: {\n ...tree.containersById,\n [targetId]: { ...node, loopSessionId: sessionId },\n },\n };\n}\n\nfunction applyStructureEvent(\n state: WorkflowSessionState,\n event: LangchainAgentEvent,\n): WorkflowSessionState {\n let containerTree = applyStructureToContainerTree(state.containerTree, event);\n containerTree = prebindLoopSessionFromStructureOpen(containerTree, event);\n\n const loopSessionId = deriveLoopSessionIdFromStructureOpen(event);\n let nextState: WorkflowSessionState = { ...state, containerTree };\n\n if (loopSessionId) {\n nextState = ensureLoopTree(nextState, loopSessionId);\n }\n\n const workflowProgress = syncWorkflowProgressFromContainerTree(\n containerTree,\n state.workflowProgress,\n );\n\n let status = nextState.status;\n if (workflowProgress.status === 'done') status = 'done';\n else if (workflowProgress.status === 'error') status = 'error';\n else if (status === 'connecting') status = 'running';\n\n const base = {\n ...nextState,\n status,\n containerTree,\n workflowProgress,\n };\n\n if (event.session_id && !state.meta.workflowRunId) {\n return {\n ...base,\n meta: { ...state.meta, workflowRunId: event.session_id },\n };\n }\n\n return base;\n}\n\nfunction ensureLoopTree(\n state: WorkflowSessionState,\n loopSessionId: string,\n): WorkflowSessionState {\n if (state.loopTreesBySessionId[loopSessionId]) return state;\n const loopTree = createWorkflowRunningLoopTree();\n return {\n ...state,\n loopTreesBySessionId: {\n ...state.loopTreesBySessionId,\n [loopSessionId]: loopTree,\n },\n activeLoopSessionId: state.activeLoopSessionId ?? loopSessionId,\n };\n}\n\n/** Pure reducer:Workflow 会话状态 + 单条事件。 */\nexport function reduceWorkflowSession(\n state: WorkflowSessionState,\n event: LangchainAgentEvent,\n eventIndex: number,\n options?: ReduceOptions,\n): WorkflowSessionState {\n if (event.event_type === 'task-list-snapshot') {\n const data = event.data as Record<string, unknown>;\n const taskListId =\n typeof data.task_list_id === 'string' ? data.task_list_id : undefined;\n const loopSessionId =\n taskListId ?? event.session_id ?? 'workflow-loop-default';\n let next = ensureLoopTree(state, loopSessionId);\n const loopTree = next.loopTreesBySessionId[loopSessionId]!;\n const reducedLoop = reduceTree(loopTree, event, eventIndex, options);\n return {\n ...next,\n loopTreesBySessionId: {\n ...next.loopTreesBySessionId,\n [loopSessionId]: reducedLoop,\n },\n activeLoopSessionId: loopSessionId,\n };\n }\n\n if (isWorkflowStructureEventType(event.event_type)) {\n return applyStructureEvent(state, event);\n }\n\n const loopSessionId =\n resolveAgentLoopSessionId(event) ?? WORKFLOW_DEFAULT_LOOP_SESSION_ID;\n let containerTree = bindLoopSessionToContainerTree(state.containerTree, event);\n containerTree = applyStructureToContainerTree(containerTree, event);\n let next = ensureLoopTree({ ...state, containerTree }, loopSessionId);\n const loopTree = next.loopTreesBySessionId[loopSessionId]!;\n const reducedLoop = reduceTree(loopTree, event, eventIndex, options);\n\n const workflowProgress = syncWorkflowProgressFromContainerTree(\n next.containerTree,\n next.workflowProgress,\n );\n\n return {\n ...next,\n workflowProgress,\n loopTreesBySessionId: {\n ...next.loopTreesBySessionId,\n [loopSessionId]: reducedLoop,\n },\n activeLoopSessionId: loopSessionId,\n status: reducedLoop.status === 'error' ? 'error' : next.status === 'connecting' ? 'running' : next.status,\n };\n}\n\n/** 从空状态回放 workflow 事件序列。 */\nexport function reduceWorkflowEvents(\n events: LangchainAgentEvent[],\n options?: ReduceOptions,\n): WorkflowSessionState {\n return events.reduce(\n (state, event, index) => reduceWorkflowSession(state, event, index, options),\n createEmptyWorkflowSessionState(),\n );\n}\n","/**\n * stageDoneSummary.ts — Stage 完成摘要(对齐 CC Agent Done 行)\n *\n * 职责:\n * 从 scoped loop tree 统计 tool uses / duration / agent turn;提取 text teaser。\n *\n * 链路位置:\n * WorkflowStageContainer 完成态显示(P2+)。\n *\n * 当前裁剪范围:\n * 不含 React;仅纯函数统计。\n */\nimport type { SessionTree } from '../../types/tree';\n\nexport interface StageDoneSummary {\n label: string;\n teaser: string;\n extraLines: number;\n}\n\nfunction countToolUses(tree: SessionTree): number {\n return Object.values(tree.byId).filter((node) => node.kind === 'tool_call').length;\n}\n\nfunction computeDurationSeconds(tree: SessionTree): number | null {\n const started = tree.meta.startedAt;\n if (started == null) return null;\n\n let maxTs = started;\n for (const node of Object.values(tree.byId)) {\n if ('endedAt' in node && typeof node.endedAt === 'number') {\n maxTs = Math.max(maxTs, node.endedAt);\n }\n if ('startedAt' in node && typeof node.startedAt === 'number') {\n maxTs = Math.max(maxTs, node.startedAt);\n }\n }\n\n const seconds = Math.round((maxTs - started) / 1000);\n return seconds > 0 ? seconds : null;\n}\n\nfunction lastTextContent(tree: SessionTree): string {\n const textNodes = Object.values(tree.byId).filter((node) => node.kind === 'text');\n if (textNodes.length === 0) return '';\n return textNodes[textNodes.length - 1]!.accumulated.trim();\n}\n\n/** 从 loop tree 构建 Stage Done 摘要 + 首行 teaser(非 display.description)。 */\nexport function buildStageDoneSummary(tree: SessionTree): StageDoneSummary | null {\n if (tree.status !== 'done' && tree.status !== 'error') return null;\n\n const toolUses = countToolUses(tree);\n const duration = computeDurationSeconds(tree);\n const durationSuffix = duration != null ? ` · ${duration}s` : '';\n\n const label =\n toolUses > 0\n ? `Done (${toolUses} tool use${toolUses === 1 ? '' : 's'}${durationSuffix})`\n : `Done (1 agent turn${durationSuffix})`;\n\n const fullText = lastTextContent(tree);\n const lines = fullText.split('\\n').map((line) => line.trim()).filter(Boolean);\n const teaser = lines[0] ?? '';\n const extraLines = Math.max(0, lines.length - 1);\n\n return { label, teaser, extraLines };\n}\n\nexport function formatTeaserExpandHint(extraLines: number, verbose: boolean): string | null {\n if (extraLines <= 0) return null;\n const shown = verbose ? Math.min(extraLines, 2) : 0;\n const hidden = extraLines - shown;\n if (hidden <= 0) return null;\n return `… +${hidden} lines (ctrl+o to expand)`;\n}\n","import { buildStageDoneSummary, type StageDoneSummary } from './stageDoneSummary';\nimport type { SessionTree } from '../../types/tree';\nimport type { WorkflowContainerRuntimeNode, WorkflowContainerTreeState } from '../../types/workflowContainer';\nimport type { WorkflowSessionState } from '../../types/workflowSession';\n\nexport function containersByLoopSessionId(\n tree: WorkflowContainerTreeState,\n): Map<string, WorkflowContainerRuntimeNode> {\n const map = new Map<string, WorkflowContainerRuntimeNode>();\n for (const node of Object.values(tree.containersById)) {\n if (node.loopSessionId) map.set(node.loopSessionId, node);\n }\n return map;\n}\n\nfunction collectProtectedLoopSessionIds(\n state: WorkflowSessionState,\n pinnedLoopSessionIds: Record<string, true>,\n): Set<string> {\n const protectedIds = new Set<string>(Object.keys(pinnedLoopSessionIds));\n const byLoop = containersByLoopSessionId(state.containerTree);\n\n if (state.activeLoopSessionId) {\n const activeContainer = byLoop.get(state.activeLoopSessionId);\n if (\n activeContainer\n && (activeContainer.status === 'running' || activeContainer.status === 'retrying')\n ) {\n protectedIds.add(state.activeLoopSessionId);\n }\n }\n\n for (const containerId of state.containerTree.activeContainerIds) {\n const node = state.containerTree.containersById[containerId];\n if (!node?.loopSessionId) continue;\n if (node.status === 'running' || node.status === 'retrying') {\n protectedIds.add(node.loopSessionId);\n }\n }\n\n for (const node of Object.values(state.containerTree.containersById)) {\n if (!node.loopSessionId) continue;\n if (node.status === 'running' || node.status === 'retrying') {\n protectedIds.add(node.loopSessionId);\n }\n }\n\n return protectedIds;\n}\n\n/**\n * P2:淘汰 completed/failed 且未 pin/不在热缓存中的 loop 树,缓存 done 摘要。\n * hotCompletedLoopSessionIds 中的 completed loop 受保护(LRU 热缓存)。\n */\nexport function evictInactiveLoopTrees(\n state: WorkflowSessionState,\n pinnedLoopSessionIds: Record<string, true>,\n): WorkflowSessionState {\n const protectedIds = collectProtectedLoopSessionIds(state, pinnedLoopSessionIds);\n\n // P2:热缓存中的 completed loop 也受保护\n for (const id of state.hotCompletedLoopSessionIds) {\n protectedIds.add(id);\n }\n\n const byLoop = containersByLoopSessionId(state.containerTree);\n const nextLoops: Record<string, SessionTree> = { ...state.loopTreesBySessionId };\n const nextSummaries: Record<string, StageDoneSummary> = {\n ...state.stageDoneSummariesByContainerId,\n };\n\n for (const [loopSessionId, tree] of Object.entries(state.loopTreesBySessionId)) {\n if (protectedIds.has(loopSessionId)) continue;\n\n const container = byLoop.get(loopSessionId);\n if (!container) continue;\n if (container.status !== 'completed' && container.status !== 'failed') continue;\n\n const summary = buildStageDoneSummary(tree);\n if (summary) {\n nextSummaries[container.container_id] = summary;\n }\n delete nextLoops[loopSessionId];\n }\n\n return {\n ...state,\n loopTreesBySessionId: nextLoops,\n stageDoneSummariesByContainerId: nextSummaries,\n };\n}\n\n/**\n * P2:将 completed loop 移到 LRU 热缓存尾部(最近使用)。\n * 如果该 loop 尚未在内存中(尚未 hydrate),仍然 touch 以预占位置。\n */\nexport function touchCompletedLoopSession(\n state: WorkflowSessionState,\n loopSessionId: string,\n): WorkflowSessionState {\n const ids = state.hotCompletedLoopSessionIds.filter((id) => id !== loopSessionId);\n ids.push(loopSessionId); // 最近使用在尾部\n return {\n ...state,\n hotCompletedLoopSessionIds: ids,\n };\n}\n\n/**\n * P2:热缓存溢出淘汰 — 超过 maxHydratedCompletedLoops 时,\n * 从头部(最旧)淘汰 completed loop 树,但保留 done 摘要。\n */\nexport function evictCompletedLoopOverflow(\n state: WorkflowSessionState,\n maxHydratedCompletedLoops: number,\n): WorkflowSessionState {\n if (state.hotCompletedLoopSessionIds.length <= maxHydratedCompletedLoops) {\n return state;\n }\n\n const overflow = state.hotCompletedLoopSessionIds.length - maxHydratedCompletedLoops;\n const evictedIds = new Set(state.hotCompletedLoopSessionIds.slice(0, overflow));\n const trimmedIds = state.hotCompletedLoopSessionIds.slice(overflow);\n\n const byLoop = containersByLoopSessionId(state.containerTree);\n const nextLoops: Record<string, SessionTree> = { ...state.loopTreesBySessionId };\n const nextSummaries: Record<string, StageDoneSummary> = {\n ...state.stageDoneSummariesByContainerId,\n };\n\n for (const id of evictedIds) {\n const tree = nextLoops[id];\n if (!tree) continue;\n const container = byLoop.get(id);\n if (container) {\n const summary = buildStageDoneSummary(tree);\n if (summary) {\n nextSummaries[container.container_id] = summary;\n }\n }\n delete nextLoops[id];\n }\n\n return {\n ...state,\n loopTreesBySessionId: nextLoops,\n stageDoneSummariesByContainerId: nextSummaries,\n hotCompletedLoopSessionIds: trimmedIds,\n };\n}\n","/**\n * WorkflowChrome.tsx — Workflow 容器树显示轨(display + scoped loop)\n */\nimport { useMemo, useState, type ReactNode } from 'react';\n\nimport { useWorkflowScaleOptions } from '../../core/context/WorkflowScaleContext';\nimport type { SessionTree } from '../../types/tree';\nimport type {\n WorkflowContainerRuntimeNode,\n WorkflowContainerTreeState,\n} from '../../types/workflowContainer';\nimport { WorkflowAggregateContainer } from './WorkflowAggregateContainer';\nimport { WorkflowContainerLine } from './WorkflowContainerLine';\nimport { WorkflowParallelGroup } from './WorkflowParallelGroup';\nimport { WorkflowRootContainer } from './WorkflowRootContainer';\nimport { WorkflowRouteContainer } from './WorkflowRouteContainer';\nimport { WorkflowStageContainer } from './WorkflowStageContainer';\nimport { WorkflowSubworkflowContainer } from './WorkflowSubworkflowContainer';\nimport { partitionWorkflowStages } from './workflowStageListUtils';\n\nexport interface WorkflowChromeProps {\n containerTree: WorkflowContainerTreeState;\n loopTreesBySessionId?: Record<string, SessionTree>;\n virtualized?: boolean;\n virtualizeThreshold?: number;\n groupParallelTools?: boolean;\n}\n\ntype ViewProps = Pick<\n WorkflowChromeProps,\n 'virtualized' | 'virtualizeThreshold' | 'groupParallelTools'\n>;\n\nfunction collectChildContainers(\n containersById: Record<string, WorkflowContainerRuntimeNode>,\n parentId: string,\n): WorkflowContainerRuntimeNode[] {\n return Object.values(containersById)\n .filter((node) => node.parent_container_id === parentId)\n .sort((a, b) => a.scope_key.localeCompare(b.scope_key));\n}\n\nfunction resolveLoopTree(\n node: WorkflowContainerRuntimeNode,\n loopTreesBySessionId: Record<string, SessionTree>,\n): SessionTree | undefined {\n if (!node.loopSessionId) return undefined;\n return loopTreesBySessionId[node.loopSessionId];\n}\n\nfunction collectSiblingItems(\n node: WorkflowContainerRuntimeNode,\n containersById: Record<string, WorkflowContainerRuntimeNode>,\n): WorkflowContainerRuntimeNode[] {\n if (!node.parent_container_id) return [];\n return collectChildContainers(containersById, node.parent_container_id).filter(\n (child) => child.scope === 'item',\n );\n}\n\nfunction renderLeafContainer(\n node: WorkflowContainerRuntimeNode,\n depth: number,\n containerTree: WorkflowContainerTreeState,\n loopTreesBySessionId: Record<string, SessionTree>,\n viewProps: ViewProps,\n): ReactNode {\n const loopTree = resolveLoopTree(node, loopTreesBySessionId);\n\n switch (node.scope) {\n case 'aggregate':\n return (\n <WorkflowAggregateContainer\n key={node.container_id}\n node={node}\n loopTree={loopTree}\n siblingItems={collectSiblingItems(node, containerTree.containersById)}\n depth={depth}\n {...viewProps}\n />\n );\n case 'branch':\n return (\n <WorkflowRouteContainer\n key={node.container_id}\n node={node}\n loopTree={loopTree}\n depth={depth}\n {...viewProps}\n />\n );\n default:\n return (\n <WorkflowStageContainer\n key={node.container_id}\n node={node}\n loopTree={loopTree}\n depth={depth}\n {...viewProps}\n />\n );\n }\n}\n\nfunction renderItemSiblings(\n items: WorkflowContainerRuntimeNode[],\n groupKey: string,\n depth: number,\n containerTree: WorkflowContainerTreeState,\n loopTreesBySessionId: Record<string, SessionTree>,\n viewProps: ViewProps,\n): ReactNode {\n if (items.length >= 2) {\n return (\n <WorkflowParallelGroup\n groupKey={groupKey}\n items={items}\n loopTreesBySessionId={loopTreesBySessionId}\n depth={depth}\n {...viewProps}\n />\n );\n }\n if (items.length === 1) {\n return renderLeafContainer(items[0]!, depth, containerTree, loopTreesBySessionId, viewProps);\n }\n return null;\n}\n\nfunction renderContainerChildren(\n parentId: string,\n containerTree: WorkflowContainerTreeState,\n loopTreesBySessionId: Record<string, SessionTree>,\n viewProps: ViewProps,\n depth: number,\n): ReactNode {\n const children = collectChildContainers(containerTree.containersById, parentId);\n const items = children.filter((node) => node.scope === 'item');\n const rest = children.filter((node) => node.scope !== 'item');\n\n return (\n <>\n {renderItemSiblings(items, parentId, depth, containerTree, loopTreesBySessionId, viewProps)}\n {rest.map((node) => renderContainerNode(node, containerTree, loopTreesBySessionId, viewProps, depth))}\n </>\n );\n}\n\nfunction renderContainerNode(\n node: WorkflowContainerRuntimeNode,\n containerTree: WorkflowContainerTreeState,\n loopTreesBySessionId: Record<string, SessionTree>,\n viewProps: ViewProps,\n depth: number,\n): ReactNode {\n const nested = renderContainerChildren(\n node.container_id,\n containerTree,\n loopTreesBySessionId,\n viewProps,\n depth + 1,\n );\n const hasNested =\n collectChildContainers(containerTree.containersById, node.container_id).length > 0;\n\n if (node.scope === 'subworkflow') {\n return (\n <WorkflowSubworkflowContainer\n key={node.container_id}\n node={node}\n depth={depth}\n >\n {hasNested ? nested : null}\n </WorkflowSubworkflowContainer>\n );\n }\n\n if (node.scope === 'stage') {\n return (\n <div\n key={node.container_id}\n className=\"lax-workflow-nested-block\"\n data-testid={`lax-workflow-nested-${node.scope}-${node.scope_key}`}\n >\n {renderLeafContainer(node, depth, containerTree, loopTreesBySessionId, viewProps)}\n {hasNested ? (\n <div className=\"lax-workflow-container-children\">{nested}</div>\n ) : null}\n </div>\n );\n }\n\n if (node.scope === 'aggregate' || node.scope === 'branch') {\n return (\n <div key={node.container_id} className=\"lax-workflow-container-children\">\n {renderLeafContainer(node, depth, containerTree, loopTreesBySessionId, viewProps)}\n {hasNested ? nested : null}\n </div>\n );\n }\n\n return renderLeafContainer(node, depth, containerTree, loopTreesBySessionId, viewProps);\n}\n\nfunction renderWorkflowStageContent(\n node: WorkflowContainerRuntimeNode,\n containerTree: WorkflowContainerTreeState,\n loopTreesBySessionId: Record<string, SessionTree>,\n viewProps: ViewProps,\n): ReactNode {\n return renderContainerNode(node, containerTree, loopTreesBySessionId, viewProps, 1);\n}\n\nfunction renderWorkflowStageRow(\n node: WorkflowContainerRuntimeNode,\n containerTree: WorkflowContainerTreeState,\n loopTreesBySessionId: Record<string, SessionTree>,\n viewProps: ViewProps,\n as: 'li' | 'div' = 'li',\n): ReactNode {\n const className = 'lax-workflow-stage-list__item';\n const content = renderWorkflowStageContent(\n node,\n containerTree,\n loopTreesBySessionId,\n viewProps,\n );\n if (as === 'div') {\n return (\n <div key={node.container_id} className={className} role=\"listitem\">\n {content}\n </div>\n );\n }\n return (\n <li key={node.container_id} className={className}>\n {content}\n </li>\n );\n}\n\nfunction WorkflowStageListPanel({\n stages,\n containerTree,\n loopTreesBySessionId,\n viewProps,\n}: {\n stages: WorkflowContainerRuntimeNode[];\n containerTree: WorkflowContainerTreeState;\n loopTreesBySessionId: Record<string, SessionTree>;\n viewProps: ViewProps;\n}) {\n const scale = useWorkflowScaleOptions();\n // P3:分页计数 — 每次点击“Show N more”递增一页,避免一次性展开 180 done stage\n const [extraCompletedPages, setExtraCompletedPages] = useState(0);\n const maxVisibleDoneCount =\n scale.completedStagePageSize + extraCompletedPages * scale.completedStagePageSize;\n\n const partition = useMemo(\n () => partitionWorkflowStages(stages, maxVisibleDoneCount),\n [stages, maxVisibleDoneCount],\n );\n\n if (partition.visible.length === 0) return null;\n\n const showMoreCount = Math.min(\n scale.completedStagePageSize,\n partition.totalDoneCount - partition.visibleDoneCount,\n );\n\n return (\n <>\n <ol className=\"lax-workflow-stage-list\" data-testid=\"lax-workflow-stage-list\">\n {partition.visible.map((node) =>\n renderWorkflowStageRow(node, containerTree, loopTreesBySessionId, viewProps),\n )}\n </ol>\n\n {partition.hiddenCount > 0 ? (\n <button\n type=\"button\"\n className=\"lax-workflow-stage-list__show-all\"\n data-testid=\"lax-workflow-stage-show-more\"\n onClick={() => setExtraCompletedPages((p) => p + 1)}\n >\n +{partition.hiddenCount} completed stages hidden · Show {showMoreCount} more\n </button>\n ) : null}\n\n {extraCompletedPages > 0 && partition.hiddenCount === 0 ? (\n <button\n type=\"button\"\n className=\"lax-workflow-stage-list__show-all\"\n data-testid=\"lax-workflow-stage-show-less\"\n onClick={() => setExtraCompletedPages(0)}\n >\n Show fewer completed stages\n </button>\n ) : null}\n\n {partition.hiddenCount > 0 ? (\n <p\n className=\"lax-workflow-stage-list__hidden-hint\"\n data-testid=\"lax-workflow-stage-hidden-hint\"\n >\n {partition.hiddenCount} completed stage{partition.hiddenCount !== 1 ? 's' : ''} hidden —\n running, pending, and failed stages are always visible.\n </p>\n ) : null}\n </>\n );\n}\n\nfunction renderWorkflowChildren(\n workflowNode: WorkflowContainerRuntimeNode,\n containerTree: WorkflowContainerTreeState,\n loopTreesBySessionId: Record<string, SessionTree>,\n viewProps: ViewProps,\n) {\n const children = collectChildContainers(\n containerTree.containersById,\n workflowNode.container_id,\n );\n const stages = children.filter((node) => node.scope === 'stage');\n const items = children.filter((node) => node.scope === 'item');\n const other = children.filter(\n (node) => node.scope !== 'stage' && node.scope !== 'item',\n );\n\n return (\n <>\n {stages.length > 0 ? (\n <WorkflowStageListPanel\n stages={stages}\n containerTree={containerTree}\n loopTreesBySessionId={loopTreesBySessionId}\n viewProps={viewProps}\n />\n ) : null}\n\n {renderItemSiblings(items, workflowNode.container_id, 1, containerTree, loopTreesBySessionId, viewProps)}\n\n {other.map((node) =>\n renderContainerNode(node, containerTree, loopTreesBySessionId, viewProps, 1),\n )}\n </>\n );\n}\n\nexport function WorkflowChrome({\n containerTree,\n loopTreesBySessionId = {},\n virtualized,\n virtualizeThreshold,\n groupParallelTools,\n}: WorkflowChromeProps) {\n const viewProps = { virtualized, virtualizeThreshold, groupParallelTools };\n const rootNodes = containerTree.rootContainerIds\n .map((id) => containerTree.containersById[id])\n .filter((node): node is WorkflowContainerRuntimeNode => node != null);\n\n if (rootNodes.length === 0) {\n return (\n <div className=\"lax-workflow-chrome\" data-testid=\"lax-workflow-chrome\">\n <WorkflowContainerLine\n variant=\"root\"\n title=\"Workflow\"\n uiStatus=\"pending\"\n statusLabel=\"pending\"\n />\n </div>\n );\n }\n\n return (\n <div className=\"lax-workflow-chrome\" data-testid=\"lax-workflow-chrome\">\n {rootNodes.map((workflowNode) => (\n <WorkflowRootContainer key={workflowNode.container_id} node={workflowNode}>\n {renderWorkflowChildren(\n workflowNode,\n containerTree,\n loopTreesBySessionId,\n viewProps,\n )}\n </WorkflowRootContainer>\n ))}\n </div>\n );\n}\n","/**\n * WorkflowAggregateContainer.tsx — Parallel aggregate 容器行\n *\n * 职责:\n * waiting (k/n) / running / Done;合并结果 teaser;D24 壳行语法。\n *\n * 链路位置:\n * WorkflowChrome → scope aggregate 节点。\n */\nimport { useCallback, useEffect, useMemo, useState, type CSSProperties } from 'react';\n\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\nimport type { SessionTree } from '../../types/tree';\nimport { AgentLoopView } from '../agentLoop/AgentLoopView';\nimport { WorkflowContainerLine } from './WorkflowContainerLine';\nimport { WorkflowExpandTrigger } from './WorkflowExpandTrigger';\nimport {\n buildAggregateLineMeta,\n buildAggregateStatusLabel,\n mapAggregateUiStatus,\n} from './workflowContainerLineUtils';\n\nexport interface WorkflowAggregateContainerProps {\n node: WorkflowContainerRuntimeNode;\n loopTree?: SessionTree;\n siblingItems?: WorkflowContainerRuntimeNode[];\n depth?: number;\n virtualized?: boolean;\n virtualizeThreshold?: number;\n groupParallelTools?: boolean;\n}\n\nfunction mergeTeaser(node: WorkflowContainerRuntimeNode): string {\n const blocks = node.content_blocks;\n if (blocks.length === 0) return '';\n const last = blocks[blocks.length - 1];\n return last?.preview ?? '';\n}\n\nexport function WorkflowAggregateContainer({\n node,\n loopTree,\n siblingItems = [],\n depth = 1,\n virtualized,\n virtualizeThreshold,\n groupParallelTools,\n}: WorkflowAggregateContainerProps) {\n const isRunning = node.status === 'running' || node.status === 'retrying';\n const isWaiting = node.status === 'pending' || node.status === 'blocked';\n const isDone = node.status === 'completed' || node.status === 'failed';\n const teaser = useMemo(() => mergeTeaser(node), [node]);\n const waitingTeaser = isWaiting ? (teaser || node.subtitle || '') : '';\n const testId = `lax-workflow-aggregate-${node.scope_key}`;\n const uiStatus = mapAggregateUiStatus(node);\n const statusLabel = buildAggregateStatusLabel(node, siblingItems);\n\n const [expanded, setExpanded] = useState(isRunning);\n\n useEffect(() => {\n if (isRunning) setExpanded(true);\n if (isDone) setExpanded(false);\n }, [isRunning, isDone]);\n\n const toggleExpanded = useCallback(() => {\n setExpanded((prev) => !prev);\n }, []);\n\n const shellToggle =\n isRunning ? toggleExpanded\n : isDone && expanded ? toggleExpanded\n : undefined;\n\n return (\n <div\n className={`lax-workflow-aggregate lax-workflow-stage-container lax-workflow-stage-container--${\n isWaiting ? 'pending' : isDone ? 'done' : 'running'\n }`}\n data-testid={testId}\n data-container-scope=\"aggregate\"\n style={{ '--lax-workflow-depth': depth } as CSSProperties}\n >\n <WorkflowContainerLine\n title={node.title}\n description={node.subtitle || undefined}\n uiStatus={uiStatus}\n meta={buildAggregateLineMeta(node)}\n statusLabel={statusLabel}\n onToggle={shellToggle}\n interactive={isRunning}\n expanded={expanded}\n titleTestId={`${testId}-title`}\n descriptionTestId={`${testId}-desc`}\n />\n\n {isWaiting && waitingTeaser ? (\n <div className=\"lax-workflow-aggregate__waiting-teaser\" data-testid={`${testId}-waiting`}>\n ⎿ {waitingTeaser}\n </div>\n ) : null}\n\n {expanded && isRunning && loopTree ? (\n <div className=\"lax-workflow-stage-container__body\" data-testid={`${testId}-body`}>\n <AgentLoopView\n tree={loopTree}\n showTaskListFooter={false}\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n />\n </div>\n ) : null}\n\n {isDone && !expanded ? (\n <WorkflowExpandTrigger\n summary={`${node.title} · done`}\n teaser={teaser || undefined}\n onToggle={() => setExpanded(true)}\n expanded={false}\n testId={`${testId}-done`}\n teaserTestId={`${testId}-teaser`}\n />\n ) : null}\n\n {isDone && expanded && loopTree ? (\n <div className=\"lax-workflow-stage-container__body\" data-testid={`${testId}-body`}>\n <AgentLoopView\n tree={loopTree}\n showTaskListFooter={false}\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n />\n </div>\n ) : null}\n </div>\n );\n}\n","/**\n * WorkflowContainerLine.tsx — Workflow 壳行 SSOT(D24 P1)\n *\n * 职责:● title (description) · meta · status 单行渲染。\n *\n * 链路位置:WorkflowChrome 根行 · WorkflowStageContainer 壳行。\n */\nimport type { CSSProperties } from 'react';\n\nexport interface WorkflowContainerLineProps {\n title: string;\n description?: string;\n uiStatus: string;\n meta?: string[];\n statusLabel: string;\n showDot?: boolean;\n variant?: 'root' | 'default';\n onToggle?: () => void;\n expanded?: boolean;\n /** false 时强制 div(done 折叠态避免与 ExpandTrigger 双 button 展开) */\n interactive?: boolean;\n titleTestId?: string;\n descriptionTestId?: string;\n headerTestId?: string;\n debugScopeKey?: string;\n verbose?: boolean;\n className?: string;\n style?: CSSProperties;\n}\n\nexport function WorkflowContainerLine({\n title,\n description,\n uiStatus,\n meta = [],\n statusLabel,\n showDot = true,\n variant = 'default',\n onToggle,\n expanded,\n interactive,\n titleTestId,\n descriptionTestId,\n headerTestId,\n debugScopeKey,\n verbose = false,\n className = '',\n style,\n}: WorkflowContainerLineProps) {\n const lineClass = [\n 'lax-workflow-container-line',\n variant === 'root' ? 'lax-workflow-container-line--root' : '',\n onToggle && interactive !== false ? 'lax-workflow-container-line--interactive' : '',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const content = (\n <>\n {showDot ? (\n <span\n className=\"lax-workflow-container-line__status-dot lax-workflow-stage-container__status-dot\"\n data-status={uiStatus}\n aria-hidden\n />\n ) : null}\n <span className=\"lax-workflow-container-line__title\" data-testid={titleTestId}>\n {title}\n </span>\n {description ? (\n <span\n className=\"lax-workflow-container-line__desc\"\n data-testid={descriptionTestId}\n >\n ({description})\n </span>\n ) : null}\n {meta.length > 0 ? (\n <span className=\"lax-workflow-container-line__meta\" data-testid={titleTestId ? `${titleTestId}-meta` : undefined}>\n {meta.join(' · ')}\n </span>\n ) : null}\n {verbose && debugScopeKey ? (\n <span className=\"lax-workflow-container-line__debug\" data-testid=\"lax-workflow-id\">\n {debugScopeKey}\n </span>\n ) : null}\n <span className=\"lax-workflow-container-line__status\">{statusLabel}</span>\n </>\n );\n\n if (onToggle && interactive !== false) {\n return (\n <button\n type=\"button\"\n className={`${lineClass} lax-workflow-stage-container__header`}\n onClick={onToggle}\n aria-expanded={expanded}\n data-testid={headerTestId}\n style={style}\n >\n {content}\n </button>\n );\n }\n\n if (onToggle) {\n return (\n <div\n className={`${lineClass} lax-workflow-container-line--static-toggle`}\n onClick={onToggle}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n onToggle();\n }\n }}\n role=\"button\"\n tabIndex={0}\n aria-expanded={expanded}\n data-testid={headerTestId}\n style={style}\n >\n {content}\n </div>\n );\n }\n\n return (\n <div className={lineClass} style={style}>\n {content}\n </div>\n );\n}\n","/**\n * WorkflowExpandTrigger.tsx — 可点击 ⎿ 摘要行(D24 P2)\n *\n * 职责:Done teaser / Parallel 组摘要的展开入口;hint 与摘要同属 button。\n *\n * 链路位置:WorkflowStageContainer · WorkflowParallelGroup。\n */\nimport type { ReactNode } from 'react';\n\nexport interface WorkflowExpandTriggerProps {\n summary: ReactNode;\n summaryTestId?: string;\n teaser?: string;\n expandHint?: string | null;\n onToggle: () => void;\n expanded?: boolean;\n testId?: string;\n teaserTestId?: string;\n className?: string;\n}\n\nexport function WorkflowExpandTrigger({\n summary,\n summaryTestId,\n teaser,\n expandHint,\n onToggle,\n expanded = false,\n testId,\n teaserTestId,\n className = '',\n}: WorkflowExpandTriggerProps) {\n return (\n <button\n type=\"button\"\n className={`lax-workflow-expand-trigger${className ? ` ${className}` : ''}`}\n onClick={onToggle}\n aria-expanded={expanded}\n data-testid={testId}\n >\n <span className=\"lax-workflow-expand-trigger__summary\" data-testid={summaryTestId}>\n ⎿ {summary}\n </span>\n {teaser ? (\n <span\n className=\"lax-workflow-expand-trigger__teaser\"\n data-testid={teaserTestId}\n >\n {teaser}\n </span>\n ) : null}\n {expandHint ? (\n <span className=\"lax-workflow-expand-trigger__hint\">{expandHint}</span>\n ) : null}\n </button>\n );\n}\n","/**\n * workflowContainerLineUtils.ts — Workflow 壳行 meta / status 辅助\n *\n * 链路位置:WorkflowContainerLine · WorkflowChrome · WorkflowStageContainer。\n */\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\nimport type { WorkflowContainerStatus } from '../../types/workflowContainer';\n\n/** 方案 A:normal 模式 meta 首段为容器 scope(workflow / stage / item …)。 */\nexport function formatContainerScopeMetaLabel(\n scope: WorkflowContainerRuntimeNode['scope'],\n): string {\n return scope;\n}\n\nfunction withScopeMeta(node: WorkflowContainerRuntimeNode, parts: string[]): string[] {\n return [formatContainerScopeMetaLabel(node.scope), ...parts];\n}\n\nexport function mapContainerUiStatus(status: WorkflowContainerStatus): string {\n switch (status) {\n case 'completed':\n return 'done';\n case 'failed':\n return 'failed';\n case 'running':\n case 'retrying':\n return 'running';\n case 'skipped':\n return 'skipped';\n default:\n return 'pending';\n }\n}\n\nexport function mapContainerStatusLabel(status: WorkflowContainerStatus): string {\n switch (status) {\n case 'completed':\n return 'done';\n case 'failed':\n return 'failed';\n case 'running':\n return 'Running…';\n case 'retrying':\n return 'Retrying…';\n case 'skipped':\n return 'skipped';\n case 'blocked':\n return 'blocked';\n case 'cancelled':\n return 'cancelled';\n default:\n return 'pending';\n }\n}\n\nexport function mapWorkflowRootStatusLabel(status: WorkflowContainerStatus): string {\n switch (status) {\n case 'completed':\n return 'done';\n case 'failed':\n return 'error';\n default:\n return 'running';\n }\n}\n\nexport function buildStageProgressMeta(node: WorkflowContainerRuntimeNode): string | null {\n const display = node.display;\n if (display?.progress_label) return display.progress_label;\n if (display?.progress_current != null && display?.progress_total != null) {\n return `Step ${display.progress_current}/${display.progress_total}`;\n }\n return null;\n}\n\nexport function buildWorkflowRootMeta(node: WorkflowContainerRuntimeNode): string[] {\n const meta: string[] = [];\n if (node.pattern) meta.push(node.pattern);\n const display = node.display;\n if (display?.progress_current != null && display?.progress_total != null) {\n meta.push(`${display.progress_current}/${display.progress_total}`);\n }\n return withScopeMeta(node, meta);\n}\n\nexport function buildStageLineMeta(node: WorkflowContainerRuntimeNode): string[] {\n const progress = buildStageProgressMeta(node);\n return withScopeMeta(node, progress ? [progress] : []);\n}\n\nexport function buildAggregateLineMeta(node: WorkflowContainerRuntimeNode): string[] {\n return withScopeMeta(node, []);\n}\n\n/** Route branch:decision_label + 可选 step progress。 */\nexport function buildRouteLineMeta(node: WorkflowContainerRuntimeNode): string[] {\n const meta: string[] = [];\n const decision = node.display?.decision_label;\n if (decision) meta.push(decision);\n const progress = buildStageProgressMeta(node);\n if (progress) meta.push(progress);\n return withScopeMeta(node, meta);\n}\n\n/** depth ≥4 时略减缩进,防深层 subworkflow 横向溢出(D24 §5.4 / R3)。 */\nexport function workflowIndentUnit(depth: number): string {\n return depth >= 4 ? '0.75rem' : '1rem';\n}\n\nfunction countSettledItems(items: WorkflowContainerRuntimeNode[]): {\n settled: number;\n total: number;\n} {\n let settled = 0;\n for (const item of items) {\n if (item.status === 'completed' || item.status === 'failed') {\n settled += 1;\n }\n }\n return { settled, total: items.length };\n}\n\n/** Aggregate waiting (k/n):display 优先,否则统计同级 parallel item。 */\nexport function buildAggregateStatusLabel(\n node: WorkflowContainerRuntimeNode,\n siblingItems: WorkflowContainerRuntimeNode[] = [],\n): string {\n const display = node.display;\n let current = display?.progress_current;\n let total = display?.progress_total;\n\n if ((current == null || total == null) && siblingItems.length > 0) {\n const { settled, total: itemTotal } = countSettledItems(siblingItems);\n current = settled;\n total = itemTotal;\n }\n\n if (node.status === 'pending' || node.status === 'blocked') {\n if (current != null && total != null) {\n return `waiting (${current}/${total})`;\n }\n return 'waiting';\n }\n\n if (current != null && total != null && (node.status === 'running' || node.status === 'retrying')) {\n return `waiting (${current}/${total})`;\n }\n\n return mapContainerStatusLabel(node.status);\n}\n\nexport function mapAggregateUiStatus(node: WorkflowContainerRuntimeNode): string {\n if (node.status === 'pending' || node.status === 'blocked') return 'pending';\n if (node.status === 'completed') return 'done';\n if (node.status === 'failed') return 'failed';\n if (node.status === 'running' || node.status === 'retrying') return 'running';\n return mapContainerUiStatus(node.status);\n}\n","/**\n * WorkflowParallelGroup.tsx — Parallel item 组摘要 + 嵌套 item 行\n */\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useStore } from 'zustand';\n\nimport { useWorkflowScaleOptions } from '../../core/context/WorkflowScaleContext';\nimport { useWorkflowSessionStoreApi } from '../../core/context/WorkflowSessionContext';\nimport {\n computeParallelGroupMetrics,\n formatParallelGroupSummary,\n} from '../../core/workflow/workflowParallelGroupMetrics';\nimport type { SessionTree } from '../../types/tree';\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\nimport { WorkflowExpandTrigger } from './WorkflowExpandTrigger';\nimport { WorkflowStageContainer } from './WorkflowStageContainer';\nimport { isActiveWorkflowContainer } from './workflowStageListUtils';\n\nexport interface WorkflowParallelGroupProps {\n groupKey: string;\n items: WorkflowContainerRuntimeNode[];\n loopTreesBySessionId: Record<string, SessionTree>;\n depth?: number;\n virtualized?: boolean;\n virtualizeThreshold?: number;\n groupParallelTools?: boolean;\n}\n\nfunction resolveLoopTree(\n node: WorkflowContainerRuntimeNode,\n loopTreesBySessionId: Record<string, SessionTree>,\n): SessionTree | undefined {\n if (!node.loopSessionId) return undefined;\n return loopTreesBySessionId[node.loopSessionId];\n}\n\nexport function WorkflowParallelGroup({\n groupKey,\n items,\n loopTreesBySessionId,\n depth = 1,\n virtualized,\n virtualizeThreshold,\n groupParallelTools,\n}: WorkflowParallelGroupProps) {\n const scale = useWorkflowScaleOptions();\n const store = useWorkflowSessionStoreApi();\n const activeLoopSessionId = useStore(store, (s) => s.state.activeLoopSessionId);\n const activeContainerIds = useStore(store, (s) => s.state.containerTree.activeContainerIds);\n\n const metrics = useMemo(() => computeParallelGroupMetrics(items), [items]);\n const summary = formatParallelGroupSummary(metrics);\n const hasRunning = metrics.running > 0;\n const hasActiveItem = useMemo(\n () => items.some((item) => isActiveWorkflowContainer(item, activeLoopSessionId, activeContainerIds)),\n [items, activeLoopSessionId, activeContainerIds],\n );\n const allSettled =\n metrics.total > 0\n && metrics.running === 0\n && metrics.completed + metrics.failed >= metrics.total;\n\n const shouldAutoExpandGroup =\n hasRunning && (!scale.onlyExpandActiveRunning || hasActiveItem);\n\n const [expanded, setExpanded] = useState(shouldAutoExpandGroup);\n\n useEffect(() => {\n if (shouldAutoExpandGroup) {\n setExpanded(true);\n return;\n }\n if (hasRunning && scale.onlyExpandActiveRunning) {\n setExpanded(false);\n return;\n }\n if (allSettled) {\n setExpanded(false);\n }\n }, [shouldAutoExpandGroup, hasRunning, allSettled, scale.onlyExpandActiveRunning]);\n\n const toggleExpanded = useCallback(() => {\n setExpanded((prev) => !prev);\n }, []);\n\n useEffect(() => {\n const onKeyDown = (event: KeyboardEvent) => {\n if (!(event.ctrlKey || event.metaKey) || event.key.toLowerCase() !== 'o') return;\n setExpanded(true);\n };\n window.addEventListener('keydown', onKeyDown);\n return () => window.removeEventListener('keydown', onKeyDown);\n }, []);\n\n const renderItem = (index: number) => {\n const item = items[index]!;\n return (\n <WorkflowStageContainer\n key={item.container_id}\n node={item}\n loopTree={resolveLoopTree(item, loopTreesBySessionId)}\n depth={depth}\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n />\n );\n };\n\n return (\n <div\n className=\"lax-workflow-parallel-group\"\n data-testid={`lax-workflow-parallel-group-${groupKey}`}\n >\n <WorkflowExpandTrigger\n summary={summary}\n expandHint={!expanded && !hasRunning ? '(ctrl+o to expand)' : null}\n onToggle={toggleExpanded}\n expanded={expanded}\n testId={`lax-workflow-parallel-group-summary-${groupKey}`}\n className=\"lax-workflow-parallel-group__summary\"\n />\n\n {expanded ? (\n <div className=\"lax-workflow-parallel-list\" data-testid=\"lax-workflow-parallel-list\">\n {items.map((_, index) => renderItem(index))}\n </div>\n ) : null}\n </div>\n );\n}\n","/**\n * workflowParallelGroupMetrics.ts — Parallel 组 sibling item 客户端聚合\n *\n * 职责:\n * 对齐 D23 §5.6;metrics_* 未填时从容器 status 统计组摘要文案。\n *\n * 链路位置:\n * WorkflowParallelGroup → 组摘要行。\n *\n * 当前裁剪范围:\n * 仅 item scope 兄弟节点;不含 Aggregate metrics。\n */\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\n\nexport interface ParallelGroupMetrics {\n total: number;\n running: number;\n completed: number;\n failed: number;\n}\n\nfunction readDisplayMetrics(items: WorkflowContainerRuntimeNode[]): ParallelGroupMetrics | null {\n let hasMetrics = false;\n let running = 0;\n let completed = 0;\n let failed = 0;\n let total = 0;\n\n for (const item of items) {\n const metrics = item.display;\n if (\n metrics?.metrics_total != null\n || metrics?.metrics_running != null\n || metrics?.metrics_completed != null\n || metrics?.metrics_failed != null\n ) {\n hasMetrics = true;\n }\n running += metrics?.metrics_running ?? 0;\n completed += metrics?.metrics_completed ?? 0;\n failed += metrics?.metrics_failed ?? 0;\n total += metrics?.metrics_total ?? 0;\n }\n\n if (!hasMetrics) return null;\n if (total <= 0) total = items.length;\n return { total, running, completed, failed };\n}\n\n/** 从 sibling item 容器统计组 metrics(display.metrics_* 优先)。 */\nexport function computeParallelGroupMetrics(\n items: WorkflowContainerRuntimeNode[],\n): ParallelGroupMetrics {\n const fromDisplay = readDisplayMetrics(items);\n if (fromDisplay) return fromDisplay;\n\n let running = 0;\n let completed = 0;\n let failed = 0;\n\n for (const item of items) {\n switch (item.status) {\n case 'running':\n case 'retrying':\n running += 1;\n break;\n case 'completed':\n completed += 1;\n break;\n case 'failed':\n failed += 1;\n break;\n default:\n break;\n }\n }\n\n return {\n total: items.length,\n running,\n completed,\n failed,\n };\n}\n\nexport function formatParallelGroupSummary(metrics: ParallelGroupMetrics): string {\n if (metrics.running > 0) {\n const n = metrics.running;\n return `Running ${n} agent${n === 1 ? '' : 's'}…`;\n }\n if (metrics.failed > 0) {\n const ok = metrics.completed;\n return `Done (${ok} agent${ok === 1 ? '' : 's'}) · ${metrics.failed} failed`;\n }\n const n = metrics.total;\n return `Done (${n} agent${n === 1 ? '' : 's'})`;\n}\n","/**\n * WorkflowStageContainer.tsx — Stage / item 容器行(CC Agent 同构)\n */\nimport { useCallback, useEffect, useMemo, useState, type CSSProperties } from 'react';\nimport { useStore } from 'zustand';\n\nimport {\n buildStageDoneSummary,\n formatTeaserExpandHint,\n} from '../../core/workflow/stageDoneSummary';\nimport { useWorkflowLoopReplayHandler } from '../../core/context/WorkflowLoopReplayContext';\nimport { useWorkflowScaleOptions } from '../../core/context/WorkflowScaleContext';\nimport { useWorkflowSessionStoreApi } from '../../core/context/WorkflowSessionContext';\nimport { useSessionViewOptions } from '../../core/context/SessionContext';\nimport { createWorkflowRunningLoopTree } from '../../core/workflow/workflowLoopTreeUtils';\nimport type { SessionTree } from '../../types/tree';\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\nimport { AgentLoopView } from '../agentLoop/AgentLoopView';\nimport { WorkflowContainerLine } from './WorkflowContainerLine';\nimport { WorkflowStageDoneBody } from './workflowStageDoneBody';\nimport { isActiveWorkflowContainer } from './workflowStageListUtils';\nimport {\n buildStageLineMeta,\n mapContainerStatusLabel,\n mapContainerUiStatus,\n workflowIndentUnit,\n} from './workflowContainerLineUtils';\n\nexport interface WorkflowStageContainerProps {\n node: WorkflowContainerRuntimeNode;\n loopTree?: SessionTree;\n depth?: number;\n virtualized?: boolean;\n virtualizeThreshold?: number;\n groupParallelTools?: boolean;\n}\n\nfunction containerTestId(node: WorkflowContainerRuntimeNode): string {\n if (node.scope === 'item') return `lax-workflow-parallel-${node.scope_key}`;\n if (node.scope === 'stage') return `lax-workflow-stage-${node.scope_key}`;\n return `lax-workflow-container-${node.scope_key}`;\n}\n\nfunction bodyTestId(node: WorkflowContainerRuntimeNode): string {\n if (node.scope === 'item') return `lax-workflow-parallel-body-${node.scope_key}`;\n return `lax-workflow-stage-body-${node.scope_key}`;\n}\n\nexport function WorkflowStageContainer({\n node,\n loopTree,\n depth = 0,\n virtualized,\n virtualizeThreshold,\n groupParallelTools,\n}: WorkflowStageContainerProps) {\n const { verbose } = useSessionViewOptions();\n const scale = useWorkflowScaleOptions();\n const store = useWorkflowSessionStoreApi();\n const replayHandler = useWorkflowLoopReplayHandler();\n const activeLoopSessionId = useStore(store, (s) => s.state.activeLoopSessionId);\n const activeContainerIds = useStore(store, (s) => s.state.containerTree.activeContainerIds);\n const cachedSummary = useStore(\n store,\n (s) => s.state.stageDoneSummariesByContainerId[node.container_id],\n );\n const pinLoopSession = useStore(store, (s) => s.pinLoopSession);\n\n const uiStatus = mapContainerUiStatus(node.status);\n const isRunning = node.status === 'running' || node.status === 'retrying';\n const isDone = node.status === 'completed' || node.status === 'failed';\n const isSkipped = node.status === 'skipped';\n\n const isActive = isActiveWorkflowContainer(node, activeLoopSessionId, activeContainerIds);\n\n const doneSummaryFromTree = useMemo(\n () => (loopTree && isDone ? buildStageDoneSummary(loopTree) : null),\n [loopTree, isDone],\n );\n const doneSummary = doneSummaryFromTree ?? (isDone ? cachedSummary : null);\n\n const shouldAutoExpandRunning =\n isRunning && !isSkipped && (!scale.onlyExpandActiveRunning || isActive);\n\n const [expanded, setExpanded] = useState(shouldAutoExpandRunning);\n\n useEffect(() => {\n if (shouldAutoExpandRunning) {\n setExpanded(true);\n return;\n }\n if (isRunning && !isSkipped && scale.onlyExpandActiveRunning) {\n setExpanded(false);\n return;\n }\n if (isDone || isSkipped) {\n setExpanded(false);\n }\n }, [shouldAutoExpandRunning, isRunning, isDone, isSkipped, scale.onlyExpandActiveRunning]);\n\n const requestLoopHydration = useCallback(() => {\n const loopSessionId = node.loopSessionId;\n if (!loopSessionId || loopTree) return;\n pinLoopSession(loopSessionId);\n void replayHandler?.(loopSessionId);\n }, [node.loopSessionId, loopTree, pinLoopSession, replayHandler]);\n\n const toggleExpanded = useCallback(() => {\n setExpanded((prev) => {\n const next = !prev;\n if (next && isDone && node.loopSessionId && !loopTree) {\n requestLoopHydration();\n }\n return next;\n });\n }, [isDone, node.loopSessionId, loopTree, requestLoopHydration]);\n\n useEffect(() => {\n const onKeyDown = (event: KeyboardEvent) => {\n if (!(event.ctrlKey || event.metaKey) || event.key.toLowerCase() !== 'o') return;\n setExpanded(true);\n requestLoopHydration();\n };\n window.addEventListener('keydown', onKeyDown);\n return () => window.removeEventListener('keydown', onKeyDown);\n }, [requestLoopHydration]);\n\n const displayTitle = node.title;\n const usesScopedLoop = Boolean(node.loopSessionId);\n const runningLoopTree: SessionTree | undefined =\n loopTree ?? (usesScopedLoop && isRunning && isActive ? createWorkflowRunningLoopTree() : undefined);\n const staticContentTeaser =\n !usesScopedLoop && !loopTree && node.content_blocks.length > 0\n ? node.content_blocks[node.content_blocks.length - 1]!.preview\n : '';\n const teaserText = doneSummary?.teaser || staticContentTeaser;\n const expandHint =\n doneSummary ? formatTeaserExpandHint(doneSummary.extraLines, verbose) : null;\n const doneLabel = doneSummary?.label ?? 'done';\n const statusLabel = isDone ? doneLabel : mapContainerStatusLabel(node.status);\n const testId = containerTestId(node);\n const isItem = node.scope === 'item';\n\n const canToggleShell = (isRunning && !isSkipped) || isDone;\n const shellToggle = canToggleShell ? toggleExpanded : undefined;\n\n return (\n <div\n className={`lax-workflow-stage-container lax-workflow-stage-container--${uiStatus}${\n isSkipped ? ' lax-workflow-stage-container--skipped' : ''\n }${isItem ? ' lax-workflow-parallel-item' : ' lax-workflow-stage'}`}\n data-testid={testId}\n data-stage-status={uiStatus}\n data-container-scope={node.scope}\n data-active={isActive ? 'true' : undefined}\n style={\n {\n '--lax-workflow-depth': depth,\n '--lax-workflow-indent-unit': workflowIndentUnit(depth),\n } as CSSProperties\n }\n >\n <WorkflowContainerLine\n title={displayTitle}\n description={node.subtitle || undefined}\n uiStatus={uiStatus}\n meta={buildStageLineMeta(node)}\n statusLabel={statusLabel}\n onToggle={shellToggle}\n interactive={canToggleShell}\n expanded={expanded}\n headerTestId={isDone ? `${testId}-done` : undefined}\n titleTestId={`${testId}-title`}\n descriptionTestId={`${testId}-desc`}\n className={\n isItem\n ? 'lax-workflow-parallel-item__header'\n : undefined\n }\n />\n\n {isDone && !expanded && (teaserText || expandHint) ? (\n <div className=\"lax-workflow-stage-container__done-teaser\">\n {teaserText ? (\n <span\n className=\"lax-workflow-stage-container__done-teaser-line\"\n data-testid={`${testId}-teaser`}\n >\n {`⎿ ${teaserText}`}\n </span>\n ) : null}\n {expandHint ? (\n <span className=\"lax-workflow-expand-trigger__hint\">{expandHint}</span>\n ) : null}\n </div>\n ) : null}\n\n {expanded && isRunning && !usesScopedLoop && node.content_blocks.length > 0 ? (\n <div\n className=\"lax-workflow-stage-container__body lax-workflow-stage-container__content-preview\"\n data-testid={bodyTestId(node)}\n >\n {node.content_blocks.map((block, index) => (\n <div\n key={`${block.kind}-${index}`}\n className=\"lax-workflow-stage-container__teaser\"\n >\n {block.preview}\n </div>\n ))}\n </div>\n ) : null}\n\n {expanded && isRunning && runningLoopTree ? (\n <div\n className={\n isItem\n ? 'lax-workflow-parallel-item__body lax-workflow-stage-container__body'\n : 'lax-workflow-stage-container__body'\n }\n data-testid={bodyTestId(node)}\n >\n <AgentLoopView\n tree={runningLoopTree}\n showTaskListFooter={false}\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n />\n </div>\n ) : null}\n\n {isDone && expanded ? (\n loopTree ? (\n <WorkflowStageDoneBody\n node={node}\n loopTree={loopTree}\n testId={bodyTestId(node)}\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n bodyClassName={\n isItem\n ? 'lax-workflow-parallel-item__body lax-workflow-stage-container__body'\n : 'lax-workflow-stage-container__body'\n }\n />\n ) : (\n <div\n className=\"lax-workflow-stage-container__body lax-workflow-loop-replay-pending\"\n data-testid={bodyTestId(node)}\n >\n {teaserText ? <p className=\"lax-workflow-stage-container__teaser\">{teaserText}</p> : null}\n <p className=\"lax-workflow-loop-replay-pending__hint\">\n {replayHandler ? 'Loading loop details…' : 'Loop details evicted from memory.'}\n </p>\n </div>\n )\n ) : null}\n </div>\n );\n}\n","/**\n * loopTreeUtils.ts — Workflow scoped loop 树辅助判断\n */\nimport type { SessionTree } from '../../types/tree';\n\n/** 是否已有可渲染的时间线节点(非空 store 壳) */\nexport function hasTimelineNodes(tree: SessionTree | undefined): boolean {\n if (!tree) return false;\n return tree.rootChildren.length > 0 || Object.keys(tree.byId).length > 0;\n}\n","/**\n * workflowStageDoneBody.tsx — Stage/Route 完成态展开体(仅 AgentLoopView 时间线)\n *\n * 禁止用 content_blocks 原始预览充展开体(会与 AgentSession 折叠流不一致)。\n */\nimport { hasTimelineNodes } from '../../core/workflow/loopTreeUtils';\nimport type { SessionTree } from '../../types/tree';\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\nimport { AgentLoopView } from '../agentLoop/AgentLoopView';\n\nexport interface WorkflowStageDoneBodyProps {\n node: WorkflowContainerRuntimeNode;\n loopTree?: SessionTree;\n testId: string;\n virtualized?: boolean;\n virtualizeThreshold?: number;\n groupParallelTools?: boolean;\n bodyClassName?: string;\n}\n\nexport function WorkflowStageDoneBody({\n loopTree,\n testId,\n virtualized,\n virtualizeThreshold,\n groupParallelTools,\n bodyClassName = 'lax-workflow-stage-container__body',\n}: WorkflowStageDoneBodyProps) {\n if (loopTree && hasTimelineNodes(loopTree)) {\n return (\n <div className={bodyClassName} data-testid={testId}>\n <AgentLoopView\n tree={loopTree}\n showTaskListFooter={false}\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n />\n </div>\n );\n }\n\n return (\n <div\n className={`${bodyClassName} lax-workflow-stage-container__empty-hint`}\n data-testid={testId}\n >\n <span className=\"lax-workflow-stage-container__empty-hint-text\">\n (此阶段暂无 Agent 时间线内容)\n </span>\n </div>\n );\n}\n","import type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\n\nexport interface WorkflowStageListPartition {\n visible: WorkflowContainerRuntimeNode[];\n hiddenCount: number;\n total: number;\n /** 当前已展示的 done stage 数量 */\n visibleDoneCount: number;\n /** done stage 总数 */\n totalDoneCount: number;\n}\n\nfunction stageSortKey(node: WorkflowContainerRuntimeNode): number {\n return node.display?.progress_current ?? 0;\n}\n\n/**\n * P3:running / failed / pending / blocked 全显;\n * done 按 maxVisibleDoneCount 分页展示(默认最近 completedStagePageSize 条)。\n * maxVisibleDoneCount 由 WorkflowStageListPanel 的 \"Show N more\" 逐页递增。\n */\nexport function partitionWorkflowStages(\n stages: WorkflowContainerRuntimeNode[],\n maxVisibleDoneCount: number,\n): WorkflowStageListPartition {\n const sorted = [...stages].sort(\n (a, b) => stageSortKey(a) - stageSortKey(b) || a.scope_key.localeCompare(b.scope_key),\n );\n\n const always: WorkflowContainerRuntimeNode[] = [];\n const done: WorkflowContainerRuntimeNode[] = [];\n\n for (const stage of sorted) {\n if (\n stage.status === 'running'\n || stage.status === 'retrying'\n || stage.status === 'failed'\n || stage.status === 'pending'\n || stage.status === 'blocked'\n ) {\n always.push(stage);\n } else if (stage.status === 'completed' || stage.status === 'skipped') {\n done.push(stage);\n } else {\n always.push(stage);\n }\n }\n\n const visibleDone = done.slice(Math.max(0, done.length - maxVisibleDoneCount));\n const visible = [...always, ...visibleDone].sort(\n (a, b) => stageSortKey(a) - stageSortKey(b) || a.scope_key.localeCompare(b.scope_key),\n );\n const hiddenCount = stages.length - visible.length;\n\n return {\n visible,\n hiddenCount,\n total: stages.length,\n visibleDoneCount: visibleDone.length,\n totalDoneCount: done.length,\n };\n}\n\nexport function isActiveWorkflowContainer(\n node: WorkflowContainerRuntimeNode,\n activeLoopSessionId: string | null,\n activeContainerIds: string[],\n): boolean {\n if (activeContainerIds.includes(node.container_id)) return true;\n if (node.loopSessionId && node.loopSessionId === activeLoopSessionId) return true;\n return false;\n}\n","/**\r\r\n * WorkflowRootContainer.tsx — Workflow 根行(始终展示子树,不折叠)\r\r\n *\r\r\n * 职责:根行壳语法 + 常驻 stage 列表。Workflow 已是页面顶层,不做 AgentSession 式根折叠。\r\r\n *\r\r\n * 链路位置:WorkflowChrome → scope workflow 根节点。\r\r\n */\r\r\nimport type { ReactNode } from 'react';\r\r\n\r\r\nimport { useSessionViewOptions } from '../../core/context/SessionContext';\r\r\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\r\r\nimport { WorkflowContainerLine } from './WorkflowContainerLine';\r\r\nimport {\r\r\n buildWorkflowRootMeta,\r\r\n mapContainerUiStatus,\r\r\n mapWorkflowRootStatusLabel,\r\r\n} from './workflowContainerLineUtils';\r\r\n\r\r\nexport interface WorkflowRootContainerProps {\r\r\n node: WorkflowContainerRuntimeNode;\r\r\n children?: ReactNode;\r\r\n}\r\r\n\r\r\nexport function WorkflowRootContainer({\r\r\n node,\r\r\n children,\r\r\n}: WorkflowRootContainerProps) {\r\r\n const { verbose } = useSessionViewOptions();\r\r\n const uiStatus = mapContainerUiStatus(node.status);\r\r\n const statusLabel = mapWorkflowRootStatusLabel(node.status);\r\r\n\r\r\n return (\r\r\n <div className=\"lax-workflow-root\" data-testid=\"lax-workflow-root\">\r\r\n <WorkflowContainerLine\r\r\n variant=\"root\"\r\r\n title={node.title}\r\r\n description={node.subtitle || undefined}\r\r\n uiStatus={uiStatus}\r\r\n meta={buildWorkflowRootMeta(node)}\r\r\n statusLabel={statusLabel}\r\r\n titleTestId=\"lax-workflow-root-title\"\r\r\n descriptionTestId=\"lax-workflow-root-desc\"\r\r\n debugScopeKey={node.scope_key}\r\r\n verbose={verbose}\r\r\n />\r\r\n\r\r\n {children ? (\r\r\n <div className=\"lax-workflow-container-tree\">{children}</div>\r\r\n ) : null}\r\r\n </div>\r\r\n );\r\r\n}\r\r\n\r","/**\n * WorkflowRouteContainer.tsx — Route branch 容器行\n *\n * 职责:selected/running 分支可展开;skipped ◌ dim 静态一行。\n *\n * 链路位置:WorkflowChrome → scope branch 节点。\n */\nimport { useCallback, useEffect, useMemo, useState, type CSSProperties } from 'react';\n\nimport {\n buildStageDoneSummary,\n formatTeaserExpandHint,\n} from '../../core/workflow/stageDoneSummary';\nimport { useSessionViewOptions } from '../../core/context/SessionContext';\nimport type { SessionTree } from '../../types/tree';\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\nimport { AgentLoopView } from '../agentLoop/AgentLoopView';\nimport { WorkflowContainerLine } from './WorkflowContainerLine';\nimport { WorkflowExpandTrigger } from './WorkflowExpandTrigger';\nimport { WorkflowStageDoneBody } from './workflowStageDoneBody';\nimport {\n buildRouteLineMeta,\n mapContainerStatusLabel,\n mapContainerUiStatus,\n workflowIndentUnit,\n} from './workflowContainerLineUtils';\n\nexport interface WorkflowRouteContainerProps {\n node: WorkflowContainerRuntimeNode;\n loopTree?: SessionTree;\n depth?: number;\n virtualized?: boolean;\n virtualizeThreshold?: number;\n groupParallelTools?: boolean;\n}\n\nexport function WorkflowRouteContainer({\n node,\n loopTree,\n depth = 1,\n virtualized,\n virtualizeThreshold,\n groupParallelTools,\n}: WorkflowRouteContainerProps) {\n const { verbose } = useSessionViewOptions();\n const isSkipped = node.status === 'skipped';\n const uiStatus = mapContainerUiStatus(node.status);\n const isRunning = !isSkipped && (node.status === 'running' || node.status === 'retrying');\n const isDone = !isSkipped && (node.status === 'completed' || node.status === 'failed');\n const testId = `lax-workflow-route-${node.scope_key}`;\n const doneSummary = useMemo(\n () => (loopTree && isDone ? buildStageDoneSummary(loopTree) : null),\n [loopTree, isDone],\n );\n const staticContentTeaser =\n !loopTree && node.content_blocks.length > 0\n ? node.content_blocks[node.content_blocks.length - 1]!.preview\n : '';\n const teaserText = doneSummary?.teaser || staticContentTeaser;\n const expandHint =\n doneSummary ? formatTeaserExpandHint(doneSummary.extraLines, verbose) : null;\n const doneLabel = doneSummary?.label ?? 'done';\n\n const [expanded, setExpanded] = useState(isRunning);\n\n useEffect(() => {\n if (isSkipped) return;\n if (isRunning) setExpanded(true);\n if (isDone) setExpanded(false);\n }, [isRunning, isDone, isSkipped]);\n\n const toggleExpanded = useCallback(() => {\n if (!isSkipped) setExpanded((prev) => !prev);\n }, [isSkipped]);\n\n const shellToggle =\n isSkipped ? undefined\n : isRunning ? toggleExpanded\n : isDone && expanded ? toggleExpanded\n : undefined;\n\n const depthStyle = {\n '--lax-workflow-depth': depth,\n '--lax-workflow-indent-unit': workflowIndentUnit(depth),\n } as CSSProperties;\n\n return (\n <div\n className={`lax-workflow-route-branch lax-workflow-stage-container lax-workflow-stage-container--${uiStatus}${\n isSkipped ? ' lax-workflow-route-branch--skipped' : ''\n }`}\n data-testid={testId}\n data-route-status={node.status}\n data-container-scope=\"branch\"\n style={depthStyle}\n >\n <WorkflowContainerLine\n title={node.title}\n description={node.subtitle || undefined}\n uiStatus={uiStatus}\n meta={buildRouteLineMeta(node)}\n statusLabel={isSkipped ? 'skipped' : mapContainerStatusLabel(node.status)}\n onToggle={shellToggle}\n interactive={!isSkipped && isRunning}\n expanded={expanded}\n titleTestId={`${testId}-title`}\n descriptionTestId={`${testId}-desc`}\n />\n\n {!isSkipped && expanded && isRunning && loopTree ? (\n <div className=\"lax-workflow-stage-container__body\" data-testid={`${testId}-body`}>\n <AgentLoopView\n tree={loopTree}\n showTaskListFooter={false}\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n />\n </div>\n ) : null}\n\n {!isSkipped && isDone && !expanded ? (\n <WorkflowExpandTrigger\n summary={`${node.title} · ${doneLabel}`}\n teaser={teaserText || undefined}\n expandHint={expandHint}\n onToggle={() => setExpanded(true)}\n expanded={false}\n testId={`${testId}-done`}\n teaserTestId={teaserText ? `${testId}-teaser` : undefined}\n />\n ) : null}\n\n {!isSkipped && isDone && expanded ? (\n <WorkflowStageDoneBody\n node={node}\n loopTree={loopTree}\n testId={`${testId}-body`}\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n />\n ) : null}\n </div>\n );\n}\n","/**\n * WorkflowSubworkflowContainer.tsx — Subworkflow 缩进 mini 根行 + 左边界\n *\n * 职责:与 workflow 根同壳行语法;嵌套子树包在 boundary 内;done 折叠为 ExpandTrigger。\n *\n * 链路位置:WorkflowChrome → scope subworkflow 节点。\n */\nimport { useCallback, useEffect, useMemo, useState, type CSSProperties, type ReactNode } from 'react';\n\nimport { useSessionViewOptions } from '../../core/context/SessionContext';\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\nimport { WorkflowContainerLine } from './WorkflowContainerLine';\nimport { WorkflowExpandTrigger } from './WorkflowExpandTrigger';\nimport {\n buildWorkflowRootMeta,\n mapContainerUiStatus,\n mapWorkflowRootStatusLabel,\n workflowIndentUnit,\n} from './workflowContainerLineUtils';\n\nexport interface WorkflowSubworkflowContainerProps {\n node: WorkflowContainerRuntimeNode;\n depth?: number;\n children?: ReactNode;\n}\n\nfunction buildDoneSummary(node: WorkflowContainerRuntimeNode): string {\n const display = node.display;\n if (display?.progress_total != null) {\n const total = display.progress_total;\n const current =\n node.status === 'completed' ? total : (display.progress_current ?? total);\n return `${current}/${total} · done`;\n }\n return 'done';\n}\n\nexport function WorkflowSubworkflowContainer({\n node,\n depth = 1,\n children,\n}: WorkflowSubworkflowContainerProps) {\n const { verbose } = useSessionViewOptions();\n const uiStatus = mapContainerUiStatus(node.status);\n const isRunning = node.status === 'running' || node.status === 'retrying';\n const isDone = node.status === 'completed' || node.status === 'failed';\n const testId = `lax-workflow-subworkflow-${node.scope_key}`;\n const teaser = useMemo(() => {\n if (node.content_blocks.length === 0) return '';\n return node.content_blocks[node.content_blocks.length - 1]?.preview ?? '';\n }, [node.content_blocks]);\n\n const [expanded, setExpanded] = useState(isRunning);\n\n useEffect(() => {\n if (isRunning) setExpanded(true);\n if (isDone) setExpanded(false);\n }, [isRunning, isDone]);\n\n const toggleExpanded = useCallback(() => {\n setExpanded((prev) => !prev);\n }, []);\n\n const shellToggle =\n isRunning ? toggleExpanded\n : isDone && expanded ? toggleExpanded\n : undefined;\n\n const depthStyle = {\n '--lax-workflow-depth': depth,\n '--lax-workflow-indent-unit': workflowIndentUnit(depth),\n } as CSSProperties;\n\n const showShellLine = !(isDone && !expanded);\n\n return (\n <div\n className=\"lax-workflow-subworkflow\"\n data-testid={testId}\n data-container-scope=\"subworkflow\"\n style={depthStyle}\n >\n {showShellLine ? (\n <WorkflowContainerLine\n variant=\"root\"\n title={node.title}\n description={node.subtitle || undefined}\n uiStatus={uiStatus}\n meta={buildWorkflowRootMeta(node)}\n statusLabel={mapWorkflowRootStatusLabel(node.status)}\n onToggle={shellToggle}\n interactive={isRunning}\n expanded={expanded}\n titleTestId={`${testId}-title`}\n descriptionTestId={`${testId}-desc`}\n debugScopeKey={node.scope_key}\n verbose={verbose}\n />\n ) : null}\n\n {expanded && children ? (\n <div\n className=\"lax-workflow-subworkflow-boundary\"\n data-testid={`${testId}-boundary`}\n style={depthStyle}\n >\n {children}\n </div>\n ) : null}\n\n {isDone && !expanded ? (\n <WorkflowExpandTrigger\n summary={`${node.title} · ${buildDoneSummary(node)}`}\n summaryTestId={`${testId}-title`}\n teaser={teaser || undefined}\n onToggle={() => setExpanded(true)}\n expanded={false}\n testId={`${testId}-done`}\n teaserTestId={teaser ? `${testId}-teaser` : undefined}\n />\n ) : null}\n </div>\n );\n}\n","/**\n * WorkflowTaskListFooter.tsx — 合并多 loop 任务列表底部 pill(§5.11.4)\n */\nimport { useMemo, useState } from 'react';\nimport { useStore } from 'zustand';\n\nimport { useWorkflowSessionStoreApi } from '../../core/context/WorkflowSessionContext';\nimport type { WorkflowSessionStoreState } from '../../core/workflowSessionStore';\nimport { TaskList } from '../TaskList';\nimport {\n deriveWorkflowTaskFooterState,\n formatWorkflowTaskFooterLabel,\n groupWorkflowTasksByLoop,\n loopSessionDisplayLabel,\n shouldShowWorkflowTaskListFooter,\n} from './workflowTaskListMerge';\n\nfunction MessageResponse({ children }: { children: React.ReactNode }) {\n return (\n <div className=\"lax-message-response\">\n <span className=\"lax-message-response__marker\">⎿ </span>\n <span className=\"lax-message-response__content\">{children}</span>\n </div>\n );\n}\n\nexport function WorkflowTaskListFooter() {\n const store = useWorkflowSessionStoreApi();\n const state = useStore(store, (s: WorkflowSessionStoreState) => s.state);\n const [expanded, setExpanded] = useState(false);\n\n const footerState = useMemo(() => deriveWorkflowTaskFooterState(state), [state]);\n const visible = shouldShowWorkflowTaskListFooter(state);\n\n if (!visible) {\n return null;\n }\n\n const label = formatWorkflowTaskFooterLabel(state);\n const groups = groupWorkflowTasksByLoop(footerState.tasks);\n\n return (\n <div className=\"lax-workflow-task-list-footer\" data-testid=\"lax-workflow-task-list-footer\">\n <button\n type=\"button\"\n className=\"lax-task-list-footer__pill lax-workflow-task-list-footer__pill\"\n data-testid=\"lax-workflow-task-list-footer-pill\"\n aria-expanded={expanded}\n onClick={() => setExpanded((v) => !v)}\n >\n {label}\n <span className=\"lax-task-list-footer__hint\">\n {expanded ? ' · ↑ to hide' : ' · ↓ to view'}\n </span>\n </button>\n {expanded ? (\n <MessageResponse>\n <div className=\"lax-workflow-task-list-groups\">\n {groups.map((group) => (\n <div\n key={group.loopSessionId}\n className=\"lax-workflow-task-list-group\"\n data-testid={`lax-workflow-task-group-${group.loopSessionId}`}\n >\n <div className=\"lax-workflow-task-list-group-title\">\n {loopSessionDisplayLabel(group.loopSessionId)}\n </div>\n <TaskList tasks={group.tasks} />\n </div>\n ))}\n </div>\n </MessageResponse>\n ) : null}\n </div>\n );\n}\n","/**\n * workflowTaskListMerge.ts — Workflow 多 loop 任务合并(§5.11.4)\n */\nimport type { Task } from '../../types/tasks';\nimport type { SessionStatus, SessionTree, TaskPhase } from '../../types/tree';\nimport type { WorkflowSessionState } from '../../types/workflowSession';\n\nimport {\n formatTaskFooterLabel,\n shouldShowTaskListFooter,\n} from '../TaskListFooter';\n\nexport interface WorkflowMergedTask extends Task {\n loopSessionId: string;\n}\n\nconst STATUS_ORDER: Record<Task['status'], number> = {\n in_progress: 0,\n pending: 1,\n completed: 2,\n};\n\nexport function mergeWorkflowLoopTasks(\n loopTreesBySessionId: Record<string, SessionTree>,\n): WorkflowMergedTask[] {\n const merged: WorkflowMergedTask[] = [];\n const loopIds = Object.keys(loopTreesBySessionId).sort();\n for (const loopSessionId of loopIds) {\n const tree = loopTreesBySessionId[loopSessionId];\n if (!tree) continue;\n for (const task of Object.values(tree.tasks)) {\n merged.push({ ...task, loopSessionId });\n }\n }\n return merged.sort((a, b) => {\n const sa = STATUS_ORDER[a.status] ?? 99;\n const sb = STATUS_ORDER[b.status] ?? 99;\n if (sa !== sb) return sa - sb;\n const loopCmp = a.loopSessionId.localeCompare(b.loopSessionId);\n if (loopCmp !== 0) return loopCmp;\n return a.id.localeCompare(b.id);\n });\n}\n\nexport function deriveWorkflowTaskPhase(trees: SessionTree[]): TaskPhase {\n if (trees.length === 0) return 'hidden';\n if (trees.some((tree) => tree.taskPhase === 'visible')) return 'visible';\n if (trees.every((tree) => tree.taskPhase === 'hidden-after-completion')) {\n return 'hidden-after-completion';\n }\n return 'hidden';\n}\n\nexport function deriveWorkflowTaskFooterState(state: WorkflowSessionState): {\n tasks: WorkflowMergedTask[];\n taskPhase: TaskPhase;\n hasEverShownTaskList: boolean;\n sessionStatus: SessionStatus;\n} {\n const trees = Object.values(state.loopTreesBySessionId);\n return {\n tasks: mergeWorkflowLoopTasks(state.loopTreesBySessionId),\n taskPhase: deriveWorkflowTaskPhase(trees),\n hasEverShownTaskList: trees.some((tree) => tree.hasEverShownTaskList),\n sessionStatus: state.status,\n };\n}\n\nexport function shouldShowWorkflowTaskListFooter(state: WorkflowSessionState): boolean {\n const { tasks, taskPhase, hasEverShownTaskList, sessionStatus } =\n deriveWorkflowTaskFooterState(state);\n return shouldShowTaskListFooter(taskPhase, tasks, hasEverShownTaskList, sessionStatus);\n}\n\nexport function formatWorkflowTaskFooterLabel(state: WorkflowSessionState): string {\n const { tasks } = deriveWorkflowTaskFooterState(state);\n return formatTaskFooterLabel(tasks);\n}\n\nexport function groupWorkflowTasksByLoop(\n tasks: WorkflowMergedTask[],\n): Array<{ loopSessionId: string; tasks: Task[] }> {\n const groups = new Map<string, Task[]>();\n for (const task of tasks) {\n const bucket = groups.get(task.loopSessionId) ?? [];\n bucket.push(task);\n groups.set(task.loopSessionId, bucket);\n }\n return Array.from(groups.entries())\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([loopSessionId, groupTasks]) => ({ loopSessionId, tasks: groupTasks }));\n}\n\nexport function loopSessionDisplayLabel(loopSessionId: string): string {\n const marker = '-';\n const idx = loopSessionId.lastIndexOf(marker);\n if (idx !== -1 && idx < loopSessionId.length - 1) {\n return loopSessionId.slice(idx + 1);\n }\n return loopSessionId;\n}\n","/**\n * groupParallelTools.ts — 主舞台 Timeline 条目分组(过渡实现)\n *\n * @deprecated Phase 4 由 core/projection GroupedToolUseAccumulator + mountCandidates 替代。\n * 对齐参考:CC GroupedToolUseContent · buildMessageLookups 并行同工具分组语义\n */\nimport type { SessionNode } from '../../types/nodes';\n\nexport type TimelineEntry =\n | { kind: 'node'; nodeId: string }\n | { kind: 'tool_group'; toolName: string; nodeIds: string[] };\n\nexport interface BuildTimelineEntriesOptions {\n /** @deprecated 使用 projection grouped_tool_use;保留至 Phase 4 迁移完成 */\n groupParallelTools?: boolean;\n hideStandalonePermissions?: boolean;\n}\n\n/** @deprecated 见 core/projection;Phase 4 删除 */\nexport function buildTimelineEntries(\n rootIds: string[],\n byId: Record<string, SessionNode | undefined>,\n options: BuildTimelineEntriesOptions = {},\n): TimelineEntry[] {\n const filtered = options.hideStandalonePermissions\n ? rootIds.filter((id) => byId[id]?.kind !== 'permission')\n : [...rootIds];\n\n if (!options.groupParallelTools) {\n return filtered.map((nodeId) => ({ kind: 'node', nodeId }));\n }\n\n const entries: TimelineEntry[] = [];\n let i = 0;\n\n while (i < filtered.length) {\n const id = filtered[i]!;\n const node = byId[id];\n\n if (node?.kind !== 'tool_call') {\n entries.push({ kind: 'node', nodeId: id });\n i += 1;\n continue;\n }\n\n const toolName = node.toolName;\n const groupIds = [id];\n let j = i + 1;\n\n while (j < filtered.length) {\n const nextId = filtered[j]!;\n const next = byId[nextId];\n if (next?.kind !== 'tool_call' || next.toolName !== toolName) break;\n groupIds.push(nextId);\n j += 1;\n }\n\n if (groupIds.length >= 2) {\n entries.push({ kind: 'tool_group', toolName, nodeIds: groupIds });\n } else {\n entries.push({ kind: 'node', nodeId: id });\n }\n\n i = j;\n }\n\n return entries;\n}\n","/**\n * 职责:默认 SubAgentNode 纵向嵌套容器 widget(方案 A 已退场)。\n * 链路位置:宿主可通过 NodeRegistry.register('subagent', SubAgentBlock) 恢复旧行为。\n * 当前裁剪范围:纵向缩进;不含横向并列布局。\n * @deprecated 方案 A 主时间线不再渲染 SubAgentBlock;子 agent progress 折叠在 AgentToolBody。\n */\nimport { useChildren, useNodeTyped } from '../../core/hooks';\nimport { useNodeRegistry } from '../../core/context/SessionContext';\nimport { TimelineItem } from '../Timeline';\n\nexport interface SubAgentBlockProps {\n nodeId: string;\n}\n\nexport function SubAgentBlock({ nodeId }: SubAgentBlockProps) {\n const node = useNodeTyped(nodeId, 'subagent');\n const childIds = useChildren(nodeId);\n const registry = useNodeRegistry();\n if (!node) return null;\n\n return (\n <div className=\"lax-subagent-block\" data-status={node.status}>\n <div className=\"lax-subagent-block__header\">SubAgent: {node.subagentId}</div>\n <div className=\"lax-subagent-block__children\">\n {childIds.map((childId) => (\n <TimelineItem key={childId} nodeId={childId} registry={registry} />\n ))}\n </div>\n </div>\n );\n}\n","/**\n * 职责:内存事件源,按序投递 events 实现 Source 接口。\n * 链路位置:历史回放、测试、AgentSession 只读时间线。\n * 当前裁剪范围:可选 delayMs 模拟流式;不含 SSE 续传。\n */\nimport type { LangchainAgentEvent } from '../types/events';\nimport type { ReplayOptions } from '../core/replay';\nimport type { Source, SourceHandler } from './types';\n\nexport interface ReplaySourceOptions extends ReplayOptions {\n /** 事件间隔毫秒;默认 0 立即投递 */\n delayMs?: number;\n}\n\nfunction sleep(ms: number, signal: AbortSignal): Promise<void> {\n if (ms <= 0) return Promise.resolve();\n return new Promise((resolve) => {\n const timer = setTimeout(resolve, ms);\n signal.addEventListener(\n 'abort',\n () => {\n clearTimeout(timer);\n resolve();\n },\n { once: true },\n );\n });\n}\n\nexport function createReplaySource(\n events: LangchainAgentEvent[],\n opts?: ReplaySourceOptions,\n): Source {\n const delayMs = opts?.delayMs ?? 0;\n\n return {\n async start(handler: SourceHandler, signal: AbortSignal): Promise<void> {\n for (const event of events) {\n if (signal.aborted) break;\n handler(event);\n if (delayMs > 0) {\n await sleep(delayMs, signal);\n }\n }\n },\n };\n}\n"],"mappings":"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","names":["useEffect","useRef","jsx","jsx","useRef","useEffect","useEffect","useMemo","useRef","createContext","useContext","jsx","createContext","useContext","createContext","useContext","createStore","readString","readString","node","loopSessionId","next","loopTree","reducedLoop","createStore","useMemo","useState","useEffect","useMemo","jsx","jsxs","jsx","jsxs","jsx","jsxs","useMemo","useEffect","useCallback","useEffect","useMemo","useState","useStore","n","useCallback","useEffect","useMemo","useState","useStore","jsx","jsx","jsxs","useStore","useMemo","useState","useEffect","useCallback","jsx","jsxs","useStore","useMemo","useState","useEffect","useCallback","jsx","jsxs","useCallback","useEffect","useMemo","useState","jsx","jsxs","useMemo","useState","useEffect","useCallback","useCallback","useEffect","useMemo","useState","jsx","jsxs","useMemo","useState","useEffect","useCallback","Fragment","jsx","jsxs","resolveLoopTree","useState","useMemo","useMemo","useState","useStore","jsx","jsxs","useStore","useState","useMemo","useStore","jsx","jsxs","useRef","useMemo","useEffect","jsx","jsxs"]}
|
|
1
|
+
{"version":3,"sources":["../src/view/AgentSession.tsx","../src/core/store.ts","../src/transport/applicationKind.ts","../src/transport/createAgentxSseSource.ts","../src/view/agentLoop/ScopedSessionStore.tsx","../src/view/agentLoop/AgentLoopView.tsx","../src/view/workflow/WorkflowSession.tsx","../src/core/context/WorkflowSessionContext.tsx","../src/core/context/WorkflowLoopReplayContext.tsx","../src/core/context/WorkflowScaleContext.tsx","../src/view/workflow/workflowScaleOptions.ts","../src/core/workflowSessionStore.ts","../src/types/workflowContainer.ts","../src/types/workflowSession.ts","../src/core/workflow/workflowLoopTreeUtils.ts","../src/types/workflowDisplay.ts","../src/core/workflow/workflowContainerProjector.ts","../src/core/workflow/loopSessionUtils.ts","../src/core/workflowStructureEvents.ts","../src/core/workflowReducer.ts","../src/core/workflow/stageDoneSummary.ts","../src/core/workflow/workflowLoopEviction.ts","../src/view/workflow/WorkflowChrome.tsx","../src/view/workflow/WorkflowAggregateContainer.tsx","../src/view/workflow/WorkflowContainerLine.tsx","../src/view/workflow/WorkflowExpandTrigger.tsx","../src/view/workflow/workflowContainerLineUtils.ts","../src/view/workflow/WorkflowParallelGroup.tsx","../src/core/workflow/workflowParallelGroupMetrics.ts","../src/view/workflow/WorkflowStageContainer.tsx","../src/core/workflow/loopTreeUtils.ts","../src/view/workflow/workflowStageDoneBody.tsx","../src/view/workflow/workflowStageListUtils.ts","../src/view/workflow/WorkflowRootContainer.tsx","../src/view/workflow/WorkflowRouteContainer.tsx","../src/view/workflow/WorkflowSubworkflowContainer.tsx","../src/view/workflow/WorkflowTaskListFooter.tsx","../src/view/workflow/workflowTaskListMerge.ts","../src/view/tools/groupParallelTools.ts","../src/view/nodes/SubAgentNode.tsx","../src/transport/createReplaySource.ts"],"sourcesContent":["/**\n * 职责:顶层容器,连接 Source → store → Timeline 渲染。\n * 链路位置:业务页面 <AgentSession source={...} /> 唯一入口。\n * 当前裁剪范围:单会话;initialEvents 支持 EventBuffer 快照续流(M3);reducer/transport 异常自吞。\n */\nimport { useEffect, useMemo, useRef, type ReactNode } from 'react';\n\nimport { createSessionStore } from '../core/store';\nimport { replayEvents } from '../core/replay';\nimport {\n SessionStoreContext,\n NodeRegistryContext,\n ToolDisplayOptionsContext,\n SessionViewOptionsContext,\n} from '../core/context/SessionContext';\nimport type { Source } from '../transport/types';\nimport { SseTransportTerminalError } from '../transport/createAgentxSseSource';\nimport type { LangchainAgentEvent, TierOverrides } from '../types/events';\nimport type { ReducerError } from '../types/tree';\nimport { createDefaultRegistry } from './defaultRegistry';\nimport type { NodeRegistry } from './NodeRegistry';\nimport { AgentLoopView } from './agentLoop/AgentLoopView';\nimport { InteractionBusContext } from '../core/context/InteractionContext';\nimport type { InteractionBus } from '../core/interaction/InteractionBus';\nimport { getNoopInteractionBus } from '../core/interaction/InteractionBus';\nimport { useInternalErrors, useSessionStatus } from '../core/hooks';\nimport type { MarkdownRenderer } from '../core/context/MarkdownRendererContext';\nimport { MarkdownRendererContext } from '../core/context/MarkdownRendererContext';\nimport {\n createDefaultToolRegistry,\n type ToolDisplayRegistry,\n} from './tools/registry';\nimport type { ToolBodyMode } from './tools/types';\nimport type { PermissionUiMode, DisplayMode } from './sessionViewOptions';\nimport { DEFAULT_SESSION_VIEW_OPTIONS } from './sessionViewOptions';\n\nexport interface AgentSessionProps {\n source: Source;\n /** 挂载时先 replay 预灌树(含 EventBuffer ingest 快照),再接 source 续流 */\n initialEvents?: LangchainAgentEvent[];\n registry?: NodeRegistry;\n tierOverrides?: TierOverrides;\n onError?: (error: Error) => void;\n autoReconnect?: boolean;\n debug?: boolean;\n /** 为 true 且主舞台节点数超过阈值时使用 VirtualTimeline(V2-E) */\n virtualized?: boolean;\n virtualizeThreshold?: number;\n /** 权限回写薄层;PermissionCard 触发 onPermissionResolve(V2-D) */\n interactionBus?: InteractionBus;\n /** 按工具名注册 Body 组件(V3-T0) */\n toolDisplayRegistry?: ToolDisplayRegistry;\n /** 工具正文默认 preview / full(V3-T0) */\n defaultBodyMode?: ToolBodyMode;\n /** @deprecated Phase 4 起由 projection GroupedToolUseAccumulator 自动分组;保留 prop 兼容 */\n groupParallelTools?: boolean;\n /** 权限 UI:standalone | inline | both(V3-T4.6);后台 bypass 时通常无 pending */\n permissionUiMode?: PermissionUiMode;\n /** 富 Markdown 渲染(simple demo 可注入 react-markdown + mermaid) */\n markdownRenderer?: MarkdownRenderer;\n /** 对齐 CLI display mode(normal / brief_only / transcript) */\n displayMode?: DisplayMode;\n /** 对齐 CC verbose;为 true 时跳过分组并展开 explore detail */\n verbose?: boolean;\n exploreFullscreenBash?: boolean;\n memoryDir?: string | null;\n workspaceRoot?: string | null;\n children?: ReactNode;\n}\n\nfunction DebugPanel() {\n const status = useSessionStatus();\n const errors = useInternalErrors();\n if (errors.length === 0) return null;\n return (\n <div className=\"lax-debug-panel\" data-testid=\"lax-debug-panel\">\n <div>status: {status}</div>\n <ul>\n {errors.map((err: ReducerError, i: number) => (\n <li key={`${err.eventIndex}-${i}`}>\n [{err.eventType}] {err.message}\n </li>\n ))}\n </ul>\n </div>\n );\n}\n\nexport function AgentSession({\n source,\n initialEvents,\n registry,\n tierOverrides: _tierOverrides,\n onError,\n autoReconnect: _autoReconnect,\n debug = false,\n virtualized = false,\n virtualizeThreshold,\n interactionBus,\n toolDisplayRegistry,\n defaultBodyMode = 'preview',\n groupParallelTools = false,\n permissionUiMode = 'standalone',\n markdownRenderer,\n displayMode = 'normal',\n verbose = false,\n exploreFullscreenBash = true,\n memoryDir = null,\n workspaceRoot = null,\n children,\n}: AgentSessionProps) {\n const storeRef = useRef<ReturnType<typeof createSessionStore> | null>(null);\n if (storeRef.current === null) {\n const replayOpts = {\n tierOverrides: _tierOverrides,\n collectDebug: debug,\n };\n const initialTree =\n initialEvents && initialEvents.length > 0\n ? replayEvents(initialEvents, replayOpts)\n : undefined;\n storeRef.current = createSessionStore(initialTree, {\n tierOverrides: _tierOverrides,\n debug,\n initialEventCount: initialEvents?.length ?? 0,\n });\n }\n const registryRef = useMemo(() => registry ?? createDefaultRegistry(), [registry]);\n const busRef = useMemo(\n () => interactionBus ?? getNoopInteractionBus(),\n [interactionBus],\n );\n const toolDisplayRef = useMemo(\n () => ({\n registry: toolDisplayRegistry ?? createDefaultToolRegistry(),\n defaultBodyMode,\n }),\n [toolDisplayRegistry, defaultBodyMode],\n );\n const sessionViewRef = useMemo(\n () => ({\n ...DEFAULT_SESSION_VIEW_OPTIONS,\n groupParallelTools,\n permissionUiMode,\n verboseReasoning: debug,\n displayMode,\n verbose,\n exploreFullscreenBash,\n memoryDir,\n workspaceRoot,\n }),\n [\n groupParallelTools,\n permissionUiMode,\n debug,\n displayMode,\n verbose,\n exploreFullscreenBash,\n memoryDir,\n workspaceRoot,\n ],\n );\n\n useEffect(() => {\n const store = storeRef.current!;\n const controller = new AbortController();\n\n void source.start((event, ctx) => {\n store.getState().applyEvent(event, ctx);\n }, controller.signal).catch((err: unknown) => {\n if (err instanceof SseTransportTerminalError) {\n const { tree } = store.getState();\n if (tree.status === 'running' || tree.status === 'connecting') {\n store.setState({ tree: { ...tree, status: 'error' } });\n }\n }\n });\n\n return () => {\n controller.abort();\n };\n }, [source, onError]);\n\n return (\n <SessionStoreContext.Provider value={storeRef.current!}>\n <InteractionBusContext.Provider value={busRef}>\n <NodeRegistryContext.Provider value={registryRef}>\n <MarkdownRendererContext.Provider value={markdownRenderer}>\n <ToolDisplayOptionsContext.Provider value={toolDisplayRef}>\n <SessionViewOptionsContext.Provider value={sessionViewRef}>\n <div className=\"lax-agent-session\" data-testid=\"lax-agent-session\">\n {children ?? (\n <AgentLoopView\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n />\n )}\n {debug ? <DebugPanel /> : null}\n </div>\n </SessionViewOptionsContext.Provider>\n </ToolDisplayOptionsContext.Provider>\n </MarkdownRendererContext.Provider>\n </NodeRegistryContext.Provider>\n </InteractionBusContext.Provider>\n </SessionStoreContext.Provider>\n );\n}\n","import { createStore, type StoreApi } from 'zustand/vanilla';\n\nimport { createEmptyTree, type ReducerError, type SessionTree } from '../types/tree';\nimport type { LangchainAgentEvent, TierOverrides } from '../types/events';\nimport { markEventIdSeen, shouldSkipDuplicateEvent } from './dedupe';\nimport { reduceTree, type ReduceOptions } from './reducer';\nimport type { SourceEventContext } from '../transport/types';\n\nexport interface SessionStoreOptions {\n tierOverrides?: TierOverrides;\n debug?: boolean;\n /** 预灌历史事件数;续流时保证 reducer eventIndex 连续 */\n initialEventCount?: number;\n /** 续传恢复:已见过的 SSE id,避免重叠帧重复建节点 */\n initialSeenEventIds?: Iterable<string>;\n}\n\nexport interface SessionStoreState {\n tree: SessionTree;\n eventCount: number;\n applyEvent: (event: LangchainAgentEvent, ctx?: SourceEventContext) => void;\n applyEvents: (events: LangchainAgentEvent[]) => void;\n reset: () => void;\n markAsError: (error?: Error) => void;\n}\n\nfunction safeReduce(\n tree: SessionTree,\n event: LangchainAgentEvent,\n eventIndex: number,\n options?: ReduceOptions,\n): { tree: SessionTree; error?: ReducerError } {\n try {\n return { tree: reduceTree(tree, event, eventIndex, options) };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n const stack = err instanceof Error ? err.stack : undefined;\n if (import.meta.env?.DEV) {\n console.error('[langchain_agentx_stream_ui] reducer error:', err);\n }\n return {\n tree: {\n ...tree,\n internalErrors: [\n ...tree.internalErrors,\n { eventIndex, eventType: event.event_type, message, stack },\n ],\n },\n };\n }\n}\n\nexport function createSessionStore(\n initialTree: SessionTree = createEmptyTree(),\n storeOptions?: SessionStoreOptions,\n): StoreApi<SessionStoreState> {\n const reduceOpts: ReduceOptions = {\n tierOverrides: storeOptions?.tierOverrides,\n collectDebug: storeOptions?.debug === true,\n };\n const initialEventCount = storeOptions?.initialEventCount ?? 0;\n const seenEventIds = new Set<string>(storeOptions?.initialSeenEventIds);\n return createStore<SessionStoreState>((set, get) => ({\n tree: initialTree,\n eventCount: initialEventCount,\n applyEvent(event, ctx) {\n const sseEventId = ctx?.sseEventId;\n if (shouldSkipDuplicateEvent(seenEventIds, sseEventId)) return;\n\n const { tree, eventCount } = get();\n const { tree: reduced } = safeReduce(tree, event, eventCount, reduceOpts);\n const nextTree: SessionTree =\n sseEventId\n ? {\n ...reduced,\n meta: { ...reduced.meta, lastEventId: sseEventId },\n }\n : reduced;\n markEventIdSeen(seenEventIds, sseEventId);\n set({ tree: nextTree, eventCount: eventCount + 1 });\n },\n applyEvents(events) {\n let { tree, eventCount } = get();\n for (const event of events) {\n const result = safeReduce(tree, event, eventCount, reduceOpts);\n tree = result.tree;\n eventCount += 1;\n }\n set({ tree, eventCount });\n },\n reset() {\n seenEventIds.clear();\n set({ tree: createEmptyTree(), eventCount: 0 });\n },\n markAsError(error?: Error) {\n const { tree } = get();\n set({\n tree: {\n ...tree,\n status: 'error',\n internalErrors: error\n ? [\n ...tree.internalErrors,\n {\n eventIndex: -1,\n eventType: 'sse_connection_failed',\n message: error.message,\n stack: error.stack,\n },\n ]\n : tree.internalErrors,\n },\n });\n },\n }));\n}\n\nexport type SessionStore = StoreApi<SessionStoreState>;\n","/**\n * applicationKind.ts — SSE meta application_kind 契约\n *\n * 职责:\n * 定义双轨 SSE 出口 kind 枚举与 mismatch 错误类型。\n *\n * 链路位置:\n * createAgentxSseSource meta 握手校验。\n *\n * 当前裁剪范围:\n * 仅 agent_session / workflow;无自动推断。\n */\nexport type ApplicationKind = 'agent_session' | 'workflow';\n\nexport class ApplicationKindMismatchError extends Error {\n readonly name = 'ApplicationKindMismatchError';\n readonly expected: ApplicationKind;\n readonly actual: string | undefined;\n\n constructor(expected: ApplicationKind, actual: string | undefined) {\n super(\n `application_kind mismatch: expected ${expected}, got ${actual ?? '(missing)'}`,\n );\n this.expected = expected;\n this.actual = actual;\n }\n}\n\nexport class MissingApplicationKindError extends Error {\n readonly name = 'MissingApplicationKindError';\n\n constructor() {\n super('application_kind missing in SSE meta frame');\n }\n}\n","/**\n * 职责:浏览器 EventSource 封装,解码 meta/agentx 命名帧并校验协议版本。\n * 链路位置:业务页面 createAgentxSseSource({ url }) → AgentSession source prop。\n *\n * 错误分层(对齐 claude-code SSETransport / Messages 管线):\n * - 传输 terminal:握手前/未 finish 断连 → reject(SseTransportTerminalError),不进 Timeline\n * - 传输 benign:finish/error 帧后的 EventSource.onerror → resolve\n * - 业务层:agentx event_type=error → reducer → ErrorNode(唯一用户可见错误文案)\n */\nimport type { LangchainAgentEvent } from '../types/events';\nimport type { Source, SourceHandler, SourceEventContext } from './types';\nimport type { ApplicationKind } from './applicationKind';\nimport {\n ApplicationKindMismatchError,\n MissingApplicationKindError,\n} from './applicationKind';\n\nexport const EXPECTED_PROTOCOL_VERSION = '1';\n\n/** 传输层 terminal 失败(须排查/fix);与 agentx error 帧(业务错误)分离。 */\nexport type SseTransportFailureKind = 'handshake_failed' | 'premature_close';\n\nexport class SseTransportTerminalError extends Error {\n readonly kind: SseTransportFailureKind;\n\n constructor(kind: SseTransportFailureKind, message: string) {\n super(message);\n this.name = 'SseTransportTerminalError';\n this.kind = kind;\n }\n}\n\nexport interface AgentxSseSourceOptions {\n url: string;\n autoReconnect?: boolean;\n reconnectDelayMs?: number;\n /** 每收到 agentx 帧 SSE id 时回调(含续传重叠 id) */\n onLastEventId?: (id: string) => void;\n /** 测试注入:替换全局 EventSource */\n EventSourceImpl?: typeof EventSource;\n /** /chat 与 /workflow 必填:校验 meta.application_kind */\n expectedApplicationKind?: ApplicationKind;\n}\n\nexport interface AgentxMetaFrame {\n protocol_version: string;\n session_id?: string | null;\n started_at?: number;\n application_kind?: ApplicationKind;\n}\n\n/** 传输层 diagnostics;不驱动 UI(对齐 CC logForDiagnostics / warn+drop)。 */\nfunction transportLog(message: string, level: 'warn' | 'error' = 'warn'): void {\n const line = `[langchain_agentx_stream_ui] SSE transport: ${message}`;\n if (level === 'error') {\n console.error(line);\n } else {\n console.warn(line);\n }\n}\n\n/** 手动重连时追加 resume 查询参数(EventSource 无法设 Last-Event-ID 请求头)。 */\nexport function buildResumeStreamUrl(\n baseUrl: string,\n lastEventId: string | null | undefined,\n queryParam = 'last_event_id',\n): string {\n if (!lastEventId) return baseUrl;\n const sep = baseUrl.includes('?') ? '&' : '?';\n return `${baseUrl}${sep}${encodeURIComponent(queryParam)}=${encodeURIComponent(lastEventId)}`;\n}\n\nexport function createAgentxSseSource(options: AgentxSseSourceOptions): Source {\n const {\n url,\n autoReconnect = true,\n reconnectDelayMs = 1000,\n onLastEventId,\n EventSourceImpl = EventSource,\n expectedApplicationKind,\n } = options;\n\n return {\n start(handler: SourceHandler, signal: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n let es: EventSource | null = null;\n let handshakeOk = false;\n let lastEventId: string | null = null;\n let fatal = false;\n /** finish/error 帧后服务端关连接;EventSource.onerror 为预期行为,非 UI 错误。 */\n let streamTerminal = false;\n\n type BufferedDelta = {\n event: LangchainAgentEvent;\n ctx?: SourceEventContext;\n };\n let bufferedDelta: BufferedDelta | null = null;\n let flushTimer: ReturnType<typeof setTimeout> | null = null;\n\n const flushBufferedDelta = (): void => {\n if (flushTimer) {\n clearTimeout(flushTimer);\n flushTimer = null;\n }\n if (!bufferedDelta) return;\n handler(bufferedDelta.event, bufferedDelta.ctx);\n bufferedDelta = null;\n };\n\n const isBufferedDeltaEvent = (event: LangchainAgentEvent): boolean =>\n event.event_type === 'text-delta' || event.event_type === 'reasoning-delta';\n\n const mergeDeltaEvent = (\n prev: LangchainAgentEvent,\n next: LangchainAgentEvent,\n ): LangchainAgentEvent | null => {\n if (prev.event_type !== next.event_type) return null;\n if (prev.step_index !== next.step_index) return null;\n if (prev.tool_name !== next.tool_name) return null;\n if (prev.session_id !== next.session_id) return null;\n\n const prevData = prev.data as { delta?: string; text?: string; content?: string };\n const nextData = next.data as { delta?: string; text?: string; content?: string };\n\n const prevChunk = prevData.delta ?? prevData.text ?? prevData.content ?? '';\n const nextChunk = nextData.delta ?? nextData.text ?? nextData.content ?? '';\n\n return {\n ...next,\n data: {\n ...next.data,\n text: `${prevChunk}${nextChunk}`,\n },\n } as LangchainAgentEvent;\n };\n\n const cleanup = (): void => {\n es?.close();\n es = null;\n };\n\n const finish = (error?: Error): void => {\n flushBufferedDelta();\n cleanup();\n if (error) reject(error);\n else resolve();\n };\n\n const failHandshake = (error: Error): void => {\n fatal = true;\n transportLog(error.message, 'error');\n cleanup();\n finish(error);\n };\n\n const failPrematureClose = (): void => {\n const error = new SseTransportTerminalError(\n 'premature_close',\n 'SSE connection lost before stream finished',\n );\n transportLog(error.message, 'error');\n cleanup();\n finish(error);\n };\n\n const connect = (resumeFromId?: string | null): void => {\n if (signal.aborted || fatal) {\n finish();\n return;\n }\n\n const connectUrl =\n resumeFromId != null && resumeFromId !== ''\n ? buildResumeStreamUrl(url, resumeFromId)\n : url;\n\n es = new EventSourceImpl(connectUrl);\n handshakeOk = false;\n\n es.addEventListener('meta', (event: MessageEvent<string>) => {\n try {\n const meta = JSON.parse(event.data) as AgentxMetaFrame;\n if (meta.protocol_version !== EXPECTED_PROTOCOL_VERSION) {\n failHandshake(\n new Error(`Unsupported protocol_version: ${meta.protocol_version}`),\n );\n return;\n }\n if (expectedApplicationKind) {\n const actual = meta.application_kind;\n if (actual === undefined || actual === null) {\n failHandshake(new MissingApplicationKindError());\n return;\n }\n if (actual !== expectedApplicationKind) {\n failHandshake(\n new ApplicationKindMismatchError(expectedApplicationKind, actual),\n );\n return;\n }\n }\n handshakeOk = true;\n } catch (err) {\n const message =\n err instanceof Error ? err.message : 'Failed to decode meta frame';\n failHandshake(new Error(message));\n }\n });\n\n es.addEventListener('agentx', (event: MessageEvent<string>) => {\n if (!handshakeOk) {\n failHandshake(new Error('Received agentx frame before meta handshake'));\n return;\n }\n try {\n const agentEvent = JSON.parse(event.data) as LangchainAgentEvent;\n const sseEventId = event.lastEventId || undefined;\n if (sseEventId) {\n lastEventId = sseEventId;\n onLastEventId?.(sseEventId);\n }\n\n const ctx = sseEventId ? { sseEventId } : undefined;\n\n if (isBufferedDeltaEvent(agentEvent)) {\n if (bufferedDelta) {\n const merged = mergeDeltaEvent(bufferedDelta.event, agentEvent);\n if (merged) {\n bufferedDelta = { event: merged, ctx };\n } else {\n flushBufferedDelta();\n bufferedDelta = { event: agentEvent, ctx };\n }\n } else {\n bufferedDelta = { event: agentEvent, ctx };\n }\n\n if (!flushTimer) {\n flushTimer = setTimeout(() => {\n flushBufferedDelta();\n }, 16);\n }\n } else {\n flushBufferedDelta();\n handler(agentEvent, ctx);\n if (\n agentEvent.event_type === 'finish'\n || agentEvent.event_type === 'error'\n ) {\n streamTerminal = true;\n }\n }\n } catch (err) {\n const message =\n err instanceof Error\n ? err.message\n : 'Failed to decode agentx frame';\n transportLog(`Dropped agentx frame: ${message}`, 'warn');\n }\n });\n\n es.onerror = () => {\n flushBufferedDelta();\n // 已收到 finish/error 帧后的关连接:EventSource 规范行为,非故障。\n if (signal.aborted || fatal || streamTerminal) {\n cleanup();\n finish();\n return;\n }\n // 握手前断连(含 HTTP 4xx/5xx、CORS):EventSource 不提供 status,只能凭「尚无 meta」判定。\n if (!handshakeOk) {\n const error = new SseTransportTerminalError(\n 'handshake_failed',\n 'SSE connection failed before meta handshake',\n );\n transportLog(error.message, 'error');\n cleanup();\n finish(error);\n return;\n }\n if (autoReconnect) {\n cleanup();\n setTimeout(() => connect(lastEventId), reconnectDelayMs);\n return;\n }\n // 已握手但未收到 finish/error 就断连:真实传输中断,须 reject 供宿主感知。\n failPrematureClose();\n };\n };\n\n signal.addEventListener('abort', () => {\n flushBufferedDelta();\n fatal = true;\n finish();\n }, { once: true });\n\n connect();\n });\n },\n };\n}\n\n/** 测试/Story 用:内存事件源 */\nexport function createMockSource(events: LangchainAgentEvent[]): Source {\n return {\n async start(handler, signal) {\n for (const event of events) {\n if (signal.aborted) break;\n handler(event);\n }\n },\n };\n}\n","/**\n * ScopedSessionStore.tsx — 外部 SessionTree 注入 SessionStore 上下文\n *\n * 职责:\n * 让 AgentLoopView 在 workflow scoped 子树渲染时复用 Timeline 组件栈。\n *\n * 链路位置:\n * AgentLoopView(tree prop)→ ScopedSessionStoreProvider。\n *\n * 当前裁剪范围:\n * 只读同步 tree prop;不接收 live applyEvent(由父 workflow store 驱动)。\n */\nimport { useEffect, useRef, type ReactNode } from 'react';\n\nimport { SessionStoreContext } from '../../core/context/SessionContext';\nimport { createSessionStore } from '../../core/store';\nimport type { SessionTree } from '../../types/tree';\n\nexport function ScopedSessionStoreProvider({\n tree,\n children,\n}: {\n tree: SessionTree;\n children: ReactNode;\n}) {\n const storeRef = useRef(createSessionStore(tree, { initialEventCount: 1 }));\n useEffect(() => {\n storeRef.current.setState({ tree });\n }, [tree]);\n\n return (\n <SessionStoreContext.Provider value={storeRef.current}>\n {children}\n </SessionStoreContext.Provider>\n );\n}\n","/**\n * AgentLoopView.tsx — CC 主舞台(Timeline + Spinner + 可选 TaskListFooter)\n *\n * 职责:\n * /chat 与 /workflow 内 agent loop 区域共用投影与节点渲染。\n *\n * 链路位置:\n * AgentSession · WorkflowSession scoped loop。\n *\n * 当前裁剪范围:\n * workflow 页 showTaskListFooter=false(合并 Footer 在 P3)。\n */\nimport type { SessionTree } from '../../types/tree';\nimport { SessionTimeline } from '../SessionTimeline';\nimport { ScopedSessionStoreProvider } from './ScopedSessionStore';\n\nexport interface AgentLoopViewProps {\n /** 传入时使用隔离 store(workflow scoped);省略则使用上层 SessionStoreContext */\n tree?: SessionTree;\n showTaskListFooter?: boolean;\n virtualized?: boolean;\n virtualizeThreshold?: number;\n groupParallelTools?: boolean;\n}\n\nfunction AgentLoopViewBody({\n showTaskListFooter = true,\n virtualized,\n virtualizeThreshold,\n groupParallelTools,\n}: Omit<AgentLoopViewProps, 'tree'>) {\n return (\n <div className=\"lax-agent-loop-view\" data-testid=\"lax-agent-loop-view\">\n <SessionTimeline\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n showTaskListFooter={showTaskListFooter}\n />\n </div>\n );\n}\n\nexport function AgentLoopView({\n tree,\n showTaskListFooter = true,\n virtualized,\n virtualizeThreshold,\n groupParallelTools,\n}: AgentLoopViewProps) {\n if (tree) {\n return (\n <ScopedSessionStoreProvider tree={tree}>\n <AgentLoopViewBody\n showTaskListFooter={showTaskListFooter}\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n />\n </ScopedSessionStoreProvider>\n );\n }\n return (\n <AgentLoopViewBody\n showTaskListFooter={showTaskListFooter}\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n />\n );\n}\n","/**\n * WorkflowSession.tsx — /workflow 页顶层容器\n *\n * 职责:\n * WorkflowChrome + scoped AgentLoopView;workflow SSE Source 写入 workflow store。\n *\n * 链路位置:\n * Simple /workflow 页 · 业务 Workflow 演示。\n *\n * 当前裁剪范围:\n * 无 WorkflowTaskListFooter(P3);permission 与 AgentSession 同构 props 子集。\n */\nimport { useEffect, useMemo, useRef, type ReactNode } from 'react';\n\nimport { WorkflowSessionStoreContext } from '../../core/context/WorkflowSessionContext';\nimport { WorkflowLoopReplayProvider } from '../../core/context/WorkflowLoopReplayContext';\nimport type { WorkflowLoopReplayHandler } from '../../core/context/WorkflowLoopReplayContext';\nimport {\n WorkflowScaleContext,\n} from '../../core/context/WorkflowScaleContext';\nimport {\n DEFAULT_WORKFLOW_SCALE_OPTIONS,\n type WorkflowScaleOptions,\n} from './workflowScaleOptions';\nimport {\n NodeRegistryContext,\n ToolDisplayOptionsContext,\n SessionViewOptionsContext,\n} from '../../core/context/SessionContext';\nimport { InteractionBusContext } from '../../core/context/InteractionContext';\nimport { MarkdownRendererContext } from '../../core/context/MarkdownRendererContext';\nimport type { MarkdownRenderer } from '../../core/context/MarkdownRendererContext';\nimport { getNoopInteractionBus } from '../../core/interaction/InteractionBus';\nimport type { InteractionBus } from '../../core/interaction/InteractionBus';\nimport { createWorkflowSessionStore } from '../../core/workflowSessionStore';\nimport { reduceWorkflowEvents } from '../../core/workflowReducer';\nimport type { Source } from '../../transport/types';\nimport { SseTransportTerminalError } from '../../transport/createAgentxSseSource';\nimport type { LangchainAgentEvent, TierOverrides } from '../../types/events';\nimport { createDefaultRegistry } from '../defaultRegistry';\nimport type { NodeRegistry } from '../NodeRegistry';\nimport {\n createDefaultToolRegistry,\n type ToolDisplayRegistry,\n} from '../tools/registry';\nimport type { ToolBodyMode } from '../tools/types';\nimport type { DisplayMode, PermissionUiMode } from '../sessionViewOptions';\nimport { DEFAULT_SESSION_VIEW_OPTIONS } from '../sessionViewOptions';\nimport { WorkflowChrome } from './WorkflowChrome';\nimport { WorkflowTaskListFooter } from './WorkflowTaskListFooter';\nimport { useStore } from 'zustand';\nimport type { WorkflowSessionStoreState } from '../../core/workflowSessionStore';\n\nexport interface WorkflowSessionProps {\n source: Source;\n initialEvents?: LangchainAgentEvent[];\n registry?: NodeRegistry;\n tierOverrides?: TierOverrides;\n onError?: (error: Error) => void;\n interactionBus?: InteractionBus;\n toolDisplayRegistry?: ToolDisplayRegistry;\n defaultBodyMode?: ToolBodyMode;\n permissionUiMode?: PermissionUiMode;\n markdownRenderer?: MarkdownRenderer;\n displayMode?: DisplayMode;\n verbose?: boolean;\n exploreFullscreenBash?: boolean;\n memoryDir?: string | null;\n workspaceRoot?: string | null;\n virtualized?: boolean;\n virtualizeThreshold?: number;\n groupParallelTools?: boolean;\n /** P1–P4:大规模 workflow 缩放选项 */\n workflowScale?: Partial<WorkflowScaleOptions>;\n /** P2:展开已淘汰 loop 时由宿主 replay 事件 */\n onRequestLoopReplay?: WorkflowLoopReplayHandler;\n children?: ReactNode;\n}\n\nexport function WorkflowSession({\n source,\n initialEvents,\n registry,\n tierOverrides,\n onError,\n interactionBus,\n toolDisplayRegistry,\n defaultBodyMode = 'preview',\n permissionUiMode = 'standalone',\n markdownRenderer,\n displayMode = 'normal',\n verbose = false,\n exploreFullscreenBash = true,\n memoryDir = null,\n workspaceRoot = null,\n virtualized = false,\n virtualizeThreshold,\n groupParallelTools = false,\n workflowScale,\n onRequestLoopReplay,\n children,\n}: WorkflowSessionProps) {\n const storeRef = useRef<ReturnType<typeof createWorkflowSessionStore> | null>(null);\n if (storeRef.current === null) {\n const initialState =\n initialEvents && initialEvents.length > 0\n ? reduceWorkflowEvents(initialEvents, { tierOverrides })\n : undefined;\n storeRef.current = createWorkflowSessionStore(initialState, {\n tierOverrides,\n initialEventCount: initialEvents?.length ?? 0,\n evictCompletedLoops: workflowScale?.evictCompletedLoops\n ?? DEFAULT_WORKFLOW_SCALE_OPTIONS.evictCompletedLoops,\n maxHydratedCompletedLoops: workflowScale?.maxHydratedCompletedLoops\n ?? DEFAULT_WORKFLOW_SCALE_OPTIONS.maxHydratedCompletedLoops,\n });\n }\n\n const scaleOptions = useMemo(\n () => ({ ...DEFAULT_WORKFLOW_SCALE_OPTIONS, ...workflowScale }),\n [workflowScale],\n );\n\n const registryRef = useMemo(() => registry ?? createDefaultRegistry(), [registry]);\n const busRef = useMemo(\n () => interactionBus ?? getNoopInteractionBus(),\n [interactionBus],\n );\n const toolDisplayRef = useMemo(\n () => ({\n registry: toolDisplayRegistry ?? createDefaultToolRegistry(),\n defaultBodyMode,\n }),\n [toolDisplayRegistry, defaultBodyMode],\n );\n const sessionViewRef = useMemo(\n () => ({\n ...DEFAULT_SESSION_VIEW_OPTIONS,\n groupParallelTools,\n permissionUiMode,\n displayMode,\n verbose,\n exploreFullscreenBash,\n memoryDir,\n workspaceRoot,\n }),\n [\n groupParallelTools,\n permissionUiMode,\n displayMode,\n verbose,\n exploreFullscreenBash,\n memoryDir,\n workspaceRoot,\n ],\n );\n\n const containerTree = useStore(\n storeRef.current!,\n (s: WorkflowSessionStoreState) => s.state.containerTree,\n );\n const loopTreesBySessionId = useStore(\n storeRef.current!,\n (s: WorkflowSessionStoreState) => s.state.loopTreesBySessionId,\n );\n\n useEffect(() => {\n const store = storeRef.current!;\n const controller = new AbortController();\n\n void source.start((event, ctx) => {\n store.getState().applyEvent(event, ctx);\n }, controller.signal).catch((err: unknown) => {\n if (err instanceof SseTransportTerminalError) {\n const { state } = store.getState();\n if (state.status === 'running') {\n store.setState({ state: { ...state, status: 'error' } });\n }\n }\n });\n\n return () => {\n controller.abort();\n };\n }, [source, onError]);\n\n return (\n <WorkflowSessionStoreContext.Provider value={storeRef.current!}>\n <WorkflowScaleContext.Provider value={scaleOptions}>\n <WorkflowLoopReplayProvider onRequestLoopReplay={onRequestLoopReplay}>\n <InteractionBusContext.Provider value={busRef}>\n <NodeRegistryContext.Provider value={registryRef}>\n <MarkdownRendererContext.Provider value={markdownRenderer}>\n <ToolDisplayOptionsContext.Provider value={toolDisplayRef}>\n <SessionViewOptionsContext.Provider value={sessionViewRef}>\n <div\n className=\"lax-agent-session lax-workflow-session\"\n data-testid=\"lax-workflow-session\"\n >\n <WorkflowChrome\n containerTree={containerTree}\n loopTreesBySessionId={loopTreesBySessionId}\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n />\n <WorkflowTaskListFooter />\n {children}\n </div>\n </SessionViewOptionsContext.Provider>\n </ToolDisplayOptionsContext.Provider>\n </MarkdownRendererContext.Provider>\n </NodeRegistryContext.Provider>\n </InteractionBusContext.Provider>\n </WorkflowLoopReplayProvider>\n </WorkflowScaleContext.Provider>\n </WorkflowSessionStoreContext.Provider>\n );\n}\n","/**\n * WorkflowSessionContext.tsx — Workflow store React 上下文\n *\n * 职责:\n * 向 WorkflowSession 子树注入 workflowSessionStore。\n *\n * 链路位置:\n * WorkflowSession Provider。\n *\n * 当前裁剪范围:\n * 与 SessionStoreContext 平行,不混用。\n */\nimport { createContext, useContext } from 'react';\nimport { useStore } from 'zustand';\n\nimport type { SessionStatus } from '../../types/tree';\nimport type { WorkflowSessionStore } from '../workflowSessionStore';\n\nexport const WorkflowSessionStoreContext = createContext<WorkflowSessionStore | null>(null);\n\nexport function useWorkflowSessionStoreApi(): WorkflowSessionStore {\n const store = useContext(WorkflowSessionStoreContext);\n if (!store) {\n throw new Error('useWorkflowSessionStoreApi must be used within WorkflowSession');\n }\n return store;\n}\n\nexport function useWorkflowSessionStatus(): SessionStatus {\n const store = useWorkflowSessionStoreApi();\n return useStore(store, (s) => s.state.status);\n}\n","import { createContext, useContext, type ReactNode } from 'react';\n\n/** 宿主按需 replay 某 loopSessionId 的事件(P2 懒加载) */\nexport type WorkflowLoopReplayHandler = (loopSessionId: string) => void | Promise<void>;\n\nconst WorkflowLoopReplayContext = createContext<WorkflowLoopReplayHandler | undefined>(\n undefined,\n);\n\nexport function WorkflowLoopReplayProvider({\n onRequestLoopReplay,\n children,\n}: {\n onRequestLoopReplay?: WorkflowLoopReplayHandler;\n children: ReactNode;\n}) {\n return (\n <WorkflowLoopReplayContext.Provider value={onRequestLoopReplay}>\n {children}\n </WorkflowLoopReplayContext.Provider>\n );\n}\n\nexport function useWorkflowLoopReplayHandler(): WorkflowLoopReplayHandler | undefined {\n return useContext(WorkflowLoopReplayContext);\n}\n","import { createContext, useContext } from 'react';\n\nimport {\n DEFAULT_WORKFLOW_SCALE_OPTIONS,\n type WorkflowScaleOptions,\n} from '../../view/workflow/workflowScaleOptions';\n\nexport const WorkflowScaleContext = createContext<WorkflowScaleOptions>(\n DEFAULT_WORKFLOW_SCALE_OPTIONS,\n);\n\nexport function useWorkflowScaleOptions(): WorkflowScaleOptions {\n return useContext(WorkflowScaleContext);\n}\n","/** Workflow 大规模编排 UI 缩放选项(P1–P4) */\nexport interface WorkflowScaleOptions {\n /**\n * P1:已弃用 — stage 壳列表不再使用虚拟滚动。\n * 保留字段以保证向后兼容,工作流主链路不再读取此值。\n * @deprecated D25 Phase 1 移除 stage shell virtualization 后不再生效。\n */\n stageVirtualizeThreshold: number;\n /** P3:默认展示的 completed done stage 上限(running/failed/pending 始终展示) */\n completedStagePageSize: number;\n /** P2:completed 且未 pin 的 loop 树移出内存,保留摘要 */\n evictCompletedLoops: boolean;\n /** P4:running 容器仅 active 自动展开 AgentLoopView */\n onlyExpandActiveRunning: boolean;\n /**\n * P1:已弃用 — parallel item shell 不再使用虚拟滚动(最大并行跨度仅 4)。\n * 保留字段以保证向后兼容,工作流主链路不再读取此值。\n * @deprecated D25 Phase 1 移除 parallel item virtualization 后不再生效。\n */\n parallelItemVirtualizeThreshold: number;\n /** P2:completed hydrated loop 热缓存上限(默认 4,与最大并行跨度对齐) */\n maxHydratedCompletedLoops: number;\n}\n\nexport const DEFAULT_WORKFLOW_SCALE_OPTIONS: WorkflowScaleOptions = {\n stageVirtualizeThreshold: 40,\n completedStagePageSize: 25,\n evictCompletedLoops: true,\n onlyExpandActiveRunning: true,\n parallelItemVirtualizeThreshold: 40,\n maxHydratedCompletedLoops: 4,\n};\n","/**\n * workflowSessionStore.ts — Workflow 页 zustand store\n *\n * 职责:\n * Source 事件写入 WorkflowSessionState;与 SessionStore 平行隔离。\n *\n * 链路位置:\n * WorkflowSession Provider → applyEvent。\n *\n * 当前裁剪范围:\n * 无多会话 Tab;dedupe 与 SessionStore 同构。\n */\nimport { createStore, type StoreApi } from 'zustand/vanilla';\n\nimport type { LangchainAgentEvent, TierOverrides } from '../types/events';\nimport type { ReducerError, SessionTree } from '../types/tree';\nimport {\n createEmptyWorkflowSessionState,\n type WorkflowSessionState,\n} from '../types/workflowSession';\nimport { markEventIdSeen, shouldSkipDuplicateEvent } from './dedupe';\nimport { createEmptyTree, type ReduceOptions, reduceTree } from './reducer';\nimport { reduceWorkflowSession } from './workflowReducer';\nimport {\n evictInactiveLoopTrees,\n evictCompletedLoopOverflow,\n touchCompletedLoopSession,\n} from './workflow/workflowLoopEviction';\nimport { filterAgentLoopReplayEvents } from './workflowStructureEvents';\nimport type { SourceEventContext } from '../transport/types';\n\nexport interface WorkflowSessionStoreOptions {\n tierOverrides?: TierOverrides;\n initialEventCount?: number;\n initialSeenEventIds?: Iterable<string>;\n /** P2:completed loop 树内存淘汰(默认 true) */\n evictCompletedLoops?: boolean;\n /** P2:completed hydrated loop 热缓存上限(默认 4) */\n maxHydratedCompletedLoops?: number;\n}\n\nexport interface WorkflowSessionStoreState {\n state: WorkflowSessionState;\n eventCount: number;\n applyEvent: (event: LangchainAgentEvent, ctx?: SourceEventContext) => void;\n applyEvents: (events: LangchainAgentEvent[]) => void;\n reset: () => void;\n markAsError: (error?: Error) => void;\n /** P2:展开 done stage 时 pin,避免淘汰 */\n pinLoopSession: (loopSessionId: string) => void;\n /** P2:宿主 replay 后灌入 loop 树 */\n hydrateLoopSession: (loopSessionId: string, events: LangchainAgentEvent[]) => void;\n}\n\nfunction safeReduceWorkflow(\n state: WorkflowSessionState,\n event: LangchainAgentEvent,\n eventIndex: number,\n options?: ReduceOptions,\n): { state: WorkflowSessionState; error?: ReducerError } {\n try {\n return { state: reduceWorkflowSession(state, event, eventIndex, options) };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n const stack = err instanceof Error ? err.stack : undefined;\n if (import.meta.env?.DEV) {\n console.error('[langchain_agentx_stream_ui] workflow reducer error:', err);\n }\n return {\n state: {\n ...state,\n internalErrors: [\n ...state.internalErrors,\n { eventIndex, eventType: event.event_type, message, stack },\n ],\n },\n };\n }\n}\n\nexport type WorkflowSessionStore = StoreApi<WorkflowSessionStoreState>;\n\nexport function createWorkflowSessionStore(\n initialState: WorkflowSessionState = createEmptyWorkflowSessionState(),\n storeOptions?: WorkflowSessionStoreOptions,\n): WorkflowSessionStore {\n const reduceOpts: ReduceOptions = {\n tierOverrides: storeOptions?.tierOverrides,\n };\n const initialEventCount = storeOptions?.initialEventCount ?? 0;\n const seenEventIds = new Set<string>(storeOptions?.initialSeenEventIds);\n const evictCompletedLoops = storeOptions?.evictCompletedLoops ?? true;\n const maxHydratedCompletedLoops = storeOptions?.maxHydratedCompletedLoops ?? 4;\n const pinnedLoopSessionIds: Record<string, true> = {};\n\n const finalizeState = (reduced: WorkflowSessionState): WorkflowSessionState => {\n if (!evictCompletedLoops) return reduced;\n return evictInactiveLoopTrees(reduced, pinnedLoopSessionIds);\n };\n\n return createStore<WorkflowSessionStoreState>((set, get) => ({\n state: initialState,\n eventCount: initialEventCount,\n applyEvent(event, ctx) {\n const sseEventId = ctx?.sseEventId;\n if (shouldSkipDuplicateEvent(seenEventIds, sseEventId)) return;\n\n const { state, eventCount } = get();\n const { state: reduced } = safeReduceWorkflow(state, event, eventCount, reduceOpts);\n const evicted = finalizeState(reduced);\n const nextMeta =\n sseEventId\n ? { ...evicted.meta, lastEventId: sseEventId }\n : evicted.meta;\n markEventIdSeen(seenEventIds, sseEventId);\n set({\n state: {\n ...evicted,\n meta: nextMeta,\n status: evicted.status === 'connecting' ? 'running' : evicted.status,\n },\n eventCount: eventCount + 1,\n });\n },\n applyEvents(events) {\n for (const event of events) {\n get().applyEvent(event);\n }\n },\n reset() {\n seenEventIds.clear();\n set({\n state: createEmptyWorkflowSessionState(),\n eventCount: 0,\n });\n },\n markAsError(error) {\n const { state } = get();\n const message = error?.message ?? 'Workflow stream error';\n set({\n state: {\n ...state,\n status: 'error',\n internalErrors: [\n ...state.internalErrors,\n {\n eventIndex: get().eventCount,\n eventType: 'stream-error',\n message,\n stack: error?.stack,\n },\n ],\n },\n });\n },\n /**\n * P2:将 completed loop 加入 LRU 热缓存并淘汰溢出。\n * running 保护由 collectProtectedLoopSessionIds 按状态自动覆盖,不再依赖永久 pin。\n */\n pinLoopSession(loopSessionId) {\n set((current) => {\n let next = touchCompletedLoopSession(current.state, loopSessionId);\n next = evictCompletedLoopOverflow(next, maxHydratedCompletedLoops);\n next = finalizeState(next);\n return { state: next };\n });\n },\n /**\n * P2:宿主 replay 后灌入 loop 树,touch LRU 并淘汰溢出。\n * completed loop 受 hotCompletedLoopSessionIds 保护,不再永久 pin。\n */\n hydrateLoopSession(loopSessionId, events) {\n const { state, eventCount } = get();\n let tree: SessionTree =\n state.loopTreesBySessionId[loopSessionId] ?? createEmptyTree();\n let idx = eventCount;\n for (const event of filterAgentLoopReplayEvents(events)) {\n tree = reduceTree(tree, event, idx, reduceOpts);\n idx += 1;\n }\n set((current) => {\n let next: WorkflowSessionState = {\n ...current.state,\n loopTreesBySessionId: {\n ...current.state.loopTreesBySessionId,\n [loopSessionId]: tree,\n },\n };\n next = touchCompletedLoopSession(next, loopSessionId);\n next = evictCompletedLoopOverflow(next, maxHydratedCompletedLoops);\n next = finalizeState(next);\n return { state: next };\n });\n },\n }));\n}\n","/**\n * workflowContainer.ts — Workflow 容器树投影类型\n *\n * 职责:\n * 容器节点、正文块、快照;对齐 SDK workflow_container_projector。\n *\n * 链路位置:\n * workflowContainerProjector → workflowReducer(P1+)→ WorkflowChrome(P2+)。\n *\n * 当前裁剪范围:\n * 不含 React 视图 props;仅投影层 state。\n */\n\nimport type { WorkflowDisplayPayload } from './workflowDisplay';\n\nexport type WorkflowContainerScope =\n | 'workflow'\n | 'stage'\n | 'item'\n | 'branch'\n | 'aggregate'\n | 'subworkflow';\n\nexport type WorkflowContainerStatus =\n | 'pending'\n | 'running'\n | 'completed'\n | 'failed'\n | 'skipped'\n | 'cancelled'\n | 'blocked'\n | 'retrying';\n\nexport type ContentBlockKind = 'reasoning' | 'text' | 'tool';\n\nexport interface WorkflowContentBlock {\n kind: ContentBlockKind;\n preview: string;\n tool_name: string | null;\n}\n\nexport interface WorkflowContainerNode {\n container_id: string;\n scope: WorkflowContainerScope;\n workflow_path: string;\n workflow_depth: number;\n scope_key: string;\n title: string;\n subtitle: string;\n status: WorkflowContainerStatus;\n pattern: string;\n parent_container_id: string | null;\n display: WorkflowDisplayPayload | null;\n content_blocks: WorkflowContentBlock[];\n is_open: boolean;\n}\n\nexport interface WorkflowContainerTreeSnapshot {\n root_container_ids: string[];\n containers: Record<string, WorkflowContainerNode>;\n active_container_ids: string[];\n}\n\n/** reducer 运行时节点:投影字段 + loop 绑定(P1) */\nexport interface WorkflowContainerRuntimeNode extends WorkflowContainerNode {\n loopSessionId: string | null;\n}\n\n/** WorkflowSession 容器树 state(P1+) */\nexport interface WorkflowContainerTreeState {\n rootContainerIds: string[];\n activeContainerIds: string[];\n containersById: Record<string, WorkflowContainerRuntimeNode>;\n}\n\nexport function createEmptyWorkflowContainerTreeState(): WorkflowContainerTreeState {\n return {\n rootContainerIds: [],\n activeContainerIds: [],\n containersById: {},\n };\n}\n\nexport function containerTreeToSnapshot(\n tree: WorkflowContainerTreeState,\n): WorkflowContainerTreeSnapshot {\n const containers: Record<string, WorkflowContainerNode> = {};\n for (const [id, node] of Object.entries(tree.containersById)) {\n const { loopSessionId: _loop, ...projection } = node;\n containers[id] = projection;\n }\n return {\n root_container_ids: [...tree.rootContainerIds],\n active_container_ids: [...tree.activeContainerIds],\n containers,\n };\n}\n\nexport type ContainerAction = 'open' | 'close' | 'append-content';\n\n/** SDK fixture expected.containers 子集(契约对照) */\nexport interface WorkflowContainerExpectedNode {\n title: string;\n subtitle: string;\n status: WorkflowContainerStatus;\n scope: WorkflowContainerScope;\n parent_container_id: string | null;\n content_blocks: WorkflowContentBlock[];\n}\n\nexport interface SdkContainerFixtureExpected {\n root_container_ids: string[];\n active_container_ids: string[];\n containers: Record<string, WorkflowContainerExpectedNode>;\n cli_tree_contains?: string[];\n}\n\nexport interface SdkContainerFixture {\n scenario: string;\n description?: string;\n events: Array<{\n event_type: string;\n data: Record<string, unknown>;\n step_index?: number | null;\n tool_name?: string | null;\n session_id?: string | null;\n timestamp?: number;\n }>;\n expected: SdkContainerFixtureExpected;\n}\n","/**\n * workflowSession.ts — Workflow 会话顶层状态\n *\n * 职责:\n * 定义 /workflow 页专用 WorkflowSessionState(与 /chat SessionTree 隔离)。\n *\n * 链路位置:\n * workflowReducer → workflowSessionStore → WorkflowSession / WorkflowChrome。\n *\n * 当前裁剪范围:\n * 不含合并 TaskListFooter(P3);parallel 结构仅基础字段。\n */\nimport type { SessionStatus, ReducerError, SessionTree } from './tree';\nimport {\n createEmptyWorkflowContainerTreeState,\n type WorkflowContainerTreeState,\n} from './workflowContainer';\n\n/** P2:stage 完成摘要缓存(loop 树淘汰后仍显示 teaser) */\nexport interface CachedStageDoneSummary {\n label: string;\n teaser: string;\n extraLines: number;\n}\n\nexport type WorkflowRunStatus = 'running' | 'done' | 'error';\n\nexport interface WorkflowStageProgress {\n stageKey: string;\n stageIndex: number;\n stageTotal?: number;\n status: 'pending' | 'running' | 'done' | 'failed';\n error?: string;\n}\n\nexport interface ParallelItemProgress {\n itemKey: string;\n itemIndex: number;\n itemTotal?: number;\n status: 'pending' | 'running' | 'done' | 'failed';\n loopSessionId: string | null;\n error?: string;\n}\n\nexport interface WorkflowProgressState {\n workflowId: string | null;\n workflowPath: string | null;\n status: WorkflowRunStatus;\n stages: WorkflowStageProgress[];\n parallelItems: Record<string, ParallelItemProgress>;\n}\n\nexport type WorkflowScopeKind = 'stage' | 'parallel-item' | 'subworkflow';\n\nexport interface WorkflowScopeFrame {\n kind: WorkflowScopeKind;\n key: string;\n loopSessionId: string | null;\n}\n\nexport interface WorkflowSessionState {\n status: SessionStatus;\n meta: {\n workflowRunId: string | null;\n startedAt: number | null;\n lastEventId: string | null;\n };\n /** SDK 容器树投影 + loopSessionId 绑定(P1 主模型) */\n containerTree: WorkflowContainerTreeState;\n /** 过渡期 dual-write;P2+ UI 逐步改读 containerTree */\n workflowProgress: WorkflowProgressState;\n loopTreesBySessionId: Record<string, SessionTree>;\n /** P2:container_id → done 摘要(loop 淘汰后) */\n stageDoneSummariesByContainerId: Record<string, CachedStageDoneSummary>;\n /** P2:completed hydrated loop LRU 热缓存(最近使用在数组尾部) */\n hotCompletedLoopSessionIds: string[];\n activeLoopSessionId: string | null;\n /** @deprecated P1 起由 containerTree.activeContainerIds 替代 */\n openScopeStack: WorkflowScopeFrame[];\n internalErrors: ReducerError[];\n}\n\nexport function createEmptyWorkflowProgress(): WorkflowProgressState {\n return {\n workflowId: null,\n workflowPath: null,\n status: 'running',\n stages: [],\n parallelItems: {},\n };\n}\n\nexport function createEmptyWorkflowSessionState(): WorkflowSessionState {\n return {\n status: 'connecting',\n meta: { workflowRunId: null, startedAt: null, lastEventId: null },\n containerTree: createEmptyWorkflowContainerTreeState(),\n workflowProgress: createEmptyWorkflowProgress(),\n loopTreesBySessionId: {},\n stageDoneSummariesByContainerId: {},\n hotCompletedLoopSessionIds: [],\n activeLoopSessionId: null,\n openScopeStack: [],\n internalErrors: [],\n };\n}\n","/**\n * workflowLoopTreeUtils.ts — Workflow scoped loop 占位树(仅 workflow 引用)\n *\n * 职责:stage running 且尚无 loop 内容时,为 AgentLoopView / Spinner 提供 startedAt。\n * 不修改 createEmptyTree 默认,避免影响 AgentSession /chat 显示。\n */\nimport { createEmptyTree, type SessionTree } from '../../types/tree';\n\n/** Workflow loop 运行占位:status running + startedAt(Spinner 门禁)。 */\nexport function createWorkflowRunningLoopTree(seedMs: number = Date.now()): SessionTree {\n const tree = createEmptyTree();\n tree.status = 'running';\n tree.meta.startedAt = seedMs;\n return tree;\n}\n","/**\n * workflowDisplay.ts — SDK WorkflowDisplayPayload 契约(TS)\n *\n * 职责:\n * 对齐 langchain_agentx WorkflowDisplayPayload;结构事件 data.display 类型。\n *\n * 链路位置:\n * workflowContainerProjector → WorkflowChrome(P2+)。\n *\n * 当前裁剪范围:\n * 只读消费;不计算 display(由 SDK enricher 注入)。\n */\n\nexport type WorkflowDisplayScope =\n | 'workflow'\n | 'stage'\n | 'item'\n | 'branch'\n | 'aggregate'\n | 'subworkflow';\n\nexport type WorkflowDisplayStatus =\n | 'pending'\n | 'running'\n | 'completed'\n | 'failed'\n | 'skipped'\n | 'cancelled'\n | 'blocked'\n | 'retrying';\n\n/** 对齐 SDK display_resolver.WorkflowDisplayPayload */\nexport interface WorkflowDisplayPayload {\n version?: number;\n scope?: WorkflowDisplayScope;\n title?: string;\n description?: string;\n workflow_title?: string;\n workflow_description?: string;\n parent_title?: string;\n breadcrumb?: string[];\n progress_current?: number;\n progress_total?: number;\n progress_label?: string;\n progress_indeterminate?: boolean;\n status?: WorkflowDisplayStatus;\n status_reason?: string;\n icon?: string;\n item_index?: number;\n item_total?: number;\n metrics_completed?: number;\n metrics_running?: number;\n metrics_failed?: number;\n metrics_total?: number;\n decision_label?: string;\n pattern?: string;\n debug_key?: string;\n}\n\nexport function readDisplayPayload(data: Record<string, unknown>): WorkflowDisplayPayload | null {\n const display = data.display;\n if (display != null && typeof display === 'object' && !Array.isArray(display)) {\n return display as WorkflowDisplayPayload;\n }\n return null;\n}\n","/**\n * workflowContainerProjector.ts — LangchainAgentEvent → 容器树投影\n *\n * 职责:\n * 对齐 SDK workflow_container_projector;维护 active set;正文路由。\n *\n * 链路位置:\n * workflowReducer(P1)← consume LangchainAgentEvent;fixture 单测 SSOT。\n *\n * 当前裁剪范围:\n * 仅投影层;不负责 React 渲染或 loop tree reduceTree。\n */\nimport type { LangchainAgentEvent } from '../../types/events';\nimport { readDisplayPayload } from '../../types/workflowDisplay';\nimport type {\n ContainerAction,\n WorkflowContainerNode,\n WorkflowContainerScope,\n WorkflowContainerStatus,\n WorkflowContainerTreeSnapshot,\n WorkflowContentBlock,\n} from '../../types/workflowContainer';\n\nconst OPEN_EVENT_TYPES = new Set<string>([\n 'workflow-start',\n 'subworkflow-start',\n 'stage-start',\n 'parallel-item-start',\n 'parallel-aggregate-start',\n 'route-branch-start',\n]);\n\nconst CLOSE_EVENT_TYPES = new Set<string>([\n 'workflow-end',\n 'workflow-failed',\n 'subworkflow-end',\n 'stage-done',\n 'stage-failed',\n 'parallel-item-done',\n 'parallel-item-failed',\n 'parallel-aggregate-done',\n 'parallel-aggregate-failed',\n 'route-branch-done',\n 'route-branch-failed',\n]);\n\nconst EVENT_TYPE_TO_SCOPE: Record<string, WorkflowContainerScope> = {\n 'workflow-start': 'workflow',\n 'workflow-end': 'workflow',\n 'workflow-failed': 'workflow',\n 'subworkflow-start': 'subworkflow',\n 'subworkflow-end': 'subworkflow',\n 'stage-start': 'stage',\n 'stage-done': 'stage',\n 'stage-failed': 'stage',\n 'parallel-item-start': 'item',\n 'parallel-item-done': 'item',\n 'parallel-item-failed': 'item',\n 'parallel-aggregate-start': 'aggregate',\n 'parallel-aggregate-done': 'aggregate',\n 'parallel-aggregate-failed': 'aggregate',\n 'route-branch-start': 'branch',\n 'route-branch-done': 'branch',\n 'route-branch-failed': 'branch',\n};\n\nconst CONTENT_EVENT_TYPES = new Set<string>([\n 'reasoning-start',\n 'reasoning-delta',\n 'reasoning-end',\n 'text-start',\n 'text-delta',\n 'text-end',\n 'tool-input',\n 'tool-input-start',\n 'tool-input-delta',\n 'tool-call',\n 'tool-result',\n 'tool-error',\n 'tool-progress',\n]);\n\nconst SCOPE_PRIORITY: Record<WorkflowContainerScope, number> = {\n workflow: 0,\n subworkflow: 1,\n aggregate: 2,\n stage: 3,\n item: 3,\n branch: 3,\n};\n\nconst FAILED_CLOSE_TYPES = new Set<string>([\n 'workflow-failed',\n 'stage-failed',\n 'parallel-item-failed',\n 'parallel-aggregate-failed',\n 'route-branch-failed',\n]);\n\nexport function buildContainerId(\n workflowPath: string,\n scope: WorkflowContainerScope,\n scopeKey: string,\n): string {\n return `${workflowPath}|${scope}:${scopeKey}`;\n}\n\nfunction readString(data: Record<string, unknown>, key: string): string | undefined {\n const value = data[key];\n return typeof value === 'string' ? value : undefined;\n}\n\nexport function resolveScopeKey(eventType: string, data: Record<string, unknown>): string {\n if (\n eventType === 'workflow-start'\n || eventType === 'workflow-end'\n || eventType === 'workflow-failed'\n ) {\n const workflowId = readString(data, 'workflow_id');\n if (workflowId) return workflowId;\n return readString(data, 'workflow_path') ?? 'workflow';\n }\n\n if (eventType === 'subworkflow-start' || eventType === 'subworkflow-end') {\n return readString(data, 'child_workflow_id') ?? 'subworkflow';\n }\n\n if (\n eventType === 'stage-start'\n || eventType === 'stage-done'\n || eventType === 'stage-failed'\n ) {\n const stageKey = readString(data, 'stage_key');\n if (stageKey) return stageKey;\n const stageIndex = data.stage_index;\n return typeof stageIndex === 'number' ? String(stageIndex) : 'stage';\n }\n\n if (\n eventType === 'parallel-item-start'\n || eventType === 'parallel-item-done'\n || eventType === 'parallel-item-failed'\n ) {\n const itemKey = readString(data, 'item_key');\n if (itemKey) return itemKey;\n const itemIndex = data.item_index;\n return typeof itemIndex === 'number' ? String(itemIndex) : 'item';\n }\n\n if (\n eventType === 'parallel-aggregate-start'\n || eventType === 'parallel-aggregate-done'\n || eventType === 'parallel-aggregate-failed'\n ) {\n return readString(data, 'aggregate_key') ?? 'aggregate';\n }\n\n if (\n eventType === 'route-branch-start'\n || eventType === 'route-branch-done'\n || eventType === 'route-branch-failed'\n ) {\n return readString(data, 'branch_key') ?? readString(data, 'branch_node') ?? 'branch';\n }\n\n const display = readDisplayPayload(data);\n if (display?.debug_key) return display.debug_key;\n\n return 'unknown';\n}\n\nfunction displayStatus(\n data: Record<string, unknown>,\n fallback: WorkflowContainerStatus,\n): WorkflowContainerStatus {\n const display = readDisplayPayload(data);\n if (display?.status) return display.status;\n return fallback;\n}\n\nfunction closeStatus(eventType: string): WorkflowContainerStatus {\n return FAILED_CLOSE_TYPES.has(eventType) ? 'failed' : 'completed';\n}\n\nfunction readPreview(data: Record<string, unknown>, ...keys: string[]): string {\n for (const key of keys) {\n const value = data[key];\n if (typeof value === 'string') return value;\n }\n return '';\n}\n\nfunction contentBlockFromEvent(event: LangchainAgentEvent): WorkflowContentBlock | null {\n const { event_type: eventType } = event;\n const payload = (event.data ?? {}) as Record<string, unknown>;\n\n if (\n eventType === 'reasoning-start'\n || eventType === 'reasoning-delta'\n || eventType === 'reasoning-end'\n ) {\n let preview = readPreview(payload, 'delta', 'text', 'reasoning');\n if (!preview && eventType === 'reasoning-start') preview = 'Thinking…';\n return { kind: 'reasoning', preview, tool_name: null };\n }\n\n if (\n eventType === 'text-start'\n || eventType === 'text-delta'\n || eventType === 'text-end'\n ) {\n const preview = readPreview(payload, 'delta', 'text');\n return { kind: 'text', preview, tool_name: null };\n }\n\n if (CONTENT_EVENT_TYPES.has(eventType)) {\n const toolName = event.tool_name ?? readString(payload, 'tool_name');\n const preview =\n readPreview(payload, 'summary', 'output', 'input', 'delta')\n || toolName\n || eventType;\n return {\n kind: 'tool',\n preview,\n tool_name: toolName ?? null,\n };\n }\n\n return null;\n}\n\nexport function resolveContentScopeKey(data: Record<string, unknown>): string | null {\n for (const keyName of ['stage_key', 'item_key', 'branch_key', 'debug_key'] as const) {\n const value = readString(data, keyName);\n if (value) return value;\n }\n const display = readDisplayPayload(data);\n return display?.debug_key ?? null;\n}\n\n/** 按容器身份索引的活跃集(并发 item 不依赖 LIFO 单栈) */\nexport class WorkflowContainerActiveSet {\n private readonly openOrder: string[] = [];\n private readonly nodes: Record<string, WorkflowContainerNode> = {};\n\n restoreNode(node: WorkflowContainerNode): void {\n this.nodes[node.container_id] = { ...node };\n if (node.is_open && !this.openOrder.includes(node.container_id)) {\n this.openOrder.push(node.container_id);\n }\n }\n\n open(node: WorkflowContainerNode): void {\n this.nodes[node.container_id] = node;\n if (!this.openOrder.includes(node.container_id)) {\n this.openOrder.push(node.container_id);\n }\n }\n\n close(containerId: string, status: WorkflowContainerStatus): void {\n const node = this.nodes[containerId];\n if (!node) return;\n node.status = status;\n node.is_open = false;\n const idx = this.openOrder.indexOf(containerId);\n if (idx !== -1) this.openOrder.splice(idx, 1);\n }\n\n get activeIds(): string[] {\n return [...this.openOrder];\n }\n\n getNode(containerId: string): WorkflowContainerNode | undefined {\n return this.nodes[containerId];\n }\n\n get nodesById(): Record<string, WorkflowContainerNode> {\n return this.nodes;\n }\n\n rankContainer(containerId: string): [number, number, number, number] {\n const node = this.nodes[containerId];\n if (!node) return [-1, -1, -1, -1];\n const openIndex = this.openOrder.indexOf(containerId);\n const scopePriority = SCOPE_PRIORITY[node.scope] ?? 0;\n return [node.workflow_depth, scopePriority, node.workflow_path.length, openIndex];\n }\n\n deepestActive(): string | null {\n if (this.openOrder.length === 0) return null;\n return this.openOrder.reduce((best, cid) =>\n this.compareRank(cid, best) > 0 ? cid : best,\n );\n }\n\n resolveContentTarget(workflowPath: string | null, scopeKey: string | null): string | null {\n if (scopeKey) {\n for (let i = this.openOrder.length - 1; i >= 0; i -= 1) {\n const containerId = this.openOrder[i]!;\n const node = this.nodes[containerId]!;\n if (node.scope_key === scopeKey && node.is_open) {\n if (workflowPath === null || node.workflow_path === workflowPath) {\n return containerId;\n }\n }\n }\n }\n\n if (workflowPath) {\n const candidates = this.openOrder.filter((cid) => {\n const node = this.nodes[cid]!;\n if (!node.is_open) return false;\n return (\n node.workflow_path === workflowPath\n || workflowPath.startsWith(`${node.workflow_path}>`)\n );\n });\n if (candidates.length > 0) {\n return candidates.reduce((best, cid) =>\n this.compareRank(cid, best) > 0 ? cid : best,\n );\n }\n }\n\n return this.deepestActive();\n }\n\n closeDescendantsOfPath(workflowPath: string, status: WorkflowContainerStatus): void {\n const toClose = this.openOrder.filter((cid) => {\n const node = this.nodes[cid]!;\n return (\n node.workflow_path === workflowPath\n || node.workflow_path.startsWith(`${workflowPath}>`)\n );\n });\n for (const containerId of toClose) {\n this.close(containerId, status);\n }\n }\n\n private compareRank(a: string, b: string): number {\n const ra = this.rankContainer(a);\n const rb = this.rankContainer(b);\n for (let i = 0; i < ra.length; i += 1) {\n if (ra[i]! > rb[i]!) return 1;\n if (ra[i]! < rb[i]!) return -1;\n }\n return 0;\n }\n\n /** 供 StateMachine 比较容器深度 rank */\n compareContainerRank(a: string, b: string): number {\n return this.compareRank(a, b);\n }\n}\n\n/** 事件 → 容器状态机(对齐 SDK reference) */\nexport class WorkflowContainerStateMachine {\n private readonly active = new WorkflowContainerActiveSet();\n private readonly rootIds: string[] = [];\n private suppressContentContainerIds: ReadonlySet<string> = new Set();\n\n get activeSet(): WorkflowContainerActiveSet {\n return this.active;\n }\n\n setSuppressContentContainerIds(ids: ReadonlySet<string>): void {\n this.suppressContentContainerIds = ids;\n }\n\n rehydrate(snapshot: WorkflowContainerTreeSnapshot): void {\n this.rootIds.length = 0;\n this.rootIds.push(...snapshot.root_container_ids);\n for (const node of Object.values(snapshot.containers)) {\n this.active.restoreNode(node);\n }\n }\n\n apply(event: LangchainAgentEvent): ContainerAction | null {\n const eventType = event.event_type;\n const data = (event.data ?? {}) as Record<string, unknown>;\n\n if (OPEN_EVENT_TYPES.has(eventType)) {\n this.openContainer(eventType, data);\n return 'open';\n }\n\n if (CLOSE_EVENT_TYPES.has(eventType)) {\n this.closeContainer(eventType, data);\n return 'close';\n }\n\n if (CONTENT_EVENT_TYPES.has(eventType)) {\n this.appendContent(event);\n return 'append-content';\n }\n\n return null;\n }\n\n snapshot(): WorkflowContainerTreeSnapshot {\n return {\n root_container_ids: [...this.rootIds],\n containers: { ...this.active.nodesById },\n active_container_ids: this.active.activeIds,\n };\n }\n\n private openContainer(eventType: string, data: Record<string, unknown>): void {\n const scope = EVENT_TYPE_TO_SCOPE[eventType];\n if (!scope) return;\n\n const workflowPath = readString(data, 'workflow_path') ?? '';\n const workflowDepth =\n typeof data.workflow_depth === 'number' ? data.workflow_depth : 0;\n const scopeKey = resolveScopeKey(eventType, data);\n const containerId = buildContainerId(workflowPath, scope, scopeKey);\n\n const display = readDisplayPayload(data);\n const title = display?.title ?? scopeKey;\n const subtitle = display?.description ?? '';\n const pattern = display?.pattern ?? '';\n const status = displayStatus(data, 'running');\n const parentId = this.resolveParentId(workflowPath, scope);\n\n const node: WorkflowContainerNode = {\n container_id: containerId,\n scope,\n workflow_path: workflowPath,\n workflow_depth: workflowDepth,\n scope_key: scopeKey,\n title,\n subtitle,\n status,\n pattern,\n parent_container_id: parentId,\n display,\n content_blocks: [],\n is_open: true,\n };\n\n this.active.open(node);\n if (scope === 'workflow' && !this.rootIds.includes(containerId)) {\n this.rootIds.push(containerId);\n }\n }\n\n private closeContainer(eventType: string, data: Record<string, unknown>): void {\n const scope = EVENT_TYPE_TO_SCOPE[eventType];\n if (!scope) return;\n\n const workflowPath = readString(data, 'workflow_path') ?? '';\n const scopeKey = resolveScopeKey(eventType, data);\n const containerId = buildContainerId(workflowPath, scope, scopeKey);\n const status = displayStatus(data, closeStatus(eventType));\n\n this.active.close(containerId, status);\n if (scope === 'workflow') {\n this.active.closeDescendantsOfPath(workflowPath, status);\n }\n }\n\n private appendContent(event: LangchainAgentEvent): void {\n const data = (event.data ?? {}) as Record<string, unknown>;\n const workflowPath = readString(data, 'workflow_path') ?? null;\n const scopeKey = resolveContentScopeKey(data);\n\n const targetId = this.active.resolveContentTarget(workflowPath, scopeKey);\n if (!targetId) return;\n if (this.suppressContentContainerIds.has(targetId)) return;\n\n const block = contentBlockFromEvent(event);\n if (!block) return;\n\n const node = this.active.getNode(targetId);\n if (!node) return;\n\n const last = node.content_blocks[node.content_blocks.length - 1];\n if (\n last\n && last.kind === block.kind\n && (block.kind === 'reasoning' || block.kind === 'text')\n ) {\n if (block.preview) {\n if (block.kind === 'reasoning' && last.preview === 'Thinking…') {\n last.preview = block.preview;\n } else {\n last.preview = `${last.preview}${block.preview}`;\n }\n }\n return;\n }\n\n node.content_blocks.push(block);\n }\n\n private resolveParentId(\n workflowPath: string,\n scope: WorkflowContainerScope,\n ): string | null {\n if (scope === 'workflow') return null;\n\n const openNodes = this.active.activeIds\n .map((cid) => this.active.getNode(cid)!)\n .filter((node) => node.is_open);\n\n if (openNodes.length === 0) return null;\n\n const prefixCandidates = openNodes.filter(\n (node) =>\n workflowPath === node.workflow_path\n || workflowPath.startsWith(`${node.workflow_path}>`),\n );\n\n if (prefixCandidates.length > 0) {\n const parent = prefixCandidates.reduce((best, node) =>\n this.active.compareContainerRank(node.container_id, best.container_id) > 0\n ? node\n : best,\n );\n if (parent.workflow_path === workflowPath && parent.scope === 'workflow') {\n return parent.container_id;\n }\n if (workflowPath.startsWith(`${parent.workflow_path}>`)) {\n return parent.container_id;\n }\n if (parent.workflow_path === workflowPath && parent.scope !== scope) {\n return parent.container_id;\n }\n }\n\n const workflowCandidates = openNodes.filter((node) => node.scope === 'workflow');\n if (workflowCandidates.length > 0) {\n return workflowCandidates.reduce((best, node) =>\n this.active.compareContainerRank(node.container_id, best.container_id) > 0\n ? node\n : best,\n ).container_id;\n }\n\n return openNodes.reduce((best, node) =>\n this.active.compareContainerRank(node.container_id, best.container_id) > 0\n ? node\n : best,\n ).container_id;\n }\n}\n\n/** LangchainAgentEvent 流 → 容器树快照 */\nexport class WorkflowContainerTreeProjector {\n private readonly machine = new WorkflowContainerStateMachine();\n\n rehydrate(snapshot: WorkflowContainerTreeSnapshot): void {\n this.machine.rehydrate(snapshot);\n }\n\n setSuppressContentContainerIds(ids: ReadonlySet<string>): void {\n this.machine.setSuppressContentContainerIds(ids);\n }\n\n consume(event: LangchainAgentEvent): ContainerAction | null {\n return this.machine.apply(event);\n }\n\n consumeAll(events: LangchainAgentEvent[]): WorkflowContainerTreeSnapshot {\n for (const event of events) {\n this.consume(event);\n }\n return this.snapshot();\n }\n\n snapshot(): WorkflowContainerTreeSnapshot {\n return this.machine.snapshot();\n }\n}\n\n/** 纯函数:快照 + 单事件 → 新快照(供 workflowReducer 双轨归约) */\nexport interface ReduceContainerSnapshotOptions {\n /** 已绑定 loop 的容器不再写入 content_blocks(过程层走 AgentLoopView) */\n suppressContentContainerIds?: ReadonlySet<string>;\n}\n\nexport function reduceContainerSnapshot(\n snapshot: WorkflowContainerTreeSnapshot,\n event: LangchainAgentEvent,\n options?: ReduceContainerSnapshotOptions,\n): WorkflowContainerTreeSnapshot {\n const projector = new WorkflowContainerTreeProjector();\n projector.rehydrate(snapshot);\n if (options?.suppressContentContainerIds?.size) {\n projector.setSuppressContentContainerIds(options.suppressContentContainerIds);\n }\n projector.consume(event);\n return projector.snapshot();\n}\n\n/** 从 open 容器集解析 agent 正文路由目标 */\nexport function resolveContentTargetFromSnapshot(\n snapshot: WorkflowContainerTreeSnapshot,\n workflowPath: string | null,\n scopeKey: string | null,\n): string | null {\n const active = new WorkflowContainerActiveSet();\n for (const containerId of snapshot.active_container_ids) {\n const node = snapshot.containers[containerId];\n if (node?.is_open) active.restoreNode(node);\n }\n return active.resolveContentTarget(workflowPath, scopeKey);\n}\n\n/** 投影快照合并 loopSessionId(projector 不管理 loop 绑定) */\nexport function mergeRuntimeContainerNodes(\n prev: Record<string, { loopSessionId: string | null }>,\n snapshot: WorkflowContainerTreeSnapshot,\n): Record<\n string,\n WorkflowContainerNode & { loopSessionId: string | null }\n> {\n const out: Record<string, WorkflowContainerNode & { loopSessionId: string | null }> = {};\n for (const [containerId, node] of Object.entries(snapshot.containers)) {\n out[containerId] = {\n ...node,\n loopSessionId: prev[containerId]?.loopSessionId ?? null,\n };\n }\n return out;\n}\n\n/** 序列化为 SDK fixture expected 对照结构 */\nexport function snapshotToExpectedFormat(\n snapshot: WorkflowContainerTreeSnapshot,\n): {\n root_container_ids: string[];\n active_container_ids: string[];\n containers: Record<\n string,\n {\n title: string;\n subtitle: string;\n status: WorkflowContainerStatus;\n scope: WorkflowContainerScope;\n parent_container_id: string | null;\n content_blocks: WorkflowContentBlock[];\n }\n >;\n} {\n const containers: Record<\n string,\n {\n title: string;\n subtitle: string;\n status: WorkflowContainerStatus;\n scope: WorkflowContainerScope;\n parent_container_id: string | null;\n content_blocks: WorkflowContentBlock[];\n }\n > = {};\n\n for (const [cid, node] of Object.entries(snapshot.containers)) {\n containers[cid] = {\n title: node.title,\n subtitle: node.subtitle,\n status: node.status,\n scope: node.scope,\n parent_container_id: node.parent_container_id,\n content_blocks: node.content_blocks.map((b) => ({\n kind: b.kind,\n preview: b.preview,\n tool_name: b.tool_name,\n })),\n };\n }\n\n return {\n root_container_ids: snapshot.root_container_ids,\n active_container_ids: snapshot.active_container_ids,\n containers,\n };\n}\n\nexport type {\n WorkflowContainerNode,\n WorkflowContainerTreeSnapshot,\n WorkflowContentBlock,\n ContainerAction,\n};\n","/**\n * loopSessionUtils.ts — Workflow loop session_id 推导(对齐 SDK WorkflowSessionIdPolicy)\n *\n * loop_session_id = `{workflow_id}-{task_key}`\n */\nimport type { LangchainAgentEvent } from '../../types/events';\nimport type { WorkflowContainerScope } from '../../types/workflowContainer';\nimport { resolveScopeKey } from './workflowContainerProjector';\n\nfunction readString(data: Record<string, unknown>, key: string): string | undefined {\n const value = data[key];\n return typeof value === 'string' ? value : undefined;\n}\n\n/** 会在其内运行 Agent loop 的结构 open 事件 → 容器 scope */\nconst LOOP_TASK_OPEN_SCOPES: Partial<Record<string, WorkflowContainerScope>> = {\n 'stage-start': 'stage',\n 'parallel-item-start': 'item',\n 'route-branch-start': 'branch',\n};\n\nexport function buildLoopSessionId(workflowId: string, taskKey: string): string {\n return `${workflowId}-${taskKey}`;\n}\n\n/** stage-start / parallel-item-start 等 open 事件预绑定 loop session。 */\nexport function deriveLoopSessionIdFromStructureOpen(\n event: LangchainAgentEvent,\n): string | null {\n if (!LOOP_TASK_OPEN_SCOPES[event.event_type]) return null;\n\n const data = (event.data ?? {}) as Record<string, unknown>;\n const workflowId = readString(data, 'workflow_id');\n if (!workflowId) return null;\n\n const taskKey = resolveScopeKey(event.event_type, data);\n if (!taskKey || taskKey === 'unknown') return null;\n\n return buildLoopSessionId(workflowId, taskKey);\n}\n\n/** agent 事件缺 session_id 时,从 workflow_id (或 workflow_path 兜底) + scope key 推导。 */\nexport function deriveLoopSessionIdFromAgentEvent(\n event: LangchainAgentEvent,\n): string | null {\n const data = (event.data ?? {}) as Record<string, unknown>;\n // 真捕获里 content 事件没有 workflow_id;但 SDK 容器投影 fixture 用 workflow_path。\n // 两者在根 workflow 上等价,所以允许 workflow_path 兜底(不破坏 D24,因为\n // workflow_id 永远优先;只是为了兼容用 workflow_path 命名 root 的 fixture)。\n const workflowId =\n readString(data, 'workflow_id') ?? readString(data, 'workflow_path');\n if (!workflowId) return null;\n\n const taskKey =\n readString(data, 'stage_key')\n ?? readString(data, 'item_key')\n ?? readString(data, 'branch_key');\n if (!taskKey) return null;\n\n return buildLoopSessionId(workflowId, taskKey);\n}\n\nexport function isLoopTaskStructureOpenEvent(eventType: string): boolean {\n return eventType in LOOP_TASK_OPEN_SCOPES;\n}\n\nexport function loopTaskScopeForStructureOpen(\n eventType: string,\n): WorkflowContainerScope | undefined {\n return LOOP_TASK_OPEN_SCOPES[eventType];\n}\n","/**\n * workflowStructureEvents.ts — Workflow 结构事件类型守卫\n *\n * 职责:\n * 区分 workflow 编排结构 event_type 与 agent loop 事件。\n *\n * 链路位置:\n * workflowReducer 路由 · hydrateLoopSession 过滤 · Source application_kind 守卫。\n *\n * 当前裁剪范围:\n * 显式集合与 backend sse.WORKFLOW_STRUCTURE_EVENT_TYPES 对齐;\n * 识别逻辑另用前缀(与 task_sync/multi_sse_bridge.py 一致),避免 SDK 新增结构类型漏判。\n */\nimport { DEFAULT_EVENT_TIERS } from '../types/events';\n\n/** 与 backend/langchain_agentx_stream_ui_backend/task_sync/multi_sse_bridge.py 对齐 */\nexport const WORKFLOW_STRUCTURE_EVENT_PREFIXES: readonly string[] = [\n 'workflow-',\n 'stage-',\n 'parallel-',\n 'route-',\n 'subworkflow-',\n];\n\n/** 显式 SSOT(文档/契约测试);新增结构类型应同时满足前缀规则或补入此集合 */\nexport const WORKFLOW_STRUCTURE_EVENT_TYPES: ReadonlySet<string> = new Set([\n 'workflow-start',\n 'workflow-end',\n 'workflow-failed',\n 'subworkflow-start',\n 'subworkflow-end',\n 'stage-start',\n 'stage-done',\n 'stage-failed',\n 'parallel-item-start',\n 'parallel-item-done',\n 'parallel-item-failed',\n 'parallel-aggregate-start',\n 'parallel-aggregate-done',\n 'parallel-aggregate-failed',\n 'route-branch-start',\n 'route-branch-done',\n 'route-branch-failed',\n]);\n\n/** session reducer(reduceTree)可处理的 event_type 白名单 */\nconst AGENT_LOOP_REPLAY_EVENT_TYPES: ReadonlySet<string> = new Set(\n Object.keys(DEFAULT_EVENT_TIERS),\n);\n\nexport function isWorkflowStructureEventType(eventType: string): boolean {\n if (WORKFLOW_STRUCTURE_EVENT_TYPES.has(eventType)) return true;\n return WORKFLOW_STRUCTURE_EVENT_PREFIXES.some((prefix) => eventType.startsWith(prefix));\n}\n\n/** agent loop hydrate/replay 允许进入 reduceTree 的事件(正文 + state/debug tier) */\nexport function isAgentLoopReplayEventType(eventType: string): boolean {\n return AGENT_LOOP_REPLAY_EVENT_TYPES.has(eventType);\n}\n\n/**\n * hydrateLoopSession / 宿主 replay:\n * 1. 白名单:只保留 reduceTree 已知 event_type\n * 2. 结构前缀/集合:双重排除 workflow 编排帧(含 session_id 误绑的 dual emission)\n */\nexport function filterAgentLoopReplayEvents<T extends { event_type: string }>(\n events: T[],\n): T[] {\n return events.filter(\n (event) =>\n isAgentLoopReplayEventType(event.event_type)\n && !isWorkflowStructureEventType(event.event_type),\n );\n}\n","/**\n * workflowReducer.ts — WorkflowSession 容器树 + agent loop 双轨归约\n *\n * 职责:\n * 结构事件经 WorkflowContainerTreeProjector 更新 containerTree;\n * agent 事件 bind loopSessionId 并写入 loopTreesBySessionId。\n *\n * 链路位置:\n * workflowSessionStore.applyEvent → reduceWorkflowSession。\n *\n * 当前裁剪范围:\n * workflowProgress 为过渡期 dual-write;P2+ UI 改读 containerTree。\n */\nimport type { LangchainAgentEvent } from '../types/events';\nimport { createWorkflowRunningLoopTree } from './workflow/workflowLoopTreeUtils';\nimport type {\n WorkflowContainerRuntimeNode,\n WorkflowContainerStatus,\n WorkflowContainerTreeState,\n} from '../types/workflowContainer';\nimport { containerTreeToSnapshot } from '../types/workflowContainer';\nimport type {\n WorkflowSessionState,\n WorkflowStageProgress,\n ParallelItemProgress,\n WorkflowRunStatus,\n WorkflowProgressState,\n} from '../types/workflowSession';\nimport { createEmptyWorkflowSessionState } from '../types/workflowSession';\nimport {\n buildContainerId,\n mergeRuntimeContainerNodes,\n reduceContainerSnapshot,\n resolveContentScopeKey,\n resolveContentTargetFromSnapshot,\n resolveScopeKey,\n} from './workflow/workflowContainerProjector';\nimport {\n deriveLoopSessionIdFromAgentEvent,\n deriveLoopSessionIdFromStructureOpen,\n loopTaskScopeForStructureOpen,\n} from './workflow/loopSessionUtils';\nimport { isWorkflowStructureEventType } from './workflowStructureEvents';\nimport { reduceTree, type ReduceOptions } from './reducer';\n\nfunction readString(data: Record<string, unknown>, key: string): string | undefined {\n const value = data[key];\n return typeof value === 'string' ? value : undefined;\n}\n\nfunction mapContainerStatusToProgressStatus(\n status: WorkflowContainerStatus,\n): WorkflowStageProgress['status'] {\n switch (status) {\n case 'completed':\n return 'done';\n case 'failed':\n return 'failed';\n case 'running':\n return 'running';\n default:\n return 'pending';\n }\n}\n\nfunction syncWorkflowProgressFromContainerTree(\n tree: WorkflowContainerTreeState,\n prev: WorkflowProgressState,\n): WorkflowProgressState {\n const workflowNodes = Object.values(tree.containersById).filter((n) => n.scope === 'workflow');\n const rootWorkflow =\n workflowNodes.find((n) => tree.rootContainerIds.includes(n.container_id)) ?? workflowNodes[0];\n\n const stages: WorkflowStageProgress[] = Object.values(tree.containersById)\n .filter((n) => n.scope === 'stage')\n .sort((a, b) => {\n const ai = a.display?.progress_current ?? 0;\n const bi = b.display?.progress_current ?? 0;\n if (ai !== bi) return ai - bi;\n return a.scope_key.localeCompare(b.scope_key);\n })\n .map((node, index) => ({\n stageKey: node.scope_key,\n stageIndex: node.display?.progress_current ?? index,\n stageTotal: node.display?.progress_total,\n status: mapContainerStatusToProgressStatus(node.status),\n error: node.display?.status_reason,\n }));\n\n const parallelItems: Record<string, ParallelItemProgress> = {};\n for (const node of Object.values(tree.containersById)) {\n if (node.scope !== 'item') continue;\n parallelItems[node.scope_key] = {\n itemKey: node.scope_key,\n itemIndex: node.display?.item_index ?? 0,\n itemTotal: node.display?.item_total,\n status: mapContainerStatusToProgressStatus(node.status),\n loopSessionId: node.loopSessionId,\n error: node.display?.status_reason,\n };\n }\n\n let runStatus: WorkflowRunStatus = prev.status;\n if (rootWorkflow) {\n if (rootWorkflow.status === 'completed') runStatus = 'done';\n else if (rootWorkflow.status === 'failed') runStatus = 'error';\n else runStatus = 'running';\n }\n\n return {\n workflowId: rootWorkflow?.scope_key ?? prev.workflowId,\n workflowPath: rootWorkflow?.workflow_path ?? prev.workflowPath,\n status: runStatus,\n stages,\n parallelItems,\n };\n}\n\nfunction loopBoundContainerIds(\n containersById: Record<string, WorkflowContainerRuntimeNode>,\n): Set<string> {\n const ids = new Set<string>();\n for (const [containerId, node] of Object.entries(containersById)) {\n if (node.loopSessionId) ids.add(containerId);\n }\n return ids;\n}\n\nfunction applyStructureToContainerTree(\n tree: WorkflowContainerTreeState,\n event: LangchainAgentEvent,\n): WorkflowContainerTreeState {\n const snapshot = reduceContainerSnapshot(containerTreeToSnapshot(tree), event, {\n suppressContentContainerIds: loopBoundContainerIds(tree.containersById),\n });\n let containersById = mergeRuntimeContainerNodes(tree.containersById, snapshot);\n containersById = enrichWorkflowRootFromStages(\n containersById,\n snapshot.root_container_ids,\n );\n return {\n rootContainerIds: snapshot.root_container_ids,\n activeContainerIds: snapshot.active_container_ids,\n containersById,\n };\n}\n\n/** stage-start 等 open 事件:预绑定 loopSessionId + 清空 content_blocks(D24 过程层 SSOT)。 */\nfunction prebindLoopSessionFromStructureOpen(\n tree: WorkflowContainerTreeState,\n event: LangchainAgentEvent,\n): WorkflowContainerTreeState {\n const loopSessionId = deriveLoopSessionIdFromStructureOpen(event);\n const scope = loopTaskScopeForStructureOpen(event.event_type);\n if (!loopSessionId || !scope) return tree;\n\n const data = (event.data ?? {}) as Record<string, unknown>;\n const workflowPath = readString(data, 'workflow_path') ?? '';\n const scopeKey = resolveScopeKey(event.event_type, data);\n const containerId = buildContainerId(workflowPath, scope, scopeKey);\n\n const node = tree.containersById[containerId];\n if (!node) return tree;\n if (node.loopSessionId === loopSessionId && node.content_blocks.length === 0) {\n return tree;\n }\n\n return {\n ...tree,\n containersById: {\n ...tree.containersById,\n [containerId]: {\n ...node,\n loopSessionId,\n content_blocks: [],\n },\n },\n };\n}\n\n/** workflow display 缺 pattern/progress 时从 stage 子节点推导(对齐 D24 根行 meta)。 */\nfunction enrichWorkflowRootFromStages(\n containersById: Record<string, WorkflowContainerRuntimeNode>,\n rootContainerIds: string[],\n): Record<string, WorkflowContainerRuntimeNode> {\n const rootId = rootContainerIds[0];\n if (!rootId) return containersById;\n\n const root = containersById[rootId];\n if (!root || root.scope !== 'workflow') return containersById;\n\n const stages = Object.values(containersById).filter(\n (node) =>\n node.scope === 'stage'\n && node.workflow_path === root.workflow_path\n && node.workflow_depth === root.workflow_depth,\n );\n if (stages.length === 0) return containersById;\n\n const pattern =\n root.pattern\n || root.display?.pattern\n || stages.find((s) => s.pattern)?.pattern\n || stages.find((s) => s.display?.pattern)?.display?.pattern\n || 'chaining';\n\n const inferredTotal = stages.reduce(\n (max, s) => Math.max(max, s.display?.progress_total ?? 0),\n 0,\n );\n const progressTotal =\n root.display?.progress_total ?? (inferredTotal > 0 ? inferredTotal : stages.length);\n\n const settled = stages.filter(\n (s) => s.status === 'completed' || s.status === 'failed',\n ).length;\n const progressCurrent =\n root.status === 'completed' || root.status === 'failed'\n ? progressTotal\n : Math.max(root.display?.progress_current ?? 0, settled);\n\n if (\n root.pattern === pattern\n && root.display?.pattern === pattern\n && root.display?.progress_total === progressTotal\n && root.display?.progress_current === progressCurrent\n ) {\n return containersById;\n }\n\n const display = root.display\n ? {\n ...root.display,\n pattern,\n progress_total: progressTotal,\n progress_current: progressCurrent,\n }\n : root.display;\n\n return {\n ...containersById,\n [rootId]: {\n ...root,\n pattern,\n display,\n },\n };\n}\n\nfunction findContainerByLoopSession(\n tree: WorkflowContainerTreeState,\n loopSessionId: string,\n): string | null {\n for (const [containerId, node] of Object.entries(tree.containersById)) {\n if (node.loopSessionId === loopSessionId) return containerId;\n }\n return null;\n}\n\nconst WORKFLOW_DEFAULT_LOOP_SESSION_ID = 'workflow-loop-default';\n\n/** Agent loop 事件 session_id;缺省时从 workflow_id + task_key 推导,再回退 active loop,最后才 default。 */\nfunction resolveAgentLoopSessionId(\n event: LangchainAgentEvent,\n activeLoopSessionId?: string | null,\n): string | null {\n if (event.session_id) return event.session_id;\n if (isWorkflowStructureEventType(event.event_type)) return null;\n if (event.event_type === 'task-list-snapshot') return null;\n\n const derived = deriveLoopSessionIdFromAgentEvent(event);\n if (derived) return derived;\n\n if (activeLoopSessionId) return activeLoopSessionId;\n\n return WORKFLOW_DEFAULT_LOOP_SESSION_ID;\n}\n\nfunction bindLoopSessionToContainerTree(\n tree: WorkflowContainerTreeState,\n event: LangchainAgentEvent,\n activeLoopSessionId?: string | null,\n): WorkflowContainerTreeState {\n const sessionId = resolveAgentLoopSessionId(event, activeLoopSessionId);\n if (!sessionId) return tree;\n\n if (findContainerByLoopSession(tree, sessionId)) return tree;\n\n const data = (event.data ?? {}) as Record<string, unknown>;\n const workflowPath = readString(data, 'workflow_path') ?? null;\n const scopeKey = resolveContentScopeKey(data);\n\n let targetId: string | null = null;\n\n if (scopeKey) {\n targetId = resolveContentTargetFromSnapshot(\n containerTreeToSnapshot(tree),\n workflowPath,\n scopeKey,\n );\n }\n\n if (!targetId) {\n for (const containerId of tree.activeContainerIds) {\n const node = tree.containersById[containerId];\n if (\n (node?.scope === 'item' || node?.scope === 'stage')\n && !node.loopSessionId\n ) {\n targetId = containerId;\n break;\n }\n }\n }\n\n if (!targetId) {\n targetId = resolveContentTargetFromSnapshot(\n containerTreeToSnapshot(tree),\n workflowPath,\n null,\n );\n }\n\n if (!targetId) return tree;\n\n const node = tree.containersById[targetId];\n if (!node || node.loopSessionId) return tree;\n\n // D24 §8.2: 只有 stage / item / branch 才承载 agent loop;aggregate / route-decision /\n // workflow 等聚合性 scope 不应被绑定 loopSessionId(否则会被 suppressContentContainerIds\n // 抹掉 content_blocks,aggregate 的 waiting teaser、route 的 decision 都会失效)。\n if (node.scope !== 'stage' && node.scope !== 'item' && node.scope !== 'branch') {\n return tree;\n }\n\n return {\n ...tree,\n containersById: {\n ...tree.containersById,\n [targetId]: { ...node, loopSessionId: sessionId },\n },\n };\n}\n\nfunction applyStructureEvent(\n state: WorkflowSessionState,\n event: LangchainAgentEvent,\n): WorkflowSessionState {\n let containerTree = applyStructureToContainerTree(state.containerTree, event);\n containerTree = prebindLoopSessionFromStructureOpen(containerTree, event);\n\n const loopSessionId = deriveLoopSessionIdFromStructureOpen(event);\n let nextState: WorkflowSessionState = { ...state, containerTree };\n\n if (loopSessionId) {\n nextState = ensureLoopTree(nextState, loopSessionId);\n }\n\n const workflowProgress = syncWorkflowProgressFromContainerTree(\n containerTree,\n state.workflowProgress,\n );\n\n let status = nextState.status;\n if (workflowProgress.status === 'done') status = 'done';\n else if (workflowProgress.status === 'error') status = 'error';\n else if (status === 'connecting') status = 'running';\n\n const base = {\n ...nextState,\n status,\n containerTree,\n workflowProgress,\n };\n\n if (event.session_id && !state.meta.workflowRunId) {\n return {\n ...base,\n meta: { ...state.meta, workflowRunId: event.session_id },\n };\n }\n\n return base;\n}\n\nfunction ensureLoopTree(\n state: WorkflowSessionState,\n loopSessionId: string,\n): WorkflowSessionState {\n if (state.loopTreesBySessionId[loopSessionId]) return state;\n const loopTree = createWorkflowRunningLoopTree();\n return {\n ...state,\n loopTreesBySessionId: {\n ...state.loopTreesBySessionId,\n [loopSessionId]: loopTree,\n },\n activeLoopSessionId: state.activeLoopSessionId ?? loopSessionId,\n };\n}\n\n/** Pure reducer:Workflow 会话状态 + 单条事件。 */\nexport function reduceWorkflowSession(\n state: WorkflowSessionState,\n event: LangchainAgentEvent,\n eventIndex: number,\n options?: ReduceOptions,\n): WorkflowSessionState {\n if (event.event_type === 'task-list-snapshot') {\n const data = event.data as Record<string, unknown>;\n const taskListId =\n typeof data.task_list_id === 'string' ? data.task_list_id : undefined;\n const loopSessionId =\n taskListId ?? event.session_id ?? 'workflow-loop-default';\n let next = ensureLoopTree(state, loopSessionId);\n const loopTree = next.loopTreesBySessionId[loopSessionId]!;\n const reducedLoop = reduceTree(loopTree, event, eventIndex, options);\n return {\n ...next,\n loopTreesBySessionId: {\n ...next.loopTreesBySessionId,\n [loopSessionId]: reducedLoop,\n },\n activeLoopSessionId: loopSessionId,\n };\n }\n\n if (isWorkflowStructureEventType(event.event_type)) {\n return applyStructureEvent(state, event);\n }\n\n const loopSessionId =\n resolveAgentLoopSessionId(event, state.activeLoopSessionId)\n ?? WORKFLOW_DEFAULT_LOOP_SESSION_ID;\n let containerTree = bindLoopSessionToContainerTree(\n state.containerTree,\n event,\n state.activeLoopSessionId,\n );\n containerTree = applyStructureToContainerTree(containerTree, event);\n let next = ensureLoopTree({ ...state, containerTree }, loopSessionId);\n const loopTree = next.loopTreesBySessionId[loopSessionId]!;\n const reducedLoop = reduceTree(loopTree, event, eventIndex, options);\n\n const workflowProgress = syncWorkflowProgressFromContainerTree(\n next.containerTree,\n next.workflowProgress,\n );\n\n return {\n ...next,\n workflowProgress,\n loopTreesBySessionId: {\n ...next.loopTreesBySessionId,\n [loopSessionId]: reducedLoop,\n },\n activeLoopSessionId: loopSessionId,\n status: reducedLoop.status === 'error' ? 'error' : next.status === 'connecting' ? 'running' : next.status,\n };\n}\n\n/** 从空状态回放 workflow 事件序列。 */\nexport function reduceWorkflowEvents(\n events: LangchainAgentEvent[],\n options?: ReduceOptions,\n): WorkflowSessionState {\n return events.reduce(\n (state, event, index) => reduceWorkflowSession(state, event, index, options),\n createEmptyWorkflowSessionState(),\n );\n}\n","/**\n * stageDoneSummary.ts — Stage 完成摘要(对齐 CC Agent Done 行)\n *\n * 职责:\n * 从 scoped loop tree 统计 tool uses / duration / agent turn;提取 text teaser。\n *\n * 链路位置:\n * WorkflowStageContainer 完成态显示(P2+)。\n *\n * 当前裁剪范围:\n * 不含 React;仅纯函数统计。\n */\nimport type { SessionTree } from '../../types/tree';\n\nexport interface StageDoneSummary {\n label: string;\n teaser: string;\n extraLines: number;\n}\n\nfunction countToolUses(tree: SessionTree): number {\n return Object.values(tree.byId).filter((node) => node.kind === 'tool_call').length;\n}\n\nfunction computeDurationSeconds(tree: SessionTree): number | null {\n const started = tree.meta.startedAt;\n if (started == null) return null;\n\n let maxTs = started;\n for (const node of Object.values(tree.byId)) {\n if ('endedAt' in node && typeof node.endedAt === 'number') {\n maxTs = Math.max(maxTs, node.endedAt);\n }\n if ('startedAt' in node && typeof node.startedAt === 'number') {\n maxTs = Math.max(maxTs, node.startedAt);\n }\n }\n\n const seconds = Math.round((maxTs - started) / 1000);\n return seconds > 0 ? seconds : null;\n}\n\nfunction lastTextContent(tree: SessionTree): string {\n const textNodes = Object.values(tree.byId).filter((node) => node.kind === 'text');\n if (textNodes.length === 0) return '';\n return textNodes[textNodes.length - 1]!.accumulated.trim();\n}\n\n/** 从 loop tree 构建 Stage Done 摘要 + 首行 teaser(非 display.description)。 */\nexport function buildStageDoneSummary(tree: SessionTree): StageDoneSummary | null {\n if (tree.status !== 'done' && tree.status !== 'error') return null;\n\n const toolUses = countToolUses(tree);\n const duration = computeDurationSeconds(tree);\n const durationSuffix = duration != null ? ` · ${duration}s` : '';\n\n const label =\n toolUses > 0\n ? `Done (${toolUses} tool use${toolUses === 1 ? '' : 's'}${durationSuffix})`\n : `Done (1 agent turn${durationSuffix})`;\n\n const fullText = lastTextContent(tree);\n const lines = fullText.split('\\n').map((line) => line.trim()).filter(Boolean);\n const teaser = lines[0] ?? '';\n const extraLines = Math.max(0, lines.length - 1);\n\n return { label, teaser, extraLines };\n}\n\nexport function formatTeaserExpandHint(extraLines: number, verbose: boolean): string | null {\n if (extraLines <= 0) return null;\n const shown = verbose ? Math.min(extraLines, 2) : 0;\n const hidden = extraLines - shown;\n if (hidden <= 0) return null;\n return `… +${hidden} lines (ctrl+o to expand)`;\n}\n","import { buildStageDoneSummary, type StageDoneSummary } from './stageDoneSummary';\nimport type { SessionTree } from '../../types/tree';\nimport type { WorkflowContainerRuntimeNode, WorkflowContainerTreeState } from '../../types/workflowContainer';\nimport type { WorkflowSessionState } from '../../types/workflowSession';\n\nexport function containersByLoopSessionId(\n tree: WorkflowContainerTreeState,\n): Map<string, WorkflowContainerRuntimeNode> {\n const map = new Map<string, WorkflowContainerRuntimeNode>();\n for (const node of Object.values(tree.containersById)) {\n if (node.loopSessionId) map.set(node.loopSessionId, node);\n }\n return map;\n}\n\nfunction collectProtectedLoopSessionIds(\n state: WorkflowSessionState,\n pinnedLoopSessionIds: Record<string, true>,\n): Set<string> {\n const protectedIds = new Set<string>(Object.keys(pinnedLoopSessionIds));\n const byLoop = containersByLoopSessionId(state.containerTree);\n\n if (state.activeLoopSessionId) {\n const activeContainer = byLoop.get(state.activeLoopSessionId);\n if (\n activeContainer\n && (activeContainer.status === 'running' || activeContainer.status === 'retrying')\n ) {\n protectedIds.add(state.activeLoopSessionId);\n }\n }\n\n for (const containerId of state.containerTree.activeContainerIds) {\n const node = state.containerTree.containersById[containerId];\n if (!node?.loopSessionId) continue;\n if (node.status === 'running' || node.status === 'retrying') {\n protectedIds.add(node.loopSessionId);\n }\n }\n\n for (const node of Object.values(state.containerTree.containersById)) {\n if (!node.loopSessionId) continue;\n if (node.status === 'running' || node.status === 'retrying') {\n protectedIds.add(node.loopSessionId);\n }\n }\n\n return protectedIds;\n}\n\n/**\n * P2:淘汰 completed/failed 且未 pin/不在热缓存中的 loop 树,缓存 done 摘要。\n * hotCompletedLoopSessionIds 中的 completed loop 受保护(LRU 热缓存)。\n */\nexport function evictInactiveLoopTrees(\n state: WorkflowSessionState,\n pinnedLoopSessionIds: Record<string, true>,\n): WorkflowSessionState {\n const protectedIds = collectProtectedLoopSessionIds(state, pinnedLoopSessionIds);\n\n // P2:热缓存中的 completed loop 也受保护\n for (const id of state.hotCompletedLoopSessionIds) {\n protectedIds.add(id);\n }\n\n const byLoop = containersByLoopSessionId(state.containerTree);\n const nextLoops: Record<string, SessionTree> = { ...state.loopTreesBySessionId };\n const nextSummaries: Record<string, StageDoneSummary> = {\n ...state.stageDoneSummariesByContainerId,\n };\n\n for (const [loopSessionId, tree] of Object.entries(state.loopTreesBySessionId)) {\n if (protectedIds.has(loopSessionId)) continue;\n\n const container = byLoop.get(loopSessionId);\n if (!container) continue;\n if (container.status !== 'completed' && container.status !== 'failed') continue;\n\n const summary = buildStageDoneSummary(tree);\n if (summary) {\n nextSummaries[container.container_id] = summary;\n }\n delete nextLoops[loopSessionId];\n }\n\n return {\n ...state,\n loopTreesBySessionId: nextLoops,\n stageDoneSummariesByContainerId: nextSummaries,\n };\n}\n\n/**\n * P2:将 completed loop 移到 LRU 热缓存尾部(最近使用)。\n * 如果该 loop 尚未在内存中(尚未 hydrate),仍然 touch 以预占位置。\n */\nexport function touchCompletedLoopSession(\n state: WorkflowSessionState,\n loopSessionId: string,\n): WorkflowSessionState {\n const ids = state.hotCompletedLoopSessionIds.filter((id) => id !== loopSessionId);\n ids.push(loopSessionId); // 最近使用在尾部\n return {\n ...state,\n hotCompletedLoopSessionIds: ids,\n };\n}\n\n/**\n * P2:热缓存溢出淘汰 — 超过 maxHydratedCompletedLoops 时,\n * 从头部(最旧)淘汰 completed loop 树,但保留 done 摘要。\n */\nexport function evictCompletedLoopOverflow(\n state: WorkflowSessionState,\n maxHydratedCompletedLoops: number,\n): WorkflowSessionState {\n if (state.hotCompletedLoopSessionIds.length <= maxHydratedCompletedLoops) {\n return state;\n }\n\n const overflow = state.hotCompletedLoopSessionIds.length - maxHydratedCompletedLoops;\n const evictedIds = new Set(state.hotCompletedLoopSessionIds.slice(0, overflow));\n const trimmedIds = state.hotCompletedLoopSessionIds.slice(overflow);\n\n const byLoop = containersByLoopSessionId(state.containerTree);\n const nextLoops: Record<string, SessionTree> = { ...state.loopTreesBySessionId };\n const nextSummaries: Record<string, StageDoneSummary> = {\n ...state.stageDoneSummariesByContainerId,\n };\n\n for (const id of evictedIds) {\n const tree = nextLoops[id];\n if (!tree) continue;\n const container = byLoop.get(id);\n if (container) {\n const summary = buildStageDoneSummary(tree);\n if (summary) {\n nextSummaries[container.container_id] = summary;\n }\n }\n delete nextLoops[id];\n }\n\n return {\n ...state,\n loopTreesBySessionId: nextLoops,\n stageDoneSummariesByContainerId: nextSummaries,\n hotCompletedLoopSessionIds: trimmedIds,\n };\n}\n","/**\n * WorkflowChrome.tsx — Workflow 容器树显示轨(display + scoped loop)\n */\nimport { useMemo, useState, type ReactNode } from 'react';\n\nimport { useWorkflowScaleOptions } from '../../core/context/WorkflowScaleContext';\nimport type { SessionTree } from '../../types/tree';\nimport type {\n WorkflowContainerRuntimeNode,\n WorkflowContainerTreeState,\n} from '../../types/workflowContainer';\nimport { WorkflowAggregateContainer } from './WorkflowAggregateContainer';\nimport { WorkflowContainerLine } from './WorkflowContainerLine';\nimport { WorkflowParallelGroup } from './WorkflowParallelGroup';\nimport { WorkflowRootContainer } from './WorkflowRootContainer';\nimport { WorkflowRouteContainer } from './WorkflowRouteContainer';\nimport { WorkflowStageContainer } from './WorkflowStageContainer';\nimport { WorkflowSubworkflowContainer } from './WorkflowSubworkflowContainer';\nimport { partitionWorkflowStages } from './workflowStageListUtils';\n\nexport interface WorkflowChromeProps {\n containerTree: WorkflowContainerTreeState;\n loopTreesBySessionId?: Record<string, SessionTree>;\n virtualized?: boolean;\n virtualizeThreshold?: number;\n groupParallelTools?: boolean;\n}\n\ntype ViewProps = Pick<\n WorkflowChromeProps,\n 'virtualized' | 'virtualizeThreshold' | 'groupParallelTools'\n>;\n\nfunction collectChildContainers(\n containersById: Record<string, WorkflowContainerRuntimeNode>,\n parentId: string,\n): WorkflowContainerRuntimeNode[] {\n return Object.values(containersById)\n .filter((node) => node.parent_container_id === parentId)\n .sort((a, b) => a.scope_key.localeCompare(b.scope_key));\n}\n\nfunction resolveLoopTree(\n node: WorkflowContainerRuntimeNode,\n loopTreesBySessionId: Record<string, SessionTree>,\n): SessionTree | undefined {\n if (!node.loopSessionId) return undefined;\n return loopTreesBySessionId[node.loopSessionId];\n}\n\nfunction collectSiblingItems(\n node: WorkflowContainerRuntimeNode,\n containersById: Record<string, WorkflowContainerRuntimeNode>,\n): WorkflowContainerRuntimeNode[] {\n if (!node.parent_container_id) return [];\n return collectChildContainers(containersById, node.parent_container_id).filter(\n (child) => child.scope === 'item',\n );\n}\n\nfunction renderLeafContainer(\n node: WorkflowContainerRuntimeNode,\n depth: number,\n containerTree: WorkflowContainerTreeState,\n loopTreesBySessionId: Record<string, SessionTree>,\n viewProps: ViewProps,\n): ReactNode {\n const loopTree = resolveLoopTree(node, loopTreesBySessionId);\n\n switch (node.scope) {\n case 'aggregate':\n return (\n <WorkflowAggregateContainer\n key={node.container_id}\n node={node}\n loopTree={loopTree}\n siblingItems={collectSiblingItems(node, containerTree.containersById)}\n depth={depth}\n {...viewProps}\n />\n );\n case 'branch':\n return (\n <WorkflowRouteContainer\n key={node.container_id}\n node={node}\n loopTree={loopTree}\n depth={depth}\n {...viewProps}\n />\n );\n default:\n return (\n <WorkflowStageContainer\n key={node.container_id}\n node={node}\n loopTree={loopTree}\n depth={depth}\n {...viewProps}\n />\n );\n }\n}\n\nfunction renderItemSiblings(\n items: WorkflowContainerRuntimeNode[],\n groupKey: string,\n depth: number,\n containerTree: WorkflowContainerTreeState,\n loopTreesBySessionId: Record<string, SessionTree>,\n viewProps: ViewProps,\n): ReactNode {\n if (items.length >= 2) {\n return (\n <WorkflowParallelGroup\n groupKey={groupKey}\n items={items}\n loopTreesBySessionId={loopTreesBySessionId}\n depth={depth}\n {...viewProps}\n />\n );\n }\n if (items.length === 1) {\n return renderLeafContainer(items[0]!, depth, containerTree, loopTreesBySessionId, viewProps);\n }\n return null;\n}\n\nfunction renderContainerChildren(\n parentId: string,\n containerTree: WorkflowContainerTreeState,\n loopTreesBySessionId: Record<string, SessionTree>,\n viewProps: ViewProps,\n depth: number,\n): ReactNode {\n const children = collectChildContainers(containerTree.containersById, parentId);\n const items = children.filter((node) => node.scope === 'item');\n const rest = children.filter((node) => node.scope !== 'item');\n\n return (\n <>\n {renderItemSiblings(items, parentId, depth, containerTree, loopTreesBySessionId, viewProps)}\n {rest.map((node) => renderContainerNode(node, containerTree, loopTreesBySessionId, viewProps, depth))}\n </>\n );\n}\n\nfunction renderContainerNode(\n node: WorkflowContainerRuntimeNode,\n containerTree: WorkflowContainerTreeState,\n loopTreesBySessionId: Record<string, SessionTree>,\n viewProps: ViewProps,\n depth: number,\n): ReactNode {\n const nested = renderContainerChildren(\n node.container_id,\n containerTree,\n loopTreesBySessionId,\n viewProps,\n depth + 1,\n );\n const hasNested =\n collectChildContainers(containerTree.containersById, node.container_id).length > 0;\n\n if (node.scope === 'subworkflow') {\n return (\n <WorkflowSubworkflowContainer\n key={node.container_id}\n node={node}\n depth={depth}\n >\n {hasNested ? nested : null}\n </WorkflowSubworkflowContainer>\n );\n }\n\n if (node.scope === 'stage') {\n return (\n <div\n key={node.container_id}\n className=\"lax-workflow-nested-block\"\n data-testid={`lax-workflow-nested-${node.scope}-${node.scope_key}`}\n >\n {renderLeafContainer(node, depth, containerTree, loopTreesBySessionId, viewProps)}\n {hasNested ? (\n <div className=\"lax-workflow-container-children\">{nested}</div>\n ) : null}\n </div>\n );\n }\n\n if (node.scope === 'aggregate' || node.scope === 'branch') {\n return (\n <div key={node.container_id} className=\"lax-workflow-container-children\">\n {renderLeafContainer(node, depth, containerTree, loopTreesBySessionId, viewProps)}\n {hasNested ? nested : null}\n </div>\n );\n }\n\n return renderLeafContainer(node, depth, containerTree, loopTreesBySessionId, viewProps);\n}\n\nfunction renderWorkflowStageContent(\n node: WorkflowContainerRuntimeNode,\n containerTree: WorkflowContainerTreeState,\n loopTreesBySessionId: Record<string, SessionTree>,\n viewProps: ViewProps,\n): ReactNode {\n return renderContainerNode(node, containerTree, loopTreesBySessionId, viewProps, 1);\n}\n\nfunction renderWorkflowStageRow(\n node: WorkflowContainerRuntimeNode,\n containerTree: WorkflowContainerTreeState,\n loopTreesBySessionId: Record<string, SessionTree>,\n viewProps: ViewProps,\n as: 'li' | 'div' = 'li',\n): ReactNode {\n const className = 'lax-workflow-stage-list__item';\n const content = renderWorkflowStageContent(\n node,\n containerTree,\n loopTreesBySessionId,\n viewProps,\n );\n if (as === 'div') {\n return (\n <div key={node.container_id} className={className} role=\"listitem\">\n {content}\n </div>\n );\n }\n return (\n <li key={node.container_id} className={className}>\n {content}\n </li>\n );\n}\n\nfunction WorkflowStageListPanel({\n stages,\n containerTree,\n loopTreesBySessionId,\n viewProps,\n}: {\n stages: WorkflowContainerRuntimeNode[];\n containerTree: WorkflowContainerTreeState;\n loopTreesBySessionId: Record<string, SessionTree>;\n viewProps: ViewProps;\n}) {\n const scale = useWorkflowScaleOptions();\n // P3:分页计数 — 每次点击“Show N more”递增一页,避免一次性展开 180 done stage\n const [extraCompletedPages, setExtraCompletedPages] = useState(0);\n const maxVisibleDoneCount =\n scale.completedStagePageSize + extraCompletedPages * scale.completedStagePageSize;\n\n const partition = useMemo(\n () => partitionWorkflowStages(stages, maxVisibleDoneCount),\n [stages, maxVisibleDoneCount],\n );\n\n if (partition.visible.length === 0) return null;\n\n const showMoreCount = Math.min(\n scale.completedStagePageSize,\n partition.totalDoneCount - partition.visibleDoneCount,\n );\n\n return (\n <>\n <ol className=\"lax-workflow-stage-list\" data-testid=\"lax-workflow-stage-list\">\n {partition.visible.map((node) =>\n renderWorkflowStageRow(node, containerTree, loopTreesBySessionId, viewProps),\n )}\n </ol>\n\n {partition.hiddenCount > 0 ? (\n <button\n type=\"button\"\n className=\"lax-workflow-stage-list__show-all\"\n data-testid=\"lax-workflow-stage-show-more\"\n onClick={() => setExtraCompletedPages((p) => p + 1)}\n >\n +{partition.hiddenCount} completed stages hidden · Show {showMoreCount} more\n </button>\n ) : null}\n\n {extraCompletedPages > 0 && partition.hiddenCount === 0 ? (\n <button\n type=\"button\"\n className=\"lax-workflow-stage-list__show-all\"\n data-testid=\"lax-workflow-stage-show-less\"\n onClick={() => setExtraCompletedPages(0)}\n >\n Show fewer completed stages\n </button>\n ) : null}\n\n {partition.hiddenCount > 0 ? (\n <p\n className=\"lax-workflow-stage-list__hidden-hint\"\n data-testid=\"lax-workflow-stage-hidden-hint\"\n >\n {partition.hiddenCount} completed stage{partition.hiddenCount !== 1 ? 's' : ''} hidden —\n running, pending, and failed stages are always visible.\n </p>\n ) : null}\n </>\n );\n}\n\nfunction renderWorkflowChildren(\n workflowNode: WorkflowContainerRuntimeNode,\n containerTree: WorkflowContainerTreeState,\n loopTreesBySessionId: Record<string, SessionTree>,\n viewProps: ViewProps,\n) {\n const children = collectChildContainers(\n containerTree.containersById,\n workflowNode.container_id,\n );\n const stages = children.filter((node) => node.scope === 'stage');\n const items = children.filter((node) => node.scope === 'item');\n const other = children.filter(\n (node) => node.scope !== 'stage' && node.scope !== 'item',\n );\n\n return (\n <>\n {stages.length > 0 ? (\n <WorkflowStageListPanel\n stages={stages}\n containerTree={containerTree}\n loopTreesBySessionId={loopTreesBySessionId}\n viewProps={viewProps}\n />\n ) : null}\n\n {renderItemSiblings(items, workflowNode.container_id, 1, containerTree, loopTreesBySessionId, viewProps)}\n\n {other.map((node) =>\n renderContainerNode(node, containerTree, loopTreesBySessionId, viewProps, 1),\n )}\n </>\n );\n}\n\nexport function WorkflowChrome({\n containerTree,\n loopTreesBySessionId = {},\n virtualized,\n virtualizeThreshold,\n groupParallelTools,\n}: WorkflowChromeProps) {\n const viewProps = { virtualized, virtualizeThreshold, groupParallelTools };\n const rootNodes = containerTree.rootContainerIds\n .map((id) => containerTree.containersById[id])\n .filter((node): node is WorkflowContainerRuntimeNode => node != null);\n\n if (rootNodes.length === 0) {\n return (\n <div className=\"lax-workflow-chrome\" data-testid=\"lax-workflow-chrome\">\n <WorkflowContainerLine\n variant=\"root\"\n title=\"Workflow\"\n uiStatus=\"pending\"\n statusLabel=\"pending\"\n />\n </div>\n );\n }\n\n return (\n <div className=\"lax-workflow-chrome\" data-testid=\"lax-workflow-chrome\">\n {rootNodes.map((workflowNode) => (\n <WorkflowRootContainer key={workflowNode.container_id} node={workflowNode}>\n {renderWorkflowChildren(\n workflowNode,\n containerTree,\n loopTreesBySessionId,\n viewProps,\n )}\n </WorkflowRootContainer>\n ))}\n </div>\n );\n}\n","/**\n * WorkflowAggregateContainer.tsx — Parallel aggregate 容器行\n *\n * 职责:\n * waiting (k/n) / running / Done;合并结果 teaser;D24 壳行语法。\n *\n * 链路位置:\n * WorkflowChrome → scope aggregate 节点。\n */\nimport { useCallback, useEffect, useMemo, useState, type CSSProperties } from 'react';\n\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\nimport type { SessionTree } from '../../types/tree';\nimport { AgentLoopView } from '../agentLoop/AgentLoopView';\nimport { WorkflowContainerLine } from './WorkflowContainerLine';\nimport { WorkflowExpandTrigger } from './WorkflowExpandTrigger';\nimport {\n buildAggregateLineMeta,\n buildAggregateStatusLabel,\n mapAggregateUiStatus,\n} from './workflowContainerLineUtils';\n\nexport interface WorkflowAggregateContainerProps {\n node: WorkflowContainerRuntimeNode;\n loopTree?: SessionTree;\n siblingItems?: WorkflowContainerRuntimeNode[];\n depth?: number;\n virtualized?: boolean;\n virtualizeThreshold?: number;\n groupParallelTools?: boolean;\n}\n\nfunction mergeTeaser(node: WorkflowContainerRuntimeNode): string {\n const blocks = node.content_blocks;\n if (blocks.length === 0) return '';\n const last = blocks[blocks.length - 1];\n return last?.preview ?? '';\n}\n\nexport function WorkflowAggregateContainer({\n node,\n loopTree,\n siblingItems = [],\n depth = 1,\n virtualized,\n virtualizeThreshold,\n groupParallelTools,\n}: WorkflowAggregateContainerProps) {\n const isRunning = node.status === 'running' || node.status === 'retrying';\n const isWaiting = node.status === 'pending' || node.status === 'blocked';\n const isDone = node.status === 'completed' || node.status === 'failed';\n const teaser = useMemo(() => mergeTeaser(node), [node]);\n const waitingTeaser = isWaiting ? (teaser || node.subtitle || '') : '';\n const testId = `lax-workflow-aggregate-${node.scope_key}`;\n const uiStatus = mapAggregateUiStatus(node);\n const statusLabel = buildAggregateStatusLabel(node, siblingItems);\n\n const [expanded, setExpanded] = useState(isRunning);\n\n useEffect(() => {\n if (isRunning) setExpanded(true);\n if (isDone) setExpanded(false);\n }, [isRunning, isDone]);\n\n const toggleExpanded = useCallback(() => {\n setExpanded((prev) => !prev);\n }, []);\n\n const shellToggle =\n isRunning ? toggleExpanded\n : isDone && expanded ? toggleExpanded\n : undefined;\n\n return (\n <div\n className={`lax-workflow-aggregate lax-workflow-stage-container lax-workflow-stage-container--${\n isWaiting ? 'pending' : isDone ? 'done' : 'running'\n }`}\n data-testid={testId}\n data-container-scope=\"aggregate\"\n style={{ '--lax-workflow-depth': depth } as CSSProperties}\n >\n <WorkflowContainerLine\n title={node.title}\n description={node.subtitle || undefined}\n uiStatus={uiStatus}\n meta={buildAggregateLineMeta(node)}\n statusLabel={statusLabel}\n onToggle={shellToggle}\n interactive={isRunning}\n expanded={expanded}\n titleTestId={`${testId}-title`}\n descriptionTestId={`${testId}-desc`}\n />\n\n {isWaiting && waitingTeaser ? (\n <div className=\"lax-workflow-aggregate__waiting-teaser\" data-testid={`${testId}-waiting`}>\n ⎿ {waitingTeaser}\n </div>\n ) : null}\n\n {expanded && isRunning && loopTree ? (\n <div className=\"lax-workflow-stage-container__body\" data-testid={`${testId}-body`}>\n <AgentLoopView\n tree={loopTree}\n showTaskListFooter={false}\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n />\n </div>\n ) : null}\n\n {isDone && !expanded ? (\n <WorkflowExpandTrigger\n summary={`${node.title} · done`}\n teaser={teaser || undefined}\n onToggle={() => setExpanded(true)}\n expanded={false}\n testId={`${testId}-done`}\n teaserTestId={`${testId}-teaser`}\n />\n ) : null}\n\n {isDone && expanded && loopTree ? (\n <div className=\"lax-workflow-stage-container__body\" data-testid={`${testId}-body`}>\n <AgentLoopView\n tree={loopTree}\n showTaskListFooter={false}\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n />\n </div>\n ) : null}\n </div>\n );\n}\n","/**\n * WorkflowContainerLine.tsx — Workflow 壳行 SSOT(D24 P1)\n *\n * 职责:● title (description) · meta · status 单行渲染。\n *\n * 链路位置:WorkflowChrome 根行 · WorkflowStageContainer 壳行。\n */\nimport type { CSSProperties } from 'react';\n\nexport interface WorkflowContainerLineProps {\n title: string;\n description?: string;\n uiStatus: string;\n meta?: string[];\n statusLabel: string;\n showDot?: boolean;\n variant?: 'root' | 'default';\n onToggle?: () => void;\n expanded?: boolean;\n /** false 时强制 div(done 折叠态避免与 ExpandTrigger 双 button 展开) */\n interactive?: boolean;\n titleTestId?: string;\n descriptionTestId?: string;\n headerTestId?: string;\n debugScopeKey?: string;\n verbose?: boolean;\n className?: string;\n style?: CSSProperties;\n}\n\nexport function WorkflowContainerLine({\n title,\n description,\n uiStatus,\n meta = [],\n statusLabel,\n showDot = true,\n variant = 'default',\n onToggle,\n expanded,\n interactive,\n titleTestId,\n descriptionTestId,\n headerTestId,\n debugScopeKey,\n verbose = false,\n className = '',\n style,\n}: WorkflowContainerLineProps) {\n const lineClass = [\n 'lax-workflow-container-line',\n variant === 'root' ? 'lax-workflow-container-line--root' : '',\n onToggle && interactive !== false ? 'lax-workflow-container-line--interactive' : '',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const content = (\n <>\n {showDot ? (\n <span\n className=\"lax-workflow-container-line__status-dot lax-workflow-stage-container__status-dot\"\n data-status={uiStatus}\n aria-hidden\n />\n ) : null}\n <span className=\"lax-workflow-container-line__title\" data-testid={titleTestId}>\n {title}\n </span>\n {description ? (\n <span\n className=\"lax-workflow-container-line__desc\"\n data-testid={descriptionTestId}\n >\n ({description})\n </span>\n ) : null}\n {meta.length > 0 ? (\n <span className=\"lax-workflow-container-line__meta\" data-testid={titleTestId ? `${titleTestId}-meta` : undefined}>\n {meta.join(' · ')}\n </span>\n ) : null}\n {verbose && debugScopeKey ? (\n <span className=\"lax-workflow-container-line__debug\" data-testid=\"lax-workflow-id\">\n {debugScopeKey}\n </span>\n ) : null}\n <span className=\"lax-workflow-container-line__status\">{statusLabel}</span>\n </>\n );\n\n if (onToggle && interactive !== false) {\n return (\n <button\n type=\"button\"\n className={`${lineClass} lax-workflow-stage-container__header`}\n onClick={onToggle}\n aria-expanded={expanded}\n data-testid={headerTestId}\n style={style}\n >\n {content}\n </button>\n );\n }\n\n if (onToggle) {\n return (\n <div\n className={`${lineClass} lax-workflow-container-line--static-toggle`}\n onClick={onToggle}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n onToggle();\n }\n }}\n role=\"button\"\n tabIndex={0}\n aria-expanded={expanded}\n data-testid={headerTestId}\n style={style}\n >\n {content}\n </div>\n );\n }\n\n return (\n <div className={lineClass} style={style}>\n {content}\n </div>\n );\n}\n","/**\n * WorkflowExpandTrigger.tsx — 可点击 ⎿ 摘要行(D24 P2)\n *\n * 职责:Done teaser / Parallel 组摘要的展开入口;hint 与摘要同属 button。\n *\n * 链路位置:WorkflowStageContainer · WorkflowParallelGroup。\n */\nimport type { ReactNode } from 'react';\n\nexport interface WorkflowExpandTriggerProps {\n summary: ReactNode;\n summaryTestId?: string;\n teaser?: string;\n expandHint?: string | null;\n onToggle: () => void;\n expanded?: boolean;\n testId?: string;\n teaserTestId?: string;\n className?: string;\n}\n\nexport function WorkflowExpandTrigger({\n summary,\n summaryTestId,\n teaser,\n expandHint,\n onToggle,\n expanded = false,\n testId,\n teaserTestId,\n className = '',\n}: WorkflowExpandTriggerProps) {\n return (\n <button\n type=\"button\"\n className={`lax-workflow-expand-trigger${className ? ` ${className}` : ''}`}\n onClick={onToggle}\n aria-expanded={expanded}\n data-testid={testId}\n >\n <span className=\"lax-workflow-expand-trigger__summary\" data-testid={summaryTestId}>\n ⎿ {summary}\n </span>\n {teaser ? (\n <span\n className=\"lax-workflow-expand-trigger__teaser\"\n data-testid={teaserTestId}\n >\n {teaser}\n </span>\n ) : null}\n {expandHint ? (\n <span className=\"lax-workflow-expand-trigger__hint\">{expandHint}</span>\n ) : null}\n </button>\n );\n}\n","/**\n * workflowContainerLineUtils.ts — Workflow 壳行 meta / status 辅助\n *\n * 链路位置:WorkflowContainerLine · WorkflowChrome · WorkflowStageContainer。\n */\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\nimport type { WorkflowContainerStatus } from '../../types/workflowContainer';\n\n/** 方案 A:normal 模式 meta 首段为容器 scope(workflow / stage / item …)。 */\nexport function formatContainerScopeMetaLabel(\n scope: WorkflowContainerRuntimeNode['scope'],\n): string {\n return scope;\n}\n\nfunction withScopeMeta(node: WorkflowContainerRuntimeNode, parts: string[]): string[] {\n return [formatContainerScopeMetaLabel(node.scope), ...parts];\n}\n\nexport function mapContainerUiStatus(status: WorkflowContainerStatus): string {\n switch (status) {\n case 'completed':\n return 'done';\n case 'failed':\n return 'failed';\n case 'running':\n case 'retrying':\n return 'running';\n case 'skipped':\n return 'skipped';\n default:\n return 'pending';\n }\n}\n\nexport function mapContainerStatusLabel(status: WorkflowContainerStatus): string {\n switch (status) {\n case 'completed':\n return 'done';\n case 'failed':\n return 'failed';\n case 'running':\n return 'Running…';\n case 'retrying':\n return 'Retrying…';\n case 'skipped':\n return 'skipped';\n case 'blocked':\n return 'blocked';\n case 'cancelled':\n return 'cancelled';\n default:\n return 'pending';\n }\n}\n\nexport function mapWorkflowRootStatusLabel(status: WorkflowContainerStatus): string {\n switch (status) {\n case 'completed':\n return 'done';\n case 'failed':\n return 'error';\n default:\n return 'running';\n }\n}\n\nexport function buildStageProgressMeta(node: WorkflowContainerRuntimeNode): string | null {\n const display = node.display;\n if (display?.progress_label) return display.progress_label;\n if (display?.progress_current != null && display?.progress_total != null) {\n return `Step ${display.progress_current}/${display.progress_total}`;\n }\n return null;\n}\n\nexport function buildWorkflowRootMeta(node: WorkflowContainerRuntimeNode): string[] {\n const meta: string[] = [];\n if (node.pattern) meta.push(node.pattern);\n const display = node.display;\n if (display?.progress_current != null && display?.progress_total != null) {\n meta.push(`${display.progress_current}/${display.progress_total}`);\n }\n return withScopeMeta(node, meta);\n}\n\nexport function buildStageLineMeta(node: WorkflowContainerRuntimeNode): string[] {\n const progress = buildStageProgressMeta(node);\n return withScopeMeta(node, progress ? [progress] : []);\n}\n\nexport function buildAggregateLineMeta(node: WorkflowContainerRuntimeNode): string[] {\n return withScopeMeta(node, []);\n}\n\n/** Route branch:decision_label + 可选 step progress。 */\nexport function buildRouteLineMeta(node: WorkflowContainerRuntimeNode): string[] {\n const meta: string[] = [];\n const decision = node.display?.decision_label;\n if (decision) meta.push(decision);\n const progress = buildStageProgressMeta(node);\n if (progress) meta.push(progress);\n return withScopeMeta(node, meta);\n}\n\n/** depth ≥4 时略减缩进,防深层 subworkflow 横向溢出(D24 §5.4 / R3)。 */\nexport function workflowIndentUnit(depth: number): string {\n return depth >= 4 ? '0.75rem' : '1rem';\n}\n\nfunction countSettledItems(items: WorkflowContainerRuntimeNode[]): {\n settled: number;\n total: number;\n} {\n let settled = 0;\n for (const item of items) {\n if (item.status === 'completed' || item.status === 'failed') {\n settled += 1;\n }\n }\n return { settled, total: items.length };\n}\n\n/** Aggregate waiting (k/n):display 优先,否则统计同级 parallel item。 */\nexport function buildAggregateStatusLabel(\n node: WorkflowContainerRuntimeNode,\n siblingItems: WorkflowContainerRuntimeNode[] = [],\n): string {\n const display = node.display;\n let current = display?.progress_current;\n let total = display?.progress_total;\n\n if ((current == null || total == null) && siblingItems.length > 0) {\n const { settled, total: itemTotal } = countSettledItems(siblingItems);\n current = settled;\n total = itemTotal;\n }\n\n if (node.status === 'pending' || node.status === 'blocked') {\n if (current != null && total != null) {\n return `waiting (${current}/${total})`;\n }\n return 'waiting';\n }\n\n if (current != null && total != null && (node.status === 'running' || node.status === 'retrying')) {\n return `waiting (${current}/${total})`;\n }\n\n return mapContainerStatusLabel(node.status);\n}\n\nexport function mapAggregateUiStatus(node: WorkflowContainerRuntimeNode): string {\n if (node.status === 'pending' || node.status === 'blocked') return 'pending';\n if (node.status === 'completed') return 'done';\n if (node.status === 'failed') return 'failed';\n if (node.status === 'running' || node.status === 'retrying') return 'running';\n return mapContainerUiStatus(node.status);\n}\n","/**\n * WorkflowParallelGroup.tsx — Parallel item 组摘要 + 嵌套 item 行\n */\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useStore } from 'zustand';\n\nimport { useWorkflowScaleOptions } from '../../core/context/WorkflowScaleContext';\nimport { useWorkflowSessionStoreApi } from '../../core/context/WorkflowSessionContext';\nimport {\n computeParallelGroupMetrics,\n formatParallelGroupSummary,\n} from '../../core/workflow/workflowParallelGroupMetrics';\nimport type { SessionTree } from '../../types/tree';\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\nimport { WorkflowExpandTrigger } from './WorkflowExpandTrigger';\nimport { WorkflowStageContainer } from './WorkflowStageContainer';\nimport { isActiveWorkflowContainer } from './workflowStageListUtils';\n\nexport interface WorkflowParallelGroupProps {\n groupKey: string;\n items: WorkflowContainerRuntimeNode[];\n loopTreesBySessionId: Record<string, SessionTree>;\n depth?: number;\n virtualized?: boolean;\n virtualizeThreshold?: number;\n groupParallelTools?: boolean;\n}\n\nfunction resolveLoopTree(\n node: WorkflowContainerRuntimeNode,\n loopTreesBySessionId: Record<string, SessionTree>,\n): SessionTree | undefined {\n if (!node.loopSessionId) return undefined;\n return loopTreesBySessionId[node.loopSessionId];\n}\n\nexport function WorkflowParallelGroup({\n groupKey,\n items,\n loopTreesBySessionId,\n depth = 1,\n virtualized,\n virtualizeThreshold,\n groupParallelTools,\n}: WorkflowParallelGroupProps) {\n const scale = useWorkflowScaleOptions();\n const store = useWorkflowSessionStoreApi();\n const activeLoopSessionId = useStore(store, (s) => s.state.activeLoopSessionId);\n const activeContainerIds = useStore(store, (s) => s.state.containerTree.activeContainerIds);\n\n const metrics = useMemo(() => computeParallelGroupMetrics(items), [items]);\n const summary = formatParallelGroupSummary(metrics);\n const hasRunning = metrics.running > 0;\n const hasActiveItem = useMemo(\n () => items.some((item) => isActiveWorkflowContainer(item, activeLoopSessionId, activeContainerIds)),\n [items, activeLoopSessionId, activeContainerIds],\n );\n const allSettled =\n metrics.total > 0\n && metrics.running === 0\n && metrics.completed + metrics.failed >= metrics.total;\n\n const shouldAutoExpandGroup =\n hasRunning && (!scale.onlyExpandActiveRunning || hasActiveItem);\n\n const [expanded, setExpanded] = useState(shouldAutoExpandGroup);\n\n useEffect(() => {\n if (shouldAutoExpandGroup) {\n setExpanded(true);\n return;\n }\n if (hasRunning && scale.onlyExpandActiveRunning) {\n setExpanded(false);\n return;\n }\n if (allSettled) {\n setExpanded(false);\n }\n }, [shouldAutoExpandGroup, hasRunning, allSettled, scale.onlyExpandActiveRunning]);\n\n const toggleExpanded = useCallback(() => {\n setExpanded((prev) => !prev);\n }, []);\n\n useEffect(() => {\n const onKeyDown = (event: KeyboardEvent) => {\n if (!(event.ctrlKey || event.metaKey) || event.key.toLowerCase() !== 'o') return;\n setExpanded(true);\n };\n window.addEventListener('keydown', onKeyDown);\n return () => window.removeEventListener('keydown', onKeyDown);\n }, []);\n\n const renderItem = (index: number) => {\n const item = items[index]!;\n return (\n <WorkflowStageContainer\n key={item.container_id}\n node={item}\n loopTree={resolveLoopTree(item, loopTreesBySessionId)}\n depth={depth}\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n />\n );\n };\n\n return (\n <div\n className=\"lax-workflow-parallel-group\"\n data-testid={`lax-workflow-parallel-group-${groupKey}`}\n >\n <WorkflowExpandTrigger\n summary={summary}\n expandHint={!expanded && !hasRunning ? '(ctrl+o to expand)' : null}\n onToggle={toggleExpanded}\n expanded={expanded}\n testId={`lax-workflow-parallel-group-summary-${groupKey}`}\n className=\"lax-workflow-parallel-group__summary\"\n />\n\n {expanded ? (\n <div className=\"lax-workflow-parallel-list\" data-testid=\"lax-workflow-parallel-list\">\n {items.map((_, index) => renderItem(index))}\n </div>\n ) : null}\n </div>\n );\n}\n","/**\n * workflowParallelGroupMetrics.ts — Parallel 组 sibling item 客户端聚合\n *\n * 职责:\n * 对齐 D23 §5.6;metrics_* 未填时从容器 status 统计组摘要文案。\n *\n * 链路位置:\n * WorkflowParallelGroup → 组摘要行。\n *\n * 当前裁剪范围:\n * 仅 item scope 兄弟节点;不含 Aggregate metrics。\n */\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\n\nexport interface ParallelGroupMetrics {\n total: number;\n running: number;\n completed: number;\n failed: number;\n}\n\nfunction readDisplayMetrics(items: WorkflowContainerRuntimeNode[]): ParallelGroupMetrics | null {\n let hasMetrics = false;\n let running = 0;\n let completed = 0;\n let failed = 0;\n let total = 0;\n\n for (const item of items) {\n const metrics = item.display;\n if (\n metrics?.metrics_total != null\n || metrics?.metrics_running != null\n || metrics?.metrics_completed != null\n || metrics?.metrics_failed != null\n ) {\n hasMetrics = true;\n }\n running += metrics?.metrics_running ?? 0;\n completed += metrics?.metrics_completed ?? 0;\n failed += metrics?.metrics_failed ?? 0;\n total += metrics?.metrics_total ?? 0;\n }\n\n if (!hasMetrics) return null;\n if (total <= 0) total = items.length;\n return { total, running, completed, failed };\n}\n\n/** 从 sibling item 容器统计组 metrics(display.metrics_* 优先)。 */\nexport function computeParallelGroupMetrics(\n items: WorkflowContainerRuntimeNode[],\n): ParallelGroupMetrics {\n const fromDisplay = readDisplayMetrics(items);\n if (fromDisplay) return fromDisplay;\n\n let running = 0;\n let completed = 0;\n let failed = 0;\n\n for (const item of items) {\n switch (item.status) {\n case 'running':\n case 'retrying':\n running += 1;\n break;\n case 'completed':\n completed += 1;\n break;\n case 'failed':\n failed += 1;\n break;\n default:\n break;\n }\n }\n\n return {\n total: items.length,\n running,\n completed,\n failed,\n };\n}\n\nexport function formatParallelGroupSummary(metrics: ParallelGroupMetrics): string {\n if (metrics.running > 0) {\n const n = metrics.running;\n return `Running ${n} agent${n === 1 ? '' : 's'}…`;\n }\n if (metrics.failed > 0) {\n const ok = metrics.completed;\n return `Done (${ok} agent${ok === 1 ? '' : 's'}) · ${metrics.failed} failed`;\n }\n const n = metrics.total;\n return `Done (${n} agent${n === 1 ? '' : 's'})`;\n}\n","/**\n * WorkflowStageContainer.tsx — Stage / item 容器行(CC Agent 同构)\n */\nimport { useCallback, useEffect, useMemo, useState, type CSSProperties } from 'react';\nimport { useStore } from 'zustand';\n\nimport {\n buildStageDoneSummary,\n formatTeaserExpandHint,\n} from '../../core/workflow/stageDoneSummary';\nimport { useWorkflowLoopReplayHandler } from '../../core/context/WorkflowLoopReplayContext';\nimport { useWorkflowScaleOptions } from '../../core/context/WorkflowScaleContext';\nimport { useWorkflowSessionStoreApi } from '../../core/context/WorkflowSessionContext';\nimport { useSessionViewOptions } from '../../core/context/SessionContext';\nimport { createWorkflowRunningLoopTree } from '../../core/workflow/workflowLoopTreeUtils';\nimport type { SessionTree } from '../../types/tree';\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\nimport { AgentLoopView } from '../agentLoop/AgentLoopView';\nimport { WorkflowContainerLine } from './WorkflowContainerLine';\nimport { WorkflowStageDoneBody } from './workflowStageDoneBody';\nimport { isActiveWorkflowContainer } from './workflowStageListUtils';\nimport {\n buildStageLineMeta,\n mapContainerStatusLabel,\n mapContainerUiStatus,\n workflowIndentUnit,\n} from './workflowContainerLineUtils';\n\nexport interface WorkflowStageContainerProps {\n node: WorkflowContainerRuntimeNode;\n loopTree?: SessionTree;\n depth?: number;\n virtualized?: boolean;\n virtualizeThreshold?: number;\n groupParallelTools?: boolean;\n}\n\nfunction containerTestId(node: WorkflowContainerRuntimeNode): string {\n if (node.scope === 'item') return `lax-workflow-parallel-${node.scope_key}`;\n if (node.scope === 'stage') return `lax-workflow-stage-${node.scope_key}`;\n return `lax-workflow-container-${node.scope_key}`;\n}\n\nfunction bodyTestId(node: WorkflowContainerRuntimeNode): string {\n if (node.scope === 'item') return `lax-workflow-parallel-body-${node.scope_key}`;\n return `lax-workflow-stage-body-${node.scope_key}`;\n}\n\nexport function WorkflowStageContainer({\n node,\n loopTree,\n depth = 0,\n virtualized,\n virtualizeThreshold,\n groupParallelTools,\n}: WorkflowStageContainerProps) {\n const { verbose } = useSessionViewOptions();\n const scale = useWorkflowScaleOptions();\n const store = useWorkflowSessionStoreApi();\n const replayHandler = useWorkflowLoopReplayHandler();\n const activeLoopSessionId = useStore(store, (s) => s.state.activeLoopSessionId);\n const activeContainerIds = useStore(store, (s) => s.state.containerTree.activeContainerIds);\n const cachedSummary = useStore(\n store,\n (s) => s.state.stageDoneSummariesByContainerId[node.container_id],\n );\n const pinLoopSession = useStore(store, (s) => s.pinLoopSession);\n\n const uiStatus = mapContainerUiStatus(node.status);\n const isRunning = node.status === 'running' || node.status === 'retrying';\n const isDone = node.status === 'completed' || node.status === 'failed';\n const isSkipped = node.status === 'skipped';\n\n const isActive = isActiveWorkflowContainer(node, activeLoopSessionId, activeContainerIds);\n\n const doneSummaryFromTree = useMemo(\n () => (loopTree && isDone ? buildStageDoneSummary(loopTree) : null),\n [loopTree, isDone],\n );\n const doneSummary = doneSummaryFromTree ?? (isDone ? cachedSummary : null);\n\n const shouldAutoExpandRunning =\n isRunning && !isSkipped && (!scale.onlyExpandActiveRunning || isActive);\n\n const [expanded, setExpanded] = useState(shouldAutoExpandRunning);\n\n useEffect(() => {\n if (shouldAutoExpandRunning) {\n setExpanded(true);\n return;\n }\n if (isRunning && !isSkipped && scale.onlyExpandActiveRunning) {\n setExpanded(false);\n return;\n }\n if (isDone || isSkipped) {\n setExpanded(false);\n }\n }, [shouldAutoExpandRunning, isRunning, isDone, isSkipped, scale.onlyExpandActiveRunning]);\n\n const requestLoopHydration = useCallback(() => {\n const loopSessionId = node.loopSessionId;\n if (!loopSessionId || loopTree) return;\n pinLoopSession(loopSessionId);\n void replayHandler?.(loopSessionId);\n }, [node.loopSessionId, loopTree, pinLoopSession, replayHandler]);\n\n const toggleExpanded = useCallback(() => {\n setExpanded((prev) => {\n const next = !prev;\n if (next && isDone && node.loopSessionId && !loopTree) {\n requestLoopHydration();\n }\n return next;\n });\n }, [isDone, node.loopSessionId, loopTree, requestLoopHydration]);\n\n useEffect(() => {\n const onKeyDown = (event: KeyboardEvent) => {\n if (!(event.ctrlKey || event.metaKey) || event.key.toLowerCase() !== 'o') return;\n setExpanded(true);\n requestLoopHydration();\n };\n window.addEventListener('keydown', onKeyDown);\n return () => window.removeEventListener('keydown', onKeyDown);\n }, [requestLoopHydration]);\n\n const displayTitle = node.title;\n const usesScopedLoop = Boolean(node.loopSessionId);\n const runningLoopTree: SessionTree | undefined =\n loopTree ?? (usesScopedLoop && isRunning && isActive ? createWorkflowRunningLoopTree() : undefined);\n const staticContentTeaser =\n !usesScopedLoop && !loopTree && node.content_blocks.length > 0\n ? node.content_blocks[node.content_blocks.length - 1]!.preview\n : '';\n const teaserText = doneSummary?.teaser || staticContentTeaser;\n const expandHint =\n doneSummary ? formatTeaserExpandHint(doneSummary.extraLines, verbose) : null;\n const doneLabel = doneSummary?.label ?? 'done';\n const statusLabel = isDone ? doneLabel : mapContainerStatusLabel(node.status);\n const testId = containerTestId(node);\n const isItem = node.scope === 'item';\n\n const canToggleShell = (isRunning && !isSkipped) || isDone;\n const shellToggle = canToggleShell ? toggleExpanded : undefined;\n\n return (\n <div\n className={`lax-workflow-stage-container lax-workflow-stage-container--${uiStatus}${\n isSkipped ? ' lax-workflow-stage-container--skipped' : ''\n }${isItem ? ' lax-workflow-parallel-item' : ' lax-workflow-stage'}`}\n data-testid={testId}\n data-stage-status={uiStatus}\n data-container-scope={node.scope}\n data-active={isActive ? 'true' : undefined}\n style={\n {\n '--lax-workflow-depth': depth,\n '--lax-workflow-indent-unit': workflowIndentUnit(depth),\n } as CSSProperties\n }\n >\n <WorkflowContainerLine\n title={displayTitle}\n description={node.subtitle || undefined}\n uiStatus={uiStatus}\n meta={buildStageLineMeta(node)}\n statusLabel={statusLabel}\n onToggle={shellToggle}\n interactive={canToggleShell}\n expanded={expanded}\n headerTestId={isDone ? `${testId}-done` : undefined}\n titleTestId={`${testId}-title`}\n descriptionTestId={`${testId}-desc`}\n className={\n isItem\n ? 'lax-workflow-parallel-item__header'\n : undefined\n }\n />\n\n {isDone && !expanded && (teaserText || expandHint) ? (\n <div className=\"lax-workflow-stage-container__done-teaser\">\n {teaserText ? (\n <span\n className=\"lax-workflow-stage-container__done-teaser-line\"\n data-testid={`${testId}-teaser`}\n >\n {`⎿ ${teaserText}`}\n </span>\n ) : null}\n {expandHint ? (\n <span className=\"lax-workflow-expand-trigger__hint\">{expandHint}</span>\n ) : null}\n </div>\n ) : null}\n\n {expanded && isRunning && !usesScopedLoop && node.content_blocks.length > 0 ? (\n <div\n className=\"lax-workflow-stage-container__body lax-workflow-stage-container__content-preview\"\n data-testid={bodyTestId(node)}\n >\n {node.content_blocks.map((block, index) => (\n <div\n key={`${block.kind}-${index}`}\n className=\"lax-workflow-stage-container__teaser\"\n >\n {block.preview}\n </div>\n ))}\n </div>\n ) : null}\n\n {expanded && isRunning && runningLoopTree ? (\n <div\n className={\n isItem\n ? 'lax-workflow-parallel-item__body lax-workflow-stage-container__body'\n : 'lax-workflow-stage-container__body'\n }\n data-testid={bodyTestId(node)}\n >\n <AgentLoopView\n tree={runningLoopTree}\n showTaskListFooter={false}\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n />\n </div>\n ) : null}\n\n {isDone && expanded ? (\n loopTree ? (\n <WorkflowStageDoneBody\n node={node}\n loopTree={loopTree}\n testId={bodyTestId(node)}\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n bodyClassName={\n isItem\n ? 'lax-workflow-parallel-item__body lax-workflow-stage-container__body'\n : 'lax-workflow-stage-container__body'\n }\n />\n ) : (\n <div\n className=\"lax-workflow-stage-container__body lax-workflow-loop-replay-pending\"\n data-testid={bodyTestId(node)}\n >\n {teaserText ? <p className=\"lax-workflow-stage-container__teaser\">{teaserText}</p> : null}\n <p className=\"lax-workflow-loop-replay-pending__hint\">\n {replayHandler ? 'Loading loop details…' : 'Loop details evicted from memory.'}\n </p>\n </div>\n )\n ) : null}\n </div>\n );\n}\n","/**\n * loopTreeUtils.ts — Workflow scoped loop 树辅助判断\n */\nimport type { SessionTree } from '../../types/tree';\n\n/** 是否已有可渲染的时间线节点(非空 store 壳) */\nexport function hasTimelineNodes(tree: SessionTree | undefined): boolean {\n if (!tree) return false;\n return tree.rootChildren.length > 0 || Object.keys(tree.byId).length > 0;\n}\n","/**\n * workflowStageDoneBody.tsx — Stage/Route 完成态展开体(仅 AgentLoopView 时间线)\n *\n * 禁止用 content_blocks 原始预览充展开体(会与 AgentSession 折叠流不一致)。\n */\nimport { hasTimelineNodes } from '../../core/workflow/loopTreeUtils';\nimport type { SessionTree } from '../../types/tree';\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\nimport { AgentLoopView } from '../agentLoop/AgentLoopView';\n\nexport interface WorkflowStageDoneBodyProps {\n node: WorkflowContainerRuntimeNode;\n loopTree?: SessionTree;\n testId: string;\n virtualized?: boolean;\n virtualizeThreshold?: number;\n groupParallelTools?: boolean;\n bodyClassName?: string;\n}\n\nexport function WorkflowStageDoneBody({\n loopTree,\n testId,\n virtualized,\n virtualizeThreshold,\n groupParallelTools,\n bodyClassName = 'lax-workflow-stage-container__body',\n}: WorkflowStageDoneBodyProps) {\n if (loopTree && hasTimelineNodes(loopTree)) {\n return (\n <div className={bodyClassName} data-testid={testId}>\n <AgentLoopView\n tree={loopTree}\n showTaskListFooter={false}\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n />\n </div>\n );\n }\n\n return (\n <div\n className={`${bodyClassName} lax-workflow-stage-container__empty-hint`}\n data-testid={testId}\n >\n <span className=\"lax-workflow-stage-container__empty-hint-text\">\n (此阶段暂无 Agent 时间线内容)\n </span>\n </div>\n );\n}\n","import type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\n\nexport interface WorkflowStageListPartition {\n visible: WorkflowContainerRuntimeNode[];\n hiddenCount: number;\n total: number;\n /** 当前已展示的 done stage 数量 */\n visibleDoneCount: number;\n /** done stage 总数 */\n totalDoneCount: number;\n}\n\nfunction stageSortKey(node: WorkflowContainerRuntimeNode): number {\n return node.display?.progress_current ?? 0;\n}\n\n/**\n * P3:running / failed / pending / blocked 全显;\n * done 按 maxVisibleDoneCount 分页展示(默认最近 completedStagePageSize 条)。\n * maxVisibleDoneCount 由 WorkflowStageListPanel 的 \"Show N more\" 逐页递增。\n */\nexport function partitionWorkflowStages(\n stages: WorkflowContainerRuntimeNode[],\n maxVisibleDoneCount: number,\n): WorkflowStageListPartition {\n const sorted = [...stages].sort(\n (a, b) => stageSortKey(a) - stageSortKey(b) || a.scope_key.localeCompare(b.scope_key),\n );\n\n const always: WorkflowContainerRuntimeNode[] = [];\n const done: WorkflowContainerRuntimeNode[] = [];\n\n for (const stage of sorted) {\n if (\n stage.status === 'running'\n || stage.status === 'retrying'\n || stage.status === 'failed'\n || stage.status === 'pending'\n || stage.status === 'blocked'\n ) {\n always.push(stage);\n } else if (stage.status === 'completed' || stage.status === 'skipped') {\n done.push(stage);\n } else {\n always.push(stage);\n }\n }\n\n const visibleDone = done.slice(Math.max(0, done.length - maxVisibleDoneCount));\n const visible = [...always, ...visibleDone].sort(\n (a, b) => stageSortKey(a) - stageSortKey(b) || a.scope_key.localeCompare(b.scope_key),\n );\n const hiddenCount = stages.length - visible.length;\n\n return {\n visible,\n hiddenCount,\n total: stages.length,\n visibleDoneCount: visibleDone.length,\n totalDoneCount: done.length,\n };\n}\n\nexport function isActiveWorkflowContainer(\n node: WorkflowContainerRuntimeNode,\n activeLoopSessionId: string | null,\n activeContainerIds: string[],\n): boolean {\n if (activeContainerIds.includes(node.container_id)) return true;\n if (node.loopSessionId && node.loopSessionId === activeLoopSessionId) return true;\n return false;\n}\n","/**\r\r\n * WorkflowRootContainer.tsx — Workflow 根行(始终展示子树,不折叠)\r\r\n *\r\r\n * 职责:根行壳语法 + 常驻 stage 列表。Workflow 已是页面顶层,不做 AgentSession 式根折叠。\r\r\n *\r\r\n * 链路位置:WorkflowChrome → scope workflow 根节点。\r\r\n */\r\r\nimport type { ReactNode } from 'react';\r\r\n\r\r\nimport { useSessionViewOptions } from '../../core/context/SessionContext';\r\r\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\r\r\nimport { WorkflowContainerLine } from './WorkflowContainerLine';\r\r\nimport {\r\r\n buildWorkflowRootMeta,\r\r\n mapContainerUiStatus,\r\r\n mapWorkflowRootStatusLabel,\r\r\n} from './workflowContainerLineUtils';\r\r\n\r\r\nexport interface WorkflowRootContainerProps {\r\r\n node: WorkflowContainerRuntimeNode;\r\r\n children?: ReactNode;\r\r\n}\r\r\n\r\r\nexport function WorkflowRootContainer({\r\r\n node,\r\r\n children,\r\r\n}: WorkflowRootContainerProps) {\r\r\n const { verbose } = useSessionViewOptions();\r\r\n const uiStatus = mapContainerUiStatus(node.status);\r\r\n const statusLabel = mapWorkflowRootStatusLabel(node.status);\r\r\n\r\r\n return (\r\r\n <div className=\"lax-workflow-root\" data-testid=\"lax-workflow-root\">\r\r\n <WorkflowContainerLine\r\r\n variant=\"root\"\r\r\n title={node.title}\r\r\n description={node.subtitle || undefined}\r\r\n uiStatus={uiStatus}\r\r\n meta={buildWorkflowRootMeta(node)}\r\r\n statusLabel={statusLabel}\r\r\n titleTestId=\"lax-workflow-root-title\"\r\r\n descriptionTestId=\"lax-workflow-root-desc\"\r\r\n debugScopeKey={node.scope_key}\r\r\n verbose={verbose}\r\r\n />\r\r\n\r\r\n {children ? (\r\r\n <div className=\"lax-workflow-container-tree\">{children}</div>\r\r\n ) : null}\r\r\n </div>\r\r\n );\r\r\n}\r\r\n\r","/**\n * WorkflowRouteContainer.tsx — Route branch 容器行\n *\n * 职责:selected/running 分支可展开;skipped ◌ dim 静态一行。\n *\n * 链路位置:WorkflowChrome → scope branch 节点。\n */\nimport { useCallback, useEffect, useMemo, useState, type CSSProperties } from 'react';\n\nimport {\n buildStageDoneSummary,\n formatTeaserExpandHint,\n} from '../../core/workflow/stageDoneSummary';\nimport { useSessionViewOptions } from '../../core/context/SessionContext';\nimport type { SessionTree } from '../../types/tree';\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\nimport { AgentLoopView } from '../agentLoop/AgentLoopView';\nimport { WorkflowContainerLine } from './WorkflowContainerLine';\nimport { WorkflowExpandTrigger } from './WorkflowExpandTrigger';\nimport { WorkflowStageDoneBody } from './workflowStageDoneBody';\nimport {\n buildRouteLineMeta,\n mapContainerStatusLabel,\n mapContainerUiStatus,\n workflowIndentUnit,\n} from './workflowContainerLineUtils';\n\nexport interface WorkflowRouteContainerProps {\n node: WorkflowContainerRuntimeNode;\n loopTree?: SessionTree;\n depth?: number;\n virtualized?: boolean;\n virtualizeThreshold?: number;\n groupParallelTools?: boolean;\n}\n\nexport function WorkflowRouteContainer({\n node,\n loopTree,\n depth = 1,\n virtualized,\n virtualizeThreshold,\n groupParallelTools,\n}: WorkflowRouteContainerProps) {\n const { verbose } = useSessionViewOptions();\n const isSkipped = node.status === 'skipped';\n const uiStatus = mapContainerUiStatus(node.status);\n const isRunning = !isSkipped && (node.status === 'running' || node.status === 'retrying');\n const isDone = !isSkipped && (node.status === 'completed' || node.status === 'failed');\n const testId = `lax-workflow-route-${node.scope_key}`;\n const doneSummary = useMemo(\n () => (loopTree && isDone ? buildStageDoneSummary(loopTree) : null),\n [loopTree, isDone],\n );\n const staticContentTeaser =\n !loopTree && node.content_blocks.length > 0\n ? node.content_blocks[node.content_blocks.length - 1]!.preview\n : '';\n const teaserText = doneSummary?.teaser || staticContentTeaser;\n const expandHint =\n doneSummary ? formatTeaserExpandHint(doneSummary.extraLines, verbose) : null;\n const doneLabel = doneSummary?.label ?? 'done';\n\n const [expanded, setExpanded] = useState(isRunning);\n\n useEffect(() => {\n if (isSkipped) return;\n if (isRunning) setExpanded(true);\n if (isDone) setExpanded(false);\n }, [isRunning, isDone, isSkipped]);\n\n const toggleExpanded = useCallback(() => {\n if (!isSkipped) setExpanded((prev) => !prev);\n }, [isSkipped]);\n\n const shellToggle =\n isSkipped ? undefined\n : isRunning ? toggleExpanded\n : isDone && expanded ? toggleExpanded\n : undefined;\n\n const depthStyle = {\n '--lax-workflow-depth': depth,\n '--lax-workflow-indent-unit': workflowIndentUnit(depth),\n } as CSSProperties;\n\n return (\n <div\n className={`lax-workflow-route-branch lax-workflow-stage-container lax-workflow-stage-container--${uiStatus}${\n isSkipped ? ' lax-workflow-route-branch--skipped' : ''\n }`}\n data-testid={testId}\n data-route-status={node.status}\n data-container-scope=\"branch\"\n style={depthStyle}\n >\n <WorkflowContainerLine\n title={node.title}\n description={node.subtitle || undefined}\n uiStatus={uiStatus}\n meta={buildRouteLineMeta(node)}\n statusLabel={isSkipped ? 'skipped' : mapContainerStatusLabel(node.status)}\n onToggle={shellToggle}\n interactive={!isSkipped && isRunning}\n expanded={expanded}\n titleTestId={`${testId}-title`}\n descriptionTestId={`${testId}-desc`}\n />\n\n {!isSkipped && expanded && isRunning && loopTree ? (\n <div className=\"lax-workflow-stage-container__body\" data-testid={`${testId}-body`}>\n <AgentLoopView\n tree={loopTree}\n showTaskListFooter={false}\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n />\n </div>\n ) : null}\n\n {!isSkipped && isDone && !expanded ? (\n <WorkflowExpandTrigger\n summary={`${node.title} · ${doneLabel}`}\n teaser={teaserText || undefined}\n expandHint={expandHint}\n onToggle={() => setExpanded(true)}\n expanded={false}\n testId={`${testId}-done`}\n teaserTestId={teaserText ? `${testId}-teaser` : undefined}\n />\n ) : null}\n\n {!isSkipped && isDone && expanded ? (\n <WorkflowStageDoneBody\n node={node}\n loopTree={loopTree}\n testId={`${testId}-body`}\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n />\n ) : null}\n </div>\n );\n}\n","/**\n * WorkflowSubworkflowContainer.tsx — Subworkflow 缩进 mini 根行 + 左边界\n *\n * 职责:与 workflow 根同壳行语法;嵌套子树包在 boundary 内;done 折叠为 ExpandTrigger。\n *\n * 链路位置:WorkflowChrome → scope subworkflow 节点。\n */\nimport { useCallback, useEffect, useMemo, useState, type CSSProperties, type ReactNode } from 'react';\n\nimport { useSessionViewOptions } from '../../core/context/SessionContext';\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\nimport { WorkflowContainerLine } from './WorkflowContainerLine';\nimport { WorkflowExpandTrigger } from './WorkflowExpandTrigger';\nimport {\n buildWorkflowRootMeta,\n mapContainerUiStatus,\n mapWorkflowRootStatusLabel,\n workflowIndentUnit,\n} from './workflowContainerLineUtils';\n\nexport interface WorkflowSubworkflowContainerProps {\n node: WorkflowContainerRuntimeNode;\n depth?: number;\n children?: ReactNode;\n}\n\nfunction buildDoneSummary(node: WorkflowContainerRuntimeNode): string {\n const display = node.display;\n if (display?.progress_total != null) {\n const total = display.progress_total;\n const current =\n node.status === 'completed' ? total : (display.progress_current ?? total);\n return `${current}/${total} · done`;\n }\n return 'done';\n}\n\nexport function WorkflowSubworkflowContainer({\n node,\n depth = 1,\n children,\n}: WorkflowSubworkflowContainerProps) {\n const { verbose } = useSessionViewOptions();\n const uiStatus = mapContainerUiStatus(node.status);\n const isRunning = node.status === 'running' || node.status === 'retrying';\n const isDone = node.status === 'completed' || node.status === 'failed';\n const testId = `lax-workflow-subworkflow-${node.scope_key}`;\n const teaser = useMemo(() => {\n if (node.content_blocks.length === 0) return '';\n return node.content_blocks[node.content_blocks.length - 1]?.preview ?? '';\n }, [node.content_blocks]);\n\n const [expanded, setExpanded] = useState(isRunning);\n\n useEffect(() => {\n if (isRunning) setExpanded(true);\n if (isDone) setExpanded(false);\n }, [isRunning, isDone]);\n\n const toggleExpanded = useCallback(() => {\n setExpanded((prev) => !prev);\n }, []);\n\n const shellToggle =\n isRunning ? toggleExpanded\n : isDone && expanded ? toggleExpanded\n : undefined;\n\n const depthStyle = {\n '--lax-workflow-depth': depth,\n '--lax-workflow-indent-unit': workflowIndentUnit(depth),\n } as CSSProperties;\n\n const showShellLine = !(isDone && !expanded);\n\n return (\n <div\n className=\"lax-workflow-subworkflow\"\n data-testid={testId}\n data-container-scope=\"subworkflow\"\n style={depthStyle}\n >\n {showShellLine ? (\n <WorkflowContainerLine\n variant=\"root\"\n title={node.title}\n description={node.subtitle || undefined}\n uiStatus={uiStatus}\n meta={buildWorkflowRootMeta(node)}\n statusLabel={mapWorkflowRootStatusLabel(node.status)}\n onToggle={shellToggle}\n interactive={isRunning}\n expanded={expanded}\n titleTestId={`${testId}-title`}\n descriptionTestId={`${testId}-desc`}\n debugScopeKey={node.scope_key}\n verbose={verbose}\n />\n ) : null}\n\n {expanded && children ? (\n <div\n className=\"lax-workflow-subworkflow-boundary\"\n data-testid={`${testId}-boundary`}\n style={depthStyle}\n >\n {children}\n </div>\n ) : null}\n\n {isDone && !expanded ? (\n <WorkflowExpandTrigger\n summary={`${node.title} · ${buildDoneSummary(node)}`}\n summaryTestId={`${testId}-title`}\n teaser={teaser || undefined}\n onToggle={() => setExpanded(true)}\n expanded={false}\n testId={`${testId}-done`}\n teaserTestId={teaser ? `${testId}-teaser` : undefined}\n />\n ) : null}\n </div>\n );\n}\n","/**\n * WorkflowTaskListFooter.tsx — 合并多 loop 任务列表底部 pill(§5.11.4)\n */\nimport { useMemo, useState } from 'react';\nimport { useStore } from 'zustand';\n\nimport { useWorkflowSessionStoreApi } from '../../core/context/WorkflowSessionContext';\nimport type { WorkflowSessionStoreState } from '../../core/workflowSessionStore';\nimport { TaskList } from '../TaskList';\nimport {\n deriveWorkflowTaskFooterState,\n formatWorkflowTaskFooterLabel,\n groupWorkflowTasksByLoop,\n loopSessionDisplayLabel,\n shouldShowWorkflowTaskListFooter,\n} from './workflowTaskListMerge';\n\nfunction MessageResponse({ children }: { children: React.ReactNode }) {\n return (\n <div className=\"lax-message-response\">\n <span className=\"lax-message-response__marker\">⎿ </span>\n <span className=\"lax-message-response__content\">{children}</span>\n </div>\n );\n}\n\nexport function WorkflowTaskListFooter() {\n const store = useWorkflowSessionStoreApi();\n const state = useStore(store, (s: WorkflowSessionStoreState) => s.state);\n const [expanded, setExpanded] = useState(false);\n\n const footerState = useMemo(() => deriveWorkflowTaskFooterState(state), [state]);\n const visible = shouldShowWorkflowTaskListFooter(state);\n\n if (!visible) {\n return null;\n }\n\n const label = formatWorkflowTaskFooterLabel(state);\n const groups = groupWorkflowTasksByLoop(footerState.tasks);\n\n return (\n <div className=\"lax-workflow-task-list-footer\" data-testid=\"lax-workflow-task-list-footer\">\n <button\n type=\"button\"\n className=\"lax-task-list-footer__pill lax-workflow-task-list-footer__pill\"\n data-testid=\"lax-workflow-task-list-footer-pill\"\n aria-expanded={expanded}\n onClick={() => setExpanded((v) => !v)}\n >\n {label}\n <span className=\"lax-task-list-footer__hint\">\n {expanded ? ' · ↑ to hide' : ' · ↓ to view'}\n </span>\n </button>\n {expanded ? (\n <MessageResponse>\n <div className=\"lax-workflow-task-list-groups\">\n {groups.map((group) => (\n <div\n key={group.loopSessionId}\n className=\"lax-workflow-task-list-group\"\n data-testid={`lax-workflow-task-group-${group.loopSessionId}`}\n >\n <div className=\"lax-workflow-task-list-group-title\">\n {loopSessionDisplayLabel(group.loopSessionId)}\n </div>\n <TaskList tasks={group.tasks} />\n </div>\n ))}\n </div>\n </MessageResponse>\n ) : null}\n </div>\n );\n}\n","/**\n * workflowTaskListMerge.ts — Workflow 多 loop 任务合并(§5.11.4)\n */\nimport type { Task } from '../../types/tasks';\nimport type { SessionStatus, SessionTree, TaskPhase } from '../../types/tree';\nimport type { WorkflowSessionState } from '../../types/workflowSession';\n\nimport {\n formatTaskFooterLabel,\n shouldShowTaskListFooter,\n} from '../TaskListFooter';\n\nexport interface WorkflowMergedTask extends Task {\n loopSessionId: string;\n}\n\nconst STATUS_ORDER: Record<Task['status'], number> = {\n in_progress: 0,\n pending: 1,\n completed: 2,\n};\n\nexport function mergeWorkflowLoopTasks(\n loopTreesBySessionId: Record<string, SessionTree>,\n): WorkflowMergedTask[] {\n const merged: WorkflowMergedTask[] = [];\n const loopIds = Object.keys(loopTreesBySessionId).sort();\n for (const loopSessionId of loopIds) {\n const tree = loopTreesBySessionId[loopSessionId];\n if (!tree) continue;\n for (const task of Object.values(tree.tasks)) {\n merged.push({ ...task, loopSessionId });\n }\n }\n return merged.sort((a, b) => {\n const sa = STATUS_ORDER[a.status] ?? 99;\n const sb = STATUS_ORDER[b.status] ?? 99;\n if (sa !== sb) return sa - sb;\n const loopCmp = a.loopSessionId.localeCompare(b.loopSessionId);\n if (loopCmp !== 0) return loopCmp;\n return a.id.localeCompare(b.id);\n });\n}\n\nexport function deriveWorkflowTaskPhase(trees: SessionTree[]): TaskPhase {\n if (trees.length === 0) return 'hidden';\n if (trees.some((tree) => tree.taskPhase === 'visible')) return 'visible';\n if (trees.every((tree) => tree.taskPhase === 'hidden-after-completion')) {\n return 'hidden-after-completion';\n }\n return 'hidden';\n}\n\nexport function deriveWorkflowTaskFooterState(state: WorkflowSessionState): {\n tasks: WorkflowMergedTask[];\n taskPhase: TaskPhase;\n hasEverShownTaskList: boolean;\n sessionStatus: SessionStatus;\n} {\n const trees = Object.values(state.loopTreesBySessionId);\n return {\n tasks: mergeWorkflowLoopTasks(state.loopTreesBySessionId),\n taskPhase: deriveWorkflowTaskPhase(trees),\n hasEverShownTaskList: trees.some((tree) => tree.hasEverShownTaskList),\n sessionStatus: state.status,\n };\n}\n\nexport function shouldShowWorkflowTaskListFooter(state: WorkflowSessionState): boolean {\n const { tasks, taskPhase, hasEverShownTaskList, sessionStatus } =\n deriveWorkflowTaskFooterState(state);\n return shouldShowTaskListFooter(taskPhase, tasks, hasEverShownTaskList, sessionStatus);\n}\n\nexport function formatWorkflowTaskFooterLabel(state: WorkflowSessionState): string {\n const { tasks } = deriveWorkflowTaskFooterState(state);\n return formatTaskFooterLabel(tasks);\n}\n\nexport function groupWorkflowTasksByLoop(\n tasks: WorkflowMergedTask[],\n): Array<{ loopSessionId: string; tasks: Task[] }> {\n const groups = new Map<string, Task[]>();\n for (const task of tasks) {\n const bucket = groups.get(task.loopSessionId) ?? [];\n bucket.push(task);\n groups.set(task.loopSessionId, bucket);\n }\n return Array.from(groups.entries())\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([loopSessionId, groupTasks]) => ({ loopSessionId, tasks: groupTasks }));\n}\n\nexport function loopSessionDisplayLabel(loopSessionId: string): string {\n const marker = '-';\n const idx = loopSessionId.lastIndexOf(marker);\n if (idx !== -1 && idx < loopSessionId.length - 1) {\n return loopSessionId.slice(idx + 1);\n }\n return loopSessionId;\n}\n","/**\n * groupParallelTools.ts — 主舞台 Timeline 条目分组(过渡实现)\n *\n * @deprecated Phase 4 由 core/projection GroupedToolUseAccumulator + mountCandidates 替代。\n * 对齐参考:CC GroupedToolUseContent · buildMessageLookups 并行同工具分组语义\n */\nimport type { SessionNode } from '../../types/nodes';\n\nexport type TimelineEntry =\n | { kind: 'node'; nodeId: string }\n | { kind: 'tool_group'; toolName: string; nodeIds: string[] };\n\nexport interface BuildTimelineEntriesOptions {\n /** @deprecated 使用 projection grouped_tool_use;保留至 Phase 4 迁移完成 */\n groupParallelTools?: boolean;\n hideStandalonePermissions?: boolean;\n}\n\n/** @deprecated 见 core/projection;Phase 4 删除 */\nexport function buildTimelineEntries(\n rootIds: string[],\n byId: Record<string, SessionNode | undefined>,\n options: BuildTimelineEntriesOptions = {},\n): TimelineEntry[] {\n const filtered = options.hideStandalonePermissions\n ? rootIds.filter((id) => byId[id]?.kind !== 'permission')\n : [...rootIds];\n\n if (!options.groupParallelTools) {\n return filtered.map((nodeId) => ({ kind: 'node', nodeId }));\n }\n\n const entries: TimelineEntry[] = [];\n let i = 0;\n\n while (i < filtered.length) {\n const id = filtered[i]!;\n const node = byId[id];\n\n if (node?.kind !== 'tool_call') {\n entries.push({ kind: 'node', nodeId: id });\n i += 1;\n continue;\n }\n\n const toolName = node.toolName;\n const groupIds = [id];\n let j = i + 1;\n\n while (j < filtered.length) {\n const nextId = filtered[j]!;\n const next = byId[nextId];\n if (next?.kind !== 'tool_call' || next.toolName !== toolName) break;\n groupIds.push(nextId);\n j += 1;\n }\n\n if (groupIds.length >= 2) {\n entries.push({ kind: 'tool_group', toolName, nodeIds: groupIds });\n } else {\n entries.push({ kind: 'node', nodeId: id });\n }\n\n i = j;\n }\n\n return entries;\n}\n","/**\n * 职责:默认 SubAgentNode 纵向嵌套容器 widget(方案 A 已退场)。\n * 链路位置:宿主可通过 NodeRegistry.register('subagent', SubAgentBlock) 恢复旧行为。\n * 当前裁剪范围:纵向缩进;不含横向并列布局。\n * @deprecated 方案 A 主时间线不再渲染 SubAgentBlock;子 agent progress 折叠在 AgentToolBody。\n */\nimport { useChildren, useNodeTyped } from '../../core/hooks';\nimport { useNodeRegistry } from '../../core/context/SessionContext';\nimport { TimelineItem } from '../Timeline';\n\nexport interface SubAgentBlockProps {\n nodeId: string;\n}\n\nexport function SubAgentBlock({ nodeId }: SubAgentBlockProps) {\n const node = useNodeTyped(nodeId, 'subagent');\n const childIds = useChildren(nodeId);\n const registry = useNodeRegistry();\n if (!node) return null;\n\n return (\n <div className=\"lax-subagent-block\" data-status={node.status}>\n <div className=\"lax-subagent-block__header\">SubAgent: {node.subagentId}</div>\n <div className=\"lax-subagent-block__children\">\n {childIds.map((childId) => (\n <TimelineItem key={childId} nodeId={childId} registry={registry} />\n ))}\n </div>\n </div>\n );\n}\n","/**\n * 职责:内存事件源,按序投递 events 实现 Source 接口。\n * 链路位置:历史回放、测试、AgentSession 只读时间线。\n * 当前裁剪范围:可选 delayMs 模拟流式;不含 SSE 续传。\n */\nimport type { LangchainAgentEvent } from '../types/events';\nimport type { ReplayOptions } from '../core/replay';\nimport type { Source, SourceHandler } from './types';\n\nexport interface ReplaySourceOptions extends ReplayOptions {\n /** 事件间隔毫秒;默认 0 立即投递 */\n delayMs?: number;\n}\n\nfunction sleep(ms: number, signal: AbortSignal): Promise<void> {\n if (ms <= 0) return Promise.resolve();\n return new Promise((resolve) => {\n const timer = setTimeout(resolve, ms);\n signal.addEventListener(\n 'abort',\n () => {\n clearTimeout(timer);\n resolve();\n },\n { once: true },\n );\n });\n}\n\nexport function createReplaySource(\n events: LangchainAgentEvent[],\n opts?: ReplaySourceOptions,\n): Source {\n const delayMs = opts?.delayMs ?? 0;\n\n return {\n async start(handler: SourceHandler, signal: AbortSignal): Promise<void> {\n for (const event of events) {\n if (signal.aborted) break;\n handler(event);\n if (delayMs > 0) {\n await sleep(delayMs, signal);\n }\n }\n },\n };\n}\n"],"mappings":"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","names":["useEffect","useRef","jsx","jsx","useRef","useEffect","useEffect","useMemo","useRef","createContext","useContext","jsx","createContext","useContext","createContext","useContext","createStore","readString","readString","node","loopSessionId","next","loopTree","reducedLoop","createStore","useMemo","useState","useEffect","useMemo","jsx","jsxs","jsx","jsxs","jsx","jsxs","useMemo","useEffect","useCallback","useEffect","useMemo","useState","useStore","n","useCallback","useEffect","useMemo","useState","useStore","jsx","jsx","jsxs","useStore","useMemo","useState","useEffect","useCallback","jsx","jsxs","useStore","useMemo","useState","useEffect","useCallback","jsx","jsxs","useCallback","useEffect","useMemo","useState","jsx","jsxs","useMemo","useState","useEffect","useCallback","useCallback","useEffect","useMemo","useState","jsx","jsxs","useMemo","useState","useEffect","useCallback","Fragment","jsx","jsxs","resolveLoopTree","useState","useMemo","useMemo","useState","useStore","jsx","jsxs","useStore","useState","useMemo","useStore","jsx","jsxs","useRef","useMemo","useEffect","jsx","jsxs"]}
|