/**
 * workflow() — sequential steps whose hand-offs are checked by the compiler.
 *
 * WHY this exists: `Sequence` is the workhorse for "A, then B, then C",
 * and every step it accepts has the same shape — takes `{ message }`,
 * returns `string`. That is exactly right for chaining LLM calls, and
 * exactly wrong the moment a step wants to hand the next one something
 * structured: `Sequence` coerces any non-string step output to `''`
 * (Sequence.ts, the step `outputMapper`), so a step that returns a parsed
 * ticket silently hands the next step nothing at all. The mistake shows up
 * as an empty prompt three steps later, at runtime, in production.
 *
 * `workflow()` closes that gap from both ends:
 *
 *   - **At compile time** — step N's OUTPUT type must be what step N+1
 *     accepts. A `Runner<{ message: string }, Ticket>` followed by a
 *     `Runner<{ orderId: string }, string>` does not compile. The chain is
 *     proven before you run it, not debugged after.
 *   - **At run time** — a step's value is handed to the next step
 *     UNCHANGED. Objects stay objects. The one convenience is the house
 *     convention: a step that returns a `string` feeds the next step's
 *     `{ message }`, because that is what every LLM runner here wants.
 *
 * Pattern: Adapter over footprintjs's `addSubFlowChartNext`, with the
 *          type-level handoff proof carried by overloads (1–8 steps).
 * Role:    core-flow/ layer, alongside Sequence/Parallel/Conditional/Loop.
 *          Pure control flow — no LLM dependency.
 * Emits:   agentfootprint.composition.enter / exit, reported as kind
 *          `'Sequence'` — a workflow IS a sequential composition, and
 *          widening the public `CompositionKind` union would break
 *          exhaustive switches in consumer code for no behavioural gain.
 *
 * THREE HONEST LIMITS, all inherited from the engine and all verified in
 * `test/core-flow/scenario/Workflow.test.ts` — worth knowing before you
 * put rich objects on the wire:
 *
 *   1. Only PLAIN DATA crosses a step boundary. A value with a prototype
 *      (Date, Map, Set, a class instance) arrives as `{}`, and `undefined`
 *      fields are dropped. Send strings, numbers, arrays and plain
 *      objects; send a timestamp as an ISO string, not a `Date`.
 *   2. A step must RETURN its output — the value handed forward is the
 *      step chart's traversal result. A step whose last stage returns
 *      nothing hands its whole scope forward instead.
 *   3. The workflow's own input keys stay visible to LATER steps too
 *      (footprintjs's `getArgs()` inherits the run's arguments). A key the
 *      previous step actually produced always wins; a key it did NOT
 *      produce can still be read from the original input rather than
 *      coming back `undefined`.
 *
 * @example  a typed three-step chain
 * ```ts
 * interface Ticket { orderId: string; angry: boolean }
 *
 * const parse: Runner<{ message: string }, Ticket> = …;
 * const lookup: Runner<Ticket, { refundUsd: number }> = …;
 * const reply: Runner<{ refundUsd: number }, string> = …;
 *
 * const intake = workflow(parse, lookup, reply);
 * const answer = await intake.run({ message: 'where is my refund?' });
 * //    ^? string — the chain's last output type
 *
 * workflow(parse, reply); // ✗ compile error: Ticket is not { refundUsd }
 * ```
 */
import { type FlowchartCheckpoint, type StructureRecorder } from 'footprintjs';
import type { RunOptions } from '../core/runner.js';
import type { RunnerPauseOutcome } from '../core/pause.js';
import type { Runner } from '../core/runner.js';
import { RunnerBase } from '../core/RunnerBase.js';
/**
 * What the NEXT step must accept, given what the previous one returns.
 *
 * A `string` output feeds `{ message }` — the convention every runner in
 * this library already speaks (LLMCall, Agent, Sequence, Swarm). Anything
 * else is handed over as-is, so the next step's input type must be that
 * same type.
 */
export type NextStepInput<TPreviousOutput> = TPreviousOutput extends string ? {
    message: string;
} : TPreviousOutput;
/** Any runner, viewed only as "a thing with a chart" — the workflow never
 *  needs a step's own input/output types at run time. */
type AnyStep = Runner<never, unknown>;
export interface WorkflowOptions {
    /** Human-friendly name for events + topology. Default `'Workflow'`. */
    readonly name?: string;
    /** Stable id used for topology + events. Default `'workflow'`. */
    readonly id?: string;
    /**
     * Optional build-time recorders passed through to footprintjs's
     * `flowChart()` factory — they observe this workflow's own nodes (Seed +
     * one mount per step + Finalize). Not propagated into the mounted step
     * charts; attach them to each step runner for full coverage.
     */
    readonly structureRecorders?: readonly StructureRecorder[];
}
/**
 * A sequential composition that passes values through untouched. Build one
 * with {@link workflow} — that factory carries the type-level chain proof.
 */
export declare class Workflow<TIn extends object = object, TOut = unknown> extends RunnerBase<TIn, TOut> {
    readonly name: string;
    readonly id: string;
    private readonly steps;
    private readonly opts;
    private currentRunContext;
    constructor(steps: readonly AnyStep[], opts?: WorkflowOptions);
    run(input: TIn, options?: RunOptions): Promise<TOut | RunnerPauseOutcome>;
    resume(checkpoint: FlowchartCheckpoint, input?: unknown, options?: RunOptions): Promise<TOut | RunnerPauseOutcome>;
    private createExecutor;
    private finalizeResult;
    private buildChart;
}
/**
 * Chain 1–8 runners into one, with every hand-off checked by the compiler.
 *
 * Step N's output type must be what step N+1 accepts — a `string` output
 * feeds the next step's `{ message }` (the house convention), anything
 * else is handed over as-is. A chain that does not line up is a COMPILE
 * error, not a silent empty value at run time.
 *
 * @example  LLM steps chain as they always have
 * ```ts
 * const draft = LLMCall.create({ provider, model }).system('Draft it.').build();
 * const edit = LLMCall.create({ provider, model }).system('Tighten it.').build();
 *
 * const pipeline = workflow(draft, edit);
 * const text = await pipeline.run({ message: 'a note about refunds' });
 * ```
 *
 * @example  structured hand-offs survive
 * ```ts
 * const classify: Runner<{ message: string }, { topic: string }> = …;
 * const answer: Runner<{ topic: string }, string> = …;
 *
 * await workflow(classify, answer).run({ message: 'my card was declined' });
 * ```
 */
export declare function workflow<A extends object, B>(s1: Runner<A, B>): Workflow<A, B>;
export declare function workflow<A extends object, B, C>(s1: Runner<A, B>, s2: Runner<NextStepInput<B>, C>): Workflow<A, C>;
export declare function workflow<A extends object, B, C, D>(s1: Runner<A, B>, s2: Runner<NextStepInput<B>, C>, s3: Runner<NextStepInput<C>, D>): Workflow<A, D>;
export declare function workflow<A extends object, B, C, D, E>(s1: Runner<A, B>, s2: Runner<NextStepInput<B>, C>, s3: Runner<NextStepInput<C>, D>, s4: Runner<NextStepInput<D>, E>): Workflow<A, E>;
export declare function workflow<A extends object, B, C, D, E, F>(s1: Runner<A, B>, s2: Runner<NextStepInput<B>, C>, s3: Runner<NextStepInput<C>, D>, s4: Runner<NextStepInput<D>, E>, s5: Runner<NextStepInput<E>, F>): Workflow<A, F>;
export declare function workflow<A extends object, B, C, D, E, F, G>(s1: Runner<A, B>, s2: Runner<NextStepInput<B>, C>, s3: Runner<NextStepInput<C>, D>, s4: Runner<NextStepInput<D>, E>, s5: Runner<NextStepInput<E>, F>, s6: Runner<NextStepInput<F>, G>): Workflow<A, G>;
export declare function workflow<A extends object, B, C, D, E, F, G, H>(s1: Runner<A, B>, s2: Runner<NextStepInput<B>, C>, s3: Runner<NextStepInput<C>, D>, s4: Runner<NextStepInput<D>, E>, s5: Runner<NextStepInput<E>, F>, s6: Runner<NextStepInput<F>, G>, s7: Runner<NextStepInput<G>, H>): Workflow<A, H>;
export declare function workflow<A extends object, B, C, D, E, F, G, H, I>(s1: Runner<A, B>, s2: Runner<NextStepInput<B>, C>, s3: Runner<NextStepInput<C>, D>, s4: Runner<NextStepInput<D>, E>, s5: Runner<NextStepInput<E>, F>, s6: Runner<NextStepInput<F>, G>, s7: Runner<NextStepInput<G>, H>, s8: Runner<NextStepInput<H>, I>): Workflow<A, I>;
export {};
