import type { SymiConfig } from "../../config/config.js";
import type { FinalizedMsgContext } from "../templating.js";
import type { ReplyPayload } from "../types.js";
export interface DispatchInput {
    ctx: FinalizedMsgContext;
    cfg: SymiConfig;
    /**
     * Mutable scratch space. By convention, middlewares write under their
     * own namespaced key (e.g. `scratch.inboundAudio`, `scratch.fastAbortPayload`).
     * Type is `unknown` so each consumer narrows; future phases may tighten
     * to a structured type once the keyset stabilizes.
     */
    scratch: Record<string, unknown>;
}
export type DispatchOutcome = {
    kind: "proceed";
} | {
    kind: "skipped";
    reason: string;
} | {
    kind: "aborted";
    reason: string;
    payload: ReplyPayload;
};
export type DispatchHandler = (input: DispatchInput) => Promise<DispatchOutcome>;
/**
 * Onion-style wrapper around a DispatchHandler. Same composition algebra
 * as TurnMiddleware (Phase 3) and PayloadMiddleware (Phase 7) — the
 * first middleware in the array is the OUTERMOST wrapper.
 */
export type DispatchMiddleware = (next: DispatchHandler) => DispatchHandler;
export declare function composeDispatchMiddleware(middlewares: readonly DispatchMiddleware[], handler: DispatchHandler): DispatchHandler;
/** Convenience — same as composeDispatchMiddleware with reversed args. */
export declare function wrapDispatchHandler(handler: DispatchHandler, middlewares: readonly DispatchMiddleware[]): DispatchHandler;
/**
 * Build a DispatchOutcome shorthand for the common cases. Reduces
 * boilerplate at call sites without changing the contract.
 */
export declare const DispatchOutcome: {
    proceed(): DispatchOutcome;
    skipped(reason: string): DispatchOutcome;
    aborted(reason: string, payload: ReplyPayload): DispatchOutcome;
};
