/**
 * Workflow runtime — event-writing glue for orchestrator actions.
 *
 * `decideNextActions` in `orchestrator.ts` is pure; this module performs
 * the actual side effects: writes events to the EventLog and (for
 * subagent dispatch) invokes the worker spawn callback.
 *
 * The `WorkerSpawnFn` indirection keeps tests isolated from the real
 * worker / bot-registry / daemon plumbing — Slice D wires the live
 * spawn function; tests pass a fake.
 *
 * Scope (Slice B-1):
 *   - dispatchGate  → writes attemptCreated(gate) + waitCreated
 *   - dispatchWork  → writes attemptCreated(work) + invokes spawn
 *   - completeNode* / completeRun* → terminal node/run writes
 *     (rootCauseEventId resolved from the latest activityFailed event)
 */
import type { WorkflowDefinition } from './definition.js';
import type { EventLog } from './events/append.js';
import type { BotSnapshot, ErrorClass, OutputRef } from './events/payloads.js';
import { replay, type Snapshot } from './events/replay.js';
import type { ActivityFailedEvent, AttemptCreatedEvent, NodeFailedEvent, NodeSucceededEvent, RunFailedEvent, RunSucceededEvent, WaitCreatedEvent } from './events/types.js';
import { type CompleteNodeFailedAction, type CompleteNodeSucceededAction, type CompleteRunFailedAction, type CompleteRunSucceededAction, type DispatchGateAction, type DispatchWorkAction } from './orchestrator.js';
import type { HostExecutorRegistry } from './hostExecutors/registry.js';
import type { ProviderReconciler } from './resume.js';
export type WorkerSpawnInput = {
    botName: string;
    /** Snapshot captured at runCreated time — caller may override workingDir etc. */
    botSnapshot?: BotSnapshot;
    prompt: string;
    workingDir?: string;
    modelOverrides?: {
        model?: string;
        reasoningEffort?: string;
    };
    toolPolicy?: {
        allow?: string[];
        deny?: string[];
    };
    /** Activity context — useful for the spawner to namespace logs / ports. */
    activityId: string;
    attemptId: string;
    nodeId: string;
    runId: string;
    /** Conventional per-attempt execution log path, used by daemon-backed workers. */
    attemptLogPath?: string;
    /**
     * Cooperative cancel handle (v0.1.4-a).  Daemon-backed workers should
     * listen and initiate graceful shutdown (SIGINT) then escalate
     * (SIGKILL) per policy.  Test-stub spawns can just inspect `aborted`
     * and resolve eagerly to `kind: 'cancelled'`.
     *
     * The abort reason is `AbortCancelReason` carrying the originating
     * `cancelRequested` event id, which the spawn must echo back in
     * `WorkerSpawnResult.kind === 'cancelled'` so dispatchWork can write
     * `activityCanceled.payload.cancelOriginEventId` without re-replaying
     * the log.
     */
    cancelSignal?: AbortSignal;
};
/** Reason payload attached to `AbortController.abort()` for spawn cancel. */
export type AbortCancelReason = {
    cancelOriginEventId: string;
};
export type WorkerSessionInfo = {
    sessionId: string;
    /** CLI-native resume id when it differs from botmux's synthetic sessionId. */
    cliSessionId?: string;
    larkAppId?: string;
    botName: string;
    cliId?: string;
    workingDir?: string;
    webPort?: number;
    logPath?: string;
    startedAt: number;
    endedAt?: number;
};
export type WorkerSpawnResult = {
    kind: 'success';
    /** Caller's worker produced this as the final structured output. */
    output: unknown;
    session: WorkerSessionInfo;
} | {
    kind: 'failure';
    errorCode: 'NetworkError' | 'WorkerCrashed' | 'OutputSchemaViolation' | 'InputValidationFailed' | 'UnknownProviderError';
    errorClass: ErrorClass;
    errorMessage: string;
    session?: WorkerSessionInfo;
} | {
    /**
     * Cancel-induced terminal (v0.1.4-a).  Returned when the worker
     * observed `cancelSignal.aborted` and shut down (cleanly via SIGINT
     * or escalated via SIGKILL).  `cancelOriginEventId` must echo the
     * value from `AbortCancelReason` so dispatchWork can populate
     * `activityCanceled.payload.cancelOriginEventId` directly.
     */
    kind: 'cancelled';
    cancelOriginEventId: string;
    session?: WorkerSessionInfo;
};
export type WorkerSpawnFn = (input: WorkerSpawnInput) => Promise<WorkerSpawnResult>;
export type WorkflowRuntimeContext = {
    log: EventLog;
    def: WorkflowDefinition;
    spawnSubagent: WorkerSpawnFn;
    hostExecutors?: HostExecutorRegistry;
    /**
     * Per-provider reconcilers consulted by `runLoop`'s recovery phase when
     * a snapshot has `danglingEffectAttempted` entries (effectAttempted
     * written but no terminal).  Default factory:
     * `createDefaultProviderReconcilers()`.  When omitted, runLoop refuses
     * to advance past dangling effects (returns `no-progress`).
     */
    reconcilers?: Map<string, ProviderReconciler>;
    /**
     * Materializer for the effect-input sidecar used by `requiresEffectInput`
     * providers (Feishu).  Default in CLI/IM entry points wraps
     * `loadEffectInputSidecar(log, activityId, attemptId)`.
     */
    loadEffectInput?: (activityId: string, attemptId: string) => Promise<unknown>;
    /** Wall-clock source — injectable for deterministic tests. */
    now?: () => number;
    /**
     * v0.1.4-a cancel responsiveness: runLoop publishes its per-tick
     * activityId→AbortController map here so out-of-band callers (e.g.
     * `cancelWorkflowRunOnDaemon`) can fire abort signals immediately
     * without waiting for the EventLog polling fallback to notice the
     * `cancelRequested` event.  Pass `undefined` on tick exit to clear.
     */
    registerAborters?: (aborters: Map<string, AbortController> | undefined) => void;
};
/**
 * Open a humanGate.stage='before' wait.  Writes:
 *   1. `attemptCreated{nodeId, activityId=gate, attemptId, attemptNumber=1}`
 *      — `inputRef` carries the RAW (pre-binding) humanGate spec so an
 *      operator can still see what the workflow author wrote.
 *   2. Resolve `humanGate.prompt` against the snapshot (output bindings).
 *      Binding failure → `activityFailed{InputBindingFailed/userFault}`,
 *      no waitCreated written.  The orchestrator picks the failure up on
 *      its next tick and emits `completeNodeFailed`.
 *   3. On success: `waitCreated{prompt: <resolved>, ...}`.
 *
 * The caller (Slice C / Slice D) is responsible for actually rendering
 * the approval card to the IM channel after this returns.
 */
export type DispatchGateResult = {
    kind: 'wait';
    attemptId: string;
    attemptCreated: AttemptCreatedEvent;
    waitCreated: WaitCreatedEvent;
} | {
    kind: 'failed';
    attemptId: string;
    attemptCreated: AttemptCreatedEvent;
    activityFailed: ActivityFailedEvent;
};
export declare function dispatchGate(ctx: WorkflowRuntimeContext, action: DispatchGateAction, options?: {
    snapshot?: Snapshot;
}): Promise<DispatchGateResult>;
/**
 * Producer policy: inline prompts <= 1 KiB; bigger spills to a blob.
 * Chosen to leave headroom under the 4 KiB inline-event cap for
 * activityId / nodeId / approvers / onTimeout and any future small
 * fields.
 */
export declare const PROMPT_INLINE_MAX_BYTES = 1024;
export declare function makePromptPreview(full: string): string;
export type DispatchWorkResult = {
    kind: 'succeeded';
    attemptId: string;
    outputRef: OutputRef;
    session: WorkerSessionInfo;
} | {
    kind: 'failed';
    attemptId: string;
    errorClass: ErrorClass;
    errorCode: string;
    errorMessage: string;
    session?: WorkerSessionInfo;
} | {
    /** Cancel-induced terminal (v0.1.4-a). */
    kind: 'cancelled';
    attemptId: string;
    cancelOriginEventId: string;
    session?: WorkerSessionInfo;
};
/**
 * Run a work activity end-to-end:
 *   1. write `attemptCreated{work}`
 *   2. for `subagent`: invoke `spawnSubagent`, persist session sidecar,
 *      write `activitySucceeded` or `activityFailed`
 *   3. for `hostExecutor`: v0 placeholder — returns `unsupported` until
 *      Slice E (executor registry) lands.  Caller can decide to surface
 *      this as a manual error or skip the run.
 *
 * The function does not retry — that's resume.ts's job after a terminal
 * `activityFailed` lands.  Orchestrator will see the failed work
 * activity on its next tick and emit `completeNodeFailed`.
 */
export declare function dispatchWork(ctx: WorkflowRuntimeContext, action: DispatchWorkAction, options?: {
    attemptNumber?: number;
    snapshot?: Snapshot;
    cancelSignal?: AbortSignal;
}): Promise<DispatchWorkResult>;
export declare function completeNodeSucceeded(ctx: WorkflowRuntimeContext, action: CompleteNodeSucceededAction): Promise<NodeSucceededEvent>;
export declare function completeNodeFailed(ctx: WorkflowRuntimeContext, action: CompleteNodeFailedAction): Promise<NodeFailedEvent>;
export declare function completeRunSucceeded(ctx: WorkflowRuntimeContext, action: CompleteRunSucceededAction): Promise<RunSucceededEvent>;
export declare function completeRunFailed(ctx: WorkflowRuntimeContext, action: CompleteRunFailedAction): Promise<RunFailedEvent>;
export type { Snapshot };
export { replay };
//# sourceMappingURL=runtime.d.ts.map