import type { Runnable, RunnableConfig } from "@langchain/core/runnables";
import type { All, PendingWrite, CheckpointMetadata, BaseCheckpointSaver, BaseStore, CheckpointListOptions, BaseCache } from "@langchain/langgraph-checkpoint";
import { Graph as DrawableGraph } from "@langchain/core/runnables/graph";
import { IterableReadableStream } from "@langchain/core/utils/stream";
import type { BaseMessage } from "@langchain/core/messages";
import type { BaseChannel } from "../channels/base.js";
import type { PregelNode } from "./read.js";
import type { Interrupt } from "../constants.js";
import type { ManagedValueSpec } from "../managed/base.js";
import { CachePolicy, RetryPolicy } from "./utils/index.js";
import { LangGraphRunnableConfig } from "./runnable_types.js";
/**
 * Selects the type of output you'll receive when streaming from the graph. See [Streaming](/langgraphjs/how-tos/#streaming) for more details.
 */
export type StreamMode = "values" | "updates" | "debug" | "messages" | "custom";
export type PregelInputType = any;
export type PregelOutputType = any;
type StreamMessageOutput = [BaseMessage, Record<string, any>];
type StreamCustomOutput = any;
type StreamDebugOutput = Record<string, any>;
type DefaultStreamMode = "updates";
export type StreamOutputMap<TStreamMode extends StreamMode | StreamMode[] | undefined, TStreamSubgraphs extends boolean, StreamUpdates, StreamValues, Nodes = string> = (undefined extends TStreamMode ? [] : StreamMode | StreamMode[] extends TStreamMode ? TStreamMode extends StreamMode[] ? TStreamMode[number] : TStreamMode : TStreamMode extends StreamMode[] ? TStreamMode[number] : []) extends infer Multiple extends StreamMode ? [TStreamSubgraphs] extends [true] ? {
    values: [string[], "values", StreamValues];
    updates: [
        string[],
        "updates",
        Record<Nodes extends string ? Nodes : string, StreamUpdates>
    ];
    messages: [string[], "messages", StreamMessageOutput];
    custom: [string[], "custom", StreamCustomOutput];
    debug: [string[], "debug", StreamDebugOutput];
}[Multiple] : {
    values: ["values", StreamValues];
    updates: [
        "updates",
        Record<Nodes extends string ? Nodes : string, StreamUpdates>
    ];
    messages: ["messages", StreamMessageOutput];
    custom: ["custom", StreamCustomOutput];
    debug: ["debug", StreamDebugOutput];
}[Multiple] : (undefined extends TStreamMode ? DefaultStreamMode : TStreamMode) extends infer Single extends StreamMode ? [TStreamSubgraphs] extends [true] ? {
    values: [string[], StreamValues];
    updates: [
        string[],
        Record<Nodes extends string ? Nodes : string, StreamUpdates>
    ];
    messages: [string[], StreamMessageOutput];
    custom: [string[], StreamCustomOutput];
    debug: [string[], StreamDebugOutput];
}[Single] : {
    values: StreamValues;
    updates: Record<Nodes extends string ? Nodes : string, StreamUpdates>;
    messages: StreamMessageOutput;
    custom: StreamCustomOutput;
    debug: StreamDebugOutput;
}[Single] : never;
/**
 * Configuration options for executing a Pregel graph.
 * These options control how the graph executes, what data is streamed, and how interrupts are handled.
 *
 * @typeParam Nodes - Mapping of node names to their {@link PregelNode} implementations
 * @typeParam Channels - Mapping of channel names to their {@link BaseChannel} or {@link ManagedValueSpec} implementations
 * @typeParam ConfigurableFieldType - Type of configurable fields in the {@link RunnableConfig} that is passed to the graph
 */
export interface PregelOptions<Nodes extends StrRecord<string, PregelNode>, Channels extends StrRecord<string, BaseChannel | ManagedValueSpec>, ConfigurableFieldType extends Record<string, any> = Record<string, any>, TStreamMode extends StreamMode | StreamMode[] | undefined = StreamMode | StreamMode[] | undefined, TSubgraphs extends boolean = boolean> extends RunnableConfig<ConfigurableFieldType> {
    /**
     * Controls what information is streamed during graph execution.
     * Multiple modes can be enabled simultaneously.
     *
     * Supported modes:
     * - "values": Streams complete state after each step
     * - "updates": Streams only state changes after each step
     * - "messages": Streams messages from within nodes
     * - "custom": Streams custom events from within nodes
     * - "debug": Streams detailed execution events for tracing & debugging
     *
     * @example
     * ```typescript
     * // Stream only values
     * streamMode: "values"
     *
     * // Stream both values and debug info
     * streamMode: ["values", "debug"]
     * ```
     *
     * @default ["values"]
     */
    streamMode?: TStreamMode;
    /**
     * Specifies which channel keys to retrieve from the checkpoint when resuming execution.
     * This is an advanced option that you generally don't need to set manually.
     * The graph will automatically determine the appropriate input keys based on its configuration.
     */
    inputKeys?: keyof Channels | Array<keyof Channels>;
    /**
     * Specifies which channel keys to include in the output stream and final result.
     * Use this to filter which parts of the graph state you want to observe.
     *
     * @example
     * ```typescript
     * // Stream only the 'result' channel
     * outputKeys: "result"
     *
     * // Stream multiple channels
     * outputKeys: ["result", "intermediateState"]
     * ```
     */
    outputKeys?: keyof Channels | Array<keyof Channels>;
    /**
     * List of nodes where execution should be interrupted BEFORE the node runs.
     * Can be used for debugging and advanced state manipulation use cases. For
     * human-in-the-loop workflows, developers should prefer the
     * @link {interrupt} function instead.
     *
     * When interrupted, a resume @link {Command} must be provided to continue
     * execution.
     *
     * @example
     * ```typescript
     * // Interrupt before specific nodes
     * interruptBefore: ["humanReview", "qualityCheck"]
     *
     * // Interrupt before all nodes
     * interruptBefore: "all"
     * ```
     */
    interruptBefore?: All | Array<keyof Nodes>;
    /**
     * List of nodes where execution should be interrupted AFTER the node runs.
     * Similar to interruptBefore, but interrupts after node completion.
     * Useful when the node's output needs to be reviewed before proceeding.
     *
     * @example
     * ```typescript
     * // Interrupt after specific nodes
     * interruptAfter: ["generateContent", "analyze"]
     *
     * // Interrupt after all nodes
     * interruptAfter: "all"
     * ```
     */
    interruptAfter?: All | Array<keyof Nodes>;
    /**
     * Enables detailed debug logging during graph execution.
     * When enabled, prints information about:
     * - Task execution
     * - Channel updates
     * - Checkpoint writes
     *
     * @default false
     */
    debug?: boolean;
    /**
     * Whether to include subgraph execution details in the stream.
     * When true, state updates from nested graphs will also be streamed.
     *
     * @default false
     */
    subgraphs?: TSubgraphs;
    /**
     * A shared value store that allows you to store and retrieve state across
     * threads. Useful for implementing long-term memory patterns.
     */
    store?: BaseStore;
    /**
     * Optional cache for the graph, useful for caching tasks.
     */
    cache?: BaseCache;
}
/**
 * Construct a type with a set of properties K of type T
 */
type StrRecord<K extends string, T> = {
    [P in K]: T;
};
export interface PregelInterface<Nodes extends StrRecord<string, PregelNode>, Channels extends StrRecord<string, BaseChannel | ManagedValueSpec>, ConfigurableFieldType extends Record<string, any> = StrRecord<string, any>> {
    lg_is_pregel: boolean;
    withConfig(config: RunnableConfig): PregelInterface<Nodes, Channels>;
    getGraphAsync(config: RunnableConfig & {
        xray?: boolean | number;
    }): Promise<DrawableGraph>;
    /** @deprecated Use getSubgraphsAsync instead. The async method will become the default in the next minor release. */
    getSubgraphs(namespace?: string, recurse?: boolean): Generator<[string, PregelInterface<any, any>]>;
    getSubgraphsAsync(namespace?: string, recurse?: boolean): AsyncGenerator<[string, PregelInterface<any, any>]>;
    getState(config: RunnableConfig, options?: {
        subgraphs?: boolean;
    }): Promise<StateSnapshot>;
    getStateHistory(config: RunnableConfig, options?: CheckpointListOptions): AsyncIterableIterator<StateSnapshot>;
    updateState(inputConfig: LangGraphRunnableConfig, values: Record<string, unknown> | unknown, asNode?: keyof Nodes | string): Promise<RunnableConfig>;
    stream(input: PregelInputType, options?: Partial<PregelOptions<Nodes, Channels, ConfigurableFieldType>>): Promise<IterableReadableStream<PregelOutputType>>;
    invoke(input: PregelInputType, options?: Partial<PregelOptions<Nodes, Channels, ConfigurableFieldType>>): Promise<PregelOutputType>;
}
/**
 * Parameters for creating a Pregel graph.
 * @internal
 */
export type PregelParams<Nodes extends StrRecord<string, PregelNode>, Channels extends StrRecord<string, BaseChannel | ManagedValueSpec>> = {
    /**
     * The name of the graph. @see {@link Runnable.name}
     */
    name?: string;
    /**
     * The nodes in the graph.
     */
    nodes: Nodes;
    /**
     * The channels in the graph.
     */
    channels: Channels;
    /**
     * Whether to validate the graph.
     *
     * @default true
     */
    autoValidate?: boolean;
    /**
     * The stream mode for the graph run. See [Streaming](/langgraphjs/how-tos/#streaming) for more details.
     *
     * @default ["values"]
     */
    streamMode?: StreamMode | StreamMode[];
    /**
     * The input channels for the graph run.
     */
    inputChannels: keyof Channels | Array<keyof Channels>;
    /**
     * The output channels for the graph run.
     */
    outputChannels: keyof Channels | Array<keyof Channels>;
    /**
     * After processing one of the nodes named in this list, the graph will be interrupted and a resume {@link Command} must be provided to proceed with the execution of this thread.
     * @default []
     */
    interruptAfter?: Array<keyof Nodes> | All;
    /**
     * Before processing one of the nodes named in this list, the graph will be interrupted and a resume {@link Command} must be provided to proceed with the execution of this thread.
     * @default []
     */
    interruptBefore?: Array<keyof Nodes> | All;
    /**
     * The channels to stream from the graph run.
     * @default []
     */
    streamChannels?: keyof Channels | Array<keyof Channels>;
    /**
     * @default undefined
     */
    stepTimeout?: number;
    /**
     * @default false
     */
    debug?: boolean;
    /**
     * The {@link BaseCheckpointSaver | checkpointer} to use for the graph run.
     */
    checkpointer?: BaseCheckpointSaver | false;
    /**
     * The default retry policy for this graph. For defaults, see {@link RetryPolicy}.
     */
    retryPolicy?: RetryPolicy;
    /**
     * The configuration for the graph run.
     */
    config?: LangGraphRunnableConfig;
    /**
     * Memory store to use for SharedValues.
     */
    store?: BaseStore;
    /**
     * Memory store to use for SharedValues.
     */
    cache?: BaseCache;
};
export interface PregelTaskDescription {
    readonly id: string;
    readonly name: string;
    readonly error?: unknown;
    readonly interrupts: Interrupt[];
    readonly state?: LangGraphRunnableConfig | StateSnapshot;
    readonly path?: TaskPath;
    readonly result?: unknown;
}
interface CacheKey {
    ns: string[];
    key: string;
    ttl?: number;
}
export interface PregelExecutableTask<NodeKey extends PropertyKey, ChannelKey extends PropertyKey> {
    readonly name: NodeKey;
    readonly input: unknown;
    readonly proc: Runnable<any, any, LangGraphRunnableConfig>;
    readonly writes: PendingWrite<ChannelKey>[];
    readonly config?: LangGraphRunnableConfig;
    readonly triggers: Array<string>;
    readonly retry_policy?: RetryPolicy;
    readonly cache_key?: CacheKey;
    readonly id: string;
    readonly path?: TaskPath;
    readonly subgraphs?: Runnable[];
    readonly writers: Runnable[];
}
export interface StateSnapshot {
    /**
     * Current values of channels
     */
    readonly values: Record<string, any> | any;
    /**
     * Nodes to execute in the next step, if any
     */
    readonly next: Array<string>;
    /**
     * Config used to fetch this snapshot
     */
    readonly config: RunnableConfig;
    /**
     * Metadata about the checkpoint
     */
    readonly metadata?: CheckpointMetadata;
    /**
     * Time when the snapshot was created
     */
    readonly createdAt?: string;
    /**
     * Config used to fetch the parent snapshot, if any
     * @default undefined
     */
    readonly parentConfig?: RunnableConfig | undefined;
    /**
     * Tasks to execute in this step. If already attempted, may contain an error.
     */
    readonly tasks: PregelTaskDescription[];
}
/**
 * Options for subscribing to multiple channels.
 */
export type MultipleChannelSubscriptionOptions = {
    /**
     * Optional tags to associate with the subscription.
     */
    tags?: string[];
};
/**
 * Options for subscribing to a single channel.
 */
export type SingleChannelSubscriptionOptions = {
    /**
     * When specified, the channel mapping will be an object with this key pointing
     * to the array of channels to subscribe to. Otherwise, the channel mapping
     * will be an array of channels.
     */
    key?: string;
    /**
     * Optional tags to associate with the subscription.
     */
    tags?: string[];
};
/**
 * Options for getting the state of the graph.
 */
export type GetStateOptions = {
    /**
     * Whether to include subgraph states.
     * @default false
     */
    subgraphs?: boolean;
};
/**
 * Used for storing/retrieving internal execution state.
 *
 * @internal
 */
export type PregelScratchpad<Resume = unknown> = {
    /** Counter for tracking call invocations */
    callCounter: number;
    /** Counter for tracking interrupts */
    interruptCounter: number;
    /** List of resume values */
    resume: Resume[];
    /** Single resume value for null task ID */
    nullResume: Resume;
    consumeNullResume: () => Resume | undefined;
    /** Counter for tracking subgraph invocations */
    subgraphCounter: number;
    /** The input to the currently executing task */
    currentTaskInput: unknown;
};
/**
 * @internal
 */
export type PregelAbortSignals = {
    /** Aborts when the user calls `stream.cancel()` or aborts the {@link AbortSignal} that they passed in via the `signal` option */
    externalAbortSignal?: AbortSignal;
    /**
     * Aborts when the currently executing task throws any error other than a {@link GraphBubbleUp}
     */
    errorAbortSignal?: AbortSignal;
    /**
     * Aborts when the currently executing task throws any error other than a {@link GraphBubbleUp}
     */
    timeoutAbortSignal?: AbortSignal;
    /**
     * A reference to the AbortSignal that is passed to the node. Aborts on step timeout, stream cancel, or when an error is thrown.
     */
    composedAbortSignal?: AbortSignal;
};
export type CallOptions = {
    func: (...args: unknown[]) => unknown | Promise<unknown>;
    name: string;
    input: unknown;
    cache?: CachePolicy;
    retry?: RetryPolicy;
    callbacks?: unknown;
};
export declare class Call {
    func: (...args: unknown[]) => unknown | Promise<unknown>;
    name: string;
    input: unknown;
    retry?: RetryPolicy;
    cache?: CachePolicy;
    callbacks?: unknown;
    readonly __lg_type = "call";
    constructor({ func, name, input, retry, cache, callbacks }: CallOptions);
}
export declare function isCall(value: unknown): value is Call;
export type SimpleTaskPath = [string, string | number];
export type VariadicTaskPath = [string, ...(string | number)[]];
export type CallTaskPath = [string, ...(string | number)[], Call] | [string, TaskPath, ...(string | number)[], Call];
export type TaskPath = SimpleTaskPath | CallTaskPath | VariadicTaskPath;
export {};
