langchain_agentx_stream_ui 0.2.2 → 0.2.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.js +6 -2
- 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/core/workflow/stageDoneSummary.ts","../src/core/workflow/workflowLoopEviction.ts","../src/types/workflowDisplay.ts","../src/core/workflow/workflowContainerProjector.ts","../src/core/workflow/loopSessionUtils.ts","../src/core/workflowStructureEvents.ts","../src/core/workflow/workflowPathUtils.ts","../src/core/workflow/nativeNestedUtils.ts","../src/core/workflow/embeddedSubworkflowUtils.ts","../src/core/workflowReducer.ts","../src/view/workflow/WorkflowChrome.tsx","../src/view/workflow/WorkflowAggregateContainer.tsx","../src/view/workflow/WorkflowContainerLine.tsx","../src/view/workflow/WorkflowExpandTrigger.tsx","../src/view/workflow/WorkflowMarkdownPreview.tsx","../src/view/workflow/workflowStageListUtils.ts","../src/view/workflow/workflowContainerLineUtils.ts","../src/view/workflow/workflowContainerMemo.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/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 const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\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 onErrorRef.current?.(err);\n } else if (err instanceof Error) {\n onErrorRef.current?.(err);\n }\n });\n\n return () => {\n controller.abort();\n };\n }, [source]);\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","/**\r\n * applicationKind.ts — SSE meta application_kind 契约\r\n *\r\n * 职责:\r\n * 定义双轨 SSE 出口 kind 枚举与 mismatch 错误类型。\r\n *\r\n * 链路位置:\r\n * createAgentxSseSource meta 握手校验。\r\n *\r\n * 当前裁剪范围:\r\n * 仅 agent_session / workflow;无自动推断。\r\n */\r\nexport type ApplicationKind = 'agent_session' | 'workflow';\r\n\r\nexport class ApplicationKindMismatchError extends Error {\r\n readonly name = 'ApplicationKindMismatchError';\r\n readonly expected: ApplicationKind;\r\n readonly actual: string | undefined;\r\n\r\n constructor(expected: ApplicationKind, actual: string | undefined) {\r\n super(\r\n `application_kind mismatch: expected ${expected}, got ${actual ?? '(missing)'}`,\r\n );\r\n this.expected = expected;\r\n this.actual = actual;\r\n }\r\n}\r\n\r\nexport class MissingApplicationKindError extends Error {\r\n readonly name = 'MissingApplicationKindError';\r\n\r\n constructor() {\r\n super('application_kind missing in SSE meta frame');\r\n }\r\n}\r\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 请求头)。 */\nfunction isSseStreamTerminalEvent(\n agentEvent: LangchainAgentEvent,\n expectedApplicationKind?: ApplicationKind,\n): boolean {\n const eventType = agentEvent.event_type;\n if (eventType === 'error') return true;\n if (expectedApplicationKind === 'workflow') {\n return eventType === 'workflow-end' || eventType === 'workflow-failed';\n }\n return eventType === 'finish';\n}\n\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 (isSseStreamTerminalEvent(agentEvent, expectedApplicationKind)) {\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","/**\r\n * ScopedSessionStore.tsx — 外部 SessionTree 注入 SessionStore 上下文\r\n *\r\n * 职责:\r\n * 让 AgentLoopView 在 workflow scoped 子树渲染时复用 Timeline 组件栈。\r\n *\r\n * 链路位置:\r\n * AgentLoopView(tree prop)→ ScopedSessionStoreProvider。\r\n *\r\n * 当前裁剪范围:\r\n * 只读同步 tree prop;不接收 live applyEvent(由父 workflow store 驱动)。\r\n */\r\nimport { useEffect, useRef, type ReactNode } from 'react';\r\n\r\nimport { SessionStoreContext } from '../../core/context/SessionContext';\r\nimport { createSessionStore } from '../../core/store';\r\nimport type { SessionTree } from '../../types/tree';\r\n\r\nexport function ScopedSessionStoreProvider({\r\n tree,\r\n children,\r\n}: {\r\n tree: SessionTree;\r\n children: ReactNode;\r\n}) {\r\n const storeRef = useRef(createSessionStore(tree, { initialEventCount: 1 }));\r\n useEffect(() => {\r\n storeRef.current.setState({ tree });\r\n }, [tree]);\r\n\r\n return (\r\n <SessionStoreContext.Provider value={storeRef.current}>\r\n {children}\r\n </SessionStoreContext.Provider>\r\n );\r\n}\r\n","/**\r\n * AgentLoopView.tsx — CC 主舞台(Timeline + Spinner + 可选 TaskListFooter)\r\n *\r\n * 职责:\r\n * /chat 与 /workflow 内 agent loop 区域共用投影与节点渲染。\r\n *\r\n * 链路位置:\r\n * AgentSession · WorkflowSession scoped loop。\r\n *\r\n * 当前裁剪范围:\r\n * workflow 页 showTaskListFooter=false(合并 Footer 在 P3)。\r\n */\r\nimport type { SessionTree } from '../../types/tree';\r\nimport { SessionTimeline } from '../SessionTimeline';\r\nimport { ScopedSessionStoreProvider } from './ScopedSessionStore';\r\n\r\nexport interface AgentLoopViewProps {\r\n /** 传入时使用隔离 store(workflow scoped);省略则使用上层 SessionStoreContext */\r\n tree?: SessionTree;\r\n showTaskListFooter?: boolean;\r\n virtualized?: boolean;\r\n virtualizeThreshold?: number;\r\n groupParallelTools?: boolean;\r\n}\r\n\r\nfunction AgentLoopViewBody({\r\n showTaskListFooter = true,\r\n virtualized,\r\n virtualizeThreshold,\r\n groupParallelTools,\r\n}: Omit<AgentLoopViewProps, 'tree'>) {\r\n return (\r\n <div className=\"lax-agent-loop-view\" data-testid=\"lax-agent-loop-view\">\r\n <SessionTimeline\r\n virtualized={virtualized}\r\n virtualizeThreshold={virtualizeThreshold}\r\n groupParallelTools={groupParallelTools}\r\n showTaskListFooter={showTaskListFooter}\r\n />\r\n </div>\r\n );\r\n}\r\n\r\nexport function AgentLoopView({\r\n tree,\r\n showTaskListFooter = true,\r\n virtualized,\r\n virtualizeThreshold,\r\n groupParallelTools,\r\n}: AgentLoopViewProps) {\r\n if (tree) {\r\n return (\r\n <ScopedSessionStoreProvider tree={tree}>\r\n <AgentLoopViewBody\r\n showTaskListFooter={showTaskListFooter}\r\n virtualized={virtualized}\r\n virtualizeThreshold={virtualizeThreshold}\r\n groupParallelTools={groupParallelTools}\r\n />\r\n </ScopedSessionStoreProvider>\r\n );\r\n }\r\n return (\r\n <AgentLoopViewBody\r\n showTaskListFooter={showTaskListFooter}\r\n virtualized={virtualized}\r\n virtualizeThreshold={virtualizeThreshold}\r\n groupParallelTools={groupParallelTools}\r\n />\r\n );\r\n}\r\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 /** SSE 流正常结束(传输 resolve);与 status=done 互补,供宿主解锁 loading */\n onStreamComplete?: () => void;\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 onStreamComplete,\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 const sessionStatus = useStore(\n storeRef.current!,\n (s: WorkflowSessionStoreState) => s.state.status,\n );\n const internalErrors = useStore(\n storeRef.current!,\n (s: WorkflowSessionStoreState) => s.state.internalErrors,\n );\n\n const onErrorRef = useRef(onError);\n const onStreamCompleteRef = useRef(onStreamComplete);\n onErrorRef.current = onError;\n onStreamCompleteRef.current = onStreamComplete;\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)\n .then(() => {\n store.getState().markStreamComplete();\n onStreamCompleteRef.current?.();\n })\n .catch((err: unknown) => {\n if (err instanceof SseTransportTerminalError) {\n store.getState().markAsError(err);\n onErrorRef.current?.(err);\n } else if (err instanceof Error) {\n onErrorRef.current?.(err);\n }\n });\n\n return () => {\n controller.abort();\n };\n }, [source]);\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 {(sessionStatus === 'error' || internalErrors.length > 0) ? (\n <div\n className=\"lax-workflow-error\"\n data-testid=\"lax-workflow-error\"\n role=\"alert\"\n >\n {internalErrors[internalErrors.length - 1]?.message\n ?? 'Workflow stream error'}\n </div>\n ) : null}\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","/**\r\n * WorkflowSessionContext.tsx — Workflow store React 上下文\r\n *\r\n * 职责:\r\n * 向 WorkflowSession 子树注入 workflowSessionStore。\r\n *\r\n * 链路位置:\r\n * WorkflowSession Provider。\r\n *\r\n * 当前裁剪范围:\r\n * 与 SessionStoreContext 平行,不混用。\r\n */\r\nimport { createContext, useContext } from 'react';\r\nimport { useStore } from 'zustand';\r\n\r\nimport type { SessionStatus } from '../../types/tree';\r\nimport type { WorkflowSessionStore } from '../workflowSessionStore';\r\n\r\nexport const WorkflowSessionStoreContext = createContext<WorkflowSessionStore | null>(null);\r\n\r\nexport function useWorkflowSessionStoreApi(): WorkflowSessionStore {\r\n const store = useContext(WorkflowSessionStoreContext);\r\n if (!store) {\r\n throw new Error('useWorkflowSessionStoreApi must be used within WorkflowSession');\r\n }\r\n return store;\r\n}\r\n\r\nexport function useWorkflowSessionStatus(): SessionStatus {\r\n const store = useWorkflowSessionStoreApi();\r\n return useStore(store, (s) => s.state.status);\r\n}\r\n","import { createContext, useContext, type ReactNode } from 'react';\r\n\r\n/** 宿主按需 replay 某 loopSessionId 的事件(P2 懒加载) */\r\nexport type WorkflowLoopReplayHandler = (loopSessionId: string) => void | Promise<void>;\r\n\r\nconst WorkflowLoopReplayContext = createContext<WorkflowLoopReplayHandler | undefined>(\r\n undefined,\r\n);\r\n\r\nexport function WorkflowLoopReplayProvider({\r\n onRequestLoopReplay,\r\n children,\r\n}: {\r\n onRequestLoopReplay?: WorkflowLoopReplayHandler;\r\n children: ReactNode;\r\n}) {\r\n return (\r\n <WorkflowLoopReplayContext.Provider value={onRequestLoopReplay}>\r\n {children}\r\n </WorkflowLoopReplayContext.Provider>\r\n );\r\n}\r\n\r\nexport function useWorkflowLoopReplayHandler(): WorkflowLoopReplayHandler | undefined {\r\n return useContext(WorkflowLoopReplayContext);\r\n}\r\n","import { createContext, useContext } from 'react';\r\n\r\nimport {\r\n DEFAULT_WORKFLOW_SCALE_OPTIONS,\r\n type WorkflowScaleOptions,\r\n} from '../../view/workflow/workflowScaleOptions';\r\n\r\nexport const WorkflowScaleContext = createContext<WorkflowScaleOptions>(\r\n DEFAULT_WORKFLOW_SCALE_OPTIONS,\r\n);\r\n\r\nexport function useWorkflowScaleOptions(): WorkflowScaleOptions {\r\n return useContext(WorkflowScaleContext);\r\n}\r\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:历史选项;折叠不变式不再因 non-active 隐藏 running 容器(见 workflow-display-rules §8) */\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 {\n finalizeWorkflowSessionOnStreamComplete,\n reduceWorkflowSession,\n} from './workflowReducer';\nimport {\n evictInactiveLoopTrees,\n evictCompletedLoopOverflow,\n touchCompletedLoopSession,\n} from './workflow/workflowLoopEviction';\nimport { filterAgentLoopReplayEvents } from './workflowStructureEvents';\nimport type { SourceEventContext } from '../transport/types';\nimport { finalizeWorkflowLoopTree } from './workflow/workflowLoopTreeUtils';\nimport type { WorkflowContainerRuntimeNode } from '../types/workflowContainer';\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 /** DES-1:分批 hydrate 进行中的 loopSessionId(store 级,不进 reducer) */\n hydratingLoopSessionIds: Record<string, true>;\n applyEvent: (event: LangchainAgentEvent, ctx?: SourceEventContext) => void;\n applyEvents: (events: LangchainAgentEvent[]) => void;\n reset: () => void;\n markAsError: (error?: Error) => void;\n /** SSE 正常结束:推断 done 并收口 running loop(嵌套 parallel 缺 workflow-end 兜底) */\n markStreamComplete: () => void;\n /** P2:展开 done stage 时 pin,避免淘汰 */\n pinLoopSession: (loopSessionId: string) => void;\n /** P2:宿主 replay 后灌入 loop 树(同步;测试与小批量) */\n hydrateLoopSession: (loopSessionId: string, events: LangchainAgentEvent[]) => void;\n /** DES-1:宿主默认 replay 路径 — 分批 + rAF yield */\n hydrateLoopSessionAsync: (\n loopSessionId: string,\n events: LangchainAgentEvent[],\n options?: HydrateLoopSessionAsyncOptions,\n ) => Promise<void>;\n}\n\nexport interface HydrateLoopSessionAsyncOptions {\n chunkSize?: number;\n signal?: AbortSignal;\n}\n\nconst DEFAULT_HYDRATE_CHUNK_SIZE = 50;\n\nfunction nextAnimationFrame(): Promise<void> {\n return new Promise((resolve) => {\n requestAnimationFrame(() => resolve());\n });\n}\n\nfunction withoutHydrating(\n ids: Record<string, true>,\n loopSessionId: string,\n): Record<string, true> {\n if (!ids[loopSessionId]) return ids;\n const next = { ...ids };\n delete next[loopSessionId];\n return next;\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\n/** scope miss / 传输断流:收口 running 容器与 loop,避免永久 Spinner(D30 A-03)。 */\nfunction finalizeWorkflowSessionOnStreamError(\n state: WorkflowSessionState,\n message: string,\n eventIndex: number,\n stack?: string,\n): WorkflowSessionState {\n const containersById: Record<string, WorkflowContainerRuntimeNode> = {\n ...state.containerTree.containersById,\n };\n for (const [id, node] of Object.entries(containersById)) {\n if (node.status === 'running' || node.status === 'pending') {\n containersById[id] = { ...node, status: 'failed', is_open: false };\n }\n }\n\n const loopTreesBySessionId = { ...state.loopTreesBySessionId };\n for (const [loopSessionId, tree] of Object.entries(loopTreesBySessionId)) {\n if (tree.status === 'running' || tree.status === 'connecting') {\n loopTreesBySessionId[loopSessionId] = finalizeWorkflowLoopTree(tree, 'error');\n }\n }\n\n return {\n ...state,\n status: 'error',\n containerTree: {\n ...state.containerTree,\n containersById,\n activeContainerIds: state.containerTree.activeContainerIds.filter(\n (id) => containersById[id]?.is_open,\n ),\n },\n loopTreesBySessionId,\n activeLoopSessionId: null,\n internalErrors: [\n ...state.internalErrors,\n { eventIndex, eventType: 'stream-error', message, stack },\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 hydratingLoopSessionIds: {},\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 hydratingLoopSessionIds: {},\n });\n },\n markAsError(error) {\n const { state, eventCount } = get();\n const message = error?.message ?? 'Workflow stream error';\n set({\n state: finalizeWorkflowSessionOnStreamError(\n state,\n message,\n eventCount,\n error?.stack,\n ),\n });\n },\n markStreamComplete() {\n set((current) => ({\n state: finalizeState(\n finalizeWorkflowSessionOnStreamComplete(current.state),\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 async hydrateLoopSessionAsync(loopSessionId, events, options) {\n const { hydratingLoopSessionIds } = get();\n if (hydratingLoopSessionIds[loopSessionId]) return;\n\n const filtered = filterAgentLoopReplayEvents(events);\n if (filtered.length === 0) return;\n\n const chunkSize = options?.chunkSize ?? DEFAULT_HYDRATE_CHUNK_SIZE;\n const signal = options?.signal;\n\n set((current) => ({\n hydratingLoopSessionIds: {\n ...current.hydratingLoopSessionIds,\n [loopSessionId]: true,\n },\n }));\n\n try {\n let tree: SessionTree =\n get().state.loopTreesBySessionId[loopSessionId] ?? createEmptyTree();\n let idx = get().eventCount;\n\n for (let offset = 0; offset < filtered.length; offset += chunkSize) {\n if (signal?.aborted) {\n throw new DOMException('Hydrate aborted', 'AbortError');\n }\n\n const chunk = filtered.slice(offset, offset + chunkSize);\n for (const event of chunk) {\n tree = reduceTree(tree, event, idx, reduceOpts);\n idx += 1;\n }\n\n const isLastChunk = offset + chunkSize >= filtered.length;\n set((current) => {\n let next: WorkflowSessionState = {\n ...current.state,\n loopTreesBySessionId: {\n ...current.state.loopTreesBySessionId,\n [loopSessionId]: tree,\n },\n };\n if (isLastChunk) {\n next = touchCompletedLoopSession(next, loopSessionId);\n next = evictCompletedLoopOverflow(next, maxHydratedCompletedLoops);\n }\n next = finalizeState(next);\n return { state: next };\n });\n\n if (!isLastChunk) {\n await nextAnimationFrame();\n }\n }\n } catch {\n set((current) => {\n const { [loopSessionId]: _removed, ...restLoops } =\n current.state.loopTreesBySessionId;\n return {\n state: { ...current.state, loopTreesBySessionId: restLoops },\n hydratingLoopSessionIds: withoutHydrating(\n current.hydratingLoopSessionIds,\n loopSessionId,\n ),\n };\n });\n return;\n }\n\n set((current) => ({\n hydratingLoopSessionIds: withoutHydrating(\n current.hydratingLoopSessionIds,\n loopSessionId,\n ),\n }));\n },\n }));\n}\n","/**\r\n * workflowContainer.ts — Workflow 容器树投影类型\r\n *\r\n * 职责:\r\n * 容器节点、正文块、快照;对齐 SDK workflow_container_projector。\r\n *\r\n * 链路位置:\r\n * workflowContainerProjector → workflowReducer(P1+)→ WorkflowChrome(P2+)。\r\n *\r\n * 当前裁剪范围:\r\n * 不含 React 视图 props;仅投影层 state。\r\n */\r\n\r\nimport type { WorkflowDisplayPayload } from './workflowDisplay';\r\n\r\nexport type WorkflowContainerScope =\r\n | 'workflow'\r\n | 'stage'\r\n | 'item'\r\n | 'branch'\r\n | 'aggregate'\r\n | 'subworkflow';\r\n\r\nexport type WorkflowContainerStatus =\r\n | 'pending'\r\n | 'running'\r\n | 'completed'\r\n | 'failed'\r\n | 'skipped'\r\n | 'cancelled'\r\n | 'blocked'\r\n | 'retrying';\r\n\r\nexport type ContentBlockKind = 'reasoning' | 'text' | 'tool';\r\n\r\nexport interface WorkflowContentBlock {\r\n kind: ContentBlockKind;\r\n preview: string;\r\n tool_name: string | null;\r\n}\r\n\r\nexport interface WorkflowContainerNode {\r\n container_id: string;\r\n scope: WorkflowContainerScope;\r\n workflow_path: string;\r\n workflow_depth: number;\r\n scope_key: string;\r\n title: string;\r\n subtitle: string;\r\n status: WorkflowContainerStatus;\r\n pattern: string;\r\n parent_container_id: string | null;\r\n display: WorkflowDisplayPayload | null;\r\n content_blocks: WorkflowContentBlock[];\r\n is_open: boolean;\r\n}\r\n\r\nexport interface WorkflowContainerTreeSnapshot {\r\n root_container_ids: string[];\r\n containers: Record<string, WorkflowContainerNode>;\r\n active_container_ids: string[];\r\n}\r\n\r\n/** reducer 运行时节点:投影字段 + loop 绑定(P1) */\r\nexport interface WorkflowContainerRuntimeNode extends WorkflowContainerNode {\r\n loopSessionId: string | null;\r\n}\r\n\r\n/** WorkflowSession 容器树 state(P1+) */\r\nexport interface WorkflowContainerTreeState {\r\n rootContainerIds: string[];\r\n activeContainerIds: string[];\r\n containersById: Record<string, WorkflowContainerRuntimeNode>;\r\n}\r\n\r\nexport function createEmptyWorkflowContainerTreeState(): WorkflowContainerTreeState {\r\n return {\r\n rootContainerIds: [],\r\n activeContainerIds: [],\r\n containersById: {},\r\n };\r\n}\r\n\r\nexport function containerTreeToSnapshot(\r\n tree: WorkflowContainerTreeState,\r\n): WorkflowContainerTreeSnapshot {\r\n const containers: Record<string, WorkflowContainerNode> = {};\r\n for (const [id, node] of Object.entries(tree.containersById)) {\r\n const { loopSessionId: _loop, ...projection } = node;\r\n containers[id] = projection;\r\n }\r\n return {\r\n root_container_ids: [...tree.rootContainerIds],\r\n active_container_ids: [...tree.activeContainerIds],\r\n containers,\r\n };\r\n}\r\n\r\nexport type ContainerAction = 'open' | 'close' | 'append-content';\r\n\r\n/** SDK fixture expected.containers 子集(契约对照) */\r\nexport interface WorkflowContainerExpectedNode {\r\n title: string;\r\n subtitle: string;\r\n status: WorkflowContainerStatus;\r\n scope: WorkflowContainerScope;\r\n parent_container_id: string | null;\r\n content_blocks: WorkflowContentBlock[];\r\n}\r\n\r\nexport interface SdkContainerFixtureExpected {\r\n root_container_ids: string[];\r\n active_container_ids: string[];\r\n containers: Record<string, WorkflowContainerExpectedNode>;\r\n cli_tree_contains?: string[];\r\n}\r\n\r\nexport interface SdkContainerFixture {\r\n scenario: string;\r\n description?: string;\r\n events: Array<{\r\n event_type: string;\r\n data: Record<string, unknown>;\r\n step_index?: number | null;\r\n tool_name?: string | null;\r\n session_id?: string | null;\r\n timestamp?: number;\r\n }>;\r\n expected: SdkContainerFixtureExpected;\r\n}\r\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, type SessionStatus } from '../../types/tree';\n\n/** scoped loop 是否仍在写入(结构帧可能早于 agent 结束)。 */\nexport function isWorkflowLoopTreeActive(tree?: SessionTree): boolean {\n return tree?.status === 'running' || tree?.status === 'connecting';\n}\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/** stage-done 等结构关闭时,将仍 running 的 scoped loop 树收口(Spinner / done 摘要)。 */\nexport function finalizeWorkflowLoopTree(\n tree: SessionTree,\n terminalStatus: Extract<SessionStatus, 'done' | 'error'> = 'done',\n): SessionTree {\n if (tree.status === 'done' || tree.status === 'error') {\n return tree;\n }\n\n const byId = { ...tree.byId };\n for (const [id, node] of Object.entries(byId)) {\n if (!node) continue;\n if (\n (node.kind === 'text' || node.kind === 'reasoning')\n && node.status === 'streaming'\n ) {\n byId[id] = { ...node, status: 'done' };\n }\n if (node.kind === 'tool_call' && node.status === 'running') {\n byId[id] = {\n ...node,\n status: terminalStatus === 'error' ? 'failed' : 'done',\n };\n }\n }\n\n return {\n ...tree,\n byId,\n activeRoundId: null,\n status: terminalStatus,\n };\n}\n","/**\r\n * stageDoneSummary.ts — Stage 完成摘要(对齐 CC Agent Done 行)\r\n *\r\n * 职责:\r\n * 从 scoped loop tree 统计 tool uses / duration / agent turn;提取 text teaser。\r\n *\r\n * 链路位置:\r\n * WorkflowStageContainer 完成态显示(P2+)。\r\n *\r\n * 当前裁剪范围:\r\n * 不含 React;仅纯函数统计。\r\n */\r\nimport type { SessionTree } from '../../types/tree';\r\n\r\nexport interface StageDoneSummary {\r\n label: string;\r\n teaser: string;\r\n extraLines: number;\r\n}\r\n\r\nfunction countToolUses(tree: SessionTree): number {\r\n return Object.values(tree.byId).filter((node) => node.kind === 'tool_call').length;\r\n}\r\n\r\nfunction computeDurationSeconds(tree: SessionTree): number | null {\r\n const started = tree.meta.startedAt;\r\n if (started == null) return null;\r\n\r\n let maxTs = started;\r\n for (const node of Object.values(tree.byId)) {\r\n if ('endedAt' in node && typeof node.endedAt === 'number') {\r\n maxTs = Math.max(maxTs, node.endedAt);\r\n }\r\n if ('startedAt' in node && typeof node.startedAt === 'number') {\r\n maxTs = Math.max(maxTs, node.startedAt);\r\n }\r\n }\r\n\r\n const seconds = Math.round((maxTs - started) / 1000);\r\n return seconds > 0 ? seconds : null;\r\n}\r\n\r\nfunction lastTextContent(tree: SessionTree): string {\r\n const textNodes = Object.values(tree.byId).filter((node) => node.kind === 'text');\r\n if (textNodes.length === 0) return '';\r\n return textNodes[textNodes.length - 1]!.accumulated.trim();\r\n}\r\n\r\n/** 从 loop tree 构建 Stage Done 摘要 + 首行 teaser(非 display.description)。 */\r\nexport function buildStageDoneSummary(tree: SessionTree): StageDoneSummary | null {\r\n if (tree.status !== 'done' && tree.status !== 'error') return null;\r\n\r\n const toolUses = countToolUses(tree);\r\n const duration = computeDurationSeconds(tree);\r\n const durationSuffix = duration != null ? ` · ${duration}s` : '';\r\n\r\n const label =\r\n toolUses > 0\r\n ? `Done (${toolUses} tool use${toolUses === 1 ? '' : 's'}${durationSuffix})`\r\n : `Done (1 agent turn${durationSuffix})`;\r\n\r\n const fullText = lastTextContent(tree);\r\n const lines = fullText.split('\\n').map((line) => line.trim()).filter(Boolean);\r\n const teaser = lines[0] ?? '';\r\n const extraLines = Math.max(0, lines.length - 1);\r\n\r\n return { label, teaser, extraLines };\r\n}\r\n\r\nexport function formatTeaserExpandHint(extraLines: number, verbose: boolean): string | null {\r\n if (extraLines <= 0) return null;\r\n const shown = verbose ? Math.min(extraLines, 2) : 0;\r\n const hidden = extraLines - shown;\r\n if (hidden <= 0) return null;\r\n return `… +${hidden} lines (ctrl+o to expand)`;\r\n}\r\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 hasRunningParallelSibling(\n node: WorkflowContainerRuntimeNode,\n tree: WorkflowContainerTreeState,\n): boolean {\n if (node.scope !== 'item' || !node.parent_container_id) return false;\n for (const sibling of Object.values(tree.containersById)) {\n if (sibling.container_id === node.container_id) continue;\n if (sibling.scope !== 'item') continue;\n if (sibling.parent_container_id !== node.parent_container_id) continue;\n if (sibling.status === 'running' || sibling.status === 'retrying') return true;\n }\n return false;\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 // 并行组内 sibling 仍 running 时,保留已完成 item 的 loop 树(避免只见 teaser 不见 tool)\n if (\n (node.status === 'completed' || node.status === 'failed')\n && hasRunningParallelSibling(node, state.containerTree)\n ) {\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 candidateEvictIds = state.hotCompletedLoopSessionIds.slice(0, overflow);\n let 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 candidateEvictIds) {\n const tree = nextLoops[id];\n if (!tree) continue;\n const container = byLoop.get(id);\n // 并行 sibling 仍 running 时不淘汰已完成 item 的 loop(与 evictInactiveLoopTrees 同构)\n if (\n container\n && hasRunningParallelSibling(container, state.containerTree)\n ) {\n if (!trimmedIds.includes(id)) {\n trimmedIds = [id, ...trimmedIds];\n }\n continue;\n }\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","/**\r\n * workflowDisplay.ts — SDK WorkflowDisplayPayload 契约(TS)\r\n *\r\n * 职责:\r\n * 对齐 langchain_agentx WorkflowDisplayPayload;结构事件 data.display 类型。\r\n *\r\n * 链路位置:\r\n * workflowContainerProjector → WorkflowChrome(P2+)。\r\n *\r\n * 当前裁剪范围:\r\n * 只读消费;不计算 display(由 SDK enricher 注入)。\r\n */\r\n\r\nexport type WorkflowDisplayScope =\r\n | 'workflow'\r\n | 'stage'\r\n | 'item'\r\n | 'branch'\r\n | 'aggregate'\r\n | 'subworkflow';\r\n\r\nexport type WorkflowDisplayStatus =\r\n | 'pending'\r\n | 'running'\r\n | 'completed'\r\n | 'failed'\r\n | 'skipped'\r\n | 'cancelled'\r\n | 'blocked'\r\n | 'retrying';\r\n\r\n/** 对齐 SDK display_resolver.WorkflowDisplayPayload */\r\nexport interface WorkflowDisplayPayload {\r\n version?: number;\r\n scope?: WorkflowDisplayScope;\r\n title?: string;\r\n description?: string;\r\n workflow_title?: string;\r\n workflow_description?: string;\r\n parent_title?: string;\r\n breadcrumb?: string[];\r\n progress_current?: number;\r\n progress_total?: number;\r\n progress_label?: string;\r\n progress_indeterminate?: boolean;\r\n status?: WorkflowDisplayStatus;\r\n status_reason?: string;\r\n icon?: string;\r\n item_index?: number;\r\n item_total?: number;\r\n metrics_completed?: number;\r\n metrics_running?: number;\r\n metrics_failed?: number;\r\n metrics_total?: number;\r\n decision_label?: string;\r\n pattern?: string;\r\n debug_key?: string;\r\n}\r\n\r\nexport function readDisplayPayload(data: Record<string, unknown>): WorkflowDisplayPayload | null {\r\n const display = data.display;\r\n if (display != null && typeof display === 'object' && !Array.isArray(display)) {\r\n return display as WorkflowDisplayPayload;\r\n }\r\n return null;\r\n}\r\n","/**\r\n * workflowContainerProjector.ts — LangchainAgentEvent → 容器树投影\r\n *\r\n * 职责:\r\n * 对齐 SDK workflow_container_projector;维护 active set;正文路由。\r\n *\r\n * 链路位置:\r\n * workflowReducer(P1)← consume LangchainAgentEvent;fixture 单测 SSOT。\r\n *\r\n * 当前裁剪范围:\r\n * 仅投影层;不负责 React 渲染或 loop tree reduceTree。\r\n */\r\nimport type { LangchainAgentEvent } from '../../types/events';\r\nimport { readDisplayPayload } from '../../types/workflowDisplay';\r\nimport type {\r\n ContainerAction,\r\n WorkflowContainerNode,\r\n WorkflowContainerScope,\r\n WorkflowContainerStatus,\r\n WorkflowContainerTreeSnapshot,\r\n WorkflowContentBlock,\r\n} from '../../types/workflowContainer';\r\n\r\nconst OPEN_EVENT_TYPES = new Set<string>([\r\n 'workflow-start',\r\n 'subworkflow-start',\r\n 'stage-start',\r\n 'parallel-item-start',\r\n 'parallel-aggregate-start',\r\n 'route-branch-start',\r\n]);\r\n\r\nconst CLOSE_EVENT_TYPES = new Set<string>([\r\n 'workflow-end',\r\n 'workflow-failed',\r\n 'subworkflow-end',\r\n 'stage-done',\r\n 'stage-failed',\r\n 'parallel-item-done',\r\n 'parallel-item-failed',\r\n 'parallel-aggregate-done',\r\n 'parallel-aggregate-failed',\r\n 'route-branch-done',\r\n 'route-branch-failed',\r\n]);\r\n\r\nconst EVENT_TYPE_TO_SCOPE: Record<string, WorkflowContainerScope> = {\r\n 'workflow-start': 'workflow',\r\n 'workflow-end': 'workflow',\r\n 'workflow-failed': 'workflow',\r\n 'subworkflow-start': 'subworkflow',\r\n 'subworkflow-end': 'subworkflow',\r\n 'stage-start': 'stage',\r\n 'stage-done': 'stage',\r\n 'stage-failed': 'stage',\r\n 'parallel-item-start': 'item',\r\n 'parallel-item-done': 'item',\r\n 'parallel-item-failed': 'item',\r\n 'parallel-aggregate-start': 'aggregate',\r\n 'parallel-aggregate-done': 'aggregate',\r\n 'parallel-aggregate-failed': 'aggregate',\r\n 'route-branch-start': 'branch',\r\n 'route-branch-done': 'branch',\r\n 'route-branch-failed': 'branch',\r\n};\r\n\r\nconst CONTENT_EVENT_TYPES = new Set<string>([\r\n 'reasoning-start',\r\n 'reasoning-delta',\r\n 'reasoning-end',\r\n 'text-start',\r\n 'text-delta',\r\n 'text-end',\r\n 'tool-input',\r\n 'tool-input-start',\r\n 'tool-input-delta',\r\n 'tool-call',\r\n 'tool-result',\r\n 'tool-error',\r\n 'tool-progress',\r\n]);\r\n\r\nconst SCOPE_PRIORITY: Record<WorkflowContainerScope, number> = {\r\n workflow: 0,\r\n subworkflow: 1,\r\n aggregate: 2,\r\n stage: 3,\r\n item: 3,\r\n branch: 3,\r\n};\r\n\r\nconst FAILED_CLOSE_TYPES = new Set<string>([\r\n 'workflow-failed',\r\n 'stage-failed',\r\n 'parallel-item-failed',\r\n 'parallel-aggregate-failed',\r\n 'route-branch-failed',\r\n]);\r\n\r\nexport function buildContainerId(\r\n workflowPath: string,\r\n scope: WorkflowContainerScope,\r\n scopeKey: string,\r\n): string {\r\n return `${workflowPath}|${scope}:${scopeKey}`;\r\n}\r\n\r\nfunction readString(data: Record<string, unknown>, key: string): string | undefined {\r\n const value = data[key];\r\n return typeof value === 'string' ? value : undefined;\r\n}\r\n\r\nexport function resolveScopeKey(eventType: string, data: Record<string, unknown>): string {\r\n if (\r\n eventType === 'workflow-start'\r\n || eventType === 'workflow-end'\r\n || eventType === 'workflow-failed'\r\n ) {\r\n const workflowId = readString(data, 'workflow_id');\r\n if (workflowId) return workflowId;\r\n return readString(data, 'workflow_path') ?? 'workflow';\r\n }\r\n\r\n if (eventType === 'subworkflow-start' || eventType === 'subworkflow-end') {\r\n return readString(data, 'child_workflow_id') ?? 'subworkflow';\r\n }\r\n\r\n if (\r\n eventType === 'stage-start'\r\n || eventType === 'stage-done'\r\n || eventType === 'stage-failed'\r\n ) {\r\n const stageKey = readString(data, 'stage_key');\r\n if (stageKey) return stageKey;\r\n const stageIndex = data.stage_index;\r\n return typeof stageIndex === 'number' ? String(stageIndex) : 'stage';\r\n }\r\n\r\n if (\r\n eventType === 'parallel-item-start'\r\n || eventType === 'parallel-item-done'\r\n || eventType === 'parallel-item-failed'\r\n ) {\r\n const itemKey = readString(data, 'item_key');\r\n if (itemKey) return itemKey;\r\n const itemIndex = data.item_index;\r\n return typeof itemIndex === 'number' ? String(itemIndex) : 'item';\r\n }\r\n\r\n if (\r\n eventType === 'parallel-aggregate-start'\r\n || eventType === 'parallel-aggregate-done'\r\n || eventType === 'parallel-aggregate-failed'\r\n ) {\r\n return readString(data, 'aggregate_key') ?? 'aggregate';\r\n }\r\n\r\n if (\r\n eventType === 'route-branch-start'\r\n || eventType === 'route-branch-done'\r\n || eventType === 'route-branch-failed'\r\n ) {\r\n return readString(data, 'branch_key') ?? readString(data, 'branch_node') ?? 'branch';\r\n }\r\n\r\n const display = readDisplayPayload(data);\r\n if (display?.debug_key) return display.debug_key;\r\n\r\n return 'unknown';\r\n}\r\n\r\nfunction displayStatus(\r\n data: Record<string, unknown>,\r\n fallback: WorkflowContainerStatus,\r\n): WorkflowContainerStatus {\r\n const display = readDisplayPayload(data);\r\n if (display?.status) return display.status;\r\n return fallback;\r\n}\r\n\r\nfunction closeStatus(eventType: string): WorkflowContainerStatus {\r\n return FAILED_CLOSE_TYPES.has(eventType) ? 'failed' : 'completed';\r\n}\r\n\r\nfunction readPreview(data: Record<string, unknown>, ...keys: string[]): string {\r\n for (const key of keys) {\r\n const value = data[key];\r\n if (typeof value === 'string') return value;\r\n }\r\n return '';\r\n}\r\n\r\nfunction contentBlockFromEvent(event: LangchainAgentEvent): WorkflowContentBlock | null {\r\n const { event_type: eventType } = event;\r\n const payload = (event.data ?? {}) as Record<string, unknown>;\r\n\r\n if (\r\n eventType === 'reasoning-start'\r\n || eventType === 'reasoning-delta'\r\n || eventType === 'reasoning-end'\r\n ) {\r\n let preview = readPreview(payload, 'delta', 'text', 'reasoning');\r\n if (!preview && eventType === 'reasoning-start') preview = 'Thinking…';\r\n return { kind: 'reasoning', preview, tool_name: null };\r\n }\r\n\r\n if (\r\n eventType === 'text-start'\r\n || eventType === 'text-delta'\r\n || eventType === 'text-end'\r\n ) {\r\n const preview = readPreview(payload, 'delta', 'text');\r\n return { kind: 'text', preview, tool_name: null };\r\n }\r\n\r\n if (CONTENT_EVENT_TYPES.has(eventType)) {\r\n const toolName = event.tool_name ?? readString(payload, 'tool_name');\r\n const preview =\r\n readPreview(payload, 'summary', 'output', 'input', 'delta')\r\n || toolName\r\n || eventType;\r\n return {\r\n kind: 'tool',\r\n preview,\r\n tool_name: toolName ?? null,\r\n };\r\n }\r\n\r\n return null;\r\n}\r\n\r\nexport function resolveContentScopeKey(data: Record<string, unknown>): string | null {\r\n for (const keyName of ['stage_key', 'item_key', 'branch_key', 'aggregate_key', 'debug_key'] as const) {\r\n const value = readString(data, keyName);\r\n if (value) return value;\r\n }\r\n const display = readDisplayPayload(data);\r\n return display?.debug_key ?? null;\r\n}\r\n\r\n/** 按容器身份索引的活跃集(并发 item 不依赖 LIFO 单栈) */\r\nexport class WorkflowContainerActiveSet {\r\n private readonly openOrder: string[] = [];\r\n private readonly nodes: Record<string, WorkflowContainerNode> = {};\r\n\r\n restoreNode(node: WorkflowContainerNode): void {\r\n this.nodes[node.container_id] = { ...node };\r\n if (node.is_open && !this.openOrder.includes(node.container_id)) {\r\n this.openOrder.push(node.container_id);\r\n }\r\n }\r\n\r\n open(node: WorkflowContainerNode): void {\r\n this.nodes[node.container_id] = node;\r\n if (!this.openOrder.includes(node.container_id)) {\r\n this.openOrder.push(node.container_id);\r\n }\r\n }\r\n\r\n close(containerId: string, status: WorkflowContainerStatus): void {\r\n const node = this.nodes[containerId];\r\n if (!node) return;\r\n node.status = status;\r\n node.is_open = false;\r\n const idx = this.openOrder.indexOf(containerId);\r\n if (idx !== -1) this.openOrder.splice(idx, 1);\r\n }\r\n\r\n get activeIds(): string[] {\r\n return [...this.openOrder];\r\n }\r\n\r\n getNode(containerId: string): WorkflowContainerNode | undefined {\r\n return this.nodes[containerId];\r\n }\r\n\r\n get nodesById(): Record<string, WorkflowContainerNode> {\r\n return this.nodes;\r\n }\r\n\r\n rankContainer(containerId: string): [number, number, number, number] {\r\n const node = this.nodes[containerId];\r\n if (!node) return [-1, -1, -1, -1];\r\n const openIndex = this.openOrder.indexOf(containerId);\r\n const scopePriority = SCOPE_PRIORITY[node.scope] ?? 0;\r\n return [node.workflow_depth, scopePriority, node.workflow_path.length, openIndex];\r\n }\r\n\r\n deepestActive(): string | null {\r\n if (this.openOrder.length === 0) return null;\r\n return this.openOrder.reduce((best, cid) =>\r\n this.compareRank(cid, best) > 0 ? cid : best,\r\n );\r\n }\r\n\r\n resolveContentTarget(workflowPath: string | null, scopeKey: string | null): string | null {\r\n if (scopeKey) {\r\n for (let i = this.openOrder.length - 1; i >= 0; i -= 1) {\r\n const containerId = this.openOrder[i]!;\r\n const node = this.nodes[containerId]!;\r\n if (node.scope_key === scopeKey && node.is_open) {\r\n if (workflowPath === null || node.workflow_path === workflowPath) {\r\n return containerId;\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (workflowPath) {\r\n const candidates = this.openOrder.filter((cid) => {\r\n const node = this.nodes[cid]!;\r\n if (!node.is_open) return false;\r\n return (\r\n node.workflow_path === workflowPath\r\n || workflowPath.startsWith(`${node.workflow_path}>`)\r\n );\r\n });\r\n if (candidates.length > 0) {\r\n return candidates.reduce((best, cid) =>\r\n this.compareRank(cid, best) > 0 ? cid : best,\r\n );\r\n }\r\n }\r\n\r\n return this.deepestActive();\r\n }\r\n\r\n closeDescendantsOfPath(workflowPath: string, status: WorkflowContainerStatus): void {\r\n const toClose = this.openOrder.filter((cid) => {\r\n const node = this.nodes[cid]!;\r\n return (\r\n node.workflow_path === workflowPath\r\n || node.workflow_path.startsWith(`${workflowPath}>`)\r\n );\r\n });\r\n for (const containerId of toClose) {\r\n this.close(containerId, status);\r\n }\r\n }\r\n\r\n private compareRank(a: string, b: string): number {\r\n const ra = this.rankContainer(a);\r\n const rb = this.rankContainer(b);\r\n for (let i = 0; i < ra.length; i += 1) {\r\n if (ra[i]! > rb[i]!) return 1;\r\n if (ra[i]! < rb[i]!) return -1;\r\n }\r\n return 0;\r\n }\r\n\r\n /** 供 StateMachine 比较容器深度 rank */\r\n compareContainerRank(a: string, b: string): number {\r\n return this.compareRank(a, b);\r\n }\r\n}\r\n\r\n/** 事件 → 容器状态机(对齐 SDK reference) */\r\nexport class WorkflowContainerStateMachine {\r\n private readonly active = new WorkflowContainerActiveSet();\r\n private readonly rootIds: string[] = [];\r\n private suppressContentContainerIds: ReadonlySet<string> = new Set();\r\n\r\n get activeSet(): WorkflowContainerActiveSet {\r\n return this.active;\r\n }\r\n\r\n setSuppressContentContainerIds(ids: ReadonlySet<string>): void {\r\n this.suppressContentContainerIds = ids;\r\n }\r\n\r\n rehydrate(snapshot: WorkflowContainerTreeSnapshot): void {\r\n this.rootIds.length = 0;\r\n this.rootIds.push(...snapshot.root_container_ids);\r\n for (const node of Object.values(snapshot.containers)) {\r\n this.active.restoreNode(node);\r\n }\r\n }\r\n\r\n apply(event: LangchainAgentEvent): ContainerAction | null {\r\n const eventType = event.event_type;\r\n const data = (event.data ?? {}) as Record<string, unknown>;\r\n\r\n if (OPEN_EVENT_TYPES.has(eventType)) {\r\n this.openContainer(eventType, data);\r\n return 'open';\r\n }\r\n\r\n if (CLOSE_EVENT_TYPES.has(eventType)) {\r\n this.closeContainer(eventType, data);\r\n return 'close';\r\n }\r\n\r\n if (CONTENT_EVENT_TYPES.has(eventType)) {\r\n this.appendContent(event);\r\n return 'append-content';\r\n }\r\n\r\n return null;\r\n }\r\n\r\n snapshot(): WorkflowContainerTreeSnapshot {\r\n return {\r\n root_container_ids: [...this.rootIds],\r\n containers: { ...this.active.nodesById },\r\n active_container_ids: this.active.activeIds,\r\n };\r\n }\r\n\r\n private openContainer(eventType: string, data: Record<string, unknown>): void {\r\n const scope = EVENT_TYPE_TO_SCOPE[eventType];\r\n if (!scope) return;\r\n\r\n const workflowPath = readString(data, 'workflow_path') ?? '';\r\n const workflowDepth =\r\n typeof data.workflow_depth === 'number' ? data.workflow_depth : 0;\r\n const scopeKey = resolveScopeKey(eventType, data);\r\n const containerId = buildContainerId(workflowPath, scope, scopeKey);\r\n\r\n const display = readDisplayPayload(data);\r\n const title = display?.title ?? scopeKey;\r\n const subtitle = display?.description ?? '';\r\n const pattern = display?.pattern ?? '';\r\n const status = displayStatus(data, 'running');\r\n const parentId = this.resolveParentId(workflowPath, scope);\r\n\r\n const node: WorkflowContainerNode = {\r\n container_id: containerId,\r\n scope,\r\n workflow_path: workflowPath,\r\n workflow_depth: workflowDepth,\r\n scope_key: scopeKey,\r\n title,\r\n subtitle,\r\n status,\r\n pattern,\r\n parent_container_id: parentId,\r\n display,\r\n content_blocks: [],\r\n is_open: true,\r\n };\r\n\r\n this.active.open(node);\r\n if (scope === 'workflow' && !this.rootIds.includes(containerId)) {\r\n this.rootIds.push(containerId);\r\n }\r\n }\r\n\r\n private closeContainer(eventType: string, data: Record<string, unknown>): void {\r\n const scope = EVENT_TYPE_TO_SCOPE[eventType];\r\n if (!scope) return;\r\n\r\n const workflowPath = readString(data, 'workflow_path') ?? '';\r\n const scopeKey = resolveScopeKey(eventType, data);\r\n const containerId = buildContainerId(workflowPath, scope, scopeKey);\r\n const status = displayStatus(data, closeStatus(eventType));\r\n\r\n this.active.close(containerId, status);\r\n if (scope === 'workflow') {\r\n this.active.closeDescendantsOfPath(workflowPath, status);\r\n }\r\n }\r\n\r\n private appendContent(event: LangchainAgentEvent): void {\r\n const data = (event.data ?? {}) as Record<string, unknown>;\r\n const workflowPath = readString(data, 'workflow_path') ?? null;\r\n const scopeKey = resolveContentScopeKey(data);\r\n\r\n const targetId = this.active.resolveContentTarget(workflowPath, scopeKey);\r\n if (!targetId) return;\r\n if (this.suppressContentContainerIds.has(targetId)) return;\r\n\r\n const block = contentBlockFromEvent(event);\r\n if (!block) return;\r\n\r\n const node = this.active.getNode(targetId);\r\n if (!node) return;\r\n\r\n const last = node.content_blocks[node.content_blocks.length - 1];\r\n if (\r\n last\r\n && last.kind === block.kind\r\n && (block.kind === 'reasoning' || block.kind === 'text')\r\n ) {\r\n if (block.preview) {\r\n if (block.kind === 'reasoning' && last.preview === 'Thinking…') {\r\n last.preview = block.preview;\r\n } else {\r\n last.preview = `${last.preview}${block.preview}`;\r\n }\r\n }\r\n return;\r\n }\r\n\r\n node.content_blocks.push(block);\r\n }\r\n\r\n private resolveParentId(\r\n workflowPath: string,\r\n scope: WorkflowContainerScope,\r\n ): string | null {\r\n if (scope === 'workflow') return null;\r\n\r\n const openNodes = this.active.activeIds\r\n .map((cid) => this.active.getNode(cid)!)\r\n .filter((node) => node.is_open);\r\n\r\n if (openNodes.length === 0) return null;\r\n\r\n const prefixCandidates = openNodes.filter(\r\n (node) =>\r\n workflowPath === node.workflow_path\r\n || workflowPath.startsWith(`${node.workflow_path}>`),\r\n );\r\n\r\n if (prefixCandidates.length > 0) {\r\n const parentCandidates = prefixCandidates.filter((node) => {\r\n // 并行 item 不应挂到已打开的 sibling item 下;否则第二路会误落到 workflow 根。\r\n if (scope === 'item') return node.scope !== 'item';\r\n if (scope === 'aggregate') return node.scope !== 'item' && node.scope !== 'aggregate';\r\n return node.scope !== scope;\r\n });\r\n if (parentCandidates.length > 0) {\r\n const parent = parentCandidates.reduce((best, node) =>\r\n this.active.compareContainerRank(node.container_id, best.container_id) > 0\r\n ? node\r\n : best,\r\n );\r\n if (parent.workflow_path === workflowPath && parent.scope === 'workflow') {\r\n return parent.container_id;\r\n }\r\n if (workflowPath.startsWith(`${parent.workflow_path}>`)) {\r\n return parent.container_id;\r\n }\r\n if (parent.workflow_path === workflowPath && parent.scope !== scope) {\r\n return parent.container_id;\r\n }\r\n }\r\n }\r\n\r\n const workflowCandidates = openNodes.filter((node) => node.scope === 'workflow');\r\n if (workflowCandidates.length > 0) {\r\n return workflowCandidates.reduce((best, node) =>\r\n this.active.compareContainerRank(node.container_id, best.container_id) > 0\r\n ? node\r\n : best,\r\n ).container_id;\r\n }\r\n\r\n return openNodes.reduce((best, node) =>\r\n this.active.compareContainerRank(node.container_id, best.container_id) > 0\r\n ? node\r\n : best,\r\n ).container_id;\r\n }\r\n}\r\n\r\n/** LangchainAgentEvent 流 → 容器树快照 */\r\nexport class WorkflowContainerTreeProjector {\r\n private readonly machine = new WorkflowContainerStateMachine();\r\n\r\n rehydrate(snapshot: WorkflowContainerTreeSnapshot): void {\r\n this.machine.rehydrate(snapshot);\r\n }\r\n\r\n setSuppressContentContainerIds(ids: ReadonlySet<string>): void {\r\n this.machine.setSuppressContentContainerIds(ids);\r\n }\r\n\r\n consume(event: LangchainAgentEvent): ContainerAction | null {\r\n return this.machine.apply(event);\r\n }\r\n\r\n consumeAll(events: LangchainAgentEvent[]): WorkflowContainerTreeSnapshot {\r\n for (const event of events) {\r\n this.consume(event);\r\n }\r\n return this.snapshot();\r\n }\r\n\r\n snapshot(): WorkflowContainerTreeSnapshot {\r\n return this.machine.snapshot();\r\n }\r\n}\r\n\r\n/** 纯函数:快照 + 单事件 → 新快照(供 workflowReducer 双轨归约) */\r\nexport interface ReduceContainerSnapshotOptions {\r\n /** 已绑定 loop 的容器不再写入 content_blocks(过程层走 AgentLoopView) */\r\n suppressContentContainerIds?: ReadonlySet<string>;\r\n}\r\n\r\nexport function reduceContainerSnapshot(\r\n snapshot: WorkflowContainerTreeSnapshot,\r\n event: LangchainAgentEvent,\r\n options?: ReduceContainerSnapshotOptions,\r\n): WorkflowContainerTreeSnapshot {\r\n const projector = new WorkflowContainerTreeProjector();\r\n projector.rehydrate(snapshot);\r\n if (options?.suppressContentContainerIds?.size) {\r\n projector.setSuppressContentContainerIds(options.suppressContentContainerIds);\r\n }\r\n projector.consume(event);\r\n return projector.snapshot();\r\n}\r\n\r\n/** 从 open 容器集解析 agent 正文路由目标 */\r\nexport function resolveContentTargetFromSnapshot(\r\n snapshot: WorkflowContainerTreeSnapshot,\r\n workflowPath: string | null,\r\n scopeKey: string | null,\r\n): string | null {\r\n const active = new WorkflowContainerActiveSet();\r\n for (const containerId of snapshot.active_container_ids) {\r\n const node = snapshot.containers[containerId];\r\n if (node?.is_open) active.restoreNode(node);\r\n }\r\n return active.resolveContentTarget(workflowPath, scopeKey);\r\n}\r\n\r\n/** 投影快照合并 loopSessionId(projector 不管理 loop 绑定) */\r\nexport function mergeRuntimeContainerNodes(\r\n prev: Record<string, { loopSessionId: string | null }>,\r\n snapshot: WorkflowContainerTreeSnapshot,\r\n): Record<\r\n string,\r\n WorkflowContainerNode & { loopSessionId: string | null }\r\n> {\r\n const out: Record<string, WorkflowContainerNode & { loopSessionId: string | null }> = {};\r\n for (const [containerId, node] of Object.entries(snapshot.containers)) {\r\n out[containerId] = {\r\n ...node,\r\n loopSessionId: prev[containerId]?.loopSessionId ?? null,\r\n };\r\n }\r\n return out;\r\n}\r\n\r\n/** 序列化为 SDK fixture expected 对照结构 */\r\nexport function snapshotToExpectedFormat(\r\n snapshot: WorkflowContainerTreeSnapshot,\r\n): {\r\n root_container_ids: string[];\r\n active_container_ids: string[];\r\n containers: Record<\r\n string,\r\n {\r\n title: string;\r\n subtitle: string;\r\n status: WorkflowContainerStatus;\r\n scope: WorkflowContainerScope;\r\n parent_container_id: string | null;\r\n content_blocks: WorkflowContentBlock[];\r\n }\r\n >;\r\n} {\r\n const containers: Record<\r\n string,\r\n {\r\n title: string;\r\n subtitle: string;\r\n status: WorkflowContainerStatus;\r\n scope: WorkflowContainerScope;\r\n parent_container_id: string | null;\r\n content_blocks: WorkflowContentBlock[];\r\n }\r\n > = {};\r\n\r\n for (const [cid, node] of Object.entries(snapshot.containers)) {\r\n containers[cid] = {\r\n title: node.title,\r\n subtitle: node.subtitle,\r\n status: node.status,\r\n scope: node.scope,\r\n parent_container_id: node.parent_container_id,\r\n content_blocks: node.content_blocks.map((b) => ({\r\n kind: b.kind,\r\n preview: b.preview,\r\n tool_name: b.tool_name,\r\n })),\r\n };\r\n }\r\n\r\n return {\r\n root_container_ids: snapshot.root_container_ids,\r\n active_container_ids: snapshot.active_container_ids,\r\n containers,\r\n };\r\n}\r\n\r\nexport type {\r\n WorkflowContainerNode,\r\n WorkflowContainerTreeSnapshot,\r\n WorkflowContentBlock,\r\n ContainerAction,\r\n};\r\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 'parallel-aggregate-start': 'aggregate',\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 ?? readString(data, 'aggregate_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","/**\r\n * workflowStructureEvents.ts — Workflow 结构事件类型守卫\r\n *\r\n * 职责:\r\n * 区分 workflow 编排结构 event_type 与 agent loop 事件。\r\n *\r\n * 链路位置:\r\n * workflowReducer 路由 · hydrateLoopSession 过滤 · Source application_kind 守卫。\r\n *\r\n * 当前裁剪范围:\r\n * 显式集合与 backend sse.WORKFLOW_STRUCTURE_EVENT_TYPES 对齐;\r\n * 识别逻辑另用前缀(与 task_sync/multi_sse_bridge.py 一致),避免 SDK 新增结构类型漏判。\r\n */\r\nimport { DEFAULT_EVENT_TIERS } from '../types/events';\r\n\r\n/** 与 backend/langchain_agentx_stream_ui_backend/task_sync/multi_sse_bridge.py 对齐 */\r\nexport const WORKFLOW_STRUCTURE_EVENT_PREFIXES: readonly string[] = [\r\n 'workflow-',\r\n 'stage-',\r\n 'parallel-',\r\n 'route-',\r\n 'subworkflow-',\r\n];\r\n\r\n/** 显式 SSOT(文档/契约测试);新增结构类型应同时满足前缀规则或补入此集合 */\r\nexport const WORKFLOW_STRUCTURE_EVENT_TYPES: ReadonlySet<string> = new Set([\r\n 'workflow-start',\r\n 'workflow-end',\r\n 'workflow-failed',\r\n 'subworkflow-start',\r\n 'subworkflow-end',\r\n 'stage-start',\r\n 'stage-done',\r\n 'stage-failed',\r\n 'parallel-item-start',\r\n 'parallel-item-done',\r\n 'parallel-item-failed',\r\n 'parallel-aggregate-start',\r\n 'parallel-aggregate-done',\r\n 'parallel-aggregate-failed',\r\n 'route-branch-start',\r\n 'route-branch-done',\r\n 'route-branch-failed',\r\n]);\r\n\r\n/** session reducer(reduceTree)可处理的 event_type 白名单 */\r\nconst AGENT_LOOP_REPLAY_EVENT_TYPES: ReadonlySet<string> = new Set(\r\n Object.keys(DEFAULT_EVENT_TIERS),\r\n);\r\n\r\nexport function isWorkflowStructureEventType(eventType: string): boolean {\r\n if (WORKFLOW_STRUCTURE_EVENT_TYPES.has(eventType)) return true;\r\n return WORKFLOW_STRUCTURE_EVENT_PREFIXES.some((prefix) => eventType.startsWith(prefix));\r\n}\r\n\r\n/** agent loop hydrate/replay 允许进入 reduceTree 的事件(正文 + state/debug tier) */\r\nexport function isAgentLoopReplayEventType(eventType: string): boolean {\r\n return AGENT_LOOP_REPLAY_EVENT_TYPES.has(eventType);\r\n}\r\n\r\n/**\r\n * hydrateLoopSession / 宿主 replay:\r\n * 1. 白名单:只保留 reduceTree 已知 event_type\r\n * 2. 结构前缀/集合:双重排除 workflow 编排帧(含 session_id 误绑的 dual emission)\r\n */\r\nexport function filterAgentLoopReplayEvents<T extends { event_type: string }>(\r\n events: T[],\r\n): T[] {\r\n return events.filter(\r\n (event) =>\r\n isAgentLoopReplayEventType(event.event_type)\r\n && !isWorkflowStructureEventType(event.event_type),\r\n );\r\n}\r\n","/**\r\n * workflowPathUtils.ts — workflow_path 分段与父子路径推导\r\n *\r\n * 多层 nested 场景(Prep → 子流并行 → Finalize)下,不得只切第一个 `>`;\r\n * 宿主 stage / 子流前缀均基于完整 segment 链推导。\r\n */\r\n\r\n/** `demo-nested>parallel_review>inner` → ['demo-nested', 'parallel_review', 'inner'] */\r\nexport function splitWorkflowPathSegments(workflowPath: string): string[] {\r\n return workflowPath.split('>').filter(Boolean);\r\n}\r\n\r\n/** 去掉末段后的父路径;单段根 workflow 返回 null。 */\r\nexport function parentWorkflowPath(workflowPath: string): string | null {\r\n const segments = splitWorkflowPathSegments(workflowPath);\r\n if (segments.length <= 1) return null;\r\n return segments.slice(0, -1).join('>');\r\n}\r\n\r\n/** 路径末段(当前嵌套 scope 名)。 */\r\nexport function lastWorkflowPathSegment(workflowPath: string): string | null {\r\n const segments = splitWorkflowPathSegments(workflowPath);\r\n return segments.length > 0 ? segments[segments.length - 1]! : null;\r\n}\r\n\r\n/** path 是否为 ancestor 的严格子路径(按 segment 前缀,避免字符串误匹配)。 */\r\nexport function isWorkflowPathUnderAncestor(\r\n workflowPath: string,\r\n ancestorPath: string,\r\n): boolean {\r\n if (workflowPath === ancestorPath) return false;\r\n const prefix = `${ancestorPath}>`;\r\n return workflowPath.startsWith(prefix);\r\n}\r\n\r\n/** path 是否在 ancestor 下(含自身)。 */\r\nexport function isWorkflowPathEqualOrUnder(\r\n workflowPath: string,\r\n ancestorPath: string,\r\n): boolean {\r\n return workflowPath === ancestorPath || isWorkflowPathUnderAncestor(workflowPath, ancestorPath);\r\n}\r\n","/**\r\n * nativeNestedUtils.ts — SDK ≥1.6.3 native nested workflow 结构检测\r\n *\r\n * 职责:\r\n * 识别 workflow_path 含 `>` 且 depth≥1 的结构事件/容器树,供 embedded 合成跳过。\r\n *\r\n * 链路位置:\r\n * embeddedSubworkflowUtils.shouldUseEmbeddedSynthesis → workflowReducer.applyStructureEvent。\r\n *\r\n * 当前裁剪范围:\r\n * 仅 D29 nested native vs embedded 分流;不含 sibling-nested 专用逻辑。\r\n */\r\nimport type { LangchainAgentEvent } from '../../types/events';\r\nimport type { WorkflowContainerTreeState } from '../../types/workflowContainer';\r\nimport { buildContainerId } from './workflowContainerProjector';\r\nimport { isWorkflowStructureEventType } from '../workflowStructureEvents';\r\nimport {\r\n isWorkflowPathEqualOrUnder,\r\n lastWorkflowPathSegment,\r\n parentWorkflowPath,\r\n splitWorkflowPathSegments,\r\n} from './workflowPathUtils';\r\n\r\nfunction readString(data: Record<string, unknown>, key: string): string | undefined {\r\n const value = data[key];\r\n return typeof value === 'string' ? value : undefined;\r\n}\r\n\r\nfunction readNumber(data: Record<string, unknown>, key: string): number | undefined {\r\n const value = data[key];\r\n return typeof value === 'number' ? value : undefined;\r\n}\r\n\r\n/** 单条结构事件是否携带 SDK native nested path(depth≥1 且 workflow_path 含 `>`)。 */\r\nexport function isNativeNestedStructureEvent(event: LangchainAgentEvent): boolean {\r\n if (!isWorkflowStructureEventType(event.event_type)) return false;\r\n const data = (event.data ?? {}) as Record<string, unknown>;\r\n const path = readString(data, 'workflow_path') ?? '';\r\n const depth = readNumber(data, 'workflow_depth') ?? 0;\r\n return depth >= 1 && path.includes('>');\r\n}\r\n\r\n/** 事件批是否含 native nested 结构 open(D29 fixture / replay 检测)。 */\r\nexport function hasNativeNestedStructureEvents(events: LangchainAgentEvent[]): boolean {\r\n return events.some((event) => isNativeNestedStructureEvent(event));\r\n}\r\n\r\n/**\r\n * 子 workflow_path 是否由「父路径 + 同名 stage」承载(native nested 典型形态)。\r\n * 例:`demo-nested>parallel_review` ↔ `demo-nested|stage:parallel_review`。\r\n * 多层:`a>b>c` ↔ `a>b|stage:c`(按完整 segment,不只切第一个 `>`)。\r\n */\r\nexport function resolveHostStageContainerId(\r\n tree: WorkflowContainerTreeState,\r\n workflowPath: string,\r\n): string | null {\r\n const parentPath = parentWorkflowPath(workflowPath);\r\n const childSegment = lastWorkflowPathSegment(workflowPath);\r\n if (!parentPath || !childSegment) return null;\r\n\r\n const stageId = buildContainerId(parentPath, 'stage', childSegment);\r\n return tree.containersById[stageId] != null ? stageId : null;\r\n}\r\n\r\nfunction isHostStageNestedChildPath(\r\n tree: WorkflowContainerTreeState,\r\n workflowPath: string,\r\n): boolean {\r\n return resolveHostStageContainerId(tree, workflowPath) != null;\r\n}\r\n\r\n/**\r\n * 容器树是否已由 SDK 投影出 native nested 路径。\r\n */\r\nexport function hasNativeNestedStructureInTree(\r\n tree: WorkflowContainerTreeState,\r\n): boolean {\r\n for (const node of Object.values(tree.containersById)) {\r\n if (node.workflow_depth < 1) continue;\r\n if (!node.workflow_path.includes('>')) continue;\r\n if (isHostStageNestedChildPath(tree, node.workflow_path)) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n}\r\n\r\nfunction clearHostStageLoopSession(\r\n tree: WorkflowContainerTreeState,\r\n hostStageId: string | null,\r\n): WorkflowContainerTreeState {\r\n if (!hostStageId) return tree;\r\n const hostStage = tree.containersById[hostStageId];\r\n if (!hostStage || hostStage.scope !== 'stage' || !hostStage.loopSessionId) return tree;\r\n\r\n return {\r\n ...tree,\r\n containersById: {\r\n ...tree.containersById,\r\n [hostStageId]: { ...hostStage, loopSessionId: null },\r\n },\r\n };\r\n}\r\n\r\n/** stage 下已有 subworkflow 容器 → 宿主 stage 仅作壳,不承载 scoped loop。 */\r\nexport function isNestedHostStageShell(\r\n tree: WorkflowContainerTreeState,\r\n stageNode: WorkflowContainerRuntimeNode,\r\n): boolean {\r\n if (stageNode.scope !== 'stage') return false;\r\n return Object.values(tree.containersById).some(\r\n (node) => node.scope === 'subworkflow' && node.parent_container_id === stageNode.container_id,\r\n );\r\n}\r\n\r\n/**\r\n * subworkflow-start / parallel-item-start:清宿主 stage 上误绑的 loopSessionId。\r\n * 内层 Agent loop 应落在 parallel item / aggregate 上。\r\n */\r\nexport function clearHostStageLoopOnNestedChildOpen(\r\n tree: WorkflowContainerTreeState,\r\n event: LangchainAgentEvent,\r\n): WorkflowContainerTreeState {\r\n const eventType = event.event_type;\r\n if (eventType !== 'subworkflow-start' && eventType !== 'parallel-item-start') return tree;\r\n\r\n const data = (event.data ?? {}) as Record<string, unknown>;\r\n const workflowPath = readString(data, 'workflow_path');\r\n if (!workflowPath) return tree;\r\n\r\n if (eventType === 'subworkflow-start') {\r\n const childWorkflowId = readString(data, 'child_workflow_id');\r\n if (!childWorkflowId) return tree;\r\n\r\n const subId = buildContainerId(workflowPath, 'subworkflow', childWorkflowId);\r\n const sub = tree.containersById[subId];\r\n const hostStageId =\r\n sub?.parent_container_id ?? resolveHostStageContainerId(tree, workflowPath);\r\n return clearHostStageLoopSession(tree, hostStageId);\r\n }\r\n\r\n return clearHostStageLoopSession(tree, resolveHostStageContainerId(tree, workflowPath));\r\n}\r\n\r\n/** @deprecated 使用 clearHostStageLoopOnNestedChildOpen */\r\nexport function clearHostStageLoopOnSubworkflowStart(\r\n tree: WorkflowContainerTreeState,\r\n event: LangchainAgentEvent,\r\n): WorkflowContainerTreeState {\r\n return clearHostStageLoopOnNestedChildOpen(tree, event);\r\n}\r\n\r\n/** native subworkflow-start 时丢弃同宿主 stage 下已过时的 embedded 合成子树。 */\r\nexport function dropStaleEmbeddedPathsOnNativeSubworkflowStart(\r\n tree: WorkflowContainerTreeState,\r\n event: LangchainAgentEvent,\r\n): WorkflowContainerTreeState {\r\n if (event.event_type !== 'subworkflow-start' || !isNativeNestedStructureEvent(event)) {\r\n return tree;\r\n }\r\n\r\n const data = (event.data ?? {}) as Record<string, unknown>;\r\n const nativeChildPath = readString(data, 'workflow_path');\r\n if (!nativeChildPath) return tree;\r\n\r\n const rootAnchor = splitWorkflowPathSegments(nativeChildPath)[0];\r\n if (!rootAnchor) return tree;\r\n\r\n let changed = false;\r\n const containersById = { ...tree.containersById };\r\n let activeContainerIds = [...tree.activeContainerIds];\r\n\r\n for (const [id, node] of Object.entries(tree.containersById)) {\r\n if (node.workflow_depth < 1) continue;\r\n if (!node.workflow_path.startsWith(`${rootAnchor}>`)) continue;\r\n if (\r\n node.workflow_path === nativeChildPath\r\n || isWorkflowPathEqualOrUnder(node.workflow_path, nativeChildPath)\r\n ) {\r\n continue;\r\n }\r\n // 保留其他合法 native 子路径(sibling-nested:stage_a / stage_b 并存)\r\n if (isHostStageNestedChildPath(tree, node.workflow_path)) continue;\r\n delete containersById[id];\r\n activeContainerIds = activeContainerIds.filter((cid) => cid !== id);\r\n changed = true;\r\n }\r\n\r\n return changed ? { ...tree, containersById, activeContainerIds } : tree;\r\n}\r\n\r","/**\r\n * embeddedSubworkflowUtils.ts — 嵌套 Parallelization 容器补全\r\n *\r\n * SDK 将 ParallelizationWorkflow 嵌入 Chaining stage 时,可能只发 stage-start\r\n *(无 subworkflow-start / parallel-item-start),loop session_id 形如\r\n * `{child_workflow_id}-{task_key}`。此处按 session_id 补全 subworkflow / item / aggregate 容器。\r\n */\r\nimport type { LangchainAgentEvent } from '../../types/events';\r\nimport { buildContainerId } from './workflowContainerProjector';\r\nimport { buildLoopSessionId } from './loopSessionUtils';\r\nimport {\r\n hasNativeNestedStructureInTree,\r\n isNativeNestedStructureEvent,\r\n} from './nativeNestedUtils';\r\nimport type {\r\n WorkflowContainerRuntimeNode,\r\n WorkflowContainerScope,\r\n WorkflowContainerTreeState,\r\n} from '../../types/workflowContainer';\r\nimport type { WorkflowSessionState } from '../../types/workflowSession';\r\n\r\nexport interface ParsedLoopSessionParts {\r\n workflowId: string;\r\n taskKey: string;\r\n}\r\n\r\n/** `{workflow_id}-{task_key}`;task_key 不含连字符(与 SDK WorkflowSessionIdPolicy 一致)。 */\r\nexport function parseLoopSessionParts(sessionId: string): ParsedLoopSessionParts | null {\r\n const trimmed = sessionId.trim();\r\n const dash = trimmed.lastIndexOf('-');\r\n if (dash <= 0 || dash >= trimmed.length - 1) return null;\r\n return {\r\n workflowId: trimmed.slice(0, dash),\r\n taskKey: trimmed.slice(dash + 1),\r\n };\r\n}\r\n\r\nexport function isEmbeddedChildLoopSession(\r\n sessionId: string,\r\n rootWorkflowId: string,\r\n): boolean {\r\n const parts = parseLoopSessionParts(sessionId);\r\n if (!parts) return false;\r\n if (parts.workflowId === rootWorkflowId) return false;\r\n // 同属根 workflow 家族(qa-review vs qa-review-pipeline)不是嵌套子流。\r\n if (parts.workflowId.startsWith(`${rootWorkflowId}-`)) return false;\r\n if (rootWorkflowId.startsWith(`${parts.workflowId}-`)) return false;\r\n // 嵌套子 workflow id 至少三段(如 demo-review-sub)。\r\n return parts.workflowId.split('-').length >= 3;\r\n}\r\n\r\nfunction readWorkflowIdFromData(data: Record<string, unknown>): string | undefined {\r\n const value = data.workflow_id;\r\n return typeof value === 'string' ? value : undefined;\r\n}\r\n\r\nfunction readStageKeyFromData(data: Record<string, unknown>): string | undefined {\r\n const value = data.stage_key;\r\n return typeof value === 'string' ? value : undefined;\r\n}\r\n\r\nexport function shouldPrebindLoopSessionFromStructureOpen(\r\n eventType: string,\r\n eventSessionId: string | null | undefined,\r\n derivedLoopSessionId: string,\r\n data: Record<string, unknown> = {},\r\n): boolean {\r\n if (!eventSessionId) return true;\r\n if (eventType !== 'stage-start') return true;\r\n if (eventSessionId === derivedLoopSessionId) return true;\r\n\r\n // 上一 stage 的 loop session_id 泄漏到容器 stage-start(嵌套 parallel_review)。\r\n const rootWorkflowId = readWorkflowIdFromData(data);\r\n const stageKey = readStageKeyFromData(data);\r\n const parsed = parseLoopSessionParts(eventSessionId);\r\n if (rootWorkflowId && stageKey && parsed) {\r\n if (parsed.workflowId === rootWorkflowId && parsed.taskKey !== stageKey) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n}\r\n\r\nfunction resolveRootWorkflow(\r\n tree: WorkflowContainerTreeState,\r\n): { workflowId: string; workflowPath: string } | null {\r\n const rootId = tree.rootContainerIds[0];\r\n if (!rootId) return null;\r\n const root = tree.containersById[rootId];\r\n if (!root || root.scope !== 'workflow') return null;\r\n return {\r\n workflowId: root.scope_key,\r\n workflowPath: root.workflow_path,\r\n };\r\n}\r\n\r\nfunction humanizeTaskTitle(taskKey: string): string {\r\n if (taskKey === 'aggregate') return 'Merge Perspectives';\r\n if (taskKey === 'architecture') return 'Architecture Path';\r\n if (taskKey === 'implementation') return 'Implementation Path';\r\n return taskKey\r\n .split('_')\r\n .map((part) => (part ? part[0]!.toUpperCase() + part.slice(1) : part))\r\n .join(' ');\r\n}\r\n\r\nfunction findEmbeddedHostStage(\r\n tree: WorkflowContainerTreeState,\r\n rootWorkflowPath: string,\r\n childWorkflowId: string,\r\n): WorkflowContainerRuntimeNode | null {\r\n const childPath = `${rootWorkflowPath}>${childWorkflowId}`;\r\n const subId = buildContainerId(childPath, 'subworkflow', childWorkflowId);\r\n const existingSub = tree.containersById[subId];\r\n if (existingSub?.parent_container_id) {\r\n return tree.containersById[existingSub.parent_container_id] ?? null;\r\n }\r\n\r\n const runningStages = tree.activeContainerIds\r\n .map((id) => tree.containersById[id])\r\n .filter(\r\n (node): node is WorkflowContainerRuntimeNode =>\r\n node != null\r\n && node.scope === 'stage'\r\n && node.workflow_path === rootWorkflowPath\r\n && node.is_open,\r\n );\r\n\r\n if (runningStages.length === 0) return null;\r\n\r\n return runningStages.reduce((best, node) =>\r\n (node.display?.progress_current ?? 0) >= (best.display?.progress_current ?? 0)\r\n ? node\r\n : best,\r\n );\r\n}\r\n\r\nfunction upsertRuntimeNode(\r\n tree: WorkflowContainerTreeState,\r\n node: WorkflowContainerRuntimeNode,\r\n): WorkflowContainerTreeState {\r\n const activeContainerIds = tree.activeContainerIds.includes(node.container_id)\r\n ? tree.activeContainerIds\r\n : node.is_open\r\n ? [...tree.activeContainerIds, node.container_id]\r\n : tree.activeContainerIds;\r\n\r\n return {\r\n ...tree,\r\n activeContainerIds,\r\n containersById: {\r\n ...tree.containersById,\r\n [node.container_id]: node,\r\n },\r\n };\r\n}\r\n\r\nfunction completeOpenItemsUnderSubworkflow(\r\n tree: WorkflowContainerTreeState,\r\n subworkflowId: string,\r\n): WorkflowContainerTreeState {\r\n let next = tree;\r\n for (const node of Object.values(tree.containersById)) {\r\n if (\r\n node.parent_container_id === subworkflowId\r\n && node.scope === 'item'\r\n && node.status === 'running'\r\n ) {\r\n next = upsertRuntimeNode(next, {\r\n ...node,\r\n status: 'completed',\r\n is_open: false,\r\n });\r\n }\r\n }\r\n const activeContainerIds = next.activeContainerIds.filter(\r\n (id) => next.containersById[id]?.is_open,\r\n );\r\n return { ...next, activeContainerIds };\r\n}\r\n\r\nfunction resolveLeafScope(taskKey: string): WorkflowContainerScope {\r\n return taskKey === 'aggregate' ? 'aggregate' : 'item';\r\n}\r\n\r\n/**\r\n * 是否应对当前会话启用 embedded 子流合成(D29 方案 B:native 优先)。\r\n * SDK ≥1.6.6 已正确发 native subworkflow 结构事件;embedded 路径仅服务旧 fixture / legacy replay。\r\n * 传入 pendingEvent 可在首条 native 结构事件到达时立即跳过合成。\r\n */\r\nexport function shouldUseEmbeddedSynthesis(\r\n treeOrState: WorkflowContainerTreeState | WorkflowSessionState,\r\n pendingEvent?: LangchainAgentEvent,\r\n): boolean {\r\n const tree = 'containerTree' in treeOrState ? treeOrState.containerTree : treeOrState;\r\n if (pendingEvent && isNativeNestedStructureEvent(pendingEvent)) {\r\n return false;\r\n }\r\n if (hasNativeNestedStructureInTree(tree)) {\r\n return false;\r\n }\r\n return true;\r\n}\r\n\r\n/** 为嵌套子流补全 subworkflow / item|aggregate 容器并绑定 loopSessionId。 */\r\nexport function ensureEmbeddedSubworkflowContainers(\r\n tree: WorkflowContainerTreeState,\r\n loopSessionId: string,\r\n): WorkflowContainerTreeState {\r\n if (!shouldUseEmbeddedSynthesis(tree)) {\r\n return tree;\r\n }\r\n\r\n const root = resolveRootWorkflow(tree);\r\n const parts = parseLoopSessionParts(loopSessionId);\r\n if (!root || !parts || !isEmbeddedChildLoopSession(loopSessionId, root.workflowId)) {\r\n return tree;\r\n }\r\n\r\n const hostStage = findEmbeddedHostStage(tree, root.workflowPath, parts.workflowId);\r\n if (!hostStage) return tree;\r\n\r\n let next = tree;\r\n\r\n if (hostStage.loopSessionId) {\r\n next = upsertRuntimeNode(next, { ...hostStage, loopSessionId: null });\r\n }\r\n\r\n const childPath = `${root.workflowPath}>${parts.workflowId}`;\r\n const subId = buildContainerId(childPath, 'subworkflow', parts.workflowId);\r\n let subNode = next.containersById[subId];\r\n if (!subNode) {\r\n subNode = {\r\n container_id: subId,\r\n scope: 'subworkflow',\r\n workflow_path: childPath,\r\n workflow_depth: hostStage.workflow_depth + 1,\r\n scope_key: parts.workflowId,\r\n title: 'Dual-Perspective Review',\r\n subtitle: 'Nested parallel sub-workflow',\r\n status: 'running',\r\n pattern: 'parallelization',\r\n parent_container_id: hostStage.container_id,\r\n display: {\r\n title: 'Dual-Perspective Review',\r\n description: 'Nested parallel sub-workflow',\r\n pattern: 'parallelization',\r\n status: 'running',\r\n },\r\n content_blocks: [],\r\n is_open: true,\r\n loopSessionId: null,\r\n };\r\n next = upsertRuntimeNode(next, subNode);\r\n }\r\n\r\n const leafScope = resolveLeafScope(parts.taskKey);\r\n const leafId = buildContainerId(childPath, leafScope, parts.taskKey);\r\n let leafNode = next.containersById[leafId];\r\n if (!leafNode) {\r\n leafNode = {\r\n container_id: leafId,\r\n scope: leafScope,\r\n workflow_path: childPath,\r\n workflow_depth: hostStage.workflow_depth + 1,\r\n scope_key: parts.taskKey,\r\n title: humanizeTaskTitle(parts.taskKey),\r\n subtitle: '',\r\n status: 'running',\r\n pattern: 'parallelization',\r\n parent_container_id: subId,\r\n display: {\r\n title: humanizeTaskTitle(parts.taskKey),\r\n pattern: 'parallelization',\r\n status: 'running',\r\n },\r\n content_blocks: [],\r\n is_open: true,\r\n loopSessionId: null,\r\n };\r\n next = upsertRuntimeNode(next, leafNode);\r\n }\r\n\r\n if (leafScope === 'aggregate') {\r\n next = completeOpenItemsUnderSubworkflow(next, subId);\r\n }\r\n\r\n if (leafNode.loopSessionId !== loopSessionId) {\r\n next = upsertRuntimeNode(next, {\r\n ...leafNode,\r\n loopSessionId,\r\n content_blocks: [],\r\n });\r\n }\r\n\r\n return next;\r\n}\r\n\r\nexport function findContainerIdByLoopSession(\r\n tree: WorkflowContainerTreeState,\r\n loopSessionId: string,\r\n): string | null {\r\n for (const [containerId, node] of Object.entries(tree.containersById)) {\r\n if (node.loopSessionId === loopSessionId) return containerId;\r\n }\r\n return null;\r\n}\r\n\r\nconst PARALLEL_ITEM_STRUCTURE_EVENTS = new Set([\r\n 'parallel-item-start',\r\n 'parallel-item-done',\r\n 'parallel-item-failed',\r\n]);\r\n\r\nfunction readItemKey(data: Record<string, unknown>): string | undefined {\r\n const value = data.item_key;\r\n return typeof value === 'string' ? value : undefined;\r\n}\r\n\r\n/**\r\n * nested parallel item:structure workflow_id(如 parallel_review)与 SDK session 前缀\r\n *(如 demo-review-sub)不一致时,以 session_id 的 task_key 与 item_key 对齐为准。\r\n */\r\nfunction resolveParallelItemLoopSessionId(\r\n eventType: string,\r\n eventSessionId: string | null | undefined,\r\n derivedLoopSessionId: string,\r\n data: Record<string, unknown>,\r\n): string | null {\r\n if (!PARALLEL_ITEM_STRUCTURE_EVENTS.has(eventType) || !eventSessionId) return null;\r\n if (eventSessionId === derivedLoopSessionId) return null;\r\n\r\n const itemKey = readItemKey(data);\r\n const parsed = parseLoopSessionParts(eventSessionId);\r\n if (itemKey && parsed?.taskKey === itemKey) {\r\n return eventSessionId;\r\n }\r\n return null;\r\n}\r\n\r\n/** structure open/close 预绑定用的 loopSessionId(aggregate 可能带 child workflow 前缀)。 */\r\nexport function resolveStructureOpenLoopSessionId(\r\n eventType: string,\r\n eventSessionId: string | null | undefined,\r\n derivedLoopSessionId: string,\r\n data: Record<string, unknown>,\r\n): string {\r\n const rootWorkflowId = readWorkflowId(data) ?? '';\r\n if (\r\n (eventType === 'parallel-aggregate-start'\r\n || eventType === 'parallel-aggregate-done'\r\n || eventType === 'parallel-aggregate-failed')\r\n && eventSessionId\r\n && isEmbeddedChildLoopSession(eventSessionId, rootWorkflowId)\r\n ) {\r\n return eventSessionId;\r\n }\r\n\r\n const parallelItemSessionId = resolveParallelItemLoopSessionId(\r\n eventType,\r\n eventSessionId,\r\n derivedLoopSessionId,\r\n data,\r\n );\r\n if (parallelItemSessionId) {\r\n return parallelItemSessionId;\r\n }\r\n\r\n return derivedLoopSessionId;\r\n}\r\n\r\nconst EMBEDDED_AGGREGATE_STRUCTURE_EVENTS = new Set([\r\n 'parallel-aggregate-start',\r\n 'parallel-aggregate-done',\r\n 'parallel-aggregate-failed',\r\n]);\r\n\r\n/** 嵌套 aggregate 结构事件的 workflow_path 落到子流路径,供 projector 开/关正确容器。 */\r\nexport function patchEmbeddedStructureEvent(\r\n event: LangchainAgentEvent,\r\n rootWorkflowId: string,\r\n): LangchainAgentEvent {\r\n if (!EMBEDDED_AGGREGATE_STRUCTURE_EVENTS.has(event.event_type)) {\r\n return event;\r\n }\r\n if (!event.session_id || !isEmbeddedChildLoopSession(event.session_id, rootWorkflowId)) {\r\n return event;\r\n }\r\n\r\n const parts = parseLoopSessionParts(event.session_id);\r\n if (!parts) return event;\r\n\r\n const data = (event.data ?? {}) as Record<string, unknown>;\r\n const rootPath = readString(data, 'workflow_path') ?? rootWorkflowId;\r\n const childPath = `${rootPath}>${parts.workflowId}`;\r\n const workflowDepth =\r\n typeof data.workflow_depth === 'number' ? data.workflow_depth + 1 : 1;\r\n\r\n return {\r\n ...event,\r\n data: {\r\n ...data,\r\n workflow_path: childPath,\r\n workflow_depth: workflowDepth,\r\n },\r\n };\r\n}\r\n\r\nfunction readString(data: Record<string, unknown>, key: string): string | undefined {\r\n const value = data[key];\r\n return typeof value === 'string' ? value : undefined;\r\n}\r\n\r\nfunction isDescendantOf(\r\n containersById: Record<string, WorkflowContainerRuntimeNode>,\r\n ancestorId: string,\r\n nodeId: string,\r\n): boolean {\r\n const seen = new Set<string>();\r\n let current = containersById[nodeId]?.parent_container_id ?? null;\r\n while (current) {\r\n if (current === ancestorId) return true;\r\n if (seen.has(current)) return false;\r\n seen.add(current);\r\n current = containersById[current]?.parent_container_id ?? null;\r\n }\r\n return false;\r\n}\r\n\r\n/** stage-done 时收口其下嵌套子流容器(避免 item/aggregate 仍 running + Spinner)。 */\r\nexport function settleCompletedStageSubtree(\r\n tree: WorkflowContainerTreeState,\r\n stageContainerId: string,\r\n): WorkflowContainerTreeState {\r\n let next = tree;\r\n for (const node of Object.values(tree.containersById)) {\r\n if (\r\n node.container_id !== stageContainerId\r\n && !isDescendantOf(tree.containersById, stageContainerId, node.container_id)\r\n ) {\r\n continue;\r\n }\r\n if (node.container_id === stageContainerId) continue;\r\n if (node.status === 'completed' || node.status === 'failed') continue;\r\n // stage-done 若早于 sibling agent 到达,不得把仍 active 的后代强行 settle\r\n if (\r\n node.status === 'running'\r\n || node.status === 'retrying'\r\n || node.status === 'pending'\r\n || node.status === 'blocked'\r\n ) {\r\n continue;\r\n }\r\n next = upsertRuntimeNode(next, {\r\n ...node,\r\n status: 'completed',\r\n is_open: false,\r\n });\r\n }\r\n const activeContainerIds = next.activeContainerIds.filter(\r\n (id) => next.containersById[id]?.is_open,\r\n );\r\n return { ...next, activeContainerIds };\r\n}\r\n\r\nfunction readWorkflowId(data: Record<string, unknown>): string | undefined {\r\n return readWorkflowIdFromData(data);\r\n}\r\n\r\nexport { buildLoopSessionId };\r\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 type { SessionTree } from '../types/tree';\nimport {\n createWorkflowRunningLoopTree,\n finalizeWorkflowLoopTree,\n} from './workflow/workflowLoopTreeUtils';\nimport { containersByLoopSessionId } from './workflow/workflowLoopEviction';\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 ensureEmbeddedSubworkflowContainers,\n findContainerIdByLoopSession,\n patchEmbeddedStructureEvent,\n resolveStructureOpenLoopSessionId,\n settleCompletedStageSubtree,\n shouldPrebindLoopSessionFromStructureOpen,\n shouldUseEmbeddedSynthesis,\n} from './workflow/embeddedSubworkflowUtils';\nimport {\n deriveLoopSessionIdFromAgentEvent,\n deriveLoopSessionIdFromStructureOpen,\n loopTaskScopeForStructureOpen,\n} from './workflow/loopSessionUtils';\nimport {\n clearHostStageLoopOnNestedChildOpen,\n isNestedHostStageShell,\n dropStaleEmbeddedPathsOnNativeSubworkflowStart,\n} from './workflow/nativeNestedUtils';\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 derivedLoopSessionId = deriveLoopSessionIdFromStructureOpen(event);\n const scope = loopTaskScopeForStructureOpen(event.event_type);\n if (!derivedLoopSessionId || !scope) return tree;\n\n const data = (event.data ?? {}) as Record<string, unknown>;\n let loopSessionId = resolveStructureOpenLoopSessionId(\n event.event_type,\n event.session_id,\n derivedLoopSessionId,\n data,\n );\n\n // shouldPrebindLoopSessionFromStructureOpen 返回 false 表示 eventSessionId 是\"泄漏\"的;\n // 此时不应阻止绑定,而是强制使用 derivedLoopSessionId。\n if (\n !shouldPrebindLoopSessionFromStructureOpen(\n event.event_type,\n event.session_id,\n derivedLoopSessionId,\n data,\n )\n ) {\n loopSessionId = derivedLoopSessionId;\n }\n\n let nextTree =\n event.event_type === 'parallel-aggregate-start'\n ? ensureEmbeddedSubworkflowContainers(tree, loopSessionId)\n : tree;\n\n const workflowPath = readString(data, 'workflow_path') ?? '';\n const scopeKey = resolveScopeKey(event.event_type, data);\n const containerId = buildContainerId(workflowPath, scope, scopeKey);\n\n let targetId = containerId;\n const embeddedTargetId = findContainerIdByLoopSession(nextTree, loopSessionId);\n if (embeddedTargetId) {\n targetId = embeddedTargetId;\n }\n\n const node = nextTree.containersById[targetId];\n if (!node) return nextTree;\n if (node.loopSessionId === loopSessionId && node.content_blocks.length === 0) {\n return nextTree;\n }\n\n return {\n ...nextTree,\n containersById: {\n ...nextTree.containersById,\n [targetId]: {\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 return findContainerIdByLoopSession(tree, loopSessionId);\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 | undefined,\n containerTree: WorkflowContainerTreeState,\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 const byLoop = containersByLoopSessionId(containerTree);\n\n if (activeLoopSessionId) {\n const activeContainer = byLoop.get(activeLoopSessionId);\n if (\n activeContainer\n && (activeContainer.status === 'running' || activeContainer.status === 'retrying')\n ) {\n return activeLoopSessionId;\n }\n }\n\n const runningLoopIds = [...byLoop.entries()]\n .filter(([, node]) => node.status === 'running' || node.status === 'retrying')\n .map(([loopSessionId]) => loopSessionId);\n if (runningLoopIds.length === 1) return runningLoopIds[0]!;\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, tree);\n if (!sessionId) return tree;\n\n let nextTree = ensureEmbeddedSubworkflowContainers(tree, sessionId);\n if (findContainerByLoopSession(nextTree, sessionId)) return nextTree;\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 = findContainerByLoopSession(nextTree, sessionId);\n\n if (!targetId && scopeKey) {\n targetId = resolveContentTargetFromSnapshot(\n containerTreeToSnapshot(nextTree),\n workflowPath,\n scopeKey,\n );\n }\n\n if (!targetId) {\n const fallbackScopes: Array<'item' | 'aggregate' | 'stage'> = ['item', 'aggregate', 'stage'];\n for (const scope of fallbackScopes) {\n for (const containerId of nextTree.activeContainerIds) {\n const node = nextTree.containersById[containerId];\n if (!node || node.loopSessionId) continue;\n if (node.scope !== scope) continue;\n if (node.scope === 'stage' && isNestedHostStageShell(nextTree, node)) continue;\n targetId = containerId;\n break;\n }\n if (targetId) break;\n }\n }\n\n if (!targetId) {\n targetId = resolveContentTargetFromSnapshot(\n containerTreeToSnapshot(nextTree),\n workflowPath,\n null,\n );\n }\n\n if (!targetId) return nextTree;\n\n const node = nextTree.containersById[targetId];\n if (!node || node.loopSessionId) return nextTree;\n\n // D24 §8.2: stage / item / branch / aggregate(Agent loop) 承载 loop;workflow / route-decision 等不绑定。\n if (node.scope === 'stage' && isNestedHostStageShell(nextTree, node)) {\n return nextTree;\n }\n\n if (\n node.scope !== 'stage'\n && node.scope !== 'item'\n && node.scope !== 'branch'\n && node.scope !== 'aggregate'\n ) {\n return nextTree;\n }\n\n return {\n ...nextTree,\n containersById: {\n ...nextTree.containersById,\n [targetId]: { ...node, loopSessionId: sessionId },\n },\n };\n}\n\nconst LOOP_TASK_STRUCTURE_CLOSE_EVENTS = new Set([\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\nfunction resolveStructureCloseLoopSessionId(\n event: LangchainAgentEvent,\n): string | null {\n const data = (event.data ?? {}) as Record<string, unknown>;\n const derived =\n deriveLoopSessionIdFromStructureOpen(event)\n ?? deriveLoopSessionIdFromAgentEvent(event);\n if (!derived && !event.session_id) return null;\n if (!derived) return event.session_id ?? null;\n return resolveStructureOpenLoopSessionId(\n event.event_type,\n event.session_id,\n derived,\n data,\n );\n}\n\nfunction finalizeLoopTreesForCompletedContainers(\n state: WorkflowSessionState,\n containerTree: WorkflowContainerTreeState,\n): WorkflowSessionState {\n let loopTreesBySessionId = state.loopTreesBySessionId;\n for (const node of Object.values(containerTree.containersById)) {\n if (!node.loopSessionId) continue;\n if (node.status !== 'completed' && node.status !== 'failed') continue;\n const loopTree = loopTreesBySessionId[node.loopSessionId];\n if (!loopTree || loopTree.status === 'done' || loopTree.status === 'error') continue;\n loopTreesBySessionId = {\n ...loopTreesBySessionId,\n [node.loopSessionId]: finalizeWorkflowLoopTree(\n loopTree,\n node.status === 'failed' ? 'error' : 'done',\n ),\n };\n }\n return { ...state, loopTreesBySessionId };\n}\n\nfunction clearActiveLoopIfFinalized(\n state: WorkflowSessionState,\n): WorkflowSessionState {\n const activeId = state.activeLoopSessionId;\n if (!activeId) return state;\n const loop = state.loopTreesBySessionId[activeId];\n if (loop && (loop.status === 'done' || loop.status === 'error')) {\n return { ...state, activeLoopSessionId: null };\n }\n return state;\n}\n\nfunction resolveRootWorkflowId(\n containerTree: WorkflowContainerTreeState,\n): string | null {\n const rootId = containerTree.rootContainerIds[0];\n const root = rootId ? containerTree.containersById[rootId] : undefined;\n return root?.scope === 'workflow' ? root.scope_key : null;\n}\nfunction findContainerForLoopSession(\n tree: WorkflowContainerTreeState,\n loopSessionId: string,\n): WorkflowContainerRuntimeNode | undefined {\n return Object.values(tree.containersById).find(\n (node) => node.loopSessionId === loopSessionId,\n );\n}\n\n/** 容器已 completed/failed 时,禁止 agent 事件把 scoped loop 拉回 running(SDK dual emission / gate start)。 */\nfunction reconcileLoopTreeWithContainerStatus(\n containerTree: WorkflowContainerTreeState,\n loopSessionId: string,\n loopTree: SessionTree,\n): SessionTree {\n const container = findContainerForLoopSession(containerTree, loopSessionId);\n if (!container) return loopTree;\n if (container.status === 'completed') {\n return finalizeWorkflowLoopTree(loopTree, 'done');\n }\n if (container.status === 'failed') {\n return finalizeWorkflowLoopTree(loopTree, 'error');\n }\n return loopTree;\n}\n\nfunction finalizeLoopTreeOnStructureClose(\n state: WorkflowSessionState,\n event: LangchainAgentEvent,\n): WorkflowSessionState {\n if (!LOOP_TASK_STRUCTURE_CLOSE_EVENTS.has(event.event_type)) {\n return state;\n }\n\n const loopSessionId = resolveStructureCloseLoopSessionId(event);\n if (!loopSessionId) return state;\n\n const loopTree = state.loopTreesBySessionId[loopSessionId];\n if (!loopTree) return state;\n\n const terminalStatus = event.event_type.endsWith('-failed') ? 'error' : 'done';\n return {\n ...state,\n loopTreesBySessionId: {\n ...state.loopTreesBySessionId,\n [loopSessionId]: finalizeWorkflowLoopTree(loopTree, terminalStatus),\n },\n };\n}\n\nfunction applyStructureEvent(\n state: WorkflowSessionState,\n event: LangchainAgentEvent,\n): WorkflowSessionState {\n const rootWorkflowId = resolveRootWorkflowId(state.containerTree);\n const useEmbeddedSynthesis = shouldUseEmbeddedSynthesis(state, event);\n const projectedEvent =\n rootWorkflowId != null && useEmbeddedSynthesis\n ? patchEmbeddedStructureEvent(event, rootWorkflowId)\n : event;\n\n let containerTree = applyStructureToContainerTree(state.containerTree, projectedEvent);\n\n if (\n projectedEvent.event_type === 'subworkflow-start'\n || projectedEvent.event_type === 'parallel-item-start'\n ) {\n containerTree = clearHostStageLoopOnNestedChildOpen(containerTree, projectedEvent);\n }\n if (projectedEvent.event_type === 'subworkflow-start') {\n containerTree = dropStaleEmbeddedPathsOnNativeSubworkflowStart(containerTree, projectedEvent);\n }\n\n const derivedLoopSessionId = deriveLoopSessionIdFromStructureOpen(projectedEvent);\n const structureData = (projectedEvent.data ?? {}) as Record<string, unknown>;\n const structureLoopSessionId = derivedLoopSessionId\n ? resolveStructureOpenLoopSessionId(\n projectedEvent.event_type,\n projectedEvent.session_id,\n derivedLoopSessionId,\n structureData,\n )\n : null;\n\n if (structureLoopSessionId && useEmbeddedSynthesis) {\n containerTree = ensureEmbeddedSubworkflowContainers(containerTree, structureLoopSessionId);\n }\n\n containerTree = prebindLoopSessionFromStructureOpen(containerTree, projectedEvent);\n\n if (\n projectedEvent.event_type === 'stage-done'\n || projectedEvent.event_type === 'stage-failed'\n ) {\n const stageKey = readString(structureData, 'stage_key');\n const workflowPath = readString(structureData, 'workflow_path') ?? '';\n if (stageKey) {\n const stageId = buildContainerId(workflowPath, 'stage', stageKey);\n if (containerTree.containersById[stageId]) {\n containerTree = settleCompletedStageSubtree(containerTree, stageId);\n }\n }\n }\n\n const loopSessionId = structureLoopSessionId ?? derivedLoopSessionId;\n let nextState: WorkflowSessionState = { ...state, containerTree };\n\n if (loopSessionId) {\n nextState = ensureLoopTree(nextState, loopSessionId);\n }\n\n nextState = finalizeLoopTreeOnStructureClose(nextState, projectedEvent);\n nextState = finalizeLoopTreesForCompletedContainers(nextState, containerTree);\n nextState = clearActiveLoopIfFinalized(nextState);\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 let reducedLoop = reduceTree(loopTree, event, eventIndex, options);\n reducedLoop = reconcileLoopTreeWithContainerStatus(\n next.containerTree,\n loopSessionId,\n reducedLoop,\n );\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, state.containerTree)\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 let reducedLoop = reduceTree(loopTree, event, eventIndex, options);\n reducedLoop = reconcileLoopTreeWithContainerStatus(\n next.containerTree,\n loopSessionId,\n reducedLoop,\n );\n\n const workflowProgress = syncWorkflowProgressFromContainerTree(\n next.containerTree,\n next.workflowProgress,\n );\n\n let status = next.status;\n if (workflowProgress.status === 'done') status = 'done';\n else if (workflowProgress.status === 'error') status = 'error';\n else if (reducedLoop.status === 'error') status = 'error';\n else if (status === 'connecting') status = 'running';\n\n return {\n ...next,\n workflowProgress,\n loopTreesBySessionId: {\n ...next.loopTreesBySessionId,\n [loopSessionId]: reducedLoop,\n },\n activeLoopSessionId: loopSessionId,\n status,\n };\n}\n\n/**\n * SSE 正常结束后兜底:根 workflow 已 completed,或全部 top-level stage 已 settle\n * 且无 running 容器时,提升 session 为 done(嵌套 parallel 缺 workflow-end 时不锁死宿主 UI)。\n */\nexport function finalizeWorkflowSessionOnStreamComplete(\n state: WorkflowSessionState,\n): WorkflowSessionState {\n if (state.status === 'done' || state.status === 'error') {\n return { ...state, activeLoopSessionId: null };\n }\n\n const tree = state.containerTree;\n const rootId = tree.rootContainerIds[0];\n if (!rootId) {\n return { ...state, status: 'done', activeLoopSessionId: null };\n }\n\n const root = tree.containersById[rootId];\n if (!root) {\n return { ...state, status: 'done', activeLoopSessionId: null };\n }\n\n const topLevelStages = Object.values(tree.containersById).filter(\n (node) =>\n node.scope === 'stage'\n && node.workflow_path === root.workflow_path\n && node.workflow_depth === root.workflow_depth,\n );\n\n const progressTotal =\n root.display?.progress_total\n ?? (topLevelStages.reduce(\n (max, s) => Math.max(max, s.display?.progress_total ?? 0),\n 0,\n ) || topLevelStages.length);\n\n const settledStageCount = topLevelStages.filter(\n (s) =>\n s.status === 'completed'\n || s.status === 'failed'\n || s.status === 'skipped',\n ).length;\n\n const progressCurrent = Math.max(\n root.display?.progress_current ?? 0,\n settledStageCount,\n );\n\n const rootParallelItems = Object.values(tree.containersById).filter(\n (node) =>\n node.scope === 'item'\n && node.workflow_path === root.workflow_path\n && node.workflow_depth === root.workflow_depth,\n );\n\n const rootParallelSettled =\n topLevelStages.length === 0\n && rootParallelItems.length > 0\n && rootParallelItems.every(\n (item) =>\n item.status === 'completed'\n || item.status === 'failed'\n || item.status === 'skipped',\n )\n && !Object.values(tree.containersById).some(\n (node) =>\n node.container_id !== rootId\n && node.workflow_path === root.workflow_path\n && node.workflow_depth === root.workflow_depth\n && (node.status === 'running'\n || node.status === 'retrying'\n || node.status === 'pending'),\n );\n\n const workflowVisuallyComplete =\n root.status === 'completed'\n || root.status === 'failed'\n || (progressTotal > 0 && progressCurrent >= progressTotal)\n || rootParallelSettled;\n\n if (!workflowVisuallyComplete) {\n return state;\n }\n\n let containersById = { ...tree.containersById };\n for (const [id, node] of Object.entries(containersById)) {\n if (node.status === 'running' || node.status === 'pending') {\n containersById[id] = { ...node, status: 'completed', is_open: false };\n }\n }\n\n const settledRoot = containersById[rootId] ?? root;\n if (settledRoot.status !== 'completed' && settledRoot.status !== 'failed') {\n containersById = {\n ...containersById,\n [rootId]: { ...settledRoot, status: 'completed', is_open: false },\n };\n }\n\n const loopTreesBySessionId = { ...state.loopTreesBySessionId };\n for (const [loopSessionId, loopTree] of Object.entries(loopTreesBySessionId)) {\n if (loopTree.status === 'running' || loopTree.status === 'connecting') {\n loopTreesBySessionId[loopSessionId] = finalizeWorkflowLoopTree(loopTree, 'done');\n }\n }\n\n const containerTree: WorkflowContainerTreeState = {\n ...tree,\n containersById,\n activeContainerIds: tree.activeContainerIds.filter(\n (id) => containersById[id]?.is_open,\n ),\n };\n\n const workflowProgress = syncWorkflowProgressFromContainerTree(\n containerTree,\n state.workflowProgress,\n );\n\n return {\n ...state,\n status: workflowProgress.status === 'error' ? 'error' : 'done',\n containerTree,\n workflowProgress,\n loopTreesBySessionId,\n activeLoopSessionId: null,\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 * 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, subtreeHasActiveWork } 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 options?: { suppressHostScopedLoop?: boolean; subtreeHasActiveWork?: boolean },\n): ReactNode {\n const loopTree = resolveLoopTree(node, loopTreesBySessionId);\n const subtreeActive =\n options?.subtreeHasActiveWork\n ?? subtreeHasActiveWork(containerTree.containersById, node.container_id);\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 suppressHostScopedLoop={options?.suppressHostScopedLoop}\n subtreeHasActiveWork={subtreeActive}\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 stageHasSubworkflowChild(\n stageId: string,\n containerTree: WorkflowContainerTreeState,\n): boolean {\n return collectChildContainers(containerTree.containersById, stageId).some(\n (node) => node.scope === 'subworkflow',\n );\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 subtreeHasActiveWork={subtreeHasActiveWork(\n containerTree.containersById,\n node.container_id,\n )}\n >\n {hasNested ? nested : null}\n </WorkflowSubworkflowContainer>\n );\n }\n\n if (node.scope === 'stage') {\n const suppressHostScopedLoop = stageHasSubworkflowChild(node.container_id, containerTree);\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(\n node,\n depth,\n containerTree,\n loopTreesBySessionId,\n viewProps,\n { suppressHostScopedLoop },\n )}\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, containerTree.containersById),\n [stages, maxVisibleDoneCount, containerTree.containersById],\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\n key={workflowNode.container_id}\n node={workflowNode}\n containersById={containerTree.containersById}\n >\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 *\n * 正文:aggregate 无 Agent loop(D24 §8.2),择优/合并结果走 content_blocks;\n * done 态用 WorkflowMarkdownPreview 渲染 GFM(表格/代码块)。\n */\nimport { useCallback, useEffect, useMemo, useState, memo, 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 { WorkflowMarkdownPreview } from './WorkflowMarkdownPreview';\nimport {\n buildAggregateLineMeta,\n buildAggregateStatusLabel,\n mapAggregateUiStatus,\n} from './workflowContainerLineUtils';\nimport {\n workflowContainerNodeVisualEqual,\n workflowContainerViewPropsEqual,\n} from './workflowContainerMemo';\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 mergeContentPreview(node: WorkflowContainerRuntimeNode): string {\n const blocks = node.content_blocks;\n if (blocks.length === 0) return '';\n return blocks\n .map((block) => block.preview?.trim() ?? '')\n .filter(Boolean)\n .join('\\n\\n');\n}\n\nexport function WorkflowAggregateContainerInner({\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 contentPreview = useMemo(() => mergeContentPreview(node), [node]);\n const waitingTeaser = isWaiting ? (contentPreview || 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 const markdownPreview = contentPreview ? (\n <WorkflowMarkdownPreview\n content={contentPreview}\n testId={`${testId}-markdown`}\n className=\"lax-workflow-aggregate__markdown lax-workflow-markdown-preview\"\n />\n ) : null;\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 <span className=\"lax-workflow-aggregate__waiting-prefix\">⎿ </span>\n <WorkflowMarkdownPreview\n content={waitingTeaser}\n className=\"lax-workflow-aggregate__markdown lax-workflow-markdown-preview\"\n />\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 {expanded && isRunning && !loopTree && contentPreview ? (\n <div\n className=\"lax-workflow-stage-container__body lax-workflow-stage-container__content-preview\"\n data-testid={`${testId}-body`}\n >\n {markdownPreview}\n </div>\n ) : null}\n\n {isDone && !expanded ? (\n <div className=\"lax-workflow-aggregate__done\" data-testid={`${testId}-done`}>\n <WorkflowExpandTrigger\n summary={`${node.title} · done`}\n onToggle={() => setExpanded(true)}\n expanded={false}\n expandHint={contentPreview ? '(click to expand)' : undefined}\n testId={`${testId}-done-trigger`}\n />\n {markdownPreview ? (\n <div className=\"lax-workflow-aggregate__done-preview\" data-testid={`${testId}-teaser`}>\n {markdownPreview}\n </div>\n ) : null}\n </div>\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\n {isDone && expanded && !loopTree && contentPreview ? (\n <div\n className=\"lax-workflow-stage-container__body lax-workflow-stage-container__content-preview\"\n data-testid={`${testId}-body`}\n >\n {markdownPreview}\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction workflowAggregateContainerPropsEqual(\n prev: WorkflowAggregateContainerProps,\n next: WorkflowAggregateContainerProps,\n): boolean {\n if (prev.loopTree !== next.loopTree) return false;\n if (!workflowContainerViewPropsEqual(prev, next)) return false;\n if (prev.siblingItems.length !== next.siblingItems.length) return false;\n for (let i = 0; i < prev.siblingItems.length; i += 1) {\n if (!workflowContainerNodeVisualEqual(prev.siblingItems[i]!, next.siblingItems[i]!)) {\n return false;\n }\n }\n return workflowContainerNodeVisualEqual(prev.node, next.node);\n}\n\nexport const WorkflowAggregateContainer = memo(\n WorkflowAggregateContainerInner,\n workflowAggregateContainerPropsEqual,\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","/**\r\n * WorkflowExpandTrigger.tsx — 可点击 ⎿ 摘要行(D24 P2)\r\n *\r\n * 职责:Done teaser / Parallel 组摘要的展开入口;hint 与摘要同属 button。\r\n *\r\n * 链路位置:WorkflowStageContainer · WorkflowParallelGroup。\r\n */\r\nimport type { ReactNode } from 'react';\r\n\r\nexport interface WorkflowExpandTriggerProps {\r\n summary: ReactNode;\r\n summaryTestId?: string;\r\n teaser?: ReactNode;\r\n expandHint?: string | null;\r\n onToggle: () => void;\r\n expanded?: boolean;\r\n testId?: string;\r\n teaserTestId?: string;\r\n className?: string;\r\n}\r\n\r\nexport function WorkflowExpandTrigger({\r\n summary,\r\n summaryTestId,\r\n teaser,\r\n expandHint,\r\n onToggle,\r\n expanded = false,\r\n testId,\r\n teaserTestId,\r\n className = '',\r\n}: WorkflowExpandTriggerProps) {\r\n return (\r\n <button\r\n type=\"button\"\r\n className={`lax-workflow-expand-trigger${className ? ` ${className}` : ''}`}\r\n onClick={onToggle}\r\n aria-expanded={expanded}\r\n data-testid={testId}\r\n >\r\n <span className=\"lax-workflow-expand-trigger__summary\" data-testid={summaryTestId}>\r\n ⎿ {summary}\r\n </span>\r\n {teaser ? (\r\n <span\r\n className=\"lax-workflow-expand-trigger__teaser\"\r\n data-testid={teaserTestId}\r\n >\r\n {teaser}\r\n </span>\r\n ) : null}\r\n {expandHint ? (\r\n <span className=\"lax-workflow-expand-trigger__hint\">{expandHint}</span>\r\n ) : null}\r\n </button>\r\n );\r\n}\r\n","/**\r\n * WorkflowMarkdownPreview — aggregate / 静态 workflow 正文 Markdown 渲染\r\n *\r\n * aggregate 节点不走 Agent loop,正文落在 content_blocks.preview(纯文本);\r\n * 与 TextNode 的 StreamingMarkdown 对齐,done 态用 RichMarkdown(GFM/表格/代码块)。\r\n */\r\nimport { RichMarkdown } from '../markdown/RichMarkdown';\r\n\r\nexport interface WorkflowMarkdownPreviewProps {\r\n content: string;\r\n testId?: string;\r\n className?: string;\r\n}\r\n\r\nexport function WorkflowMarkdownPreview({\r\n content,\r\n testId,\r\n className = 'lax-workflow-markdown-preview',\r\n}: WorkflowMarkdownPreviewProps) {\r\n if (!content.trim()) return null;\r\n return (\r\n <div className={className} data-testid={testId}>\r\n <RichMarkdown content={content} deferDiagrams />\r\n </div>\r\n );\r\n}\r\n","import type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\n\nconst ACTIVE_CONTAINER_STATUSES = new Set<WorkflowContainerRuntimeNode['status']>([\n 'running',\n 'retrying',\n 'pending',\n 'blocked',\n]);\n\nfunction isDescendantContainer(\n containersById: Record<string, WorkflowContainerRuntimeNode>,\n ancestorId: string,\n nodeId: string,\n): boolean {\n const seen = new Set<string>();\n let current = containersById[nodeId]?.parent_container_id ?? null;\n while (current) {\n if (current === ancestorId) return true;\n if (seen.has(current)) return false;\n seen.add(current);\n current = containersById[current]?.parent_container_id ?? null;\n }\n return false;\n}\n\n/** 子树内是否仍有未 settle 的容器(parallel mid-run 时 subworkflow 不得折叠)。 */\nexport function subtreeHasActiveWork(\n containersById: Record<string, WorkflowContainerRuntimeNode>,\n rootContainerId: string,\n): boolean {\n for (const node of Object.values(containersById)) {\n if (node.container_id === rootContainerId) continue;\n if (!isDescendantContainer(containersById, rootContainerId, node.container_id)) continue;\n if (ACTIVE_CONTAINER_STATUSES.has(node.status)) return true;\n }\n return false;\n}\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 containersById?: Record<string, WorkflowContainerRuntimeNode>,\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 containersById\n && subtreeHasActiveWork(containersById, stage.container_id)\n ) {\n always.push(stage);\n continue;\n }\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 (\n node.status === 'completed'\n || node.status === 'failed'\n || node.status === 'skipped'\n ) {\n return false;\n }\n if (node.loopSessionId && node.loopSessionId === activeLoopSessionId) return true;\n return false;\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';\nimport { subtreeHasActiveWork } from './workflowStageListUtils';\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\n/** 子树仍有 active 容器时,根 progress 不计入未 settle 的 stage(防 mid-run 误显示 3/3)。 */\nexport function buildEffectiveWorkflowRootMeta(\n node: WorkflowContainerRuntimeNode,\n containersById: Record<string, WorkflowContainerRuntimeNode>,\n): string[] {\n const meta: string[] = [];\n if (node.pattern) meta.push(node.pattern);\n const topStages = Object.values(containersById).filter(\n (n) => n.scope === 'stage' && n.parent_container_id === node.container_id,\n );\n const total = node.display?.progress_total ?? Math.max(topStages.length, 1);\n let settled = 0;\n for (const stage of topStages) {\n if (subtreeHasActiveWork(containersById, stage.container_id)) continue;\n if (\n stage.status === 'completed'\n || stage.status === 'failed'\n || stage.status === 'skipped'\n ) {\n settled += 1;\n }\n }\n if (total > 0) meta.push(`${settled}/${total}`);\n return withScopeMeta(node, meta);\n}\n\nexport function isWorkflowRootVisuallyActive(\n node: WorkflowContainerRuntimeNode,\n containersById: Record<string, WorkflowContainerRuntimeNode>,\n): boolean {\n if (node.status === 'running' || node.status === 'retrying') return true;\n return subtreeHasActiveWork(containersById, node.container_id);\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 * workflowContainerMemo.ts — Workflow 容器 memo 比较(DES-3)\n */\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\nimport type { WorkflowDisplayPayload } from '../../types/workflowDisplay';\n\nfunction displayVisualEqual(\n a: WorkflowDisplayPayload | null,\n b: WorkflowDisplayPayload | null,\n): boolean {\n if (a === b) return true;\n if (a === null || b === null) return false;\n if (a.progress_current !== b.progress_current) return false;\n if (a.status !== b.status) return false;\n return true;\n}\n\nexport function workflowContainerNodeVisualEqual(\n a: WorkflowContainerRuntimeNode,\n b: WorkflowContainerRuntimeNode,\n): boolean {\n if (a.container_id !== b.container_id) return false;\n if (a.status !== b.status) return false;\n if (a.is_open !== b.is_open) return false;\n if (a.loopSessionId !== b.loopSessionId) return false;\n if (a.title !== b.title) return false;\n if (a.subtitle !== b.subtitle) return false;\n if (a.content_blocks.length !== b.content_blocks.length) return false;\n if (!displayVisualEqual(a.display, b.display)) return false;\n return true;\n}\n\nexport interface WorkflowContainerViewProps {\n depth?: number;\n virtualized?: boolean;\n virtualizeThreshold?: number;\n groupParallelTools?: boolean;\n}\n\nexport function workflowContainerViewPropsEqual(\n prev: WorkflowContainerViewProps,\n next: WorkflowContainerViewProps,\n): boolean {\n return (\n prev.depth === next.depth\n && prev.virtualized === next.virtualized\n && prev.virtualizeThreshold === next.virtualizeThreshold\n && prev.groupParallelTools === next.groupParallelTools\n );\n}\n","/**\n * WorkflowParallelGroup.tsx — Parallel item 组摘要 + 嵌套 item 行\n */\nimport { useCallback, useEffect, useMemo, useState, memo } from 'react';\n\nimport {\n computeParallelGroupMetrics,\n formatParallelGroupSummary,\n parallelGroupHasActiveWork,\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 {\n workflowContainerNodeVisualEqual,\n workflowContainerViewPropsEqual,\n} from './workflowContainerMemo';\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 WorkflowParallelGroupInner({\n groupKey,\n items,\n loopTreesBySessionId,\n depth = 1,\n virtualized,\n virtualizeThreshold,\n groupParallelTools,\n}: WorkflowParallelGroupProps) {\n const metrics = useMemo(() => computeParallelGroupMetrics(items), [items]);\n const summary = formatParallelGroupSummary(metrics);\n /** 原则 A · L2:容器 status + scoped loop 双轨(结构帧可能早于 agent) */\n const hasActiveWork = useMemo(\n () => parallelGroupHasActiveWork(items, loopTreesBySessionId),\n [items, loopTreesBySessionId],\n );\n const allSettled =\n metrics.total > 0\n && metrics.running === 0\n && metrics.completed + metrics.failed >= metrics.total;\n\n const [expanded, setExpanded] = useState(hasActiveWork);\n\n useEffect(() => {\n if (hasActiveWork) {\n setExpanded(true);\n return;\n }\n if (allSettled) {\n setExpanded(false);\n }\n }, [hasActiveWork, allSettled]);\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={\n !expanded && hasActiveWork\n ? '(click to expand agents)'\n : !expanded && !hasActiveWork\n ? '(ctrl+o to expand)'\n : null\n }\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\nfunction workflowParallelGroupPropsEqual(\n prev: WorkflowParallelGroupProps,\n next: WorkflowParallelGroupProps,\n): boolean {\n if (prev.groupKey !== next.groupKey) return false;\n if (!workflowContainerViewPropsEqual(prev, next)) return false;\n if (prev.items.length !== next.items.length) return false;\n for (let i = 0; i < prev.items.length; i += 1) {\n const prevItem = prev.items[i]!;\n const nextItem = next.items[i]!;\n if (!workflowContainerNodeVisualEqual(prevItem, nextItem)) return false;\n const loopSessionId = prevItem.loopSessionId;\n if (loopSessionId) {\n if (prev.loopTreesBySessionId[loopSessionId] !== next.loopTreesBySessionId[loopSessionId]) {\n return false;\n }\n }\n }\n return true;\n}\n\nexport const WorkflowParallelGroup = memo(WorkflowParallelGroupInner, workflowParallelGroupPropsEqual);\n","/**\r\n * workflowParallelGroupMetrics.ts — Parallel 组 sibling item 客户端聚合\r\n *\r\n * 职责:\r\n * 对齐 D23 §5.6;metrics_* 未填时从容器 status 统计组摘要文案。\r\n *\r\n * 链路位置:\r\n * WorkflowParallelGroup → 组摘要行。\r\n *\r\n * 当前裁剪范围:\r\n * 仅 item scope 兄弟节点;不含 Aggregate metrics。\r\n */\r\nimport { isWorkflowLoopTreeActive } from './workflowLoopTreeUtils';\r\nimport type { SessionTree } from '../../types/tree';\r\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\r\n\r\nexport interface ParallelGroupMetrics {\r\n total: number;\r\n running: number;\r\n completed: number;\r\n failed: number;\r\n}\r\n\r\nconst ACTIVE_ITEM_STATUSES = new Set<WorkflowContainerRuntimeNode['status']>([\r\n 'running',\r\n 'retrying',\r\n 'pending',\r\n 'blocked',\r\n]);\r\n\r\nfunction countMetricsFromContainerStatus(\r\n items: WorkflowContainerRuntimeNode[],\r\n): ParallelGroupMetrics {\r\n let running = 0;\r\n let completed = 0;\r\n let failed = 0;\r\n\r\n for (const item of items) {\r\n if (ACTIVE_ITEM_STATUSES.has(item.status)) {\r\n running += 1;\r\n continue;\r\n }\r\n switch (item.status) {\r\n case 'completed':\r\n completed += 1;\r\n break;\r\n case 'failed':\r\n failed += 1;\r\n break;\r\n default:\r\n break;\r\n }\r\n }\r\n\r\n return {\r\n total: items.length,\r\n running,\r\n completed,\r\n failed,\r\n };\r\n}\r\n\r\nfunction readDisplayMetrics(items: WorkflowContainerRuntimeNode[]): ParallelGroupMetrics | null {\r\n let hasMetrics = false;\r\n let running = 0;\r\n let completed = 0;\r\n let failed = 0;\r\n let total = 0;\r\n\r\n for (const item of items) {\r\n const metrics = item.display;\r\n if (\r\n metrics?.metrics_total != null\r\n || metrics?.metrics_running != null\r\n || metrics?.metrics_completed != null\r\n || metrics?.metrics_failed != null\r\n ) {\r\n hasMetrics = true;\r\n }\r\n running += metrics?.metrics_running ?? 0;\r\n completed += metrics?.metrics_completed ?? 0;\r\n failed += metrics?.metrics_failed ?? 0;\r\n total += metrics?.metrics_total ?? 0;\r\n }\r\n\r\n if (!hasMetrics) return null;\r\n if (total <= 0) total = items.length;\r\n return { total, running, completed, failed };\r\n}\r\n\r\n/** display.metrics_* 与容器 status 双轨取 max,防 SDK 滞后导致组误折。 */\r\nfunction mergeParallelGroupMetrics(\r\n fromDisplay: ParallelGroupMetrics,\r\n fromStatus: ParallelGroupMetrics,\r\n itemCount: number,\r\n): ParallelGroupMetrics {\r\n return {\r\n total: Math.max(fromDisplay.total, fromStatus.total, itemCount),\r\n running: Math.max(fromDisplay.running, fromStatus.running),\r\n completed: Math.max(fromDisplay.completed, fromStatus.completed),\r\n failed: Math.max(fromDisplay.failed, fromStatus.failed),\r\n };\r\n}\r\n\r\n/** 从 sibling item 容器统计组 metrics(display.metrics_* 优先,status 兜底/校正)。 */\r\nexport function computeParallelGroupMetrics(\r\n items: WorkflowContainerRuntimeNode[],\r\n): ParallelGroupMetrics {\r\n const fromStatus = countMetricsFromContainerStatus(items);\r\n const fromDisplay = readDisplayMetrics(items);\r\n if (!fromDisplay) return fromStatus;\r\n return mergeParallelGroupMetrics(fromDisplay, fromStatus, items.length);\r\n}\r\n\r\n/**\r\n * 原则 A · L2:组内仍有 active 工作(容器 status 或 scoped loop 未 settle)→ 不得折叠。\r\n * 结构帧(parallel-item-done)可能早于 loop finish,须双轨校验。\r\n */\r\nexport function parallelGroupHasActiveWork(\r\n items: WorkflowContainerRuntimeNode[],\r\n loopTreesBySessionId: Record<string, SessionTree> = {},\r\n): boolean {\r\n const metrics = computeParallelGroupMetrics(items);\r\n if (metrics.running > 0) return true;\r\n for (const item of items) {\r\n const loopSessionId = item.loopSessionId;\r\n if (!loopSessionId) continue;\r\n if (isWorkflowLoopTreeActive(loopTreesBySessionId[loopSessionId])) return true;\r\n }\r\n return false;\r\n}\r\n\r\nexport function formatParallelGroupSummary(metrics: ParallelGroupMetrics): string {\r\n if (metrics.running > 0) {\r\n const n = metrics.running;\r\n return `Running ${n} agent${n === 1 ? '' : 's'}…`;\r\n }\r\n if (metrics.failed > 0) {\r\n const ok = metrics.completed;\r\n return `Done (${ok} agent${ok === 1 ? '' : 's'}) · ${metrics.failed} failed`;\r\n }\r\n const n = metrics.total;\r\n return `Done (${n} agent${n === 1 ? '' : 's'})`;\r\n}\r\n","/**\n * WorkflowStageContainer.tsx — Stage / item 容器行(CC Agent 同构)\n */\nimport { useCallback, useEffect, useMemo, useState, memo, 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 { useWorkflowSessionStoreApi } from '../../core/context/WorkflowSessionContext';\nimport { useSessionViewOptions } from '../../core/context/SessionContext';\nimport {\n createWorkflowRunningLoopTree,\n isWorkflowLoopTreeActive,\n} 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';\nimport {\n workflowContainerNodeVisualEqual,\n workflowContainerViewPropsEqual,\n} from './workflowContainerMemo';\n\nexport interface WorkflowStageContainerProps {\n node: WorkflowContainerRuntimeNode;\n loopTree?: SessionTree;\n depth?: number;\n virtualized?: boolean;\n virtualizeThreshold?: number;\n groupParallelTools?: boolean;\n /** 嵌套 parallel 宿主 stage:仅作壳,不展示 scoped loop / Spinner */\n suppressHostScopedLoop?: boolean;\n /** 子树内仍有 active 容器时,宿主 stage 不得显示 done(stage-done 可能早于 agent 结束) */\n subtreeHasActiveWork?: 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 WorkflowStageContainerInner({\n node,\n loopTree,\n depth = 0,\n virtualized,\n virtualizeThreshold,\n groupParallelTools,\n suppressHostScopedLoop = false,\n subtreeHasActiveWork = false,\n}: WorkflowStageContainerProps) {\n const { verbose } = useSessionViewOptions();\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 isRunning = node.status === 'running' || node.status === 'retrying';\n const isDone = node.status === 'completed' || node.status === 'failed';\n const isSkipped = node.status === 'skipped';\n const loopStillActive = isWorkflowLoopTreeActive(loopTree);\n const effectivelyRunning =\n isRunning || loopStillActive || (subtreeHasActiveWork && isDone);\n const effectivelyDone = isDone && !subtreeHasActiveWork && !loopStillActive;\n\n const uiStatus = mapContainerUiStatus(effectivelyRunning ? 'running' : node.status);\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 /** 原则 A:仍在执行 → 保持展开;原则 B:effectivelyDone → 立刻折(不等兄弟) */\n const shouldAutoExpandRunning = effectivelyRunning && !isSkipped;\n\n const [expanded, setExpanded] = useState(shouldAutoExpandRunning);\n\n useEffect(() => {\n if (shouldAutoExpandRunning) {\n setExpanded(true);\n return;\n }\n if (effectivelyDone || isSkipped) {\n setExpanded(false);\n }\n }, [shouldAutoExpandRunning, effectivelyDone, isSkipped]);\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 testId = containerTestId(node);\n const isItem = node.scope === 'item';\n const displayTitle = node.title;\n\n const usesScopedLoop = Boolean(node.loopSessionId) && !suppressHostScopedLoop;\n const runningLoopTree: SessionTree | undefined =\n loopTree\n ?? (usesScopedLoop && effectivelyRunning ? createWorkflowRunningLoopTree() : undefined);\n const itemLoopVirtualized = isItem ? false : virtualized;\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 = effectivelyDone\n ? doneLabel\n : suppressHostScopedLoop && effectivelyRunning\n ? 'running'\n : mapContainerStatusLabel(effectivelyRunning ? 'running' : node.status);\n\n const canToggleShell = (effectivelyRunning && !isSkipped) || effectivelyDone;\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={effectivelyDone ? `${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 {effectivelyDone && !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 && effectivelyRunning && 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={itemLoopVirtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n />\n </div>\n ) : null}\n\n {effectivelyDone && expanded ? (\n loopTree ? (\n <WorkflowStageDoneBody\n node={node}\n loopTree={loopTree}\n testId={bodyTestId(node)}\n virtualized={itemLoopVirtualized}\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\nfunction workflowStageContainerPropsEqual(\n prev: WorkflowStageContainerProps,\n next: WorkflowStageContainerProps,\n): boolean {\n if (prev.suppressHostScopedLoop !== next.suppressHostScopedLoop) return false;\n if (prev.subtreeHasActiveWork !== next.subtreeHasActiveWork) return false;\n if (prev.loopTree !== next.loopTree) return false;\n if (!workflowContainerViewPropsEqual(prev, next)) return false;\n return workflowContainerNodeVisualEqual(prev.node, next.node);\n}\n\nexport const WorkflowStageContainer = memo(WorkflowStageContainerInner, workflowStageContainerPropsEqual);\n","/**\r\n * loopTreeUtils.ts — Workflow scoped loop 树辅助判断\r\n */\r\nimport type { SessionTree } from '../../types/tree';\r\n\r\n/** 是否已有可渲染的时间线节点(非空 store 壳) */\r\nexport function hasTimelineNodes(tree: SessionTree | undefined): boolean {\r\n if (!tree) return false;\r\n return tree.rootChildren.length > 0 || Object.keys(tree.byId).length > 0;\r\n}\r\n","/**\r\n * workflowStageDoneBody.tsx — Stage/Route 完成态展开体(仅 AgentLoopView 时间线)\r\n *\r\n * 禁止用 content_blocks 原始预览充展开体(会与 AgentSession 折叠流不一致)。\r\n */\r\nimport { hasTimelineNodes } from '../../core/workflow/loopTreeUtils';\r\nimport type { SessionTree } from '../../types/tree';\r\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\r\nimport { AgentLoopView } from '../agentLoop/AgentLoopView';\r\n\r\nexport interface WorkflowStageDoneBodyProps {\r\n node: WorkflowContainerRuntimeNode;\r\n loopTree?: SessionTree;\r\n testId: string;\r\n virtualized?: boolean;\r\n virtualizeThreshold?: number;\r\n groupParallelTools?: boolean;\r\n bodyClassName?: string;\r\n}\r\n\r\nexport function WorkflowStageDoneBody({\r\n loopTree,\r\n testId,\r\n virtualized,\r\n virtualizeThreshold,\r\n groupParallelTools,\r\n bodyClassName = 'lax-workflow-stage-container__body',\r\n}: WorkflowStageDoneBodyProps) {\r\n if (loopTree && hasTimelineNodes(loopTree)) {\r\n return (\r\n <div className={bodyClassName} data-testid={testId}>\r\n <AgentLoopView\r\n tree={loopTree}\r\n showTaskListFooter={false}\r\n virtualized={virtualized}\r\n virtualizeThreshold={virtualizeThreshold}\r\n groupParallelTools={groupParallelTools}\r\n />\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div\r\n className={`${bodyClassName} lax-workflow-stage-container__empty-hint`}\r\n data-testid={testId}\r\n >\r\n <span className=\"lax-workflow-stage-container__empty-hint-text\">\r\n (此阶段暂无 Agent 时间线内容)\r\n </span>\r\n </div>\r\n );\r\n}\r\n","/**\r\n * WorkflowRootContainer.tsx — Workflow 根行(始终展示子树,不折叠)\r\n *\r\n * 职责:根行壳语法 + 常驻 stage 列表。Workflow 已是页面顶层,不做 AgentSession 式根折叠。\r\n *\r\n * 链路位置:WorkflowChrome → scope workflow 根节点。\r\n */\r\nimport type { ReactNode } from 'react';\r\n\r\nimport { useSessionViewOptions } from '../../core/context/SessionContext';\r\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\r\nimport { WorkflowContainerLine } from './WorkflowContainerLine';\r\nimport {\r\n buildEffectiveWorkflowRootMeta,\r\n buildWorkflowRootMeta,\r\n isWorkflowRootVisuallyActive,\r\n mapContainerUiStatus,\r\n mapWorkflowRootStatusLabel,\r\n} from './workflowContainerLineUtils';\r\n\r\nexport interface WorkflowRootContainerProps {\r\n node: WorkflowContainerRuntimeNode;\r\n children?: ReactNode;\r\n containersById?: Record<string, WorkflowContainerRuntimeNode>;\r\n}\r\n\r\nexport function WorkflowRootContainer({\r\n node,\r\n children,\r\n containersById,\r\n}: WorkflowRootContainerProps) {\r\n const { verbose } = useSessionViewOptions();\r\n const visuallyActive = containersById\r\n ? isWorkflowRootVisuallyActive(node, containersById)\r\n : node.status === 'running' || node.status === 'retrying';\r\n const uiStatus = mapContainerUiStatus(visuallyActive ? 'running' : node.status);\r\n const statusLabel = mapWorkflowRootStatusLabel(visuallyActive ? 'running' : node.status);\r\n const meta = containersById\r\n ? buildEffectiveWorkflowRootMeta(node, containersById)\r\n : buildWorkflowRootMeta(node);\r\n\r\n return (\r\n <div className=\"lax-workflow-root\" data-testid=\"lax-workflow-root\">\r\n <WorkflowContainerLine\r\n variant=\"root\"\r\n title={node.title}\r\n description={node.subtitle || undefined}\r\n uiStatus={uiStatus}\r\n meta={meta}\r\n statusLabel={statusLabel}\r\n titleTestId=\"lax-workflow-root-title\"\r\n descriptionTestId=\"lax-workflow-root-desc\"\r\n debugScopeKey={node.scope_key}\r\n verbose={verbose}\r\n />\r\n\r\n {children ? (\r\n <div className=\"lax-workflow-container-tree\">{children}</div>\r\n ) : null}\r\n </div>\r\n );\r\n}\r\n\r\n","/**\r\n * WorkflowRouteContainer.tsx — Route branch 容器行\r\n *\r\n * 职责:selected/running 分支可展开;skipped ◌ dim 静态一行。\r\n *\r\n * 链路位置:WorkflowChrome → scope branch 节点。\r\n */\r\nimport { useCallback, useEffect, useMemo, useState, type CSSProperties } from 'react';\r\n\r\nimport {\r\n buildStageDoneSummary,\r\n formatTeaserExpandHint,\r\n} from '../../core/workflow/stageDoneSummary';\r\nimport { useSessionViewOptions } from '../../core/context/SessionContext';\r\nimport type { SessionTree } from '../../types/tree';\r\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\r\nimport { AgentLoopView } from '../agentLoop/AgentLoopView';\r\nimport { WorkflowContainerLine } from './WorkflowContainerLine';\r\nimport { WorkflowExpandTrigger } from './WorkflowExpandTrigger';\r\nimport { WorkflowStageDoneBody } from './workflowStageDoneBody';\r\nimport {\r\n buildRouteLineMeta,\r\n mapContainerStatusLabel,\r\n mapContainerUiStatus,\r\n workflowIndentUnit,\r\n} from './workflowContainerLineUtils';\r\n\r\nexport interface WorkflowRouteContainerProps {\r\n node: WorkflowContainerRuntimeNode;\r\n loopTree?: SessionTree;\r\n depth?: number;\r\n virtualized?: boolean;\r\n virtualizeThreshold?: number;\r\n groupParallelTools?: boolean;\r\n}\r\n\r\nexport function WorkflowRouteContainer({\r\n node,\r\n loopTree,\r\n depth = 1,\r\n virtualized,\r\n virtualizeThreshold,\r\n groupParallelTools,\r\n}: WorkflowRouteContainerProps) {\r\n const { verbose } = useSessionViewOptions();\r\n const isSkipped = node.status === 'skipped';\r\n const uiStatus = mapContainerUiStatus(node.status);\r\n const isRunning = !isSkipped && (node.status === 'running' || node.status === 'retrying');\r\n const isDone = !isSkipped && (node.status === 'completed' || node.status === 'failed');\r\n const testId = `lax-workflow-route-${node.scope_key}`;\r\n const doneSummary = useMemo(\r\n () => (loopTree && isDone ? buildStageDoneSummary(loopTree) : null),\r\n [loopTree, isDone],\r\n );\r\n const staticContentTeaser =\r\n !loopTree && node.content_blocks.length > 0\r\n ? node.content_blocks[node.content_blocks.length - 1]!.preview\r\n : '';\r\n const teaserText = doneSummary?.teaser || staticContentTeaser;\r\n const expandHint =\r\n doneSummary ? formatTeaserExpandHint(doneSummary.extraLines, verbose) : null;\r\n const doneLabel = doneSummary?.label ?? 'done';\r\n\r\n const [expanded, setExpanded] = useState(isRunning);\r\n\r\n useEffect(() => {\r\n if (isSkipped) return;\r\n if (isRunning) setExpanded(true);\r\n if (isDone) setExpanded(false);\r\n }, [isRunning, isDone, isSkipped]);\r\n\r\n const toggleExpanded = useCallback(() => {\r\n if (!isSkipped) setExpanded((prev) => !prev);\r\n }, [isSkipped]);\r\n\r\n const shellToggle =\r\n isSkipped ? undefined\r\n : isRunning ? toggleExpanded\r\n : isDone && expanded ? toggleExpanded\r\n : undefined;\r\n\r\n const depthStyle = {\r\n '--lax-workflow-depth': depth,\r\n '--lax-workflow-indent-unit': workflowIndentUnit(depth),\r\n } as CSSProperties;\r\n\r\n return (\r\n <div\r\n className={`lax-workflow-route-branch lax-workflow-stage-container lax-workflow-stage-container--${uiStatus}${\r\n isSkipped ? ' lax-workflow-route-branch--skipped' : ''\r\n }`}\r\n data-testid={testId}\r\n data-route-status={node.status}\r\n data-container-scope=\"branch\"\r\n style={depthStyle}\r\n >\r\n <WorkflowContainerLine\r\n title={node.title}\r\n description={node.subtitle || undefined}\r\n uiStatus={uiStatus}\r\n meta={buildRouteLineMeta(node)}\r\n statusLabel={isSkipped ? 'skipped' : mapContainerStatusLabel(node.status)}\r\n onToggle={shellToggle}\r\n interactive={!isSkipped && isRunning}\r\n expanded={expanded}\r\n titleTestId={`${testId}-title`}\r\n descriptionTestId={`${testId}-desc`}\r\n />\r\n\r\n {!isSkipped && expanded && isRunning && loopTree ? (\r\n <div className=\"lax-workflow-stage-container__body\" data-testid={`${testId}-body`}>\r\n <AgentLoopView\r\n tree={loopTree}\r\n showTaskListFooter={false}\r\n virtualized={virtualized}\r\n virtualizeThreshold={virtualizeThreshold}\r\n groupParallelTools={groupParallelTools}\r\n />\r\n </div>\r\n ) : null}\r\n\r\n {!isSkipped && isDone && !expanded ? (\r\n <WorkflowExpandTrigger\r\n summary={`${node.title} · ${doneLabel}`}\r\n teaser={teaserText || undefined}\r\n expandHint={expandHint}\r\n onToggle={() => setExpanded(true)}\r\n expanded={false}\r\n testId={`${testId}-done`}\r\n teaserTestId={teaserText ? `${testId}-teaser` : undefined}\r\n />\r\n ) : null}\r\n\r\n {!isSkipped && isDone && expanded ? (\r\n <WorkflowStageDoneBody\r\n node={node}\r\n loopTree={loopTree}\r\n testId={`${testId}-body`}\r\n virtualized={virtualized}\r\n virtualizeThreshold={virtualizeThreshold}\r\n groupParallelTools={groupParallelTools}\r\n />\r\n ) : null}\r\n </div>\r\n );\r\n}\r\n","/**\r\n * WorkflowSubworkflowContainer.tsx — Subworkflow 缩进 mini 根行 + 左边界\r\n *\r\n * 职责:与 workflow 根同壳行语法;嵌套子树包在 boundary 内;done 折叠为 ExpandTrigger。\r\n *\r\n * 链路位置:WorkflowChrome → scope subworkflow 节点。\r\n */\r\nimport { useCallback, useEffect, useMemo, useState, type CSSProperties, type ReactNode } from 'react';\r\n\r\nimport { useSessionViewOptions } from '../../core/context/SessionContext';\r\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\r\nimport { WorkflowContainerLine } from './WorkflowContainerLine';\r\nimport { WorkflowExpandTrigger } from './WorkflowExpandTrigger';\r\nimport {\r\n buildWorkflowRootMeta,\r\n mapContainerUiStatus,\r\n mapWorkflowRootStatusLabel,\r\n workflowIndentUnit,\r\n} from './workflowContainerLineUtils';\r\n\r\nexport interface WorkflowSubworkflowContainerProps {\r\n node: WorkflowContainerRuntimeNode;\r\n depth?: number;\r\n children?: ReactNode;\r\n /** 子树内仍有 running/pending 容器时为 true,阻止 subworkflow-end 过早折叠 */\r\n subtreeHasActiveWork?: boolean;\r\n}\r\n\r\nfunction buildDoneSummary(node: WorkflowContainerRuntimeNode): string {\r\n const display = node.display;\r\n if (display?.progress_total != null) {\r\n const total = display.progress_total;\r\n const current =\r\n node.status === 'completed' ? total : (display.progress_current ?? total);\r\n return `${current}/${total} · done`;\r\n }\r\n return 'done';\r\n}\r\n\r\nexport function WorkflowSubworkflowContainer({\r\n node,\r\n depth = 1,\r\n children,\r\n subtreeHasActiveWork = false,\r\n}: WorkflowSubworkflowContainerProps) {\r\n const { verbose } = useSessionViewOptions();\r\n const isRunning = node.status === 'running' || node.status === 'retrying';\r\n const isDone = node.status === 'completed' || node.status === 'failed';\r\n const effectivelyRunning = isRunning || subtreeHasActiveWork;\r\n const effectivelyDone = isDone && !subtreeHasActiveWork;\r\n const uiStatus = mapContainerUiStatus(\r\n effectivelyRunning ? 'running' : node.status,\r\n );\r\n const testId = `lax-workflow-subworkflow-${node.scope_key}`;\r\n const teaser = useMemo(() => {\r\n if (node.content_blocks.length === 0) return '';\r\n return node.content_blocks[node.content_blocks.length - 1]?.preview ?? '';\r\n }, [node.content_blocks]);\r\n\r\n const [expanded, setExpanded] = useState(effectivelyRunning);\r\n\r\n useEffect(() => {\r\n if (effectivelyRunning) setExpanded(true);\r\n else if (effectivelyDone) setExpanded(false);\r\n }, [effectivelyRunning, effectivelyDone]);\r\n\r\n const toggleExpanded = useCallback(() => {\r\n setExpanded((prev) => !prev);\r\n }, []);\r\n\r\n const shellToggle =\r\n effectivelyRunning ? toggleExpanded\r\n : effectivelyDone && expanded ? toggleExpanded\r\n : undefined;\r\n\r\n const depthStyle = {\r\n '--lax-workflow-depth': depth,\r\n '--lax-workflow-indent-unit': workflowIndentUnit(depth),\r\n } as CSSProperties;\r\n\r\n const showShellLine = !(effectivelyDone && !expanded);\r\n\r\n return (\r\n <div\r\n className=\"lax-workflow-subworkflow\"\r\n data-testid={testId}\r\n data-container-scope=\"subworkflow\"\r\n style={depthStyle}\r\n >\r\n {showShellLine ? (\r\n <WorkflowContainerLine\r\n variant=\"root\"\r\n title={node.title}\r\n description={node.subtitle || undefined}\r\n uiStatus={uiStatus}\r\n meta={buildWorkflowRootMeta(node)}\r\n statusLabel={mapWorkflowRootStatusLabel(\r\n effectivelyRunning ? 'running' : node.status,\r\n )}\r\n onToggle={shellToggle}\r\n interactive={effectivelyRunning}\r\n expanded={expanded}\r\n titleTestId={`${testId}-title`}\r\n descriptionTestId={`${testId}-desc`}\r\n debugScopeKey={node.scope_key}\r\n verbose={verbose}\r\n />\r\n ) : null}\r\n\r\n {expanded && children ? (\r\n <div\r\n className=\"lax-workflow-subworkflow-boundary\"\r\n data-testid={`${testId}-boundary`}\r\n style={depthStyle}\r\n >\r\n {children}\r\n </div>\r\n ) : null}\r\n\r\n {!expanded && children ? (\r\n <WorkflowExpandTrigger\r\n summary={`${node.title} · ${effectivelyDone ? buildDoneSummary(node) : 'running'}`}\r\n summaryTestId={`${testId}-title`}\r\n teaser={teaser || undefined}\r\n expandHint={effectivelyRunning ? '(click to expand subworkflow)' : undefined}\r\n onToggle={() => setExpanded(true)}\r\n expanded={false}\r\n testId={effectivelyDone ? `${testId}-done` : `${testId}-running-collapsed`}\r\n teaserTestId={teaser ? `${testId}-teaser` : undefined}\r\n />\r\n ) : null}\r\n </div>\r\n );\r\n}\r\n","/**\r\n * WorkflowTaskListFooter.tsx — 合并多 loop 任务列表底部 pill(§5.11.4)\r\n */\r\nimport { useMemo, useState } from 'react';\r\nimport { useStore } from 'zustand';\r\n\r\nimport { useWorkflowSessionStoreApi } from '../../core/context/WorkflowSessionContext';\r\nimport type { WorkflowSessionStoreState } from '../../core/workflowSessionStore';\r\nimport { TaskList } from '../TaskList';\r\nimport {\r\n deriveWorkflowTaskFooterState,\r\n formatWorkflowTaskFooterLabel,\r\n groupWorkflowTasksByLoop,\r\n loopSessionDisplayLabel,\r\n shouldShowWorkflowTaskListFooter,\r\n} from './workflowTaskListMerge';\r\n\r\nfunction MessageResponse({ children }: { children: React.ReactNode }) {\r\n return (\r\n <div className=\"lax-message-response\">\r\n <span className=\"lax-message-response__marker\">⎿ </span>\r\n <span className=\"lax-message-response__content\">{children}</span>\r\n </div>\r\n );\r\n}\r\n\r\nexport function WorkflowTaskListFooter() {\r\n const store = useWorkflowSessionStoreApi();\r\n const state = useStore(store, (s: WorkflowSessionStoreState) => s.state);\r\n const [expanded, setExpanded] = useState(false);\r\n\r\n const footerState = useMemo(() => deriveWorkflowTaskFooterState(state), [state]);\r\n const visible = shouldShowWorkflowTaskListFooter(state);\r\n\r\n if (!visible) {\r\n return null;\r\n }\r\n\r\n const label = formatWorkflowTaskFooterLabel(state);\r\n const groups = groupWorkflowTasksByLoop(footerState.tasks);\r\n\r\n return (\r\n <div className=\"lax-workflow-task-list-footer\" data-testid=\"lax-workflow-task-list-footer\">\r\n <button\r\n type=\"button\"\r\n className=\"lax-task-list-footer__pill lax-workflow-task-list-footer__pill\"\r\n data-testid=\"lax-workflow-task-list-footer-pill\"\r\n aria-expanded={expanded}\r\n onClick={() => setExpanded((v) => !v)}\r\n >\r\n {label}\r\n <span className=\"lax-task-list-footer__hint\">\r\n {expanded ? ' · ↑ to hide' : ' · ↓ to view'}\r\n </span>\r\n </button>\r\n {expanded ? (\r\n <MessageResponse>\r\n <div className=\"lax-workflow-task-list-groups\">\r\n {groups.map((group) => (\r\n <div\r\n key={group.loopSessionId}\r\n className=\"lax-workflow-task-list-group\"\r\n data-testid={`lax-workflow-task-group-${group.loopSessionId}`}\r\n >\r\n <div className=\"lax-workflow-task-list-group-title\">\r\n {loopSessionDisplayLabel(group.loopSessionId)}\r\n </div>\r\n <TaskList tasks={group.tasks} />\r\n </div>\r\n ))}\r\n </div>\r\n </MessageResponse>\r\n ) : null}\r\n </div>\r\n );\r\n}\r\n","/**\r\n * workflowTaskListMerge.ts — Workflow 多 loop 任务合并(§5.11.4)\r\n */\r\nimport type { Task } from '../../types/tasks';\r\nimport type { SessionStatus, SessionTree, TaskPhase } from '../../types/tree';\r\nimport type { WorkflowSessionState } from '../../types/workflowSession';\r\n\r\nimport {\r\n formatTaskFooterLabel,\r\n shouldShowTaskListFooter,\r\n} from '../TaskListFooter';\r\n\r\nexport interface WorkflowMergedTask extends Task {\r\n loopSessionId: string;\r\n}\r\n\r\nconst STATUS_ORDER: Record<Task['status'], number> = {\r\n in_progress: 0,\r\n pending: 1,\r\n completed: 2,\r\n};\r\n\r\nexport function mergeWorkflowLoopTasks(\r\n loopTreesBySessionId: Record<string, SessionTree>,\r\n): WorkflowMergedTask[] {\r\n const merged: WorkflowMergedTask[] = [];\r\n const loopIds = Object.keys(loopTreesBySessionId).sort();\r\n for (const loopSessionId of loopIds) {\r\n const tree = loopTreesBySessionId[loopSessionId];\r\n if (!tree) continue;\r\n for (const task of Object.values(tree.tasks)) {\r\n merged.push({ ...task, loopSessionId });\r\n }\r\n }\r\n return merged.sort((a, b) => {\r\n const sa = STATUS_ORDER[a.status] ?? 99;\r\n const sb = STATUS_ORDER[b.status] ?? 99;\r\n if (sa !== sb) return sa - sb;\r\n const loopCmp = a.loopSessionId.localeCompare(b.loopSessionId);\r\n if (loopCmp !== 0) return loopCmp;\r\n return a.id.localeCompare(b.id);\r\n });\r\n}\r\n\r\nexport function deriveWorkflowTaskPhase(trees: SessionTree[]): TaskPhase {\r\n if (trees.length === 0) return 'hidden';\r\n if (trees.some((tree) => tree.taskPhase === 'visible')) return 'visible';\r\n if (trees.every((tree) => tree.taskPhase === 'hidden-after-completion')) {\r\n return 'hidden-after-completion';\r\n }\r\n return 'hidden';\r\n}\r\n\r\nexport function deriveWorkflowTaskFooterState(state: WorkflowSessionState): {\r\n tasks: WorkflowMergedTask[];\r\n taskPhase: TaskPhase;\r\n hasEverShownTaskList: boolean;\r\n sessionStatus: SessionStatus;\r\n} {\r\n const trees = Object.values(state.loopTreesBySessionId);\r\n return {\r\n tasks: mergeWorkflowLoopTasks(state.loopTreesBySessionId),\r\n taskPhase: deriveWorkflowTaskPhase(trees),\r\n hasEverShownTaskList: trees.some((tree) => tree.hasEverShownTaskList),\r\n sessionStatus: state.status,\r\n };\r\n}\r\n\r\nexport function shouldShowWorkflowTaskListFooter(state: WorkflowSessionState): boolean {\r\n const { tasks, taskPhase, hasEverShownTaskList, sessionStatus } =\r\n deriveWorkflowTaskFooterState(state);\r\n return shouldShowTaskListFooter(taskPhase, tasks, hasEverShownTaskList, sessionStatus);\r\n}\r\n\r\nexport function formatWorkflowTaskFooterLabel(state: WorkflowSessionState): string {\r\n const { tasks } = deriveWorkflowTaskFooterState(state);\r\n return formatTaskFooterLabel(tasks);\r\n}\r\n\r\nexport function groupWorkflowTasksByLoop(\r\n tasks: WorkflowMergedTask[],\r\n): Array<{ loopSessionId: string; tasks: Task[] }> {\r\n const groups = new Map<string, Task[]>();\r\n for (const task of tasks) {\r\n const bucket = groups.get(task.loopSessionId) ?? [];\r\n bucket.push(task);\r\n groups.set(task.loopSessionId, bucket);\r\n }\r\n return Array.from(groups.entries())\r\n .sort(([a], [b]) => a.localeCompare(b))\r\n .map(([loopSessionId, groupTasks]) => ({ loopSessionId, tasks: groupTasks }));\r\n}\r\n\r\nexport function loopSessionDisplayLabel(loopSessionId: string): string {\r\n const marker = '-';\r\n const idx = loopSessionId.lastIndexOf(marker);\r\n if (idx !== -1 && idx < loopSessionId.length - 1) {\r\n return loopSessionId.slice(idx + 1);\r\n }\r\n return loopSessionId;\r\n}\r\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","/**\r\n * 职责:默认 SubAgentNode 纵向嵌套容器 widget(方案 A 已退场)。\r\n * 链路位置:宿主可通过 NodeRegistry.register('subagent', SubAgentBlock) 恢复旧行为。\r\n * 当前裁剪范围:纵向缩进;不含横向并列布局。\r\n * @deprecated 方案 A 主时间线不再渲染 SubAgentBlock;子 agent progress 折叠在 AgentToolBody。\r\n */\r\nimport { useChildren, useNodeTyped } from '../../core/hooks';\r\nimport { useNodeRegistry } from '../../core/context/SessionContext';\r\nimport { TimelineItem } from '../Timeline';\r\n\r\nexport interface SubAgentBlockProps {\r\n nodeId: string;\r\n}\r\n\r\nexport function SubAgentBlock({ nodeId }: SubAgentBlockProps) {\r\n const node = useNodeTyped(nodeId, 'subagent');\r\n const childIds = useChildren(nodeId);\r\n const registry = useNodeRegistry();\r\n if (!node) return null;\r\n\r\n return (\r\n <div className=\"lax-subagent-block\" data-status={node.status}>\r\n <div className=\"lax-subagent-block__header\">SubAgent: {node.subagentId}</div>\r\n <div className=\"lax-subagent-block__children\">\r\n {childIds.map((childId) => (\r\n <TimelineItem key={childId} nodeId={childId} registry={registry} />\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","/**\r\n * 职责:内存事件源,按序投递 events 实现 Source 接口。\r\n * 链路位置:历史回放、测试、AgentSession 只读时间线。\r\n * 当前裁剪范围:可选 delayMs 模拟流式;不含 SSE 续传。\r\n */\r\nimport type { LangchainAgentEvent } from '../types/events';\r\nimport type { ReplayOptions } from '../core/replay';\r\nimport type { Source, SourceHandler } from './types';\r\n\r\nexport interface ReplaySourceOptions extends ReplayOptions {\r\n /** 事件间隔毫秒;默认 0 立即投递 */\r\n delayMs?: number;\r\n}\r\n\r\nfunction sleep(ms: number, signal: AbortSignal): Promise<void> {\r\n if (ms <= 0) return Promise.resolve();\r\n return new Promise((resolve) => {\r\n const timer = setTimeout(resolve, ms);\r\n signal.addEventListener(\r\n 'abort',\r\n () => {\r\n clearTimeout(timer);\r\n resolve();\r\n },\r\n { once: true },\r\n );\r\n });\r\n}\r\n\r\nexport function createReplaySource(\r\n events: LangchainAgentEvent[],\r\n opts?: ReplaySourceOptions,\r\n): Source {\r\n const delayMs = opts?.delayMs ?? 0;\r\n\r\n return {\r\n async start(handler: SourceHandler, signal: AbortSignal): Promise<void> {\r\n for (const event of events) {\r\n if (signal.aborted) break;\r\n handler(event);\r\n if (delayMs > 0) {\r\n await sleep(delayMs, signal);\r\n }\r\n }\r\n },\r\n };\r\n}\r\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","readString","readString","readString","readString","node","loopSessionId","next","loopTree","reducedLoop","createStore","useMemo","useState","useEffect","useMemo","jsx","jsxs","jsx","jsxs","jsx","jsx","jsxs","useMemo","useEffect","useCallback","useEffect","useMemo","useState","memo","n","useCallback","useEffect","useMemo","useState","memo","useStore","jsx","jsx","jsxs","subtreeHasActiveWork","useStore","useMemo","useState","useEffect","useCallback","memo","jsx","jsxs","useMemo","useState","useEffect","useCallback","memo","jsx","jsxs","useCallback","useEffect","useMemo","useState","jsx","jsxs","useMemo","useState","useEffect","useCallback","useCallback","useEffect","useMemo","useState","jsx","jsxs","subtreeHasActiveWork","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/core/workflow/stageDoneSummary.ts","../src/core/workflow/workflowLoopEviction.ts","../src/types/workflowDisplay.ts","../src/core/workflow/workflowContainerProjector.ts","../src/core/workflow/loopSessionUtils.ts","../src/core/workflowStructureEvents.ts","../src/core/workflow/workflowPathUtils.ts","../src/core/workflow/nativeNestedUtils.ts","../src/core/workflow/embeddedSubworkflowUtils.ts","../src/core/workflowReducer.ts","../src/view/workflow/WorkflowChrome.tsx","../src/view/workflow/WorkflowAggregateContainer.tsx","../src/view/workflow/WorkflowContainerLine.tsx","../src/view/workflow/WorkflowExpandTrigger.tsx","../src/view/workflow/WorkflowMarkdownPreview.tsx","../src/view/workflow/workflowStageListUtils.ts","../src/view/workflow/workflowContainerLineUtils.ts","../src/view/workflow/workflowContainerMemo.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/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 const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\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 onErrorRef.current?.(err);\n } else if (err instanceof Error) {\n onErrorRef.current?.(err);\n }\n });\n\n return () => {\n controller.abort();\n };\n }, [source]);\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","/**\r\n * applicationKind.ts — SSE meta application_kind 契约\r\n *\r\n * 职责:\r\n * 定义双轨 SSE 出口 kind 枚举与 mismatch 错误类型。\r\n *\r\n * 链路位置:\r\n * createAgentxSseSource meta 握手校验。\r\n *\r\n * 当前裁剪范围:\r\n * 仅 agent_session / workflow;无自动推断。\r\n */\r\nexport type ApplicationKind = 'agent_session' | 'workflow';\r\n\r\nexport class ApplicationKindMismatchError extends Error {\r\n readonly name = 'ApplicationKindMismatchError';\r\n readonly expected: ApplicationKind;\r\n readonly actual: string | undefined;\r\n\r\n constructor(expected: ApplicationKind, actual: string | undefined) {\r\n super(\r\n `application_kind mismatch: expected ${expected}, got ${actual ?? '(missing)'}`,\r\n );\r\n this.expected = expected;\r\n this.actual = actual;\r\n }\r\n}\r\n\r\nexport class MissingApplicationKindError extends Error {\r\n readonly name = 'MissingApplicationKindError';\r\n\r\n constructor() {\r\n super('application_kind missing in SSE meta frame');\r\n }\r\n}\r\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 请求头)。 */\nfunction isSseStreamTerminalEvent(\n agentEvent: LangchainAgentEvent,\n expectedApplicationKind?: ApplicationKind,\n): boolean {\n const eventType = agentEvent.event_type;\n if (eventType === 'error') return true;\n if (expectedApplicationKind === 'workflow') {\n return eventType === 'workflow-end' || eventType === 'workflow-failed';\n }\n return eventType === 'finish';\n}\n\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 (isSseStreamTerminalEvent(agentEvent, expectedApplicationKind)) {\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","/**\r\n * ScopedSessionStore.tsx — 外部 SessionTree 注入 SessionStore 上下文\r\n *\r\n * 职责:\r\n * 让 AgentLoopView 在 workflow scoped 子树渲染时复用 Timeline 组件栈。\r\n *\r\n * 链路位置:\r\n * AgentLoopView(tree prop)→ ScopedSessionStoreProvider。\r\n *\r\n * 当前裁剪范围:\r\n * 只读同步 tree prop;不接收 live applyEvent(由父 workflow store 驱动)。\r\n */\r\nimport { useEffect, useRef, type ReactNode } from 'react';\r\n\r\nimport { SessionStoreContext } from '../../core/context/SessionContext';\r\nimport { createSessionStore } from '../../core/store';\r\nimport type { SessionTree } from '../../types/tree';\r\n\r\nexport function ScopedSessionStoreProvider({\r\n tree,\r\n children,\r\n}: {\r\n tree: SessionTree;\r\n children: ReactNode;\r\n}) {\r\n const storeRef = useRef(createSessionStore(tree, { initialEventCount: 1 }));\r\n useEffect(() => {\r\n storeRef.current.setState({ tree });\r\n }, [tree]);\r\n\r\n return (\r\n <SessionStoreContext.Provider value={storeRef.current}>\r\n {children}\r\n </SessionStoreContext.Provider>\r\n );\r\n}\r\n","/**\r\n * AgentLoopView.tsx — CC 主舞台(Timeline + Spinner + 可选 TaskListFooter)\r\n *\r\n * 职责:\r\n * /chat 与 /workflow 内 agent loop 区域共用投影与节点渲染。\r\n *\r\n * 链路位置:\r\n * AgentSession · WorkflowSession scoped loop。\r\n *\r\n * 当前裁剪范围:\r\n * workflow 页 showTaskListFooter=false(合并 Footer 在 P3)。\r\n */\r\nimport type { SessionTree } from '../../types/tree';\r\nimport { SessionTimeline } from '../SessionTimeline';\r\nimport { ScopedSessionStoreProvider } from './ScopedSessionStore';\r\n\r\nexport interface AgentLoopViewProps {\r\n /** 传入时使用隔离 store(workflow scoped);省略则使用上层 SessionStoreContext */\r\n tree?: SessionTree;\r\n showTaskListFooter?: boolean;\r\n virtualized?: boolean;\r\n virtualizeThreshold?: number;\r\n groupParallelTools?: boolean;\r\n}\r\n\r\nfunction AgentLoopViewBody({\r\n showTaskListFooter = true,\r\n virtualized,\r\n virtualizeThreshold,\r\n groupParallelTools,\r\n}: Omit<AgentLoopViewProps, 'tree'>) {\r\n return (\r\n <div className=\"lax-agent-loop-view\" data-testid=\"lax-agent-loop-view\">\r\n <SessionTimeline\r\n virtualized={virtualized}\r\n virtualizeThreshold={virtualizeThreshold}\r\n groupParallelTools={groupParallelTools}\r\n showTaskListFooter={showTaskListFooter}\r\n />\r\n </div>\r\n );\r\n}\r\n\r\nexport function AgentLoopView({\r\n tree,\r\n showTaskListFooter = true,\r\n virtualized,\r\n virtualizeThreshold,\r\n groupParallelTools,\r\n}: AgentLoopViewProps) {\r\n if (tree) {\r\n return (\r\n <ScopedSessionStoreProvider tree={tree}>\r\n <AgentLoopViewBody\r\n showTaskListFooter={showTaskListFooter}\r\n virtualized={virtualized}\r\n virtualizeThreshold={virtualizeThreshold}\r\n groupParallelTools={groupParallelTools}\r\n />\r\n </ScopedSessionStoreProvider>\r\n );\r\n }\r\n return (\r\n <AgentLoopViewBody\r\n showTaskListFooter={showTaskListFooter}\r\n virtualized={virtualized}\r\n virtualizeThreshold={virtualizeThreshold}\r\n groupParallelTools={groupParallelTools}\r\n />\r\n );\r\n}\r\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 /** SSE 流正常结束(传输 resolve);与 status=done 互补,供宿主解锁 loading */\n onStreamComplete?: () => void;\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 onStreamComplete,\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 const sessionStatus = useStore(\n storeRef.current!,\n (s: WorkflowSessionStoreState) => s.state.status,\n );\n const internalErrors = useStore(\n storeRef.current!,\n (s: WorkflowSessionStoreState) => s.state.internalErrors,\n );\n\n const onErrorRef = useRef(onError);\n const onStreamCompleteRef = useRef(onStreamComplete);\n onErrorRef.current = onError;\n onStreamCompleteRef.current = onStreamComplete;\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)\n .then(() => {\n store.getState().markStreamComplete();\n onStreamCompleteRef.current?.();\n })\n .catch((err: unknown) => {\n if (err instanceof SseTransportTerminalError) {\n store.getState().markAsError(err);\n onErrorRef.current?.(err);\n } else if (err instanceof Error) {\n onErrorRef.current?.(err);\n }\n });\n\n return () => {\n controller.abort();\n };\n }, [source]);\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 {(sessionStatus === 'error' || internalErrors.length > 0) ? (\n <div\n className=\"lax-workflow-error\"\n data-testid=\"lax-workflow-error\"\n role=\"alert\"\n >\n {internalErrors[internalErrors.length - 1]?.message\n ?? 'Workflow stream error'}\n </div>\n ) : null}\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","/**\r\n * WorkflowSessionContext.tsx — Workflow store React 上下文\r\n *\r\n * 职责:\r\n * 向 WorkflowSession 子树注入 workflowSessionStore。\r\n *\r\n * 链路位置:\r\n * WorkflowSession Provider。\r\n *\r\n * 当前裁剪范围:\r\n * 与 SessionStoreContext 平行,不混用。\r\n */\r\nimport { createContext, useContext } from 'react';\r\nimport { useStore } from 'zustand';\r\n\r\nimport type { SessionStatus } from '../../types/tree';\r\nimport type { WorkflowSessionStore } from '../workflowSessionStore';\r\n\r\nexport const WorkflowSessionStoreContext = createContext<WorkflowSessionStore | null>(null);\r\n\r\nexport function useWorkflowSessionStoreApi(): WorkflowSessionStore {\r\n const store = useContext(WorkflowSessionStoreContext);\r\n if (!store) {\r\n throw new Error('useWorkflowSessionStoreApi must be used within WorkflowSession');\r\n }\r\n return store;\r\n}\r\n\r\nexport function useWorkflowSessionStatus(): SessionStatus {\r\n const store = useWorkflowSessionStoreApi();\r\n return useStore(store, (s) => s.state.status);\r\n}\r\n","import { createContext, useContext, type ReactNode } from 'react';\r\n\r\n/** 宿主按需 replay 某 loopSessionId 的事件(P2 懒加载) */\r\nexport type WorkflowLoopReplayHandler = (loopSessionId: string) => void | Promise<void>;\r\n\r\nconst WorkflowLoopReplayContext = createContext<WorkflowLoopReplayHandler | undefined>(\r\n undefined,\r\n);\r\n\r\nexport function WorkflowLoopReplayProvider({\r\n onRequestLoopReplay,\r\n children,\r\n}: {\r\n onRequestLoopReplay?: WorkflowLoopReplayHandler;\r\n children: ReactNode;\r\n}) {\r\n return (\r\n <WorkflowLoopReplayContext.Provider value={onRequestLoopReplay}>\r\n {children}\r\n </WorkflowLoopReplayContext.Provider>\r\n );\r\n}\r\n\r\nexport function useWorkflowLoopReplayHandler(): WorkflowLoopReplayHandler | undefined {\r\n return useContext(WorkflowLoopReplayContext);\r\n}\r\n","import { createContext, useContext } from 'react';\r\n\r\nimport {\r\n DEFAULT_WORKFLOW_SCALE_OPTIONS,\r\n type WorkflowScaleOptions,\r\n} from '../../view/workflow/workflowScaleOptions';\r\n\r\nexport const WorkflowScaleContext = createContext<WorkflowScaleOptions>(\r\n DEFAULT_WORKFLOW_SCALE_OPTIONS,\r\n);\r\n\r\nexport function useWorkflowScaleOptions(): WorkflowScaleOptions {\r\n return useContext(WorkflowScaleContext);\r\n}\r\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:历史选项;折叠不变式不再因 non-active 隐藏 running 容器(见 workflow-display-rules §8) */\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 {\n finalizeWorkflowSessionOnStreamComplete,\n reduceWorkflowSession,\n} from './workflowReducer';\nimport {\n evictInactiveLoopTrees,\n evictCompletedLoopOverflow,\n touchCompletedLoopSession,\n} from './workflow/workflowLoopEviction';\nimport { filterAgentLoopReplayEvents } from './workflowStructureEvents';\nimport type { SourceEventContext } from '../transport/types';\nimport { finalizeWorkflowLoopTree } from './workflow/workflowLoopTreeUtils';\nimport type { WorkflowContainerRuntimeNode } from '../types/workflowContainer';\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 /** DES-1:分批 hydrate 进行中的 loopSessionId(store 级,不进 reducer) */\n hydratingLoopSessionIds: Record<string, true>;\n applyEvent: (event: LangchainAgentEvent, ctx?: SourceEventContext) => void;\n applyEvents: (events: LangchainAgentEvent[]) => void;\n reset: () => void;\n markAsError: (error?: Error) => void;\n /** SSE 正常结束:推断 done 并收口 running loop(嵌套 parallel 缺 workflow-end 兜底) */\n markStreamComplete: () => void;\n /** P2:展开 done stage 时 pin,避免淘汰 */\n pinLoopSession: (loopSessionId: string) => void;\n /** P2:宿主 replay 后灌入 loop 树(同步;测试与小批量) */\n hydrateLoopSession: (loopSessionId: string, events: LangchainAgentEvent[]) => void;\n /** DES-1:宿主默认 replay 路径 — 分批 + rAF yield */\n hydrateLoopSessionAsync: (\n loopSessionId: string,\n events: LangchainAgentEvent[],\n options?: HydrateLoopSessionAsyncOptions,\n ) => Promise<void>;\n}\n\nexport interface HydrateLoopSessionAsyncOptions {\n chunkSize?: number;\n signal?: AbortSignal;\n}\n\nconst DEFAULT_HYDRATE_CHUNK_SIZE = 50;\n\nfunction nextAnimationFrame(): Promise<void> {\n return new Promise((resolve) => {\n requestAnimationFrame(() => resolve());\n });\n}\n\nfunction withoutHydrating(\n ids: Record<string, true>,\n loopSessionId: string,\n): Record<string, true> {\n if (!ids[loopSessionId]) return ids;\n const next = { ...ids };\n delete next[loopSessionId];\n return next;\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\n/** scope miss / 传输断流:收口 running 容器与 loop,避免永久 Spinner(D30 A-03)。 */\nfunction finalizeWorkflowSessionOnStreamError(\n state: WorkflowSessionState,\n message: string,\n eventIndex: number,\n stack?: string,\n): WorkflowSessionState {\n const containersById: Record<string, WorkflowContainerRuntimeNode> = {\n ...state.containerTree.containersById,\n };\n for (const [id, node] of Object.entries(containersById)) {\n if (node.status === 'running' || node.status === 'pending') {\n containersById[id] = { ...node, status: 'failed', is_open: false };\n }\n }\n\n const loopTreesBySessionId = { ...state.loopTreesBySessionId };\n for (const [loopSessionId, tree] of Object.entries(loopTreesBySessionId)) {\n if (tree.status === 'running' || tree.status === 'connecting') {\n loopTreesBySessionId[loopSessionId] = finalizeWorkflowLoopTree(tree, 'error');\n }\n }\n\n return {\n ...state,\n status: 'error',\n containerTree: {\n ...state.containerTree,\n containersById,\n activeContainerIds: state.containerTree.activeContainerIds.filter(\n (id) => containersById[id]?.is_open,\n ),\n },\n loopTreesBySessionId,\n activeLoopSessionId: null,\n internalErrors: [\n ...state.internalErrors,\n { eventIndex, eventType: 'stream-error', message, stack },\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 hydratingLoopSessionIds: {},\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 hydratingLoopSessionIds: {},\n });\n },\n markAsError(error) {\n const { state, eventCount } = get();\n const message = error?.message ?? 'Workflow stream error';\n set({\n state: finalizeWorkflowSessionOnStreamError(\n state,\n message,\n eventCount,\n error?.stack,\n ),\n });\n },\n markStreamComplete() {\n set((current) => ({\n state: finalizeState(\n finalizeWorkflowSessionOnStreamComplete(current.state),\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 async hydrateLoopSessionAsync(loopSessionId, events, options) {\n const { hydratingLoopSessionIds } = get();\n if (hydratingLoopSessionIds[loopSessionId]) return;\n\n const filtered = filterAgentLoopReplayEvents(events);\n if (filtered.length === 0) return;\n\n const chunkSize = options?.chunkSize ?? DEFAULT_HYDRATE_CHUNK_SIZE;\n const signal = options?.signal;\n\n set((current) => ({\n hydratingLoopSessionIds: {\n ...current.hydratingLoopSessionIds,\n [loopSessionId]: true,\n },\n }));\n\n try {\n let tree: SessionTree =\n get().state.loopTreesBySessionId[loopSessionId] ?? createEmptyTree();\n let idx = get().eventCount;\n\n for (let offset = 0; offset < filtered.length; offset += chunkSize) {\n if (signal?.aborted) {\n throw new DOMException('Hydrate aborted', 'AbortError');\n }\n\n const chunk = filtered.slice(offset, offset + chunkSize);\n for (const event of chunk) {\n tree = reduceTree(tree, event, idx, reduceOpts);\n idx += 1;\n }\n\n const isLastChunk = offset + chunkSize >= filtered.length;\n set((current) => {\n let next: WorkflowSessionState = {\n ...current.state,\n loopTreesBySessionId: {\n ...current.state.loopTreesBySessionId,\n [loopSessionId]: tree,\n },\n };\n if (isLastChunk) {\n next = touchCompletedLoopSession(next, loopSessionId);\n next = evictCompletedLoopOverflow(next, maxHydratedCompletedLoops);\n }\n next = finalizeState(next);\n return { state: next };\n });\n\n if (!isLastChunk) {\n await nextAnimationFrame();\n }\n }\n } catch {\n set((current) => {\n const { [loopSessionId]: _removed, ...restLoops } =\n current.state.loopTreesBySessionId;\n return {\n state: { ...current.state, loopTreesBySessionId: restLoops },\n hydratingLoopSessionIds: withoutHydrating(\n current.hydratingLoopSessionIds,\n loopSessionId,\n ),\n };\n });\n return;\n }\n\n set((current) => ({\n hydratingLoopSessionIds: withoutHydrating(\n current.hydratingLoopSessionIds,\n loopSessionId,\n ),\n }));\n },\n }));\n}\n","/**\r\n * workflowContainer.ts — Workflow 容器树投影类型\r\n *\r\n * 职责:\r\n * 容器节点、正文块、快照;对齐 SDK workflow_container_projector。\r\n *\r\n * 链路位置:\r\n * workflowContainerProjector → workflowReducer(P1+)→ WorkflowChrome(P2+)。\r\n *\r\n * 当前裁剪范围:\r\n * 不含 React 视图 props;仅投影层 state。\r\n */\r\n\r\nimport type { WorkflowDisplayPayload } from './workflowDisplay';\r\n\r\nexport type WorkflowContainerScope =\r\n | 'workflow'\r\n | 'stage'\r\n | 'item'\r\n | 'branch'\r\n | 'aggregate'\r\n | 'subworkflow';\r\n\r\nexport type WorkflowContainerStatus =\r\n | 'pending'\r\n | 'running'\r\n | 'completed'\r\n | 'failed'\r\n | 'skipped'\r\n | 'cancelled'\r\n | 'blocked'\r\n | 'retrying';\r\n\r\nexport type ContentBlockKind = 'reasoning' | 'text' | 'tool';\r\n\r\nexport interface WorkflowContentBlock {\r\n kind: ContentBlockKind;\r\n preview: string;\r\n tool_name: string | null;\r\n}\r\n\r\nexport interface WorkflowContainerNode {\r\n container_id: string;\r\n scope: WorkflowContainerScope;\r\n workflow_path: string;\r\n workflow_depth: number;\r\n scope_key: string;\r\n title: string;\r\n subtitle: string;\r\n status: WorkflowContainerStatus;\r\n pattern: string;\r\n parent_container_id: string | null;\r\n display: WorkflowDisplayPayload | null;\r\n content_blocks: WorkflowContentBlock[];\r\n is_open: boolean;\r\n}\r\n\r\nexport interface WorkflowContainerTreeSnapshot {\r\n root_container_ids: string[];\r\n containers: Record<string, WorkflowContainerNode>;\r\n active_container_ids: string[];\r\n}\r\n\r\n/** reducer 运行时节点:投影字段 + loop 绑定(P1) */\r\nexport interface WorkflowContainerRuntimeNode extends WorkflowContainerNode {\r\n loopSessionId: string | null;\r\n}\r\n\r\n/** WorkflowSession 容器树 state(P1+) */\r\nexport interface WorkflowContainerTreeState {\r\n rootContainerIds: string[];\r\n activeContainerIds: string[];\r\n containersById: Record<string, WorkflowContainerRuntimeNode>;\r\n}\r\n\r\nexport function createEmptyWorkflowContainerTreeState(): WorkflowContainerTreeState {\r\n return {\r\n rootContainerIds: [],\r\n activeContainerIds: [],\r\n containersById: {},\r\n };\r\n}\r\n\r\nexport function containerTreeToSnapshot(\r\n tree: WorkflowContainerTreeState,\r\n): WorkflowContainerTreeSnapshot {\r\n const containers: Record<string, WorkflowContainerNode> = {};\r\n for (const [id, node] of Object.entries(tree.containersById)) {\r\n const { loopSessionId: _loop, ...projection } = node;\r\n containers[id] = projection;\r\n }\r\n return {\r\n root_container_ids: [...tree.rootContainerIds],\r\n active_container_ids: [...tree.activeContainerIds],\r\n containers,\r\n };\r\n}\r\n\r\nexport type ContainerAction = 'open' | 'close' | 'append-content';\r\n\r\n/** SDK fixture expected.containers 子集(契约对照) */\r\nexport interface WorkflowContainerExpectedNode {\r\n title: string;\r\n subtitle: string;\r\n status: WorkflowContainerStatus;\r\n scope: WorkflowContainerScope;\r\n parent_container_id: string | null;\r\n content_blocks: WorkflowContentBlock[];\r\n}\r\n\r\nexport interface SdkContainerFixtureExpected {\r\n root_container_ids: string[];\r\n active_container_ids: string[];\r\n containers: Record<string, WorkflowContainerExpectedNode>;\r\n cli_tree_contains?: string[];\r\n}\r\n\r\nexport interface SdkContainerFixture {\r\n scenario: string;\r\n description?: string;\r\n events: Array<{\r\n event_type: string;\r\n data: Record<string, unknown>;\r\n step_index?: number | null;\r\n tool_name?: string | null;\r\n session_id?: string | null;\r\n timestamp?: number;\r\n }>;\r\n expected: SdkContainerFixtureExpected;\r\n}\r\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, type SessionStatus } from '../../types/tree';\n\n/** scoped loop 是否仍在写入(结构帧可能早于 agent 结束)。 */\nexport function isWorkflowLoopTreeActive(tree?: SessionTree): boolean {\n return tree?.status === 'running' || tree?.status === 'connecting';\n}\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/** stage-done 等结构关闭时,将仍 running 的 scoped loop 树收口(Spinner / done 摘要)。 */\nexport function finalizeWorkflowLoopTree(\n tree: SessionTree,\n terminalStatus: Extract<SessionStatus, 'done' | 'error'> = 'done',\n): SessionTree {\n if (tree.status === 'done' || tree.status === 'error') {\n return tree;\n }\n\n const byId = { ...tree.byId };\n for (const [id, node] of Object.entries(byId)) {\n if (!node) continue;\n if (\n (node.kind === 'text' || node.kind === 'reasoning')\n && node.status === 'streaming'\n ) {\n byId[id] = { ...node, status: 'done' };\n }\n if (node.kind === 'tool_call' && node.status === 'running') {\n byId[id] = {\n ...node,\n status: terminalStatus === 'error' ? 'failed' : 'done',\n };\n }\n }\n\n return {\n ...tree,\n byId,\n activeRoundId: null,\n status: terminalStatus,\n };\n}\n","/**\r\n * stageDoneSummary.ts — Stage 完成摘要(对齐 CC Agent Done 行)\r\n *\r\n * 职责:\r\n * 从 scoped loop tree 统计 tool uses / duration / agent turn;提取 text teaser。\r\n *\r\n * 链路位置:\r\n * WorkflowStageContainer 完成态显示(P2+)。\r\n *\r\n * 当前裁剪范围:\r\n * 不含 React;仅纯函数统计。\r\n */\r\nimport type { SessionTree } from '../../types/tree';\r\n\r\nexport interface StageDoneSummary {\r\n label: string;\r\n teaser: string;\r\n extraLines: number;\r\n}\r\n\r\nfunction countToolUses(tree: SessionTree): number {\r\n return Object.values(tree.byId).filter((node) => node.kind === 'tool_call').length;\r\n}\r\n\r\nfunction computeDurationSeconds(tree: SessionTree): number | null {\r\n const started = tree.meta.startedAt;\r\n if (started == null) return null;\r\n\r\n let maxTs = started;\r\n for (const node of Object.values(tree.byId)) {\r\n if ('endedAt' in node && typeof node.endedAt === 'number') {\r\n maxTs = Math.max(maxTs, node.endedAt);\r\n }\r\n if ('startedAt' in node && typeof node.startedAt === 'number') {\r\n maxTs = Math.max(maxTs, node.startedAt);\r\n }\r\n }\r\n\r\n const seconds = Math.round((maxTs - started) / 1000);\r\n return seconds > 0 ? seconds : null;\r\n}\r\n\r\nfunction lastTextContent(tree: SessionTree): string {\r\n const textNodes = Object.values(tree.byId).filter((node) => node.kind === 'text');\r\n if (textNodes.length === 0) return '';\r\n return textNodes[textNodes.length - 1]!.accumulated.trim();\r\n}\r\n\r\n/** 从 loop tree 构建 Stage Done 摘要 + 首行 teaser(非 display.description)。 */\r\nexport function buildStageDoneSummary(tree: SessionTree): StageDoneSummary | null {\r\n if (tree.status !== 'done' && tree.status !== 'error') return null;\r\n\r\n const toolUses = countToolUses(tree);\r\n const duration = computeDurationSeconds(tree);\r\n const durationSuffix = duration != null ? ` · ${duration}s` : '';\r\n\r\n const label =\r\n toolUses > 0\r\n ? `Done (${toolUses} tool use${toolUses === 1 ? '' : 's'}${durationSuffix})`\r\n : `Done (1 agent turn${durationSuffix})`;\r\n\r\n const fullText = lastTextContent(tree);\r\n const lines = fullText.split('\\n').map((line) => line.trim()).filter(Boolean);\r\n const teaser = lines[0] ?? '';\r\n const extraLines = Math.max(0, lines.length - 1);\r\n\r\n return { label, teaser, extraLines };\r\n}\r\n\r\nexport function formatTeaserExpandHint(extraLines: number, verbose: boolean): string | null {\r\n if (extraLines <= 0) return null;\r\n const shown = verbose ? Math.min(extraLines, 2) : 0;\r\n const hidden = extraLines - shown;\r\n if (hidden <= 0) return null;\r\n return `… +${hidden} lines (ctrl+o to expand)`;\r\n}\r\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 hasRunningParallelSibling(\n node: WorkflowContainerRuntimeNode,\n tree: WorkflowContainerTreeState,\n): boolean {\n if (node.scope !== 'item' || !node.parent_container_id) return false;\n for (const sibling of Object.values(tree.containersById)) {\n if (sibling.container_id === node.container_id) continue;\n if (sibling.scope !== 'item') continue;\n if (sibling.parent_container_id !== node.parent_container_id) continue;\n if (sibling.status === 'running' || sibling.status === 'retrying') return true;\n }\n return false;\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 // 并行组内 sibling 仍 running 时,保留已完成 item 的 loop 树(避免只见 teaser 不见 tool)\n if (\n (node.status === 'completed' || node.status === 'failed')\n && hasRunningParallelSibling(node, state.containerTree)\n ) {\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 candidateEvictIds = state.hotCompletedLoopSessionIds.slice(0, overflow);\n let 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 candidateEvictIds) {\n const tree = nextLoops[id];\n if (!tree) continue;\n const container = byLoop.get(id);\n // 并行 sibling 仍 running 时不淘汰已完成 item 的 loop(与 evictInactiveLoopTrees 同构)\n if (\n container\n && hasRunningParallelSibling(container, state.containerTree)\n ) {\n if (!trimmedIds.includes(id)) {\n trimmedIds = [id, ...trimmedIds];\n }\n continue;\n }\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","/**\r\n * workflowDisplay.ts — SDK WorkflowDisplayPayload 契约(TS)\r\n *\r\n * 职责:\r\n * 对齐 langchain_agentx WorkflowDisplayPayload;结构事件 data.display 类型。\r\n *\r\n * 链路位置:\r\n * workflowContainerProjector → WorkflowChrome(P2+)。\r\n *\r\n * 当前裁剪范围:\r\n * 只读消费;不计算 display(由 SDK enricher 注入)。\r\n */\r\n\r\nexport type WorkflowDisplayScope =\r\n | 'workflow'\r\n | 'stage'\r\n | 'item'\r\n | 'branch'\r\n | 'aggregate'\r\n | 'subworkflow';\r\n\r\nexport type WorkflowDisplayStatus =\r\n | 'pending'\r\n | 'running'\r\n | 'completed'\r\n | 'failed'\r\n | 'skipped'\r\n | 'cancelled'\r\n | 'blocked'\r\n | 'retrying';\r\n\r\n/** 对齐 SDK display_resolver.WorkflowDisplayPayload */\r\nexport interface WorkflowDisplayPayload {\r\n version?: number;\r\n scope?: WorkflowDisplayScope;\r\n title?: string;\r\n description?: string;\r\n workflow_title?: string;\r\n workflow_description?: string;\r\n parent_title?: string;\r\n breadcrumb?: string[];\r\n progress_current?: number;\r\n progress_total?: number;\r\n progress_label?: string;\r\n progress_indeterminate?: boolean;\r\n status?: WorkflowDisplayStatus;\r\n status_reason?: string;\r\n icon?: string;\r\n item_index?: number;\r\n item_total?: number;\r\n metrics_completed?: number;\r\n metrics_running?: number;\r\n metrics_failed?: number;\r\n metrics_total?: number;\r\n decision_label?: string;\r\n pattern?: string;\r\n debug_key?: string;\r\n}\r\n\r\nexport function readDisplayPayload(data: Record<string, unknown>): WorkflowDisplayPayload | null {\r\n const display = data.display;\r\n if (display != null && typeof display === 'object' && !Array.isArray(display)) {\r\n return display as WorkflowDisplayPayload;\r\n }\r\n return null;\r\n}\r\n","/**\r\n * workflowContainerProjector.ts — LangchainAgentEvent → 容器树投影\r\n *\r\n * 职责:\r\n * 对齐 SDK workflow_container_projector;维护 active set;正文路由。\r\n *\r\n * 链路位置:\r\n * workflowReducer(P1)← consume LangchainAgentEvent;fixture 单测 SSOT。\r\n *\r\n * 当前裁剪范围:\r\n * 仅投影层;不负责 React 渲染或 loop tree reduceTree。\r\n */\r\nimport type { LangchainAgentEvent } from '../../types/events';\r\nimport { readDisplayPayload } from '../../types/workflowDisplay';\r\nimport type {\r\n ContainerAction,\r\n WorkflowContainerNode,\r\n WorkflowContainerScope,\r\n WorkflowContainerStatus,\r\n WorkflowContainerTreeSnapshot,\r\n WorkflowContentBlock,\r\n} from '../../types/workflowContainer';\r\n\r\nconst OPEN_EVENT_TYPES = new Set<string>([\r\n 'workflow-start',\r\n 'subworkflow-start',\r\n 'stage-start',\r\n 'parallel-item-start',\r\n 'parallel-aggregate-start',\r\n 'route-branch-start',\r\n]);\r\n\r\nconst CLOSE_EVENT_TYPES = new Set<string>([\r\n 'workflow-end',\r\n 'workflow-failed',\r\n 'subworkflow-end',\r\n 'stage-done',\r\n 'stage-failed',\r\n 'parallel-item-done',\r\n 'parallel-item-failed',\r\n 'parallel-aggregate-done',\r\n 'parallel-aggregate-failed',\r\n 'route-branch-done',\r\n 'route-branch-failed',\r\n]);\r\n\r\nconst EVENT_TYPE_TO_SCOPE: Record<string, WorkflowContainerScope> = {\r\n 'workflow-start': 'workflow',\r\n 'workflow-end': 'workflow',\r\n 'workflow-failed': 'workflow',\r\n 'subworkflow-start': 'subworkflow',\r\n 'subworkflow-end': 'subworkflow',\r\n 'stage-start': 'stage',\r\n 'stage-done': 'stage',\r\n 'stage-failed': 'stage',\r\n 'parallel-item-start': 'item',\r\n 'parallel-item-done': 'item',\r\n 'parallel-item-failed': 'item',\r\n 'parallel-aggregate-start': 'aggregate',\r\n 'parallel-aggregate-done': 'aggregate',\r\n 'parallel-aggregate-failed': 'aggregate',\r\n 'route-branch-start': 'branch',\r\n 'route-branch-done': 'branch',\r\n 'route-branch-failed': 'branch',\r\n};\r\n\r\nconst CONTENT_EVENT_TYPES = new Set<string>([\r\n 'reasoning-start',\r\n 'reasoning-delta',\r\n 'reasoning-end',\r\n 'text-start',\r\n 'text-delta',\r\n 'text-end',\r\n 'tool-input',\r\n 'tool-input-start',\r\n 'tool-input-delta',\r\n 'tool-call',\r\n 'tool-result',\r\n 'tool-error',\r\n 'tool-progress',\r\n]);\r\n\r\nconst SCOPE_PRIORITY: Record<WorkflowContainerScope, number> = {\r\n workflow: 0,\r\n subworkflow: 1,\r\n aggregate: 2,\r\n stage: 3,\r\n item: 3,\r\n branch: 3,\r\n};\r\n\r\nconst FAILED_CLOSE_TYPES = new Set<string>([\r\n 'workflow-failed',\r\n 'stage-failed',\r\n 'parallel-item-failed',\r\n 'parallel-aggregate-failed',\r\n 'route-branch-failed',\r\n]);\r\n\r\nexport function buildContainerId(\r\n workflowPath: string,\r\n scope: WorkflowContainerScope,\r\n scopeKey: string,\r\n): string {\r\n return `${workflowPath}|${scope}:${scopeKey}`;\r\n}\r\n\r\nfunction readString(data: Record<string, unknown>, key: string): string | undefined {\r\n const value = data[key];\r\n return typeof value === 'string' ? value : undefined;\r\n}\r\n\r\nexport function resolveScopeKey(eventType: string, data: Record<string, unknown>): string {\r\n if (\r\n eventType === 'workflow-start'\r\n || eventType === 'workflow-end'\r\n || eventType === 'workflow-failed'\r\n ) {\r\n const workflowId = readString(data, 'workflow_id');\r\n if (workflowId) return workflowId;\r\n return readString(data, 'workflow_path') ?? 'workflow';\r\n }\r\n\r\n if (eventType === 'subworkflow-start' || eventType === 'subworkflow-end') {\r\n return readString(data, 'child_workflow_id') ?? 'subworkflow';\r\n }\r\n\r\n if (\r\n eventType === 'stage-start'\r\n || eventType === 'stage-done'\r\n || eventType === 'stage-failed'\r\n ) {\r\n const stageKey = readString(data, 'stage_key');\r\n if (stageKey) return stageKey;\r\n const stageIndex = data.stage_index;\r\n return typeof stageIndex === 'number' ? String(stageIndex) : 'stage';\r\n }\r\n\r\n if (\r\n eventType === 'parallel-item-start'\r\n || eventType === 'parallel-item-done'\r\n || eventType === 'parallel-item-failed'\r\n ) {\r\n const itemKey = readString(data, 'item_key');\r\n if (itemKey) return itemKey;\r\n const itemIndex = data.item_index;\r\n return typeof itemIndex === 'number' ? String(itemIndex) : 'item';\r\n }\r\n\r\n if (\r\n eventType === 'parallel-aggregate-start'\r\n || eventType === 'parallel-aggregate-done'\r\n || eventType === 'parallel-aggregate-failed'\r\n ) {\r\n return readString(data, 'aggregate_key') ?? 'aggregate';\r\n }\r\n\r\n if (\r\n eventType === 'route-branch-start'\r\n || eventType === 'route-branch-done'\r\n || eventType === 'route-branch-failed'\r\n ) {\r\n return readString(data, 'branch_key') ?? readString(data, 'branch_node') ?? 'branch';\r\n }\r\n\r\n const display = readDisplayPayload(data);\r\n if (display?.debug_key) return display.debug_key;\r\n\r\n return 'unknown';\r\n}\r\n\r\nfunction displayStatus(\r\n data: Record<string, unknown>,\r\n fallback: WorkflowContainerStatus,\r\n): WorkflowContainerStatus {\r\n const display = readDisplayPayload(data);\r\n if (display?.status) return display.status;\r\n return fallback;\r\n}\r\n\r\nfunction closeStatus(eventType: string): WorkflowContainerStatus {\r\n return FAILED_CLOSE_TYPES.has(eventType) ? 'failed' : 'completed';\r\n}\r\n\r\nfunction readPreview(data: Record<string, unknown>, ...keys: string[]): string {\r\n for (const key of keys) {\r\n const value = data[key];\r\n if (typeof value === 'string') return value;\r\n }\r\n return '';\r\n}\r\n\r\nfunction contentBlockFromEvent(event: LangchainAgentEvent): WorkflowContentBlock | null {\r\n const { event_type: eventType } = event;\r\n const payload = (event.data ?? {}) as Record<string, unknown>;\r\n\r\n if (\r\n eventType === 'reasoning-start'\r\n || eventType === 'reasoning-delta'\r\n || eventType === 'reasoning-end'\r\n ) {\r\n let preview = readPreview(payload, 'delta', 'text', 'reasoning');\r\n if (!preview && eventType === 'reasoning-start') preview = 'Thinking…';\r\n return { kind: 'reasoning', preview, tool_name: null };\r\n }\r\n\r\n if (\r\n eventType === 'text-start'\r\n || eventType === 'text-delta'\r\n || eventType === 'text-end'\r\n ) {\r\n const preview = readPreview(payload, 'delta', 'text');\r\n return { kind: 'text', preview, tool_name: null };\r\n }\r\n\r\n if (CONTENT_EVENT_TYPES.has(eventType)) {\r\n const toolName = event.tool_name ?? readString(payload, 'tool_name');\r\n const preview =\r\n readPreview(payload, 'summary', 'output', 'input', 'delta')\r\n || toolName\r\n || eventType;\r\n return {\r\n kind: 'tool',\r\n preview,\r\n tool_name: toolName ?? null,\r\n };\r\n }\r\n\r\n return null;\r\n}\r\n\r\nexport function resolveContentScopeKey(data: Record<string, unknown>): string | null {\r\n for (const keyName of ['stage_key', 'item_key', 'branch_key', 'aggregate_key', 'debug_key'] as const) {\r\n const value = readString(data, keyName);\r\n if (value) return value;\r\n }\r\n const display = readDisplayPayload(data);\r\n return display?.debug_key ?? null;\r\n}\r\n\r\n/** 按容器身份索引的活跃集(并发 item 不依赖 LIFO 单栈) */\r\nexport class WorkflowContainerActiveSet {\r\n private readonly openOrder: string[] = [];\r\n private readonly nodes: Record<string, WorkflowContainerNode> = {};\r\n\r\n restoreNode(node: WorkflowContainerNode): void {\r\n this.nodes[node.container_id] = { ...node };\r\n if (node.is_open && !this.openOrder.includes(node.container_id)) {\r\n this.openOrder.push(node.container_id);\r\n }\r\n }\r\n\r\n open(node: WorkflowContainerNode): void {\r\n this.nodes[node.container_id] = node;\r\n if (!this.openOrder.includes(node.container_id)) {\r\n this.openOrder.push(node.container_id);\r\n }\r\n }\r\n\r\n close(containerId: string, status: WorkflowContainerStatus): void {\r\n const node = this.nodes[containerId];\r\n if (!node) return;\r\n node.status = status;\r\n node.is_open = false;\r\n const idx = this.openOrder.indexOf(containerId);\r\n if (idx !== -1) this.openOrder.splice(idx, 1);\r\n }\r\n\r\n get activeIds(): string[] {\r\n return [...this.openOrder];\r\n }\r\n\r\n getNode(containerId: string): WorkflowContainerNode | undefined {\r\n return this.nodes[containerId];\r\n }\r\n\r\n get nodesById(): Record<string, WorkflowContainerNode> {\r\n return this.nodes;\r\n }\r\n\r\n rankContainer(containerId: string): [number, number, number, number] {\r\n const node = this.nodes[containerId];\r\n if (!node) return [-1, -1, -1, -1];\r\n const openIndex = this.openOrder.indexOf(containerId);\r\n const scopePriority = SCOPE_PRIORITY[node.scope] ?? 0;\r\n return [node.workflow_depth, scopePriority, node.workflow_path.length, openIndex];\r\n }\r\n\r\n deepestActive(): string | null {\r\n if (this.openOrder.length === 0) return null;\r\n return this.openOrder.reduce((best, cid) =>\r\n this.compareRank(cid, best) > 0 ? cid : best,\r\n );\r\n }\r\n\r\n resolveContentTarget(workflowPath: string | null, scopeKey: string | null): string | null {\r\n if (scopeKey) {\r\n for (let i = this.openOrder.length - 1; i >= 0; i -= 1) {\r\n const containerId = this.openOrder[i]!;\r\n const node = this.nodes[containerId]!;\r\n if (node.scope_key === scopeKey && node.is_open) {\r\n if (workflowPath === null || node.workflow_path === workflowPath) {\r\n return containerId;\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (workflowPath) {\r\n const candidates = this.openOrder.filter((cid) => {\r\n const node = this.nodes[cid]!;\r\n if (!node.is_open) return false;\r\n return (\r\n node.workflow_path === workflowPath\r\n || workflowPath.startsWith(`${node.workflow_path}>`)\r\n );\r\n });\r\n if (candidates.length > 0) {\r\n return candidates.reduce((best, cid) =>\r\n this.compareRank(cid, best) > 0 ? cid : best,\r\n );\r\n }\r\n }\r\n\r\n return this.deepestActive();\r\n }\r\n\r\n closeDescendantsOfPath(workflowPath: string, status: WorkflowContainerStatus): void {\r\n const toClose = this.openOrder.filter((cid) => {\r\n const node = this.nodes[cid]!;\r\n return (\r\n node.workflow_path === workflowPath\r\n || node.workflow_path.startsWith(`${workflowPath}>`)\r\n );\r\n });\r\n for (const containerId of toClose) {\r\n this.close(containerId, status);\r\n }\r\n }\r\n\r\n private compareRank(a: string, b: string): number {\r\n const ra = this.rankContainer(a);\r\n const rb = this.rankContainer(b);\r\n for (let i = 0; i < ra.length; i += 1) {\r\n if (ra[i]! > rb[i]!) return 1;\r\n if (ra[i]! < rb[i]!) return -1;\r\n }\r\n return 0;\r\n }\r\n\r\n /** 供 StateMachine 比较容器深度 rank */\r\n compareContainerRank(a: string, b: string): number {\r\n return this.compareRank(a, b);\r\n }\r\n}\r\n\r\n/** 事件 → 容器状态机(对齐 SDK reference) */\r\nexport class WorkflowContainerStateMachine {\r\n private readonly active = new WorkflowContainerActiveSet();\r\n private readonly rootIds: string[] = [];\r\n private suppressContentContainerIds: ReadonlySet<string> = new Set();\r\n\r\n get activeSet(): WorkflowContainerActiveSet {\r\n return this.active;\r\n }\r\n\r\n setSuppressContentContainerIds(ids: ReadonlySet<string>): void {\r\n this.suppressContentContainerIds = ids;\r\n }\r\n\r\n rehydrate(snapshot: WorkflowContainerTreeSnapshot): void {\r\n this.rootIds.length = 0;\r\n this.rootIds.push(...snapshot.root_container_ids);\r\n for (const node of Object.values(snapshot.containers)) {\r\n this.active.restoreNode(node);\r\n }\r\n }\r\n\r\n apply(event: LangchainAgentEvent): ContainerAction | null {\r\n const eventType = event.event_type;\r\n const data = (event.data ?? {}) as Record<string, unknown>;\r\n\r\n if (OPEN_EVENT_TYPES.has(eventType)) {\r\n this.openContainer(eventType, data);\r\n return 'open';\r\n }\r\n\r\n if (CLOSE_EVENT_TYPES.has(eventType)) {\r\n this.closeContainer(eventType, data);\r\n return 'close';\r\n }\r\n\r\n if (CONTENT_EVENT_TYPES.has(eventType)) {\r\n this.appendContent(event);\r\n return 'append-content';\r\n }\r\n\r\n return null;\r\n }\r\n\r\n snapshot(): WorkflowContainerTreeSnapshot {\r\n return {\r\n root_container_ids: [...this.rootIds],\r\n containers: { ...this.active.nodesById },\r\n active_container_ids: this.active.activeIds,\r\n };\r\n }\r\n\r\n private openContainer(eventType: string, data: Record<string, unknown>): void {\r\n const scope = EVENT_TYPE_TO_SCOPE[eventType];\r\n if (!scope) return;\r\n\r\n const workflowPath = readString(data, 'workflow_path') ?? '';\r\n const workflowDepth =\r\n typeof data.workflow_depth === 'number' ? data.workflow_depth : 0;\r\n const scopeKey = resolveScopeKey(eventType, data);\r\n const containerId = buildContainerId(workflowPath, scope, scopeKey);\r\n\r\n const display = readDisplayPayload(data);\r\n const title = display?.title ?? scopeKey;\r\n const subtitle = display?.description ?? '';\r\n const pattern = display?.pattern ?? '';\r\n const status = displayStatus(data, 'running');\r\n const parentId = this.resolveParentId(workflowPath, scope);\r\n\r\n const node: WorkflowContainerNode = {\r\n container_id: containerId,\r\n scope,\r\n workflow_path: workflowPath,\r\n workflow_depth: workflowDepth,\r\n scope_key: scopeKey,\r\n title,\r\n subtitle,\r\n status,\r\n pattern,\r\n parent_container_id: parentId,\r\n display,\r\n content_blocks: [],\r\n is_open: true,\r\n };\r\n\r\n this.active.open(node);\r\n if (scope === 'workflow' && !this.rootIds.includes(containerId)) {\r\n this.rootIds.push(containerId);\r\n }\r\n }\r\n\r\n private closeContainer(eventType: string, data: Record<string, unknown>): void {\r\n const scope = EVENT_TYPE_TO_SCOPE[eventType];\r\n if (!scope) return;\r\n\r\n const workflowPath = readString(data, 'workflow_path') ?? '';\r\n const scopeKey = resolveScopeKey(eventType, data);\r\n const containerId = buildContainerId(workflowPath, scope, scopeKey);\r\n const status = displayStatus(data, closeStatus(eventType));\r\n\r\n this.active.close(containerId, status);\r\n if (scope === 'workflow') {\r\n this.active.closeDescendantsOfPath(workflowPath, status);\r\n }\r\n }\r\n\r\n private appendContent(event: LangchainAgentEvent): void {\r\n const data = (event.data ?? {}) as Record<string, unknown>;\r\n const workflowPath = readString(data, 'workflow_path') ?? null;\r\n const scopeKey = resolveContentScopeKey(data);\r\n\r\n const targetId = this.active.resolveContentTarget(workflowPath, scopeKey);\r\n if (!targetId) return;\r\n if (this.suppressContentContainerIds.has(targetId)) return;\r\n\r\n const block = contentBlockFromEvent(event);\r\n if (!block) return;\r\n\r\n const node = this.active.getNode(targetId);\r\n if (!node) return;\r\n\r\n const last = node.content_blocks[node.content_blocks.length - 1];\r\n if (\r\n last\r\n && last.kind === block.kind\r\n && (block.kind === 'reasoning' || block.kind === 'text')\r\n ) {\r\n if (block.preview) {\r\n if (block.kind === 'reasoning' && last.preview === 'Thinking…') {\r\n last.preview = block.preview;\r\n } else {\r\n last.preview = `${last.preview}${block.preview}`;\r\n }\r\n }\r\n return;\r\n }\r\n\r\n node.content_blocks.push(block);\r\n }\r\n\r\n private resolveParentId(\r\n workflowPath: string,\r\n scope: WorkflowContainerScope,\r\n ): string | null {\r\n if (scope === 'workflow') return null;\r\n\r\n const openNodes = this.active.activeIds\r\n .map((cid) => this.active.getNode(cid)!)\r\n .filter((node) => node.is_open);\r\n\r\n if (openNodes.length === 0) return null;\r\n\r\n const prefixCandidates = openNodes.filter(\r\n (node) =>\r\n workflowPath === node.workflow_path\r\n || workflowPath.startsWith(`${node.workflow_path}>`),\r\n );\r\n\r\n if (prefixCandidates.length > 0) {\r\n const parentCandidates = prefixCandidates.filter((node) => {\r\n // 并行 item 不应挂到已打开的 sibling item 下;否则第二路会误落到 workflow 根。\r\n if (scope === 'item') return node.scope !== 'item';\r\n if (scope === 'aggregate') return node.scope !== 'item' && node.scope !== 'aggregate';\r\n return node.scope !== scope;\r\n });\r\n if (parentCandidates.length > 0) {\r\n const parent = parentCandidates.reduce((best, node) =>\r\n this.active.compareContainerRank(node.container_id, best.container_id) > 0\r\n ? node\r\n : best,\r\n );\r\n if (parent.workflow_path === workflowPath && parent.scope === 'workflow') {\r\n return parent.container_id;\r\n }\r\n if (workflowPath.startsWith(`${parent.workflow_path}>`)) {\r\n return parent.container_id;\r\n }\r\n if (parent.workflow_path === workflowPath && parent.scope !== scope) {\r\n return parent.container_id;\r\n }\r\n }\r\n }\r\n\r\n const workflowCandidates = openNodes.filter((node) => node.scope === 'workflow');\r\n if (workflowCandidates.length > 0) {\r\n return workflowCandidates.reduce((best, node) =>\r\n this.active.compareContainerRank(node.container_id, best.container_id) > 0\r\n ? node\r\n : best,\r\n ).container_id;\r\n }\r\n\r\n return openNodes.reduce((best, node) =>\r\n this.active.compareContainerRank(node.container_id, best.container_id) > 0\r\n ? node\r\n : best,\r\n ).container_id;\r\n }\r\n}\r\n\r\n/** LangchainAgentEvent 流 → 容器树快照 */\r\nexport class WorkflowContainerTreeProjector {\r\n private readonly machine = new WorkflowContainerStateMachine();\r\n\r\n rehydrate(snapshot: WorkflowContainerTreeSnapshot): void {\r\n this.machine.rehydrate(snapshot);\r\n }\r\n\r\n setSuppressContentContainerIds(ids: ReadonlySet<string>): void {\r\n this.machine.setSuppressContentContainerIds(ids);\r\n }\r\n\r\n consume(event: LangchainAgentEvent): ContainerAction | null {\r\n return this.machine.apply(event);\r\n }\r\n\r\n consumeAll(events: LangchainAgentEvent[]): WorkflowContainerTreeSnapshot {\r\n for (const event of events) {\r\n this.consume(event);\r\n }\r\n return this.snapshot();\r\n }\r\n\r\n snapshot(): WorkflowContainerTreeSnapshot {\r\n return this.machine.snapshot();\r\n }\r\n}\r\n\r\n/** 纯函数:快照 + 单事件 → 新快照(供 workflowReducer 双轨归约) */\r\nexport interface ReduceContainerSnapshotOptions {\r\n /** 已绑定 loop 的容器不再写入 content_blocks(过程层走 AgentLoopView) */\r\n suppressContentContainerIds?: ReadonlySet<string>;\r\n}\r\n\r\nexport function reduceContainerSnapshot(\r\n snapshot: WorkflowContainerTreeSnapshot,\r\n event: LangchainAgentEvent,\r\n options?: ReduceContainerSnapshotOptions,\r\n): WorkflowContainerTreeSnapshot {\r\n const projector = new WorkflowContainerTreeProjector();\r\n projector.rehydrate(snapshot);\r\n if (options?.suppressContentContainerIds?.size) {\r\n projector.setSuppressContentContainerIds(options.suppressContentContainerIds);\r\n }\r\n projector.consume(event);\r\n return projector.snapshot();\r\n}\r\n\r\n/** 从 open 容器集解析 agent 正文路由目标 */\r\nexport function resolveContentTargetFromSnapshot(\r\n snapshot: WorkflowContainerTreeSnapshot,\r\n workflowPath: string | null,\r\n scopeKey: string | null,\r\n): string | null {\r\n const active = new WorkflowContainerActiveSet();\r\n for (const containerId of snapshot.active_container_ids) {\r\n const node = snapshot.containers[containerId];\r\n if (node?.is_open) active.restoreNode(node);\r\n }\r\n return active.resolveContentTarget(workflowPath, scopeKey);\r\n}\r\n\r\n/** 投影快照合并 loopSessionId(projector 不管理 loop 绑定) */\r\nexport function mergeRuntimeContainerNodes(\r\n prev: Record<string, { loopSessionId: string | null }>,\r\n snapshot: WorkflowContainerTreeSnapshot,\r\n): Record<\r\n string,\r\n WorkflowContainerNode & { loopSessionId: string | null }\r\n> {\r\n const out: Record<string, WorkflowContainerNode & { loopSessionId: string | null }> = {};\r\n for (const [containerId, node] of Object.entries(snapshot.containers)) {\r\n out[containerId] = {\r\n ...node,\r\n loopSessionId: prev[containerId]?.loopSessionId ?? null,\r\n };\r\n }\r\n return out;\r\n}\r\n\r\n/** 序列化为 SDK fixture expected 对照结构 */\r\nexport function snapshotToExpectedFormat(\r\n snapshot: WorkflowContainerTreeSnapshot,\r\n): {\r\n root_container_ids: string[];\r\n active_container_ids: string[];\r\n containers: Record<\r\n string,\r\n {\r\n title: string;\r\n subtitle: string;\r\n status: WorkflowContainerStatus;\r\n scope: WorkflowContainerScope;\r\n parent_container_id: string | null;\r\n content_blocks: WorkflowContentBlock[];\r\n }\r\n >;\r\n} {\r\n const containers: Record<\r\n string,\r\n {\r\n title: string;\r\n subtitle: string;\r\n status: WorkflowContainerStatus;\r\n scope: WorkflowContainerScope;\r\n parent_container_id: string | null;\r\n content_blocks: WorkflowContentBlock[];\r\n }\r\n > = {};\r\n\r\n for (const [cid, node] of Object.entries(snapshot.containers)) {\r\n containers[cid] = {\r\n title: node.title,\r\n subtitle: node.subtitle,\r\n status: node.status,\r\n scope: node.scope,\r\n parent_container_id: node.parent_container_id,\r\n content_blocks: node.content_blocks.map((b) => ({\r\n kind: b.kind,\r\n preview: b.preview,\r\n tool_name: b.tool_name,\r\n })),\r\n };\r\n }\r\n\r\n return {\r\n root_container_ids: snapshot.root_container_ids,\r\n active_container_ids: snapshot.active_container_ids,\r\n containers,\r\n };\r\n}\r\n\r\nexport type {\r\n WorkflowContainerNode,\r\n WorkflowContainerTreeSnapshot,\r\n WorkflowContentBlock,\r\n ContainerAction,\r\n};\r\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 'parallel-aggregate-start': 'aggregate',\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 ?? readString(data, 'aggregate_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","/**\r\n * workflowStructureEvents.ts — Workflow 结构事件类型守卫\r\n *\r\n * 职责:\r\n * 区分 workflow 编排结构 event_type 与 agent loop 事件。\r\n *\r\n * 链路位置:\r\n * workflowReducer 路由 · hydrateLoopSession 过滤 · Source application_kind 守卫。\r\n *\r\n * 当前裁剪范围:\r\n * 显式集合与 backend sse.WORKFLOW_STRUCTURE_EVENT_TYPES 对齐;\r\n * 识别逻辑另用前缀(与 task_sync/multi_sse_bridge.py 一致),避免 SDK 新增结构类型漏判。\r\n */\r\nimport { DEFAULT_EVENT_TIERS } from '../types/events';\r\n\r\n/** 与 backend/langchain_agentx_stream_ui_backend/task_sync/multi_sse_bridge.py 对齐 */\r\nexport const WORKFLOW_STRUCTURE_EVENT_PREFIXES: readonly string[] = [\r\n 'workflow-',\r\n 'stage-',\r\n 'parallel-',\r\n 'route-',\r\n 'subworkflow-',\r\n];\r\n\r\n/** 显式 SSOT(文档/契约测试);新增结构类型应同时满足前缀规则或补入此集合 */\r\nexport const WORKFLOW_STRUCTURE_EVENT_TYPES: ReadonlySet<string> = new Set([\r\n 'workflow-start',\r\n 'workflow-end',\r\n 'workflow-failed',\r\n 'subworkflow-start',\r\n 'subworkflow-end',\r\n 'stage-start',\r\n 'stage-done',\r\n 'stage-failed',\r\n 'parallel-item-start',\r\n 'parallel-item-done',\r\n 'parallel-item-failed',\r\n 'parallel-aggregate-start',\r\n 'parallel-aggregate-done',\r\n 'parallel-aggregate-failed',\r\n 'route-branch-start',\r\n 'route-branch-done',\r\n 'route-branch-failed',\r\n]);\r\n\r\n/** session reducer(reduceTree)可处理的 event_type 白名单 */\r\nconst AGENT_LOOP_REPLAY_EVENT_TYPES: ReadonlySet<string> = new Set(\r\n Object.keys(DEFAULT_EVENT_TIERS),\r\n);\r\n\r\nexport function isWorkflowStructureEventType(eventType: string): boolean {\r\n if (WORKFLOW_STRUCTURE_EVENT_TYPES.has(eventType)) return true;\r\n return WORKFLOW_STRUCTURE_EVENT_PREFIXES.some((prefix) => eventType.startsWith(prefix));\r\n}\r\n\r\n/** agent loop hydrate/replay 允许进入 reduceTree 的事件(正文 + state/debug tier) */\r\nexport function isAgentLoopReplayEventType(eventType: string): boolean {\r\n return AGENT_LOOP_REPLAY_EVENT_TYPES.has(eventType);\r\n}\r\n\r\n/**\r\n * hydrateLoopSession / 宿主 replay:\r\n * 1. 白名单:只保留 reduceTree 已知 event_type\r\n * 2. 结构前缀/集合:双重排除 workflow 编排帧(含 session_id 误绑的 dual emission)\r\n */\r\nexport function filterAgentLoopReplayEvents<T extends { event_type: string }>(\r\n events: T[],\r\n): T[] {\r\n return events.filter(\r\n (event) =>\r\n isAgentLoopReplayEventType(event.event_type)\r\n && !isWorkflowStructureEventType(event.event_type),\r\n );\r\n}\r\n","/**\r\n * workflowPathUtils.ts — workflow_path 分段与父子路径推导\r\n *\r\n * 多层 nested 场景(Prep → 子流并行 → Finalize)下,不得只切第一个 `>`;\r\n * 宿主 stage / 子流前缀均基于完整 segment 链推导。\r\n */\r\n\r\n/** `demo-nested>parallel_review>inner` → ['demo-nested', 'parallel_review', 'inner'] */\r\nexport function splitWorkflowPathSegments(workflowPath: string): string[] {\r\n return workflowPath.split('>').filter(Boolean);\r\n}\r\n\r\n/** 去掉末段后的父路径;单段根 workflow 返回 null。 */\r\nexport function parentWorkflowPath(workflowPath: string): string | null {\r\n const segments = splitWorkflowPathSegments(workflowPath);\r\n if (segments.length <= 1) return null;\r\n return segments.slice(0, -1).join('>');\r\n}\r\n\r\n/** 路径末段(当前嵌套 scope 名)。 */\r\nexport function lastWorkflowPathSegment(workflowPath: string): string | null {\r\n const segments = splitWorkflowPathSegments(workflowPath);\r\n return segments.length > 0 ? segments[segments.length - 1]! : null;\r\n}\r\n\r\n/** path 是否为 ancestor 的严格子路径(按 segment 前缀,避免字符串误匹配)。 */\r\nexport function isWorkflowPathUnderAncestor(\r\n workflowPath: string,\r\n ancestorPath: string,\r\n): boolean {\r\n if (workflowPath === ancestorPath) return false;\r\n const prefix = `${ancestorPath}>`;\r\n return workflowPath.startsWith(prefix);\r\n}\r\n\r\n/** path 是否在 ancestor 下(含自身)。 */\r\nexport function isWorkflowPathEqualOrUnder(\r\n workflowPath: string,\r\n ancestorPath: string,\r\n): boolean {\r\n return workflowPath === ancestorPath || isWorkflowPathUnderAncestor(workflowPath, ancestorPath);\r\n}\r\n","/**\r\n * nativeNestedUtils.ts — SDK ≥1.6.3 native nested workflow 结构检测\r\n *\r\n * 职责:\r\n * 识别 workflow_path 含 `>` 且 depth≥1 的结构事件/容器树,供 embedded 合成跳过。\r\n *\r\n * 链路位置:\r\n * embeddedSubworkflowUtils.shouldUseEmbeddedSynthesis → workflowReducer.applyStructureEvent。\r\n *\r\n * 当前裁剪范围:\r\n * 仅 D29 nested native vs embedded 分流;不含 sibling-nested 专用逻辑。\r\n */\r\nimport type { LangchainAgentEvent } from '../../types/events';\r\nimport type { WorkflowContainerTreeState } from '../../types/workflowContainer';\r\nimport { buildContainerId } from './workflowContainerProjector';\r\nimport { isWorkflowStructureEventType } from '../workflowStructureEvents';\r\nimport {\r\n isWorkflowPathEqualOrUnder,\r\n lastWorkflowPathSegment,\r\n parentWorkflowPath,\r\n splitWorkflowPathSegments,\r\n} from './workflowPathUtils';\r\n\r\nfunction readString(data: Record<string, unknown>, key: string): string | undefined {\r\n const value = data[key];\r\n return typeof value === 'string' ? value : undefined;\r\n}\r\n\r\nfunction readNumber(data: Record<string, unknown>, key: string): number | undefined {\r\n const value = data[key];\r\n return typeof value === 'number' ? value : undefined;\r\n}\r\n\r\n/** 单条结构事件是否携带 SDK native nested path(depth≥1 且 workflow_path 含 `>`)。 */\r\nexport function isNativeNestedStructureEvent(event: LangchainAgentEvent): boolean {\r\n if (!isWorkflowStructureEventType(event.event_type)) return false;\r\n const data = (event.data ?? {}) as Record<string, unknown>;\r\n const path = readString(data, 'workflow_path') ?? '';\r\n const depth = readNumber(data, 'workflow_depth') ?? 0;\r\n return depth >= 1 && path.includes('>');\r\n}\r\n\r\n/** 事件批是否含 native nested 结构 open(D29 fixture / replay 检测)。 */\r\nexport function hasNativeNestedStructureEvents(events: LangchainAgentEvent[]): boolean {\r\n return events.some((event) => isNativeNestedStructureEvent(event));\r\n}\r\n\r\n/**\r\n * 子 workflow_path 是否由「父路径 + 同名 stage」承载(native nested 典型形态)。\r\n * 例:`demo-nested>parallel_review` ↔ `demo-nested|stage:parallel_review`。\r\n * 多层:`a>b>c` ↔ `a>b|stage:c`(按完整 segment,不只切第一个 `>`)。\r\n */\r\nexport function resolveHostStageContainerId(\r\n tree: WorkflowContainerTreeState,\r\n workflowPath: string,\r\n): string | null {\r\n const parentPath = parentWorkflowPath(workflowPath);\r\n const childSegment = lastWorkflowPathSegment(workflowPath);\r\n if (!parentPath || !childSegment) return null;\r\n\r\n const stageId = buildContainerId(parentPath, 'stage', childSegment);\r\n return tree.containersById[stageId] != null ? stageId : null;\r\n}\r\n\r\nfunction isHostStageNestedChildPath(\r\n tree: WorkflowContainerTreeState,\r\n workflowPath: string,\r\n): boolean {\r\n return resolveHostStageContainerId(tree, workflowPath) != null;\r\n}\r\n\r\n/**\r\n * 容器树是否已由 SDK 投影出 native nested 路径。\r\n */\r\nexport function hasNativeNestedStructureInTree(\r\n tree: WorkflowContainerTreeState,\r\n): boolean {\r\n for (const node of Object.values(tree.containersById)) {\r\n if (node.workflow_depth < 1) continue;\r\n if (!node.workflow_path.includes('>')) continue;\r\n if (isHostStageNestedChildPath(tree, node.workflow_path)) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n}\r\n\r\nfunction clearHostStageLoopSession(\r\n tree: WorkflowContainerTreeState,\r\n hostStageId: string | null,\r\n): WorkflowContainerTreeState {\r\n if (!hostStageId) return tree;\r\n const hostStage = tree.containersById[hostStageId];\r\n if (!hostStage || hostStage.scope !== 'stage' || !hostStage.loopSessionId) return tree;\r\n\r\n return {\r\n ...tree,\r\n containersById: {\r\n ...tree.containersById,\r\n [hostStageId]: { ...hostStage, loopSessionId: null },\r\n },\r\n };\r\n}\r\n\r\n/** stage 下已有 subworkflow 容器 → 宿主 stage 仅作壳,不承载 scoped loop。 */\r\nexport function isNestedHostStageShell(\r\n tree: WorkflowContainerTreeState,\r\n stageNode: WorkflowContainerRuntimeNode,\r\n): boolean {\r\n if (stageNode.scope !== 'stage') return false;\r\n return Object.values(tree.containersById).some(\r\n (node) => node.scope === 'subworkflow' && node.parent_container_id === stageNode.container_id,\r\n );\r\n}\r\n\r\n/**\r\n * subworkflow-start / parallel-item-start:清宿主 stage 上误绑的 loopSessionId。\r\n * 内层 Agent loop 应落在 parallel item / aggregate 上。\r\n */\r\nexport function clearHostStageLoopOnNestedChildOpen(\r\n tree: WorkflowContainerTreeState,\r\n event: LangchainAgentEvent,\r\n): WorkflowContainerTreeState {\r\n const eventType = event.event_type;\r\n if (eventType !== 'subworkflow-start' && eventType !== 'parallel-item-start') return tree;\r\n\r\n const data = (event.data ?? {}) as Record<string, unknown>;\r\n const workflowPath = readString(data, 'workflow_path');\r\n if (!workflowPath) return tree;\r\n\r\n if (eventType === 'subworkflow-start') {\r\n const childWorkflowId = readString(data, 'child_workflow_id');\r\n if (!childWorkflowId) return tree;\r\n\r\n const subId = buildContainerId(workflowPath, 'subworkflow', childWorkflowId);\r\n const sub = tree.containersById[subId];\r\n const hostStageId =\r\n sub?.parent_container_id ?? resolveHostStageContainerId(tree, workflowPath);\r\n return clearHostStageLoopSession(tree, hostStageId);\r\n }\r\n\r\n return clearHostStageLoopSession(tree, resolveHostStageContainerId(tree, workflowPath));\r\n}\r\n\r\n/** @deprecated 使用 clearHostStageLoopOnNestedChildOpen */\r\nexport function clearHostStageLoopOnSubworkflowStart(\r\n tree: WorkflowContainerTreeState,\r\n event: LangchainAgentEvent,\r\n): WorkflowContainerTreeState {\r\n return clearHostStageLoopOnNestedChildOpen(tree, event);\r\n}\r\n\r\n/** native subworkflow-start 时丢弃同宿主 stage 下已过时的 embedded 合成子树。 */\r\nexport function dropStaleEmbeddedPathsOnNativeSubworkflowStart(\r\n tree: WorkflowContainerTreeState,\r\n event: LangchainAgentEvent,\r\n): WorkflowContainerTreeState {\r\n if (event.event_type !== 'subworkflow-start' || !isNativeNestedStructureEvent(event)) {\r\n return tree;\r\n }\r\n\r\n const data = (event.data ?? {}) as Record<string, unknown>;\r\n const nativeChildPath = readString(data, 'workflow_path');\r\n if (!nativeChildPath) return tree;\r\n\r\n const rootAnchor = splitWorkflowPathSegments(nativeChildPath)[0];\r\n if (!rootAnchor) return tree;\r\n\r\n let changed = false;\r\n const containersById = { ...tree.containersById };\r\n let activeContainerIds = [...tree.activeContainerIds];\r\n\r\n for (const [id, node] of Object.entries(tree.containersById)) {\r\n if (node.workflow_depth < 1) continue;\r\n if (!node.workflow_path.startsWith(`${rootAnchor}>`)) continue;\r\n if (\r\n node.workflow_path === nativeChildPath\r\n || isWorkflowPathEqualOrUnder(node.workflow_path, nativeChildPath)\r\n ) {\r\n continue;\r\n }\r\n // 保留其他合法 native 子路径(sibling-nested:stage_a / stage_b 并存)\r\n if (isHostStageNestedChildPath(tree, node.workflow_path)) continue;\r\n delete containersById[id];\r\n activeContainerIds = activeContainerIds.filter((cid) => cid !== id);\r\n changed = true;\r\n }\r\n\r\n return changed ? { ...tree, containersById, activeContainerIds } : tree;\r\n}\r\n\r","/**\r\n * embeddedSubworkflowUtils.ts — 嵌套 Parallelization 容器补全\r\n *\r\n * SDK 将 ParallelizationWorkflow 嵌入 Chaining stage 时,可能只发 stage-start\r\n *(无 subworkflow-start / parallel-item-start),loop session_id 形如\r\n * `{child_workflow_id}-{task_key}`。此处按 session_id 补全 subworkflow / item / aggregate 容器。\r\n */\r\nimport type { LangchainAgentEvent } from '../../types/events';\r\nimport { buildContainerId } from './workflowContainerProjector';\r\nimport { buildLoopSessionId } from './loopSessionUtils';\r\nimport {\r\n hasNativeNestedStructureInTree,\r\n isNativeNestedStructureEvent,\r\n} from './nativeNestedUtils';\r\nimport type {\r\n WorkflowContainerRuntimeNode,\r\n WorkflowContainerScope,\r\n WorkflowContainerTreeState,\r\n} from '../../types/workflowContainer';\r\nimport type { WorkflowSessionState } from '../../types/workflowSession';\r\n\r\nexport interface ParsedLoopSessionParts {\r\n workflowId: string;\r\n taskKey: string;\r\n}\r\n\r\n/** `{workflow_id}-{task_key}`;task_key 不含连字符(与 SDK WorkflowSessionIdPolicy 一致)。 */\r\nexport function parseLoopSessionParts(sessionId: string): ParsedLoopSessionParts | null {\r\n const trimmed = sessionId.trim();\r\n const dash = trimmed.lastIndexOf('-');\r\n if (dash <= 0 || dash >= trimmed.length - 1) return null;\r\n return {\r\n workflowId: trimmed.slice(0, dash),\r\n taskKey: trimmed.slice(dash + 1),\r\n };\r\n}\r\n\r\nexport function isEmbeddedChildLoopSession(\r\n sessionId: string,\r\n rootWorkflowId: string,\r\n): boolean {\r\n const parts = parseLoopSessionParts(sessionId);\r\n if (!parts) return false;\r\n if (parts.workflowId === rootWorkflowId) return false;\r\n // 同属根 workflow 家族(qa-review vs qa-review-pipeline)不是嵌套子流。\r\n if (parts.workflowId.startsWith(`${rootWorkflowId}-`)) return false;\r\n if (rootWorkflowId.startsWith(`${parts.workflowId}-`)) return false;\r\n // 嵌套子 workflow id 至少三段(如 demo-review-sub)。\r\n return parts.workflowId.split('-').length >= 3;\r\n}\r\n\r\nfunction readWorkflowIdFromData(data: Record<string, unknown>): string | undefined {\r\n const value = data.workflow_id;\r\n return typeof value === 'string' ? value : undefined;\r\n}\r\n\r\nfunction readStageKeyFromData(data: Record<string, unknown>): string | undefined {\r\n const value = data.stage_key;\r\n return typeof value === 'string' ? value : undefined;\r\n}\r\n\r\nexport function shouldPrebindLoopSessionFromStructureOpen(\r\n eventType: string,\r\n eventSessionId: string | null | undefined,\r\n derivedLoopSessionId: string,\r\n data: Record<string, unknown> = {},\r\n): boolean {\r\n if (!eventSessionId) return true;\r\n if (eventType !== 'stage-start') return true;\r\n if (eventSessionId === derivedLoopSessionId) return true;\r\n\r\n // 上一 stage 的 loop session_id 泄漏到容器 stage-start(嵌套 parallel_review)。\r\n const rootWorkflowId = readWorkflowIdFromData(data);\r\n const stageKey = readStageKeyFromData(data);\r\n const parsed = parseLoopSessionParts(eventSessionId);\r\n if (rootWorkflowId && stageKey && parsed) {\r\n if (parsed.workflowId === rootWorkflowId && parsed.taskKey !== stageKey) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n}\r\n\r\nfunction resolveRootWorkflow(\r\n tree: WorkflowContainerTreeState,\r\n): { workflowId: string; workflowPath: string } | null {\r\n const rootId = tree.rootContainerIds[0];\r\n if (!rootId) return null;\r\n const root = tree.containersById[rootId];\r\n if (!root || root.scope !== 'workflow') return null;\r\n return {\r\n workflowId: root.scope_key,\r\n workflowPath: root.workflow_path,\r\n };\r\n}\r\n\r\nfunction humanizeTaskTitle(taskKey: string): string {\r\n if (taskKey === 'aggregate') return 'Merge Perspectives';\r\n if (taskKey === 'architecture') return 'Architecture Path';\r\n if (taskKey === 'implementation') return 'Implementation Path';\r\n return taskKey\r\n .split('_')\r\n .map((part) => (part ? part[0]!.toUpperCase() + part.slice(1) : part))\r\n .join(' ');\r\n}\r\n\r\nfunction findEmbeddedHostStage(\r\n tree: WorkflowContainerTreeState,\r\n rootWorkflowPath: string,\r\n childWorkflowId: string,\r\n): WorkflowContainerRuntimeNode | null {\r\n const childPath = `${rootWorkflowPath}>${childWorkflowId}`;\r\n const subId = buildContainerId(childPath, 'subworkflow', childWorkflowId);\r\n const existingSub = tree.containersById[subId];\r\n if (existingSub?.parent_container_id) {\r\n return tree.containersById[existingSub.parent_container_id] ?? null;\r\n }\r\n\r\n const runningStages = tree.activeContainerIds\r\n .map((id) => tree.containersById[id])\r\n .filter(\r\n (node): node is WorkflowContainerRuntimeNode =>\r\n node != null\r\n && node.scope === 'stage'\r\n && node.workflow_path === rootWorkflowPath\r\n && node.is_open,\r\n );\r\n\r\n if (runningStages.length === 0) return null;\r\n\r\n return runningStages.reduce((best, node) =>\r\n (node.display?.progress_current ?? 0) >= (best.display?.progress_current ?? 0)\r\n ? node\r\n : best,\r\n );\r\n}\r\n\r\nfunction upsertRuntimeNode(\r\n tree: WorkflowContainerTreeState,\r\n node: WorkflowContainerRuntimeNode,\r\n): WorkflowContainerTreeState {\r\n const activeContainerIds = tree.activeContainerIds.includes(node.container_id)\r\n ? tree.activeContainerIds\r\n : node.is_open\r\n ? [...tree.activeContainerIds, node.container_id]\r\n : tree.activeContainerIds;\r\n\r\n return {\r\n ...tree,\r\n activeContainerIds,\r\n containersById: {\r\n ...tree.containersById,\r\n [node.container_id]: node,\r\n },\r\n };\r\n}\r\n\r\nfunction completeOpenItemsUnderSubworkflow(\r\n tree: WorkflowContainerTreeState,\r\n subworkflowId: string,\r\n): WorkflowContainerTreeState {\r\n let next = tree;\r\n for (const node of Object.values(tree.containersById)) {\r\n if (\r\n node.parent_container_id === subworkflowId\r\n && node.scope === 'item'\r\n && node.status === 'running'\r\n ) {\r\n next = upsertRuntimeNode(next, {\r\n ...node,\r\n status: 'completed',\r\n is_open: false,\r\n });\r\n }\r\n }\r\n const activeContainerIds = next.activeContainerIds.filter(\r\n (id) => next.containersById[id]?.is_open,\r\n );\r\n return { ...next, activeContainerIds };\r\n}\r\n\r\nfunction resolveLeafScope(taskKey: string): WorkflowContainerScope {\r\n return taskKey === 'aggregate' ? 'aggregate' : 'item';\r\n}\r\n\r\n/**\r\n * 是否应对当前会话启用 embedded 子流合成(D29 方案 B:native 优先)。\r\n * SDK ≥1.6.6 已正确发 native subworkflow 结构事件;embedded 路径仅服务旧 fixture / legacy replay。\r\n * 传入 pendingEvent 可在首条 native 结构事件到达时立即跳过合成。\r\n */\r\nexport function shouldUseEmbeddedSynthesis(\r\n treeOrState: WorkflowContainerTreeState | WorkflowSessionState,\r\n pendingEvent?: LangchainAgentEvent,\r\n): boolean {\r\n const tree = 'containerTree' in treeOrState ? treeOrState.containerTree : treeOrState;\r\n if (pendingEvent && isNativeNestedStructureEvent(pendingEvent)) {\r\n return false;\r\n }\r\n if (hasNativeNestedStructureInTree(tree)) {\r\n return false;\r\n }\r\n return true;\r\n}\r\n\r\n/** 为嵌套子流补全 subworkflow / item|aggregate 容器并绑定 loopSessionId。 */\r\nexport function ensureEmbeddedSubworkflowContainers(\r\n tree: WorkflowContainerTreeState,\r\n loopSessionId: string,\r\n): WorkflowContainerTreeState {\r\n if (!shouldUseEmbeddedSynthesis(tree)) {\r\n return tree;\r\n }\r\n\r\n const root = resolveRootWorkflow(tree);\r\n const parts = parseLoopSessionParts(loopSessionId);\r\n if (!root || !parts || !isEmbeddedChildLoopSession(loopSessionId, root.workflowId)) {\r\n return tree;\r\n }\r\n\r\n const hostStage = findEmbeddedHostStage(tree, root.workflowPath, parts.workflowId);\r\n if (!hostStage) return tree;\r\n\r\n let next = tree;\r\n\r\n if (hostStage.loopSessionId) {\r\n next = upsertRuntimeNode(next, { ...hostStage, loopSessionId: null });\r\n }\r\n\r\n const childPath = `${root.workflowPath}>${parts.workflowId}`;\r\n const subId = buildContainerId(childPath, 'subworkflow', parts.workflowId);\r\n let subNode = next.containersById[subId];\r\n if (!subNode) {\r\n subNode = {\r\n container_id: subId,\r\n scope: 'subworkflow',\r\n workflow_path: childPath,\r\n workflow_depth: hostStage.workflow_depth + 1,\r\n scope_key: parts.workflowId,\r\n title: 'Dual-Perspective Review',\r\n subtitle: 'Nested parallel sub-workflow',\r\n status: 'running',\r\n pattern: 'parallelization',\r\n parent_container_id: hostStage.container_id,\r\n display: {\r\n title: 'Dual-Perspective Review',\r\n description: 'Nested parallel sub-workflow',\r\n pattern: 'parallelization',\r\n status: 'running',\r\n },\r\n content_blocks: [],\r\n is_open: true,\r\n loopSessionId: null,\r\n };\r\n next = upsertRuntimeNode(next, subNode);\r\n }\r\n\r\n const leafScope = resolveLeafScope(parts.taskKey);\r\n const leafId = buildContainerId(childPath, leafScope, parts.taskKey);\r\n let leafNode = next.containersById[leafId];\r\n if (!leafNode) {\r\n leafNode = {\r\n container_id: leafId,\r\n scope: leafScope,\r\n workflow_path: childPath,\r\n workflow_depth: hostStage.workflow_depth + 1,\r\n scope_key: parts.taskKey,\r\n title: humanizeTaskTitle(parts.taskKey),\r\n subtitle: '',\r\n status: 'running',\r\n pattern: 'parallelization',\r\n parent_container_id: subId,\r\n display: {\r\n title: humanizeTaskTitle(parts.taskKey),\r\n pattern: 'parallelization',\r\n status: 'running',\r\n },\r\n content_blocks: [],\r\n is_open: true,\r\n loopSessionId: null,\r\n };\r\n next = upsertRuntimeNode(next, leafNode);\r\n }\r\n\r\n if (leafScope === 'aggregate') {\r\n next = completeOpenItemsUnderSubworkflow(next, subId);\r\n }\r\n\r\n if (leafNode.loopSessionId !== loopSessionId) {\r\n next = upsertRuntimeNode(next, {\r\n ...leafNode,\r\n loopSessionId,\r\n content_blocks: [],\r\n });\r\n }\r\n\r\n return next;\r\n}\r\n\r\nexport function findContainerIdByLoopSession(\r\n tree: WorkflowContainerTreeState,\r\n loopSessionId: string,\r\n): string | null {\r\n for (const [containerId, node] of Object.entries(tree.containersById)) {\r\n if (node.loopSessionId === loopSessionId) return containerId;\r\n }\r\n return null;\r\n}\r\n\r\nconst PARALLEL_ITEM_STRUCTURE_EVENTS = new Set([\r\n 'parallel-item-start',\r\n 'parallel-item-done',\r\n 'parallel-item-failed',\r\n]);\r\n\r\nfunction readItemKey(data: Record<string, unknown>): string | undefined {\r\n const value = data.item_key;\r\n return typeof value === 'string' ? value : undefined;\r\n}\r\n\r\n/**\r\n * nested parallel item:structure workflow_id(如 parallel_review)与 SDK session 前缀\r\n *(如 demo-review-sub)不一致时,以 session_id 的 task_key 与 item_key 对齐为准。\r\n */\r\nfunction resolveParallelItemLoopSessionId(\r\n eventType: string,\r\n eventSessionId: string | null | undefined,\r\n derivedLoopSessionId: string,\r\n data: Record<string, unknown>,\r\n): string | null {\r\n if (!PARALLEL_ITEM_STRUCTURE_EVENTS.has(eventType) || !eventSessionId) return null;\r\n if (eventSessionId === derivedLoopSessionId) return null;\r\n\r\n const itemKey = readItemKey(data);\r\n const parsed = parseLoopSessionParts(eventSessionId);\r\n if (itemKey && parsed?.taskKey === itemKey) {\r\n return eventSessionId;\r\n }\r\n // task_key 含连字符时(如 wiki-l1-l1-demo-repo-core),lastIndexOf 解析会失真;\r\n // structure data.workflow_id 也可能是 stage key(l1)而非子流 id(wiki-l1)。\r\n // 以 event.session_id 后缀 `-{item_key}` 与 SDK 真跑 session 对齐。\r\n if (itemKey && eventSessionId.endsWith(`-${itemKey}`)) {\r\n return eventSessionId;\r\n }\r\n return null;\r\n}\r\n\r\n/** structure open/close 预绑定用的 loopSessionId(aggregate 可能带 child workflow 前缀)。 */\r\nexport function resolveStructureOpenLoopSessionId(\r\n eventType: string,\r\n eventSessionId: string | null | undefined,\r\n derivedLoopSessionId: string,\r\n data: Record<string, unknown>,\r\n): string {\r\n const rootWorkflowId = readWorkflowId(data) ?? '';\r\n if (\r\n (eventType === 'parallel-aggregate-start'\r\n || eventType === 'parallel-aggregate-done'\r\n || eventType === 'parallel-aggregate-failed')\r\n && eventSessionId\r\n && isEmbeddedChildLoopSession(eventSessionId, rootWorkflowId)\r\n ) {\r\n return eventSessionId;\r\n }\r\n\r\n const parallelItemSessionId = resolveParallelItemLoopSessionId(\r\n eventType,\r\n eventSessionId,\r\n derivedLoopSessionId,\r\n data,\r\n );\r\n if (parallelItemSessionId) {\r\n return parallelItemSessionId;\r\n }\r\n\r\n return derivedLoopSessionId;\r\n}\r\n\r\nconst EMBEDDED_AGGREGATE_STRUCTURE_EVENTS = new Set([\r\n 'parallel-aggregate-start',\r\n 'parallel-aggregate-done',\r\n 'parallel-aggregate-failed',\r\n]);\r\n\r\n/** 嵌套 aggregate 结构事件的 workflow_path 落到子流路径,供 projector 开/关正确容器。 */\r\nexport function patchEmbeddedStructureEvent(\r\n event: LangchainAgentEvent,\r\n rootWorkflowId: string,\r\n): LangchainAgentEvent {\r\n if (!EMBEDDED_AGGREGATE_STRUCTURE_EVENTS.has(event.event_type)) {\r\n return event;\r\n }\r\n if (!event.session_id || !isEmbeddedChildLoopSession(event.session_id, rootWorkflowId)) {\r\n return event;\r\n }\r\n\r\n const parts = parseLoopSessionParts(event.session_id);\r\n if (!parts) return event;\r\n\r\n const data = (event.data ?? {}) as Record<string, unknown>;\r\n const rootPath = readString(data, 'workflow_path') ?? rootWorkflowId;\r\n const childPath = `${rootPath}>${parts.workflowId}`;\r\n const workflowDepth =\r\n typeof data.workflow_depth === 'number' ? data.workflow_depth + 1 : 1;\r\n\r\n return {\r\n ...event,\r\n data: {\r\n ...data,\r\n workflow_path: childPath,\r\n workflow_depth: workflowDepth,\r\n },\r\n };\r\n}\r\n\r\nfunction readString(data: Record<string, unknown>, key: string): string | undefined {\r\n const value = data[key];\r\n return typeof value === 'string' ? value : undefined;\r\n}\r\n\r\nfunction isDescendantOf(\r\n containersById: Record<string, WorkflowContainerRuntimeNode>,\r\n ancestorId: string,\r\n nodeId: string,\r\n): boolean {\r\n const seen = new Set<string>();\r\n let current = containersById[nodeId]?.parent_container_id ?? null;\r\n while (current) {\r\n if (current === ancestorId) return true;\r\n if (seen.has(current)) return false;\r\n seen.add(current);\r\n current = containersById[current]?.parent_container_id ?? null;\r\n }\r\n return false;\r\n}\r\n\r\n/** stage-done 时收口其下嵌套子流容器(避免 item/aggregate 仍 running + Spinner)。 */\r\nexport function settleCompletedStageSubtree(\r\n tree: WorkflowContainerTreeState,\r\n stageContainerId: string,\r\n): WorkflowContainerTreeState {\r\n let next = tree;\r\n for (const node of Object.values(tree.containersById)) {\r\n if (\r\n node.container_id !== stageContainerId\r\n && !isDescendantOf(tree.containersById, stageContainerId, node.container_id)\r\n ) {\r\n continue;\r\n }\r\n if (node.container_id === stageContainerId) continue;\r\n if (node.status === 'completed' || node.status === 'failed') continue;\r\n // stage-done 若早于 sibling agent 到达,不得把仍 active 的后代强行 settle\r\n if (\r\n node.status === 'running'\r\n || node.status === 'retrying'\r\n || node.status === 'pending'\r\n || node.status === 'blocked'\r\n ) {\r\n continue;\r\n }\r\n next = upsertRuntimeNode(next, {\r\n ...node,\r\n status: 'completed',\r\n is_open: false,\r\n });\r\n }\r\n const activeContainerIds = next.activeContainerIds.filter(\r\n (id) => next.containersById[id]?.is_open,\r\n );\r\n return { ...next, activeContainerIds };\r\n}\r\n\r\nfunction readWorkflowId(data: Record<string, unknown>): string | undefined {\r\n return readWorkflowIdFromData(data);\r\n}\r\n\r\nexport { buildLoopSessionId };\r\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 type { SessionTree } from '../types/tree';\nimport {\n createWorkflowRunningLoopTree,\n finalizeWorkflowLoopTree,\n} from './workflow/workflowLoopTreeUtils';\nimport { containersByLoopSessionId } from './workflow/workflowLoopEviction';\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 ensureEmbeddedSubworkflowContainers,\n findContainerIdByLoopSession,\n patchEmbeddedStructureEvent,\n resolveStructureOpenLoopSessionId,\n settleCompletedStageSubtree,\n shouldPrebindLoopSessionFromStructureOpen,\n shouldUseEmbeddedSynthesis,\n} from './workflow/embeddedSubworkflowUtils';\nimport {\n deriveLoopSessionIdFromAgentEvent,\n deriveLoopSessionIdFromStructureOpen,\n loopTaskScopeForStructureOpen,\n} from './workflow/loopSessionUtils';\nimport {\n clearHostStageLoopOnNestedChildOpen,\n isNestedHostStageShell,\n dropStaleEmbeddedPathsOnNativeSubworkflowStart,\n} from './workflow/nativeNestedUtils';\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 derivedLoopSessionId = deriveLoopSessionIdFromStructureOpen(event);\n const scope = loopTaskScopeForStructureOpen(event.event_type);\n if (!derivedLoopSessionId || !scope) return tree;\n\n const data = (event.data ?? {}) as Record<string, unknown>;\n let loopSessionId = resolveStructureOpenLoopSessionId(\n event.event_type,\n event.session_id,\n derivedLoopSessionId,\n data,\n );\n\n // shouldPrebindLoopSessionFromStructureOpen 返回 false 表示 eventSessionId 是\"泄漏\"的;\n // 此时不应阻止绑定,而是强制使用 derivedLoopSessionId。\n if (\n !shouldPrebindLoopSessionFromStructureOpen(\n event.event_type,\n event.session_id,\n derivedLoopSessionId,\n data,\n )\n ) {\n loopSessionId = derivedLoopSessionId;\n }\n\n let nextTree =\n event.event_type === 'parallel-aggregate-start'\n ? ensureEmbeddedSubworkflowContainers(tree, loopSessionId)\n : tree;\n\n const workflowPath = readString(data, 'workflow_path') ?? '';\n const scopeKey = resolveScopeKey(event.event_type, data);\n const containerId = buildContainerId(workflowPath, scope, scopeKey);\n\n let targetId = containerId;\n const embeddedTargetId = findContainerIdByLoopSession(nextTree, loopSessionId);\n if (embeddedTargetId) {\n targetId = embeddedTargetId;\n }\n\n const node = nextTree.containersById[targetId];\n if (!node) return nextTree;\n if (node.loopSessionId === loopSessionId && node.content_blocks.length === 0) {\n return nextTree;\n }\n\n return {\n ...nextTree,\n containersById: {\n ...nextTree.containersById,\n [targetId]: {\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 return findContainerIdByLoopSession(tree, loopSessionId);\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 | undefined,\n containerTree: WorkflowContainerTreeState,\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 const byLoop = containersByLoopSessionId(containerTree);\n\n if (activeLoopSessionId) {\n const activeContainer = byLoop.get(activeLoopSessionId);\n if (\n activeContainer\n && (activeContainer.status === 'running' || activeContainer.status === 'retrying')\n ) {\n return activeLoopSessionId;\n }\n }\n\n const runningLoopIds = [...byLoop.entries()]\n .filter(([, node]) => node.status === 'running' || node.status === 'retrying')\n .map(([loopSessionId]) => loopSessionId);\n if (runningLoopIds.length === 1) return runningLoopIds[0]!;\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, tree);\n if (!sessionId) return tree;\n\n let nextTree = ensureEmbeddedSubworkflowContainers(tree, sessionId);\n if (findContainerByLoopSession(nextTree, sessionId)) return nextTree;\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 = findContainerByLoopSession(nextTree, sessionId);\n\n if (!targetId && scopeKey) {\n targetId = resolveContentTargetFromSnapshot(\n containerTreeToSnapshot(nextTree),\n workflowPath,\n scopeKey,\n );\n }\n\n if (!targetId) {\n const fallbackScopes: Array<'item' | 'aggregate' | 'stage'> = ['item', 'aggregate', 'stage'];\n for (const scope of fallbackScopes) {\n for (const containerId of nextTree.activeContainerIds) {\n const node = nextTree.containersById[containerId];\n if (!node || node.loopSessionId) continue;\n if (node.scope !== scope) continue;\n if (node.scope === 'stage' && isNestedHostStageShell(nextTree, node)) continue;\n targetId = containerId;\n break;\n }\n if (targetId) break;\n }\n }\n\n if (!targetId) {\n targetId = resolveContentTargetFromSnapshot(\n containerTreeToSnapshot(nextTree),\n workflowPath,\n null,\n );\n }\n\n if (!targetId) return nextTree;\n\n const node = nextTree.containersById[targetId];\n if (!node || node.loopSessionId) return nextTree;\n\n // D24 §8.2: stage / item / branch / aggregate(Agent loop) 承载 loop;workflow / route-decision 等不绑定。\n if (node.scope === 'stage' && isNestedHostStageShell(nextTree, node)) {\n return nextTree;\n }\n\n if (\n node.scope !== 'stage'\n && node.scope !== 'item'\n && node.scope !== 'branch'\n && node.scope !== 'aggregate'\n ) {\n return nextTree;\n }\n\n return {\n ...nextTree,\n containersById: {\n ...nextTree.containersById,\n [targetId]: { ...node, loopSessionId: sessionId },\n },\n };\n}\n\nconst LOOP_TASK_STRUCTURE_CLOSE_EVENTS = new Set([\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\nfunction resolveStructureCloseLoopSessionId(\n event: LangchainAgentEvent,\n): string | null {\n const data = (event.data ?? {}) as Record<string, unknown>;\n const derived =\n deriveLoopSessionIdFromStructureOpen(event)\n ?? deriveLoopSessionIdFromAgentEvent(event);\n if (!derived && !event.session_id) return null;\n if (!derived) return event.session_id ?? null;\n return resolveStructureOpenLoopSessionId(\n event.event_type,\n event.session_id,\n derived,\n data,\n );\n}\n\nfunction finalizeLoopTreesForCompletedContainers(\n state: WorkflowSessionState,\n containerTree: WorkflowContainerTreeState,\n): WorkflowSessionState {\n let loopTreesBySessionId = state.loopTreesBySessionId;\n for (const node of Object.values(containerTree.containersById)) {\n if (!node.loopSessionId) continue;\n if (node.status !== 'completed' && node.status !== 'failed') continue;\n const loopTree = loopTreesBySessionId[node.loopSessionId];\n if (!loopTree || loopTree.status === 'done' || loopTree.status === 'error') continue;\n loopTreesBySessionId = {\n ...loopTreesBySessionId,\n [node.loopSessionId]: finalizeWorkflowLoopTree(\n loopTree,\n node.status === 'failed' ? 'error' : 'done',\n ),\n };\n }\n return { ...state, loopTreesBySessionId };\n}\n\nfunction clearActiveLoopIfFinalized(\n state: WorkflowSessionState,\n): WorkflowSessionState {\n const activeId = state.activeLoopSessionId;\n if (!activeId) return state;\n const loop = state.loopTreesBySessionId[activeId];\n if (loop && (loop.status === 'done' || loop.status === 'error')) {\n return { ...state, activeLoopSessionId: null };\n }\n return state;\n}\n\nfunction resolveRootWorkflowId(\n containerTree: WorkflowContainerTreeState,\n): string | null {\n const rootId = containerTree.rootContainerIds[0];\n const root = rootId ? containerTree.containersById[rootId] : undefined;\n return root?.scope === 'workflow' ? root.scope_key : null;\n}\nfunction findContainerForLoopSession(\n tree: WorkflowContainerTreeState,\n loopSessionId: string,\n): WorkflowContainerRuntimeNode | undefined {\n return Object.values(tree.containersById).find(\n (node) => node.loopSessionId === loopSessionId,\n );\n}\n\n/** 容器已 completed/failed 时,禁止 agent 事件把 scoped loop 拉回 running(SDK dual emission / gate start)。 */\nfunction reconcileLoopTreeWithContainerStatus(\n containerTree: WorkflowContainerTreeState,\n loopSessionId: string,\n loopTree: SessionTree,\n): SessionTree {\n const container = findContainerForLoopSession(containerTree, loopSessionId);\n if (!container) return loopTree;\n if (container.status === 'completed') {\n return finalizeWorkflowLoopTree(loopTree, 'done');\n }\n if (container.status === 'failed') {\n return finalizeWorkflowLoopTree(loopTree, 'error');\n }\n return loopTree;\n}\n\nfunction finalizeLoopTreeOnStructureClose(\n state: WorkflowSessionState,\n event: LangchainAgentEvent,\n): WorkflowSessionState {\n if (!LOOP_TASK_STRUCTURE_CLOSE_EVENTS.has(event.event_type)) {\n return state;\n }\n\n const loopSessionId = resolveStructureCloseLoopSessionId(event);\n if (!loopSessionId) return state;\n\n const loopTree = state.loopTreesBySessionId[loopSessionId];\n if (!loopTree) return state;\n\n const terminalStatus = event.event_type.endsWith('-failed') ? 'error' : 'done';\n return {\n ...state,\n loopTreesBySessionId: {\n ...state.loopTreesBySessionId,\n [loopSessionId]: finalizeWorkflowLoopTree(loopTree, terminalStatus),\n },\n };\n}\n\nfunction applyStructureEvent(\n state: WorkflowSessionState,\n event: LangchainAgentEvent,\n): WorkflowSessionState {\n const rootWorkflowId = resolveRootWorkflowId(state.containerTree);\n const useEmbeddedSynthesis = shouldUseEmbeddedSynthesis(state, event);\n const projectedEvent =\n rootWorkflowId != null && useEmbeddedSynthesis\n ? patchEmbeddedStructureEvent(event, rootWorkflowId)\n : event;\n\n let containerTree = applyStructureToContainerTree(state.containerTree, projectedEvent);\n\n if (\n projectedEvent.event_type === 'subworkflow-start'\n || projectedEvent.event_type === 'parallel-item-start'\n ) {\n containerTree = clearHostStageLoopOnNestedChildOpen(containerTree, projectedEvent);\n }\n if (projectedEvent.event_type === 'subworkflow-start') {\n containerTree = dropStaleEmbeddedPathsOnNativeSubworkflowStart(containerTree, projectedEvent);\n }\n\n const derivedLoopSessionId = deriveLoopSessionIdFromStructureOpen(projectedEvent);\n const structureData = (projectedEvent.data ?? {}) as Record<string, unknown>;\n const structureLoopSessionId = derivedLoopSessionId\n ? resolveStructureOpenLoopSessionId(\n projectedEvent.event_type,\n projectedEvent.session_id,\n derivedLoopSessionId,\n structureData,\n )\n : null;\n\n if (structureLoopSessionId && useEmbeddedSynthesis) {\n containerTree = ensureEmbeddedSubworkflowContainers(containerTree, structureLoopSessionId);\n }\n\n containerTree = prebindLoopSessionFromStructureOpen(containerTree, projectedEvent);\n\n if (\n projectedEvent.event_type === 'stage-done'\n || projectedEvent.event_type === 'stage-failed'\n ) {\n const stageKey = readString(structureData, 'stage_key');\n const workflowPath = readString(structureData, 'workflow_path') ?? '';\n if (stageKey) {\n const stageId = buildContainerId(workflowPath, 'stage', stageKey);\n if (containerTree.containersById[stageId]) {\n containerTree = settleCompletedStageSubtree(containerTree, stageId);\n }\n }\n }\n\n const loopSessionId = structureLoopSessionId ?? derivedLoopSessionId;\n let nextState: WorkflowSessionState = { ...state, containerTree };\n\n if (loopSessionId) {\n nextState = ensureLoopTree(nextState, loopSessionId);\n }\n\n nextState = finalizeLoopTreeOnStructureClose(nextState, projectedEvent);\n nextState = finalizeLoopTreesForCompletedContainers(nextState, containerTree);\n nextState = clearActiveLoopIfFinalized(nextState);\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 let reducedLoop = reduceTree(loopTree, event, eventIndex, options);\n reducedLoop = reconcileLoopTreeWithContainerStatus(\n next.containerTree,\n loopSessionId,\n reducedLoop,\n );\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, state.containerTree)\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 let reducedLoop = reduceTree(loopTree, event, eventIndex, options);\n reducedLoop = reconcileLoopTreeWithContainerStatus(\n next.containerTree,\n loopSessionId,\n reducedLoop,\n );\n\n const workflowProgress = syncWorkflowProgressFromContainerTree(\n next.containerTree,\n next.workflowProgress,\n );\n\n let status = next.status;\n if (workflowProgress.status === 'done') status = 'done';\n else if (workflowProgress.status === 'error') status = 'error';\n else if (reducedLoop.status === 'error') status = 'error';\n else if (status === 'connecting') status = 'running';\n\n return {\n ...next,\n workflowProgress,\n loopTreesBySessionId: {\n ...next.loopTreesBySessionId,\n [loopSessionId]: reducedLoop,\n },\n activeLoopSessionId: loopSessionId,\n status,\n };\n}\n\n/**\n * SSE 正常结束后兜底:根 workflow 已 completed,或全部 top-level stage 已 settle\n * 且无 running 容器时,提升 session 为 done(嵌套 parallel 缺 workflow-end 时不锁死宿主 UI)。\n */\nexport function finalizeWorkflowSessionOnStreamComplete(\n state: WorkflowSessionState,\n): WorkflowSessionState {\n if (state.status === 'done' || state.status === 'error') {\n return { ...state, activeLoopSessionId: null };\n }\n\n const tree = state.containerTree;\n const rootId = tree.rootContainerIds[0];\n if (!rootId) {\n return { ...state, status: 'done', activeLoopSessionId: null };\n }\n\n const root = tree.containersById[rootId];\n if (!root) {\n return { ...state, status: 'done', activeLoopSessionId: null };\n }\n\n const topLevelStages = Object.values(tree.containersById).filter(\n (node) =>\n node.scope === 'stage'\n && node.workflow_path === root.workflow_path\n && node.workflow_depth === root.workflow_depth,\n );\n\n const progressTotal =\n root.display?.progress_total\n ?? (topLevelStages.reduce(\n (max, s) => Math.max(max, s.display?.progress_total ?? 0),\n 0,\n ) || topLevelStages.length);\n\n const settledStageCount = topLevelStages.filter(\n (s) =>\n s.status === 'completed'\n || s.status === 'failed'\n || s.status === 'skipped',\n ).length;\n\n const progressCurrent = Math.max(\n root.display?.progress_current ?? 0,\n settledStageCount,\n );\n\n const rootParallelItems = Object.values(tree.containersById).filter(\n (node) =>\n node.scope === 'item'\n && node.workflow_path === root.workflow_path\n && node.workflow_depth === root.workflow_depth,\n );\n\n const rootParallelSettled =\n topLevelStages.length === 0\n && rootParallelItems.length > 0\n && rootParallelItems.every(\n (item) =>\n item.status === 'completed'\n || item.status === 'failed'\n || item.status === 'skipped',\n )\n && !Object.values(tree.containersById).some(\n (node) =>\n node.container_id !== rootId\n && node.workflow_path === root.workflow_path\n && node.workflow_depth === root.workflow_depth\n && (node.status === 'running'\n || node.status === 'retrying'\n || node.status === 'pending'),\n );\n\n const workflowVisuallyComplete =\n root.status === 'completed'\n || root.status === 'failed'\n || (progressTotal > 0 && progressCurrent >= progressTotal)\n || rootParallelSettled;\n\n if (!workflowVisuallyComplete) {\n return state;\n }\n\n let containersById = { ...tree.containersById };\n for (const [id, node] of Object.entries(containersById)) {\n if (node.status === 'running' || node.status === 'pending') {\n containersById[id] = { ...node, status: 'completed', is_open: false };\n }\n }\n\n const settledRoot = containersById[rootId] ?? root;\n if (settledRoot.status !== 'completed' && settledRoot.status !== 'failed') {\n containersById = {\n ...containersById,\n [rootId]: { ...settledRoot, status: 'completed', is_open: false },\n };\n }\n\n const loopTreesBySessionId = { ...state.loopTreesBySessionId };\n for (const [loopSessionId, loopTree] of Object.entries(loopTreesBySessionId)) {\n if (loopTree.status === 'running' || loopTree.status === 'connecting') {\n loopTreesBySessionId[loopSessionId] = finalizeWorkflowLoopTree(loopTree, 'done');\n }\n }\n\n const containerTree: WorkflowContainerTreeState = {\n ...tree,\n containersById,\n activeContainerIds: tree.activeContainerIds.filter(\n (id) => containersById[id]?.is_open,\n ),\n };\n\n const workflowProgress = syncWorkflowProgressFromContainerTree(\n containerTree,\n state.workflowProgress,\n );\n\n return {\n ...state,\n status: workflowProgress.status === 'error' ? 'error' : 'done',\n containerTree,\n workflowProgress,\n loopTreesBySessionId,\n activeLoopSessionId: null,\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 * 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, subtreeHasActiveWork } 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 options?: { suppressHostScopedLoop?: boolean; subtreeHasActiveWork?: boolean },\n): ReactNode {\n const loopTree = resolveLoopTree(node, loopTreesBySessionId);\n const subtreeActive =\n options?.subtreeHasActiveWork\n ?? subtreeHasActiveWork(containerTree.containersById, node.container_id);\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 suppressHostScopedLoop={options?.suppressHostScopedLoop}\n subtreeHasActiveWork={subtreeActive}\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 stageHasSubworkflowChild(\n stageId: string,\n containerTree: WorkflowContainerTreeState,\n): boolean {\n return collectChildContainers(containerTree.containersById, stageId).some(\n (node) => node.scope === 'subworkflow',\n );\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 subtreeHasActiveWork={subtreeHasActiveWork(\n containerTree.containersById,\n node.container_id,\n )}\n >\n {hasNested ? nested : null}\n </WorkflowSubworkflowContainer>\n );\n }\n\n if (node.scope === 'stage') {\n const suppressHostScopedLoop = stageHasSubworkflowChild(node.container_id, containerTree);\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(\n node,\n depth,\n containerTree,\n loopTreesBySessionId,\n viewProps,\n { suppressHostScopedLoop },\n )}\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, containerTree.containersById),\n [stages, maxVisibleDoneCount, containerTree.containersById],\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\n key={workflowNode.container_id}\n node={workflowNode}\n containersById={containerTree.containersById}\n >\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 *\n * 正文:aggregate 无 Agent loop(D24 §8.2),择优/合并结果走 content_blocks;\n * done 态用 WorkflowMarkdownPreview 渲染 GFM(表格/代码块)。\n */\nimport { useCallback, useEffect, useMemo, useState, memo, 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 { WorkflowMarkdownPreview } from './WorkflowMarkdownPreview';\nimport {\n buildAggregateLineMeta,\n buildAggregateStatusLabel,\n mapAggregateUiStatus,\n} from './workflowContainerLineUtils';\nimport {\n workflowContainerNodeVisualEqual,\n workflowContainerViewPropsEqual,\n} from './workflowContainerMemo';\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 mergeContentPreview(node: WorkflowContainerRuntimeNode): string {\n const blocks = node.content_blocks;\n if (blocks.length === 0) return '';\n return blocks\n .map((block) => block.preview?.trim() ?? '')\n .filter(Boolean)\n .join('\\n\\n');\n}\n\nexport function WorkflowAggregateContainerInner({\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 contentPreview = useMemo(() => mergeContentPreview(node), [node]);\n const waitingTeaser = isWaiting ? (contentPreview || 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 const markdownPreview = contentPreview ? (\n <WorkflowMarkdownPreview\n content={contentPreview}\n testId={`${testId}-markdown`}\n className=\"lax-workflow-aggregate__markdown lax-workflow-markdown-preview\"\n />\n ) : null;\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 <span className=\"lax-workflow-aggregate__waiting-prefix\">⎿ </span>\n <WorkflowMarkdownPreview\n content={waitingTeaser}\n className=\"lax-workflow-aggregate__markdown lax-workflow-markdown-preview\"\n />\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 {expanded && isRunning && !loopTree && contentPreview ? (\n <div\n className=\"lax-workflow-stage-container__body lax-workflow-stage-container__content-preview\"\n data-testid={`${testId}-body`}\n >\n {markdownPreview}\n </div>\n ) : null}\n\n {isDone && !expanded ? (\n <div className=\"lax-workflow-aggregate__done\" data-testid={`${testId}-done`}>\n <WorkflowExpandTrigger\n summary={`${node.title} · done`}\n onToggle={() => setExpanded(true)}\n expanded={false}\n expandHint={contentPreview ? '(click to expand)' : undefined}\n testId={`${testId}-done-trigger`}\n />\n {markdownPreview ? (\n <div className=\"lax-workflow-aggregate__done-preview\" data-testid={`${testId}-teaser`}>\n {markdownPreview}\n </div>\n ) : null}\n </div>\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\n {isDone && expanded && !loopTree && contentPreview ? (\n <div\n className=\"lax-workflow-stage-container__body lax-workflow-stage-container__content-preview\"\n data-testid={`${testId}-body`}\n >\n {markdownPreview}\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction workflowAggregateContainerPropsEqual(\n prev: WorkflowAggregateContainerProps,\n next: WorkflowAggregateContainerProps,\n): boolean {\n if (prev.loopTree !== next.loopTree) return false;\n if (!workflowContainerViewPropsEqual(prev, next)) return false;\n if (prev.siblingItems.length !== next.siblingItems.length) return false;\n for (let i = 0; i < prev.siblingItems.length; i += 1) {\n if (!workflowContainerNodeVisualEqual(prev.siblingItems[i]!, next.siblingItems[i]!)) {\n return false;\n }\n }\n return workflowContainerNodeVisualEqual(prev.node, next.node);\n}\n\nexport const WorkflowAggregateContainer = memo(\n WorkflowAggregateContainerInner,\n workflowAggregateContainerPropsEqual,\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","/**\r\n * WorkflowExpandTrigger.tsx — 可点击 ⎿ 摘要行(D24 P2)\r\n *\r\n * 职责:Done teaser / Parallel 组摘要的展开入口;hint 与摘要同属 button。\r\n *\r\n * 链路位置:WorkflowStageContainer · WorkflowParallelGroup。\r\n */\r\nimport type { ReactNode } from 'react';\r\n\r\nexport interface WorkflowExpandTriggerProps {\r\n summary: ReactNode;\r\n summaryTestId?: string;\r\n teaser?: ReactNode;\r\n expandHint?: string | null;\r\n onToggle: () => void;\r\n expanded?: boolean;\r\n testId?: string;\r\n teaserTestId?: string;\r\n className?: string;\r\n}\r\n\r\nexport function WorkflowExpandTrigger({\r\n summary,\r\n summaryTestId,\r\n teaser,\r\n expandHint,\r\n onToggle,\r\n expanded = false,\r\n testId,\r\n teaserTestId,\r\n className = '',\r\n}: WorkflowExpandTriggerProps) {\r\n return (\r\n <button\r\n type=\"button\"\r\n className={`lax-workflow-expand-trigger${className ? ` ${className}` : ''}`}\r\n onClick={onToggle}\r\n aria-expanded={expanded}\r\n data-testid={testId}\r\n >\r\n <span className=\"lax-workflow-expand-trigger__summary\" data-testid={summaryTestId}>\r\n ⎿ {summary}\r\n </span>\r\n {teaser ? (\r\n <span\r\n className=\"lax-workflow-expand-trigger__teaser\"\r\n data-testid={teaserTestId}\r\n >\r\n {teaser}\r\n </span>\r\n ) : null}\r\n {expandHint ? (\r\n <span className=\"lax-workflow-expand-trigger__hint\">{expandHint}</span>\r\n ) : null}\r\n </button>\r\n );\r\n}\r\n","/**\r\n * WorkflowMarkdownPreview — aggregate / 静态 workflow 正文 Markdown 渲染\r\n *\r\n * aggregate 节点不走 Agent loop,正文落在 content_blocks.preview(纯文本);\r\n * 与 TextNode 的 StreamingMarkdown 对齐,done 态用 RichMarkdown(GFM/表格/代码块)。\r\n */\r\nimport { RichMarkdown } from '../markdown/RichMarkdown';\r\n\r\nexport interface WorkflowMarkdownPreviewProps {\r\n content: string;\r\n testId?: string;\r\n className?: string;\r\n}\r\n\r\nexport function WorkflowMarkdownPreview({\r\n content,\r\n testId,\r\n className = 'lax-workflow-markdown-preview',\r\n}: WorkflowMarkdownPreviewProps) {\r\n if (!content.trim()) return null;\r\n return (\r\n <div className={className} data-testid={testId}>\r\n <RichMarkdown content={content} deferDiagrams />\r\n </div>\r\n );\r\n}\r\n","import type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\n\nconst ACTIVE_CONTAINER_STATUSES = new Set<WorkflowContainerRuntimeNode['status']>([\n 'running',\n 'retrying',\n 'pending',\n 'blocked',\n]);\n\nfunction isDescendantContainer(\n containersById: Record<string, WorkflowContainerRuntimeNode>,\n ancestorId: string,\n nodeId: string,\n): boolean {\n const seen = new Set<string>();\n let current = containersById[nodeId]?.parent_container_id ?? null;\n while (current) {\n if (current === ancestorId) return true;\n if (seen.has(current)) return false;\n seen.add(current);\n current = containersById[current]?.parent_container_id ?? null;\n }\n return false;\n}\n\n/** 子树内是否仍有未 settle 的容器(parallel mid-run 时 subworkflow 不得折叠)。 */\nexport function subtreeHasActiveWork(\n containersById: Record<string, WorkflowContainerRuntimeNode>,\n rootContainerId: string,\n): boolean {\n for (const node of Object.values(containersById)) {\n if (node.container_id === rootContainerId) continue;\n if (!isDescendantContainer(containersById, rootContainerId, node.container_id)) continue;\n if (ACTIVE_CONTAINER_STATUSES.has(node.status)) return true;\n }\n return false;\n}\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 containersById?: Record<string, WorkflowContainerRuntimeNode>,\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 containersById\n && subtreeHasActiveWork(containersById, stage.container_id)\n ) {\n always.push(stage);\n continue;\n }\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 (\n node.status === 'completed'\n || node.status === 'failed'\n || node.status === 'skipped'\n ) {\n return false;\n }\n if (node.loopSessionId && node.loopSessionId === activeLoopSessionId) return true;\n return false;\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';\nimport { subtreeHasActiveWork } from './workflowStageListUtils';\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\n/** 子树仍有 active 容器时,根 progress 不计入未 settle 的 stage(防 mid-run 误显示 3/3)。 */\nexport function buildEffectiveWorkflowRootMeta(\n node: WorkflowContainerRuntimeNode,\n containersById: Record<string, WorkflowContainerRuntimeNode>,\n): string[] {\n const meta: string[] = [];\n if (node.pattern) meta.push(node.pattern);\n const topStages = Object.values(containersById).filter(\n (n) => n.scope === 'stage' && n.parent_container_id === node.container_id,\n );\n const total = node.display?.progress_total ?? Math.max(topStages.length, 1);\n let settled = 0;\n for (const stage of topStages) {\n if (subtreeHasActiveWork(containersById, stage.container_id)) continue;\n if (\n stage.status === 'completed'\n || stage.status === 'failed'\n || stage.status === 'skipped'\n ) {\n settled += 1;\n }\n }\n if (total > 0) meta.push(`${settled}/${total}`);\n return withScopeMeta(node, meta);\n}\n\nexport function isWorkflowRootVisuallyActive(\n node: WorkflowContainerRuntimeNode,\n containersById: Record<string, WorkflowContainerRuntimeNode>,\n): boolean {\n if (node.status === 'running' || node.status === 'retrying') return true;\n return subtreeHasActiveWork(containersById, node.container_id);\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 * workflowContainerMemo.ts — Workflow 容器 memo 比较(DES-3)\n */\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\nimport type { WorkflowDisplayPayload } from '../../types/workflowDisplay';\n\nfunction displayVisualEqual(\n a: WorkflowDisplayPayload | null,\n b: WorkflowDisplayPayload | null,\n): boolean {\n if (a === b) return true;\n if (a === null || b === null) return false;\n if (a.progress_current !== b.progress_current) return false;\n if (a.status !== b.status) return false;\n return true;\n}\n\nexport function workflowContainerNodeVisualEqual(\n a: WorkflowContainerRuntimeNode,\n b: WorkflowContainerRuntimeNode,\n): boolean {\n if (a.container_id !== b.container_id) return false;\n if (a.status !== b.status) return false;\n if (a.is_open !== b.is_open) return false;\n if (a.loopSessionId !== b.loopSessionId) return false;\n if (a.title !== b.title) return false;\n if (a.subtitle !== b.subtitle) return false;\n if (a.content_blocks.length !== b.content_blocks.length) return false;\n if (!displayVisualEqual(a.display, b.display)) return false;\n return true;\n}\n\nexport interface WorkflowContainerViewProps {\n depth?: number;\n virtualized?: boolean;\n virtualizeThreshold?: number;\n groupParallelTools?: boolean;\n}\n\nexport function workflowContainerViewPropsEqual(\n prev: WorkflowContainerViewProps,\n next: WorkflowContainerViewProps,\n): boolean {\n return (\n prev.depth === next.depth\n && prev.virtualized === next.virtualized\n && prev.virtualizeThreshold === next.virtualizeThreshold\n && prev.groupParallelTools === next.groupParallelTools\n );\n}\n","/**\n * WorkflowParallelGroup.tsx — Parallel item 组摘要 + 嵌套 item 行\n */\nimport { useCallback, useEffect, useMemo, useState, memo } from 'react';\n\nimport {\n computeParallelGroupMetrics,\n formatParallelGroupSummary,\n parallelGroupHasActiveWork,\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 {\n workflowContainerNodeVisualEqual,\n workflowContainerViewPropsEqual,\n} from './workflowContainerMemo';\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 WorkflowParallelGroupInner({\n groupKey,\n items,\n loopTreesBySessionId,\n depth = 1,\n virtualized,\n virtualizeThreshold,\n groupParallelTools,\n}: WorkflowParallelGroupProps) {\n const metrics = useMemo(() => computeParallelGroupMetrics(items), [items]);\n const summary = formatParallelGroupSummary(metrics);\n /** 原则 A · L2:容器 status + scoped loop 双轨(结构帧可能早于 agent) */\n const hasActiveWork = useMemo(\n () => parallelGroupHasActiveWork(items, loopTreesBySessionId),\n [items, loopTreesBySessionId],\n );\n const allSettled =\n metrics.total > 0\n && metrics.running === 0\n && metrics.completed + metrics.failed >= metrics.total;\n\n const [expanded, setExpanded] = useState(hasActiveWork);\n\n useEffect(() => {\n if (hasActiveWork) {\n setExpanded(true);\n return;\n }\n if (allSettled) {\n setExpanded(false);\n }\n }, [hasActiveWork, allSettled]);\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={\n !expanded && hasActiveWork\n ? '(click to expand agents)'\n : !expanded && !hasActiveWork\n ? '(ctrl+o to expand)'\n : null\n }\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\nfunction workflowParallelGroupPropsEqual(\n prev: WorkflowParallelGroupProps,\n next: WorkflowParallelGroupProps,\n): boolean {\n if (prev.groupKey !== next.groupKey) return false;\n if (!workflowContainerViewPropsEqual(prev, next)) return false;\n if (prev.items.length !== next.items.length) return false;\n for (let i = 0; i < prev.items.length; i += 1) {\n const prevItem = prev.items[i]!;\n const nextItem = next.items[i]!;\n if (!workflowContainerNodeVisualEqual(prevItem, nextItem)) return false;\n const loopSessionId = prevItem.loopSessionId;\n if (loopSessionId) {\n if (prev.loopTreesBySessionId[loopSessionId] !== next.loopTreesBySessionId[loopSessionId]) {\n return false;\n }\n }\n }\n return true;\n}\n\nexport const WorkflowParallelGroup = memo(WorkflowParallelGroupInner, workflowParallelGroupPropsEqual);\n","/**\r\n * workflowParallelGroupMetrics.ts — Parallel 组 sibling item 客户端聚合\r\n *\r\n * 职责:\r\n * 对齐 D23 §5.6;metrics_* 未填时从容器 status 统计组摘要文案。\r\n *\r\n * 链路位置:\r\n * WorkflowParallelGroup → 组摘要行。\r\n *\r\n * 当前裁剪范围:\r\n * 仅 item scope 兄弟节点;不含 Aggregate metrics。\r\n */\r\nimport { isWorkflowLoopTreeActive } from './workflowLoopTreeUtils';\r\nimport type { SessionTree } from '../../types/tree';\r\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\r\n\r\nexport interface ParallelGroupMetrics {\r\n total: number;\r\n running: number;\r\n completed: number;\r\n failed: number;\r\n}\r\n\r\nconst ACTIVE_ITEM_STATUSES = new Set<WorkflowContainerRuntimeNode['status']>([\r\n 'running',\r\n 'retrying',\r\n 'pending',\r\n 'blocked',\r\n]);\r\n\r\nfunction countMetricsFromContainerStatus(\r\n items: WorkflowContainerRuntimeNode[],\r\n): ParallelGroupMetrics {\r\n let running = 0;\r\n let completed = 0;\r\n let failed = 0;\r\n\r\n for (const item of items) {\r\n if (ACTIVE_ITEM_STATUSES.has(item.status)) {\r\n running += 1;\r\n continue;\r\n }\r\n switch (item.status) {\r\n case 'completed':\r\n completed += 1;\r\n break;\r\n case 'failed':\r\n failed += 1;\r\n break;\r\n default:\r\n break;\r\n }\r\n }\r\n\r\n return {\r\n total: items.length,\r\n running,\r\n completed,\r\n failed,\r\n };\r\n}\r\n\r\nfunction readDisplayMetrics(items: WorkflowContainerRuntimeNode[]): ParallelGroupMetrics | null {\r\n let hasMetrics = false;\r\n let running = 0;\r\n let completed = 0;\r\n let failed = 0;\r\n let total = 0;\r\n\r\n for (const item of items) {\r\n const metrics = item.display;\r\n if (\r\n metrics?.metrics_total != null\r\n || metrics?.metrics_running != null\r\n || metrics?.metrics_completed != null\r\n || metrics?.metrics_failed != null\r\n ) {\r\n hasMetrics = true;\r\n }\r\n running += metrics?.metrics_running ?? 0;\r\n completed += metrics?.metrics_completed ?? 0;\r\n failed += metrics?.metrics_failed ?? 0;\r\n total += metrics?.metrics_total ?? 0;\r\n }\r\n\r\n if (!hasMetrics) return null;\r\n if (total <= 0) total = items.length;\r\n return { total, running, completed, failed };\r\n}\r\n\r\n/** display.metrics_* 与容器 status 双轨取 max,防 SDK 滞后导致组误折。 */\r\nfunction mergeParallelGroupMetrics(\r\n fromDisplay: ParallelGroupMetrics,\r\n fromStatus: ParallelGroupMetrics,\r\n itemCount: number,\r\n): ParallelGroupMetrics {\r\n return {\r\n total: Math.max(fromDisplay.total, fromStatus.total, itemCount),\r\n running: Math.max(fromDisplay.running, fromStatus.running),\r\n completed: Math.max(fromDisplay.completed, fromStatus.completed),\r\n failed: Math.max(fromDisplay.failed, fromStatus.failed),\r\n };\r\n}\r\n\r\n/** 从 sibling item 容器统计组 metrics(display.metrics_* 优先,status 兜底/校正)。 */\r\nexport function computeParallelGroupMetrics(\r\n items: WorkflowContainerRuntimeNode[],\r\n): ParallelGroupMetrics {\r\n const fromStatus = countMetricsFromContainerStatus(items);\r\n const fromDisplay = readDisplayMetrics(items);\r\n if (!fromDisplay) return fromStatus;\r\n return mergeParallelGroupMetrics(fromDisplay, fromStatus, items.length);\r\n}\r\n\r\n/**\r\n * 原则 A · L2:组内仍有 active 工作(容器 status 或 scoped loop 未 settle)→ 不得折叠。\r\n * 结构帧(parallel-item-done)可能早于 loop finish,须双轨校验。\r\n */\r\nexport function parallelGroupHasActiveWork(\r\n items: WorkflowContainerRuntimeNode[],\r\n loopTreesBySessionId: Record<string, SessionTree> = {},\r\n): boolean {\r\n const metrics = computeParallelGroupMetrics(items);\r\n if (metrics.running > 0) return true;\r\n for (const item of items) {\r\n const loopSessionId = item.loopSessionId;\r\n if (!loopSessionId) continue;\r\n if (isWorkflowLoopTreeActive(loopTreesBySessionId[loopSessionId])) return true;\r\n }\r\n return false;\r\n}\r\n\r\nexport function formatParallelGroupSummary(metrics: ParallelGroupMetrics): string {\r\n if (metrics.running > 0) {\r\n const n = metrics.running;\r\n return `Running ${n} agent${n === 1 ? '' : 's'}…`;\r\n }\r\n if (metrics.failed > 0) {\r\n const ok = metrics.completed;\r\n return `Done (${ok} agent${ok === 1 ? '' : 's'}) · ${metrics.failed} failed`;\r\n }\r\n const n = metrics.total;\r\n return `Done (${n} agent${n === 1 ? '' : 's'})`;\r\n}\r\n","/**\n * WorkflowStageContainer.tsx — Stage / item 容器行(CC Agent 同构)\n */\nimport { useCallback, useEffect, useMemo, useState, memo, 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 { useWorkflowSessionStoreApi } from '../../core/context/WorkflowSessionContext';\nimport { useSessionViewOptions } from '../../core/context/SessionContext';\nimport {\n createWorkflowRunningLoopTree,\n isWorkflowLoopTreeActive,\n} 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';\nimport {\n workflowContainerNodeVisualEqual,\n workflowContainerViewPropsEqual,\n} from './workflowContainerMemo';\n\nexport interface WorkflowStageContainerProps {\n node: WorkflowContainerRuntimeNode;\n loopTree?: SessionTree;\n depth?: number;\n virtualized?: boolean;\n virtualizeThreshold?: number;\n groupParallelTools?: boolean;\n /** 嵌套 parallel 宿主 stage:仅作壳,不展示 scoped loop / Spinner */\n suppressHostScopedLoop?: boolean;\n /** 子树内仍有 active 容器时,宿主 stage 不得显示 done(stage-done 可能早于 agent 结束) */\n subtreeHasActiveWork?: 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 WorkflowStageContainerInner({\n node,\n loopTree,\n depth = 0,\n virtualized,\n virtualizeThreshold,\n groupParallelTools,\n suppressHostScopedLoop = false,\n subtreeHasActiveWork = false,\n}: WorkflowStageContainerProps) {\n const { verbose } = useSessionViewOptions();\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 isRunning = node.status === 'running' || node.status === 'retrying';\n const isDone = node.status === 'completed' || node.status === 'failed';\n const isSkipped = node.status === 'skipped';\n const loopStillActive = isWorkflowLoopTreeActive(loopTree);\n const effectivelyRunning =\n isRunning || loopStillActive || (subtreeHasActiveWork && isDone);\n const effectivelyDone = isDone && !subtreeHasActiveWork && !loopStillActive;\n\n const uiStatus = mapContainerUiStatus(effectivelyRunning ? 'running' : node.status);\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 /** 原则 A:仍在执行 → 保持展开;原则 B:effectivelyDone → 立刻折(不等兄弟) */\n const shouldAutoExpandRunning = effectivelyRunning && !isSkipped;\n\n const [expanded, setExpanded] = useState(shouldAutoExpandRunning);\n\n useEffect(() => {\n if (shouldAutoExpandRunning) {\n setExpanded(true);\n return;\n }\n if (effectivelyDone || isSkipped) {\n setExpanded(false);\n }\n }, [shouldAutoExpandRunning, effectivelyDone, isSkipped]);\n\n const requestLoopHydration = useCallback(() => {\n if (suppressHostScopedLoop) return;\n const loopSessionId = node.loopSessionId;\n if (!loopSessionId || loopTree) return;\n pinLoopSession(loopSessionId);\n void replayHandler?.(loopSessionId);\n }, [suppressHostScopedLoop, 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 testId = containerTestId(node);\n const isItem = node.scope === 'item';\n const displayTitle = node.title;\n\n const usesScopedLoop = Boolean(node.loopSessionId) && !suppressHostScopedLoop;\n const runningLoopTree: SessionTree | undefined =\n loopTree\n ?? (usesScopedLoop && effectivelyRunning ? createWorkflowRunningLoopTree() : undefined);\n const itemLoopVirtualized = isItem ? false : virtualized;\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 = effectivelyDone\n ? doneLabel\n : suppressHostScopedLoop && effectivelyRunning\n ? 'running'\n : mapContainerStatusLabel(effectivelyRunning ? 'running' : node.status);\n\n const canToggleShell = (effectivelyRunning && !isSkipped) || effectivelyDone;\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={effectivelyDone ? `${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 {effectivelyDone && !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 && effectivelyRunning && 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={itemLoopVirtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n />\n </div>\n ) : null}\n\n {effectivelyDone && expanded ? (\n loopTree ? (\n <WorkflowStageDoneBody\n node={node}\n loopTree={loopTree}\n testId={bodyTestId(node)}\n virtualized={itemLoopVirtualized}\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 ) : suppressHostScopedLoop ? null : (\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\nfunction workflowStageContainerPropsEqual(\n prev: WorkflowStageContainerProps,\n next: WorkflowStageContainerProps,\n): boolean {\n if (prev.suppressHostScopedLoop !== next.suppressHostScopedLoop) return false;\n if (prev.subtreeHasActiveWork !== next.subtreeHasActiveWork) return false;\n if (prev.loopTree !== next.loopTree) return false;\n if (!workflowContainerViewPropsEqual(prev, next)) return false;\n return workflowContainerNodeVisualEqual(prev.node, next.node);\n}\n\nexport const WorkflowStageContainer = memo(WorkflowStageContainerInner, workflowStageContainerPropsEqual);\n","/**\r\n * loopTreeUtils.ts — Workflow scoped loop 树辅助判断\r\n */\r\nimport type { SessionTree } from '../../types/tree';\r\n\r\n/** 是否已有可渲染的时间线节点(非空 store 壳) */\r\nexport function hasTimelineNodes(tree: SessionTree | undefined): boolean {\r\n if (!tree) return false;\r\n return tree.rootChildren.length > 0 || Object.keys(tree.byId).length > 0;\r\n}\r\n","/**\r\n * workflowStageDoneBody.tsx — Stage/Route 完成态展开体(仅 AgentLoopView 时间线)\r\n *\r\n * 禁止用 content_blocks 原始预览充展开体(会与 AgentSession 折叠流不一致)。\r\n */\r\nimport { hasTimelineNodes } from '../../core/workflow/loopTreeUtils';\r\nimport type { SessionTree } from '../../types/tree';\r\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\r\nimport { AgentLoopView } from '../agentLoop/AgentLoopView';\r\n\r\nexport interface WorkflowStageDoneBodyProps {\r\n node: WorkflowContainerRuntimeNode;\r\n loopTree?: SessionTree;\r\n testId: string;\r\n virtualized?: boolean;\r\n virtualizeThreshold?: number;\r\n groupParallelTools?: boolean;\r\n bodyClassName?: string;\r\n}\r\n\r\nexport function WorkflowStageDoneBody({\r\n loopTree,\r\n testId,\r\n virtualized,\r\n virtualizeThreshold,\r\n groupParallelTools,\r\n bodyClassName = 'lax-workflow-stage-container__body',\r\n}: WorkflowStageDoneBodyProps) {\r\n if (loopTree && hasTimelineNodes(loopTree)) {\r\n return (\r\n <div className={bodyClassName} data-testid={testId}>\r\n <AgentLoopView\r\n tree={loopTree}\r\n showTaskListFooter={false}\r\n virtualized={virtualized}\r\n virtualizeThreshold={virtualizeThreshold}\r\n groupParallelTools={groupParallelTools}\r\n />\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div\r\n className={`${bodyClassName} lax-workflow-stage-container__empty-hint`}\r\n data-testid={testId}\r\n >\r\n <span className=\"lax-workflow-stage-container__empty-hint-text\">\r\n (此阶段暂无 Agent 时间线内容)\r\n </span>\r\n </div>\r\n );\r\n}\r\n","/**\r\n * WorkflowRootContainer.tsx — Workflow 根行(始终展示子树,不折叠)\r\n *\r\n * 职责:根行壳语法 + 常驻 stage 列表。Workflow 已是页面顶层,不做 AgentSession 式根折叠。\r\n *\r\n * 链路位置:WorkflowChrome → scope workflow 根节点。\r\n */\r\nimport type { ReactNode } from 'react';\r\n\r\nimport { useSessionViewOptions } from '../../core/context/SessionContext';\r\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\r\nimport { WorkflowContainerLine } from './WorkflowContainerLine';\r\nimport {\r\n buildEffectiveWorkflowRootMeta,\r\n buildWorkflowRootMeta,\r\n isWorkflowRootVisuallyActive,\r\n mapContainerUiStatus,\r\n mapWorkflowRootStatusLabel,\r\n} from './workflowContainerLineUtils';\r\n\r\nexport interface WorkflowRootContainerProps {\r\n node: WorkflowContainerRuntimeNode;\r\n children?: ReactNode;\r\n containersById?: Record<string, WorkflowContainerRuntimeNode>;\r\n}\r\n\r\nexport function WorkflowRootContainer({\r\n node,\r\n children,\r\n containersById,\r\n}: WorkflowRootContainerProps) {\r\n const { verbose } = useSessionViewOptions();\r\n const visuallyActive = containersById\r\n ? isWorkflowRootVisuallyActive(node, containersById)\r\n : node.status === 'running' || node.status === 'retrying';\r\n const uiStatus = mapContainerUiStatus(visuallyActive ? 'running' : node.status);\r\n const statusLabel = mapWorkflowRootStatusLabel(visuallyActive ? 'running' : node.status);\r\n const meta = containersById\r\n ? buildEffectiveWorkflowRootMeta(node, containersById)\r\n : buildWorkflowRootMeta(node);\r\n\r\n return (\r\n <div className=\"lax-workflow-root\" data-testid=\"lax-workflow-root\">\r\n <WorkflowContainerLine\r\n variant=\"root\"\r\n title={node.title}\r\n description={node.subtitle || undefined}\r\n uiStatus={uiStatus}\r\n meta={meta}\r\n statusLabel={statusLabel}\r\n titleTestId=\"lax-workflow-root-title\"\r\n descriptionTestId=\"lax-workflow-root-desc\"\r\n debugScopeKey={node.scope_key}\r\n verbose={verbose}\r\n />\r\n\r\n {children ? (\r\n <div className=\"lax-workflow-container-tree\">{children}</div>\r\n ) : null}\r\n </div>\r\n );\r\n}\r\n\r\n","/**\r\n * WorkflowRouteContainer.tsx — Route branch 容器行\r\n *\r\n * 职责:selected/running 分支可展开;skipped ◌ dim 静态一行。\r\n *\r\n * 链路位置:WorkflowChrome → scope branch 节点。\r\n */\r\nimport { useCallback, useEffect, useMemo, useState, type CSSProperties } from 'react';\r\n\r\nimport {\r\n buildStageDoneSummary,\r\n formatTeaserExpandHint,\r\n} from '../../core/workflow/stageDoneSummary';\r\nimport { useSessionViewOptions } from '../../core/context/SessionContext';\r\nimport type { SessionTree } from '../../types/tree';\r\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\r\nimport { AgentLoopView } from '../agentLoop/AgentLoopView';\r\nimport { WorkflowContainerLine } from './WorkflowContainerLine';\r\nimport { WorkflowExpandTrigger } from './WorkflowExpandTrigger';\r\nimport { WorkflowStageDoneBody } from './workflowStageDoneBody';\r\nimport {\r\n buildRouteLineMeta,\r\n mapContainerStatusLabel,\r\n mapContainerUiStatus,\r\n workflowIndentUnit,\r\n} from './workflowContainerLineUtils';\r\n\r\nexport interface WorkflowRouteContainerProps {\r\n node: WorkflowContainerRuntimeNode;\r\n loopTree?: SessionTree;\r\n depth?: number;\r\n virtualized?: boolean;\r\n virtualizeThreshold?: number;\r\n groupParallelTools?: boolean;\r\n}\r\n\r\nexport function WorkflowRouteContainer({\r\n node,\r\n loopTree,\r\n depth = 1,\r\n virtualized,\r\n virtualizeThreshold,\r\n groupParallelTools,\r\n}: WorkflowRouteContainerProps) {\r\n const { verbose } = useSessionViewOptions();\r\n const isSkipped = node.status === 'skipped';\r\n const uiStatus = mapContainerUiStatus(node.status);\r\n const isRunning = !isSkipped && (node.status === 'running' || node.status === 'retrying');\r\n const isDone = !isSkipped && (node.status === 'completed' || node.status === 'failed');\r\n const testId = `lax-workflow-route-${node.scope_key}`;\r\n const doneSummary = useMemo(\r\n () => (loopTree && isDone ? buildStageDoneSummary(loopTree) : null),\r\n [loopTree, isDone],\r\n );\r\n const staticContentTeaser =\r\n !loopTree && node.content_blocks.length > 0\r\n ? node.content_blocks[node.content_blocks.length - 1]!.preview\r\n : '';\r\n const teaserText = doneSummary?.teaser || staticContentTeaser;\r\n const expandHint =\r\n doneSummary ? formatTeaserExpandHint(doneSummary.extraLines, verbose) : null;\r\n const doneLabel = doneSummary?.label ?? 'done';\r\n\r\n const [expanded, setExpanded] = useState(isRunning);\r\n\r\n useEffect(() => {\r\n if (isSkipped) return;\r\n if (isRunning) setExpanded(true);\r\n if (isDone) setExpanded(false);\r\n }, [isRunning, isDone, isSkipped]);\r\n\r\n const toggleExpanded = useCallback(() => {\r\n if (!isSkipped) setExpanded((prev) => !prev);\r\n }, [isSkipped]);\r\n\r\n const shellToggle =\r\n isSkipped ? undefined\r\n : isRunning ? toggleExpanded\r\n : isDone && expanded ? toggleExpanded\r\n : undefined;\r\n\r\n const depthStyle = {\r\n '--lax-workflow-depth': depth,\r\n '--lax-workflow-indent-unit': workflowIndentUnit(depth),\r\n } as CSSProperties;\r\n\r\n return (\r\n <div\r\n className={`lax-workflow-route-branch lax-workflow-stage-container lax-workflow-stage-container--${uiStatus}${\r\n isSkipped ? ' lax-workflow-route-branch--skipped' : ''\r\n }`}\r\n data-testid={testId}\r\n data-route-status={node.status}\r\n data-container-scope=\"branch\"\r\n style={depthStyle}\r\n >\r\n <WorkflowContainerLine\r\n title={node.title}\r\n description={node.subtitle || undefined}\r\n uiStatus={uiStatus}\r\n meta={buildRouteLineMeta(node)}\r\n statusLabel={isSkipped ? 'skipped' : mapContainerStatusLabel(node.status)}\r\n onToggle={shellToggle}\r\n interactive={!isSkipped && isRunning}\r\n expanded={expanded}\r\n titleTestId={`${testId}-title`}\r\n descriptionTestId={`${testId}-desc`}\r\n />\r\n\r\n {!isSkipped && expanded && isRunning && loopTree ? (\r\n <div className=\"lax-workflow-stage-container__body\" data-testid={`${testId}-body`}>\r\n <AgentLoopView\r\n tree={loopTree}\r\n showTaskListFooter={false}\r\n virtualized={virtualized}\r\n virtualizeThreshold={virtualizeThreshold}\r\n groupParallelTools={groupParallelTools}\r\n />\r\n </div>\r\n ) : null}\r\n\r\n {!isSkipped && isDone && !expanded ? (\r\n <WorkflowExpandTrigger\r\n summary={`${node.title} · ${doneLabel}`}\r\n teaser={teaserText || undefined}\r\n expandHint={expandHint}\r\n onToggle={() => setExpanded(true)}\r\n expanded={false}\r\n testId={`${testId}-done`}\r\n teaserTestId={teaserText ? `${testId}-teaser` : undefined}\r\n />\r\n ) : null}\r\n\r\n {!isSkipped && isDone && expanded ? (\r\n <WorkflowStageDoneBody\r\n node={node}\r\n loopTree={loopTree}\r\n testId={`${testId}-body`}\r\n virtualized={virtualized}\r\n virtualizeThreshold={virtualizeThreshold}\r\n groupParallelTools={groupParallelTools}\r\n />\r\n ) : null}\r\n </div>\r\n );\r\n}\r\n","/**\r\n * WorkflowSubworkflowContainer.tsx — Subworkflow 缩进 mini 根行 + 左边界\r\n *\r\n * 职责:与 workflow 根同壳行语法;嵌套子树包在 boundary 内;done 折叠为 ExpandTrigger。\r\n *\r\n * 链路位置:WorkflowChrome → scope subworkflow 节点。\r\n */\r\nimport { useCallback, useEffect, useMemo, useState, type CSSProperties, type ReactNode } from 'react';\r\n\r\nimport { useSessionViewOptions } from '../../core/context/SessionContext';\r\nimport type { WorkflowContainerRuntimeNode } from '../../types/workflowContainer';\r\nimport { WorkflowContainerLine } from './WorkflowContainerLine';\r\nimport { WorkflowExpandTrigger } from './WorkflowExpandTrigger';\r\nimport {\r\n buildWorkflowRootMeta,\r\n mapContainerUiStatus,\r\n mapWorkflowRootStatusLabel,\r\n workflowIndentUnit,\r\n} from './workflowContainerLineUtils';\r\n\r\nexport interface WorkflowSubworkflowContainerProps {\r\n node: WorkflowContainerRuntimeNode;\r\n depth?: number;\r\n children?: ReactNode;\r\n /** 子树内仍有 running/pending 容器时为 true,阻止 subworkflow-end 过早折叠 */\r\n subtreeHasActiveWork?: boolean;\r\n}\r\n\r\nfunction buildDoneSummary(node: WorkflowContainerRuntimeNode): string {\r\n const display = node.display;\r\n if (display?.progress_total != null) {\r\n const total = display.progress_total;\r\n const current =\r\n node.status === 'completed' ? total : (display.progress_current ?? total);\r\n return `${current}/${total} · done`;\r\n }\r\n return 'done';\r\n}\r\n\r\nexport function WorkflowSubworkflowContainer({\r\n node,\r\n depth = 1,\r\n children,\r\n subtreeHasActiveWork = false,\r\n}: WorkflowSubworkflowContainerProps) {\r\n const { verbose } = useSessionViewOptions();\r\n const isRunning = node.status === 'running' || node.status === 'retrying';\r\n const isDone = node.status === 'completed' || node.status === 'failed';\r\n const effectivelyRunning = isRunning || subtreeHasActiveWork;\r\n const effectivelyDone = isDone && !subtreeHasActiveWork;\r\n const uiStatus = mapContainerUiStatus(\r\n effectivelyRunning ? 'running' : node.status,\r\n );\r\n const testId = `lax-workflow-subworkflow-${node.scope_key}`;\r\n const teaser = useMemo(() => {\r\n if (node.content_blocks.length === 0) return '';\r\n return node.content_blocks[node.content_blocks.length - 1]?.preview ?? '';\r\n }, [node.content_blocks]);\r\n\r\n const [expanded, setExpanded] = useState(effectivelyRunning);\r\n\r\n useEffect(() => {\r\n if (effectivelyRunning) setExpanded(true);\r\n else if (effectivelyDone) setExpanded(false);\r\n }, [effectivelyRunning, effectivelyDone]);\r\n\r\n const toggleExpanded = useCallback(() => {\r\n setExpanded((prev) => !prev);\r\n }, []);\r\n\r\n const shellToggle =\r\n effectivelyRunning ? toggleExpanded\r\n : effectivelyDone && expanded ? toggleExpanded\r\n : undefined;\r\n\r\n const depthStyle = {\r\n '--lax-workflow-depth': depth,\r\n '--lax-workflow-indent-unit': workflowIndentUnit(depth),\r\n } as CSSProperties;\r\n\r\n const showShellLine = !(effectivelyDone && !expanded);\r\n\r\n return (\r\n <div\r\n className=\"lax-workflow-subworkflow\"\r\n data-testid={testId}\r\n data-container-scope=\"subworkflow\"\r\n style={depthStyle}\r\n >\r\n {showShellLine ? (\r\n <WorkflowContainerLine\r\n variant=\"root\"\r\n title={node.title}\r\n description={node.subtitle || undefined}\r\n uiStatus={uiStatus}\r\n meta={buildWorkflowRootMeta(node)}\r\n statusLabel={mapWorkflowRootStatusLabel(\r\n effectivelyRunning ? 'running' : node.status,\r\n )}\r\n onToggle={shellToggle}\r\n interactive={effectivelyRunning}\r\n expanded={expanded}\r\n titleTestId={`${testId}-title`}\r\n descriptionTestId={`${testId}-desc`}\r\n debugScopeKey={node.scope_key}\r\n verbose={verbose}\r\n />\r\n ) : null}\r\n\r\n {expanded && children ? (\r\n <div\r\n className=\"lax-workflow-subworkflow-boundary\"\r\n data-testid={`${testId}-boundary`}\r\n style={depthStyle}\r\n >\r\n {children}\r\n </div>\r\n ) : null}\r\n\r\n {!expanded && children ? (\r\n <WorkflowExpandTrigger\r\n summary={`${node.title} · ${effectivelyDone ? buildDoneSummary(node) : 'running'}`}\r\n summaryTestId={`${testId}-title`}\r\n teaser={teaser || undefined}\r\n expandHint={effectivelyRunning ? '(click to expand subworkflow)' : undefined}\r\n onToggle={() => setExpanded(true)}\r\n expanded={false}\r\n testId={effectivelyDone ? `${testId}-done` : `${testId}-running-collapsed`}\r\n teaserTestId={teaser ? `${testId}-teaser` : undefined}\r\n />\r\n ) : null}\r\n </div>\r\n );\r\n}\r\n","/**\r\n * WorkflowTaskListFooter.tsx — 合并多 loop 任务列表底部 pill(§5.11.4)\r\n */\r\nimport { useMemo, useState } from 'react';\r\nimport { useStore } from 'zustand';\r\n\r\nimport { useWorkflowSessionStoreApi } from '../../core/context/WorkflowSessionContext';\r\nimport type { WorkflowSessionStoreState } from '../../core/workflowSessionStore';\r\nimport { TaskList } from '../TaskList';\r\nimport {\r\n deriveWorkflowTaskFooterState,\r\n formatWorkflowTaskFooterLabel,\r\n groupWorkflowTasksByLoop,\r\n loopSessionDisplayLabel,\r\n shouldShowWorkflowTaskListFooter,\r\n} from './workflowTaskListMerge';\r\n\r\nfunction MessageResponse({ children }: { children: React.ReactNode }) {\r\n return (\r\n <div className=\"lax-message-response\">\r\n <span className=\"lax-message-response__marker\">⎿ </span>\r\n <span className=\"lax-message-response__content\">{children}</span>\r\n </div>\r\n );\r\n}\r\n\r\nexport function WorkflowTaskListFooter() {\r\n const store = useWorkflowSessionStoreApi();\r\n const state = useStore(store, (s: WorkflowSessionStoreState) => s.state);\r\n const [expanded, setExpanded] = useState(false);\r\n\r\n const footerState = useMemo(() => deriveWorkflowTaskFooterState(state), [state]);\r\n const visible = shouldShowWorkflowTaskListFooter(state);\r\n\r\n if (!visible) {\r\n return null;\r\n }\r\n\r\n const label = formatWorkflowTaskFooterLabel(state);\r\n const groups = groupWorkflowTasksByLoop(footerState.tasks);\r\n\r\n return (\r\n <div className=\"lax-workflow-task-list-footer\" data-testid=\"lax-workflow-task-list-footer\">\r\n <button\r\n type=\"button\"\r\n className=\"lax-task-list-footer__pill lax-workflow-task-list-footer__pill\"\r\n data-testid=\"lax-workflow-task-list-footer-pill\"\r\n aria-expanded={expanded}\r\n onClick={() => setExpanded((v) => !v)}\r\n >\r\n {label}\r\n <span className=\"lax-task-list-footer__hint\">\r\n {expanded ? ' · ↑ to hide' : ' · ↓ to view'}\r\n </span>\r\n </button>\r\n {expanded ? (\r\n <MessageResponse>\r\n <div className=\"lax-workflow-task-list-groups\">\r\n {groups.map((group) => (\r\n <div\r\n key={group.loopSessionId}\r\n className=\"lax-workflow-task-list-group\"\r\n data-testid={`lax-workflow-task-group-${group.loopSessionId}`}\r\n >\r\n <div className=\"lax-workflow-task-list-group-title\">\r\n {loopSessionDisplayLabel(group.loopSessionId)}\r\n </div>\r\n <TaskList tasks={group.tasks} />\r\n </div>\r\n ))}\r\n </div>\r\n </MessageResponse>\r\n ) : null}\r\n </div>\r\n );\r\n}\r\n","/**\r\n * workflowTaskListMerge.ts — Workflow 多 loop 任务合并(§5.11.4)\r\n */\r\nimport type { Task } from '../../types/tasks';\r\nimport type { SessionStatus, SessionTree, TaskPhase } from '../../types/tree';\r\nimport type { WorkflowSessionState } from '../../types/workflowSession';\r\n\r\nimport {\r\n formatTaskFooterLabel,\r\n shouldShowTaskListFooter,\r\n} from '../TaskListFooter';\r\n\r\nexport interface WorkflowMergedTask extends Task {\r\n loopSessionId: string;\r\n}\r\n\r\nconst STATUS_ORDER: Record<Task['status'], number> = {\r\n in_progress: 0,\r\n pending: 1,\r\n completed: 2,\r\n};\r\n\r\nexport function mergeWorkflowLoopTasks(\r\n loopTreesBySessionId: Record<string, SessionTree>,\r\n): WorkflowMergedTask[] {\r\n const merged: WorkflowMergedTask[] = [];\r\n const loopIds = Object.keys(loopTreesBySessionId).sort();\r\n for (const loopSessionId of loopIds) {\r\n const tree = loopTreesBySessionId[loopSessionId];\r\n if (!tree) continue;\r\n for (const task of Object.values(tree.tasks)) {\r\n merged.push({ ...task, loopSessionId });\r\n }\r\n }\r\n return merged.sort((a, b) => {\r\n const sa = STATUS_ORDER[a.status] ?? 99;\r\n const sb = STATUS_ORDER[b.status] ?? 99;\r\n if (sa !== sb) return sa - sb;\r\n const loopCmp = a.loopSessionId.localeCompare(b.loopSessionId);\r\n if (loopCmp !== 0) return loopCmp;\r\n return a.id.localeCompare(b.id);\r\n });\r\n}\r\n\r\nexport function deriveWorkflowTaskPhase(trees: SessionTree[]): TaskPhase {\r\n if (trees.length === 0) return 'hidden';\r\n if (trees.some((tree) => tree.taskPhase === 'visible')) return 'visible';\r\n if (trees.every((tree) => tree.taskPhase === 'hidden-after-completion')) {\r\n return 'hidden-after-completion';\r\n }\r\n return 'hidden';\r\n}\r\n\r\nexport function deriveWorkflowTaskFooterState(state: WorkflowSessionState): {\r\n tasks: WorkflowMergedTask[];\r\n taskPhase: TaskPhase;\r\n hasEverShownTaskList: boolean;\r\n sessionStatus: SessionStatus;\r\n} {\r\n const trees = Object.values(state.loopTreesBySessionId);\r\n return {\r\n tasks: mergeWorkflowLoopTasks(state.loopTreesBySessionId),\r\n taskPhase: deriveWorkflowTaskPhase(trees),\r\n hasEverShownTaskList: trees.some((tree) => tree.hasEverShownTaskList),\r\n sessionStatus: state.status,\r\n };\r\n}\r\n\r\nexport function shouldShowWorkflowTaskListFooter(state: WorkflowSessionState): boolean {\r\n const { tasks, taskPhase, hasEverShownTaskList, sessionStatus } =\r\n deriveWorkflowTaskFooterState(state);\r\n return shouldShowTaskListFooter(taskPhase, tasks, hasEverShownTaskList, sessionStatus);\r\n}\r\n\r\nexport function formatWorkflowTaskFooterLabel(state: WorkflowSessionState): string {\r\n const { tasks } = deriveWorkflowTaskFooterState(state);\r\n return formatTaskFooterLabel(tasks);\r\n}\r\n\r\nexport function groupWorkflowTasksByLoop(\r\n tasks: WorkflowMergedTask[],\r\n): Array<{ loopSessionId: string; tasks: Task[] }> {\r\n const groups = new Map<string, Task[]>();\r\n for (const task of tasks) {\r\n const bucket = groups.get(task.loopSessionId) ?? [];\r\n bucket.push(task);\r\n groups.set(task.loopSessionId, bucket);\r\n }\r\n return Array.from(groups.entries())\r\n .sort(([a], [b]) => a.localeCompare(b))\r\n .map(([loopSessionId, groupTasks]) => ({ loopSessionId, tasks: groupTasks }));\r\n}\r\n\r\nexport function loopSessionDisplayLabel(loopSessionId: string): string {\r\n const marker = '-';\r\n const idx = loopSessionId.lastIndexOf(marker);\r\n if (idx !== -1 && idx < loopSessionId.length - 1) {\r\n return loopSessionId.slice(idx + 1);\r\n }\r\n return loopSessionId;\r\n}\r\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","/**\r\n * 职责:默认 SubAgentNode 纵向嵌套容器 widget(方案 A 已退场)。\r\n * 链路位置:宿主可通过 NodeRegistry.register('subagent', SubAgentBlock) 恢复旧行为。\r\n * 当前裁剪范围:纵向缩进;不含横向并列布局。\r\n * @deprecated 方案 A 主时间线不再渲染 SubAgentBlock;子 agent progress 折叠在 AgentToolBody。\r\n */\r\nimport { useChildren, useNodeTyped } from '../../core/hooks';\r\nimport { useNodeRegistry } from '../../core/context/SessionContext';\r\nimport { TimelineItem } from '../Timeline';\r\n\r\nexport interface SubAgentBlockProps {\r\n nodeId: string;\r\n}\r\n\r\nexport function SubAgentBlock({ nodeId }: SubAgentBlockProps) {\r\n const node = useNodeTyped(nodeId, 'subagent');\r\n const childIds = useChildren(nodeId);\r\n const registry = useNodeRegistry();\r\n if (!node) return null;\r\n\r\n return (\r\n <div className=\"lax-subagent-block\" data-status={node.status}>\r\n <div className=\"lax-subagent-block__header\">SubAgent: {node.subagentId}</div>\r\n <div className=\"lax-subagent-block__children\">\r\n {childIds.map((childId) => (\r\n <TimelineItem key={childId} nodeId={childId} registry={registry} />\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","/**\r\n * 职责:内存事件源,按序投递 events 实现 Source 接口。\r\n * 链路位置:历史回放、测试、AgentSession 只读时间线。\r\n * 当前裁剪范围:可选 delayMs 模拟流式;不含 SSE 续传。\r\n */\r\nimport type { LangchainAgentEvent } from '../types/events';\r\nimport type { ReplayOptions } from '../core/replay';\r\nimport type { Source, SourceHandler } from './types';\r\n\r\nexport interface ReplaySourceOptions extends ReplayOptions {\r\n /** 事件间隔毫秒;默认 0 立即投递 */\r\n delayMs?: number;\r\n}\r\n\r\nfunction sleep(ms: number, signal: AbortSignal): Promise<void> {\r\n if (ms <= 0) return Promise.resolve();\r\n return new Promise((resolve) => {\r\n const timer = setTimeout(resolve, ms);\r\n signal.addEventListener(\r\n 'abort',\r\n () => {\r\n clearTimeout(timer);\r\n resolve();\r\n },\r\n { once: true },\r\n );\r\n });\r\n}\r\n\r\nexport function createReplaySource(\r\n events: LangchainAgentEvent[],\r\n opts?: ReplaySourceOptions,\r\n): Source {\r\n const delayMs = opts?.delayMs ?? 0;\r\n\r\n return {\r\n async start(handler: SourceHandler, signal: AbortSignal): Promise<void> {\r\n for (const event of events) {\r\n if (signal.aborted) break;\r\n handler(event);\r\n if (delayMs > 0) {\r\n await sleep(delayMs, signal);\r\n }\r\n }\r\n },\r\n };\r\n}\r\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","readString","readString","readString","readString","node","loopSessionId","next","loopTree","reducedLoop","createStore","useMemo","useState","useEffect","useMemo","jsx","jsxs","jsx","jsxs","jsx","jsx","jsxs","useMemo","useEffect","useCallback","useEffect","useMemo","useState","memo","n","useCallback","useEffect","useMemo","useState","memo","useStore","jsx","jsx","jsxs","subtreeHasActiveWork","useStore","useMemo","useState","useEffect","useCallback","memo","jsx","jsxs","useMemo","useState","useEffect","useCallback","memo","jsx","jsxs","useCallback","useEffect","useMemo","useState","jsx","jsxs","useMemo","useState","useEffect","useCallback","useCallback","useEffect","useMemo","useState","jsx","jsxs","subtreeHasActiveWork","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"]}
|