import type { FlowDefinition, FlowState, NodeExecutionSnapshot, NodeStatus } from "./types.js"; /** Result of resolving one available router against the current expression context. */ export interface RouterResolution { /** First matching route target. `null` means every branch loses. */ selectedTarget: string | null; /** Exclusive nodes belonging only to unselected route targets, in definition order. */ skippedNodeIds: string[]; } /** Available router that cannot make a deterministic choice from the current snapshot. */ export interface UnresolvedRouterResolution { /** Why the router remains available for a later drain pass. */ unresolved: "not-ready" | "no-match"; } /** * Resolve the first matching route for a router that is currently available. * * Route conditions use the same bounded context as node preconditions and bindings. Resolution * is deliberately separate from state computation: unavailable routers return `undefined` * without evaluating any route. Losing route targets and their exclusive downstream paths are * returned for the caller to mark skipped. Exclusivity follows hard `flow` edges only and keeps * selected routes, unsettled-router targets, shared convergence, and externally reachable nodes * live. A declared producer output that is not complete yet returns a retryable unresolved result; * malformed expressions still throw their path-bearing evaluator error. * * @param flow - Parsed flow containing the router and branch graph. * @param routerNodeId - Router execution identity. * @param snapshots - Current node snapshots used for admission and expression values. * @returns The selected target and losing nodes, an unresolved reason while available but not * decidable, or `undefined` while the router is unavailable. */ export declare function resolveAvailableRouter(flow: FlowDefinition, routerNodeId: string, snapshots: Map): RouterResolution | UnresolvedRouterResolution | undefined; /** * Compute the full {@link FlowState} from a flow definition and caller-supplied node ID sets. * * This is the primary engine function. It is stateless and side-effect-free — calling it * twice with the same arguments always returns an equivalent result. * * Edge semantics applied during computation: * - `'flow'` — hard dependency: target cannot start until source is `complete` or `skipped`. * - `'parallel'` — soft dependency: target may run while source is still running. * - `'optional'` — advisory: target can start regardless of source state. * * A node is `available` when every incoming `'flow'`-type edge has a complete or skipped source * and every authored precondition evaluates true. * A node is `not_started` when at least one hard predecessor is still pending. * The flow is `done` when every non-optional node is `complete` or `skipped`. * * This set-based overload has statuses but no completed output fields. Use * {@link computeFlowStateFromSnapshots} when a precondition reads node output. * * Prefer {@link computeFlowStateFromSnapshots} for callers that track full `NodeExecution` * state (interaction statuses such as `awaiting_approval`, `awaiting_input`, `failed`). * * @param flow - The parsed flow definition. * @param completedIds - Set of node IDs that have finished successfully. * @param runningIds - Set of node IDs currently executing. Defaults to an empty set. * @param skippedIds - Set of node IDs that were explicitly skipped. Skipped nodes count * as satisfied for downstream dependency checks. Defaults to an empty set. * @returns A {@link FlowState} describing every active runtime node. * @docLink packages/flow-engine/concepts#compute-flow-state */ export declare function computeFlowState(flow: FlowDefinition, completedIds: Set, runningIds?: Set, skippedIds?: Set): FlowState; /** * Snapshot-based variant of {@link computeFlowState}. * * Accepts a map of `NodeExecutionSnapshot` values carrying the current status and * interaction metadata for every node the caller knows about. Nodes absent from the * map are treated as `not_started`. * * This is the preferred API for the turn-based runner, which has a full `FlowExecution` * and needs to convey richer statuses (`awaiting_approval`, `awaiting_input`, `failed`) * back to the engine so downstream availability is computed correctly. * * Engine semantics: * - A node is `available` when all its incoming `'flow'`-type predecessors are `complete` * or `skipped`. Any other upstream status — including `awaiting_approval`, * `awaiting_input`, and `failed` — is treated as blocking. Every authored precondition * must also evaluate true against the snapshot expression context. * - Optionality is **not** a term here: `failed` blocks whether or not the node is optional. * An optional node's dependents proceed because an optional node never reaches a terminal * `failed` in the first place — its exhausted failure resolves to `skipped` * (`resolveTerminalFailureStatus`), which passes. The one exception is a router, which * stays `failed` even when optional. * - The flow is `done` when every non-optional node is `complete` or `skipped`. A single * required node stuck in `failed` keeps `done` false. * * @param flow - The parsed flow definition. * @param snapshots - Map from node ID to its current {@link NodeExecutionSnapshot}. * Missing entries default to `not_started` with no interaction metadata. * @returns A {@link FlowState} describing every active runtime node, * including interaction fields (`approval`, `input`, `output`, `error`) copied * from the matching snapshot. * @docLink packages/flow-engine/concepts#compute-flow-state-from-snapshots */ export declare function computeFlowStateFromSnapshots(flow: FlowDefinition, snapshots: Map): FlowState; /** * Returns `true` when the given status prevents downstream nodes from starting. * * Only `'complete'` and `'skipped'` satisfy a hard (`'flow'`-type) edge dependency. * All other statuses — including `'awaiting_approval'`, `'awaiting_input'`, and * `'failed'` — are considered blocking. * * Use this helper in the FlowAdapter and the turn-based orchestrator instead of * hard-coding the two-value whitelist inline. * * @param status - The {@link NodeStatus} to evaluate. * @returns `true` if the status prevents dependents from becoming `available`. * @docLink packages/flow-engine/concepts#is-blocking */ export declare function isBlocking(status: NodeStatus): boolean; /** * Returns the IDs of nodes that become newly `available` after a specific node completes. * * More efficient than recomputing the full {@link FlowState} when only the downstream * impact of a single completion is needed. Only the direct successors of `justCompleted` * are evaluated — the rest of the graph is untouched. * * @param flow - The parsed flow definition. * @param justCompleted - ID of the node that just finished (will be added to the * effective completed set before evaluating successors). * @param completedIds - Set of node IDs already known to be complete before this call. * @param skippedIds - Set of node IDs that were explicitly skipped. Defaults to an empty set. * @returns Array of node IDs whose hard dependencies are now fully satisfied and that * were not already available before `justCompleted` finished. Unlike executable-node-filtered * helpers, this walks raw edge targets and does not filter by node type — if a `group`, * `sub-flow`, or `router` node is a direct successor, its ID can appear here. Callers that * dispatch these IDs are responsible for filtering inert nodes. * @docLink packages/flow-engine/concepts#resolve-next-nodes */ export declare function resolveNextNodes(flow: FlowDefinition, justCompleted: string, completedIds: Set, skippedIds?: Set): string[]; /** * Returns the IDs of optional nodes that have not yet started and can be safely skipped. * * A node is skippable when it is: * 1. Not yet complete (absent from `completedIds`). * 2. Marked `optional` (`FlowNode.data.optional === true`). * 3. Not connected via a `'flow'`-type edge to any non-optional downstream node * (i.e. skipping it cannot starve a required node of a hard dependency). * * The runner may call this to present the user with a list of nodes they can bypass * without breaking the flow's required path. * * @param flow - The parsed flow definition. * @param completedIds - Set of node IDs that have already completed (excluded from results). * @returns Array of node IDs that are safe to skip at this point in the execution. * @docLink packages/flow-engine/concepts#compute-skippable */ export declare function computeSkippable(flow: FlowDefinition, completedIds: Set): string[]; //# sourceMappingURL=engine.d.ts.map