const require_timeout = require("./pregel/utils/timeout.cjs");
//#region src/constants.ts
/** Special reserved node name denoting the start of a graph. */
const START = "__start__";
/** Special reserved node name denoting the end of a graph. */
const END = "__end__";
const INPUT = "__input__";
const COPY = "__copy__";
const ERROR = "__error__";
/**
* Special reserved write key recording the name of the node whose execution
* failed, so node-level error handlers see the same failure provenance after a
* checkpoint resume. Value format in pending writes:
* `[taskId, ERROR_SOURCE_NODE, nodeName: string]`.
*/
const ERROR_SOURCE_NODE = "__error_source_node__";
/** Special reserved cache namespaces */
const CACHE_NS_WRITES = "__pregel_ns_writes";
/**
* System-wide upper bound on how many supersteps a {@link DeltaChannel} may go
* without writing a {@link DeltaSnapshot} blob. Once a channel's
* supersteps-since-snapshot counter reaches this value, a snapshot is forced
* even if the channel's own `snapshotFrequency` has not been reached — this
* prevents unbounded ancestor walks on threads where a delta channel exists
* but is no longer being updated.
*
* Overridable via the `LANGGRAPH_DELTA_MAX_SUPERSTEPS_SINCE_SNAPSHOT`
* environment variable. Read lazily so test/runtime overrides take effect.
*
* @remarks Beta.
*/
function getDeltaMaxSuperstepsSinceSnapshot() {
	const raw = typeof process !== "undefined" ? process.env?.LANGGRAPH_DELTA_MAX_SUPERSTEPS_SINCE_SNAPSHOT : void 0;
	if (raw !== void 0 && raw !== "") {
		const parsed = Number.parseInt(raw, 10);
		if (Number.isFinite(parsed) && parsed > 0) return parsed;
	}
	return 5e3;
}
const CONFIG_KEY_SEND = "__pregel_send";
/** config key containing function used to call a node (push task) */
const CONFIG_KEY_CALL = "__pregel_call";
const CONFIG_KEY_READ = "__pregel_read";
const CONFIG_KEY_CHECKPOINTER = "__pregel_checkpointer";
const CONFIG_KEY_RESUMING = "__pregel_resuming";
const CONFIG_KEY_TASK_ID = "__pregel_task_id";
const CONFIG_KEY_STREAM = "__pregel_stream";
const CONFIG_KEY_RESUME_VALUE = "__pregel_resume_value";
const CONFIG_KEY_RESUME_MAP = "__pregel_resume_map";
const CONFIG_KEY_SCRATCHPAD = "__pregel_scratchpad";
/** config key containing state from previous invocation of graph for the given thread */
const CONFIG_KEY_PREVIOUS_STATE = "__pregel_previous";
const CONFIG_KEY_DURABILITY = "__pregel_durability";
const CONFIG_KEY_CHECKPOINT_ID = "checkpoint_id";
const CONFIG_KEY_CHECKPOINT_NS = "checkpoint_ns";
const CONFIG_KEY_NODE_FINISHED = "__pregel_node_finished";
/**
* Config key holding a {@link NodeError} (failed source node + error) for the
* current node-level error handler invocation. Injected when an error handler
* task is prepared after the failing node's retry policy is exhausted.
*/
const CONFIG_KEY_NODE_ERROR = "__pregel_node_error";
const CONFIG_KEY_CHECKPOINT_MAP = "checkpoint_map";
const CONFIG_KEY_REPLAY_STATE = "__pregel_replay_state";
const CONFIG_KEY_ABORT_SIGNALS = "__pregel_abort_signals";
/** Special channel reserved for graph interrupts */
const INTERRUPT = "__interrupt__";
/** Special channel reserved for graph resume */
const RESUME = "__resume__";
/** Special channel reserved for cases when a task exits without any writes */
const NO_WRITES = "__no_writes__";
/** Special channel reserved for graph return */
const RETURN = "__return__";
/** Special channel reserved for graph previous state */
const PREVIOUS = "__previous__";
const TAG_HIDDEN = "langsmith:hidden";
const TAG_NOSTREAM = "langsmith:nostream";
const SELF = "__self__";
const TASKS = "__pregel_tasks";
const PUSH = "__pregel_push";
const PULL = "__pregel_pull";
const NULL_TASK_ID = "00000000-0000-0000-0000-000000000000";
const RESERVED = [
	TAG_HIDDEN,
	INPUT,
	INTERRUPT,
	RESUME,
	ERROR,
	ERROR_SOURCE_NODE,
	NO_WRITES,
	CONFIG_KEY_SEND,
	CONFIG_KEY_READ,
	CONFIG_KEY_CHECKPOINTER,
	CONFIG_KEY_DURABILITY,
	CONFIG_KEY_STREAM,
	CONFIG_KEY_RESUMING,
	CONFIG_KEY_TASK_ID,
	CONFIG_KEY_CALL,
	CONFIG_KEY_RESUME_VALUE,
	CONFIG_KEY_SCRATCHPAD,
	CONFIG_KEY_PREVIOUS_STATE,
	CONFIG_KEY_CHECKPOINT_MAP,
	CONFIG_KEY_CHECKPOINT_NS,
	CONFIG_KEY_CHECKPOINT_ID,
	CONFIG_KEY_REPLAY_STATE
];
/**
* Symbol used internally to identify Command instances.
* Exported to support cross-version type compatibility.
* @internal
*/
const COMMAND_SYMBOL = Symbol.for("langgraph.command");
/**
* Instance of a {@link Command} class.
*
* This is used to avoid IntelliSense suggesting public fields
* of {@link Command} class when a plain object is expected.
*
* @see {@link Command}
* @internal
*/
var CommandInstance = class {
	[COMMAND_SYMBOL];
	constructor(args) {
		this[COMMAND_SYMBOL] = args;
	}
};
function _isSendInterface(x) {
	const operation = x;
	return operation !== null && operation !== void 0 && typeof operation.node === "string" && operation.args !== void 0;
}
/**
*
* A message or packet to send to a specific node in the graph.
*
* The `Send` class is used within a `StateGraph`'s conditional edges to
* dynamically invoke a node with a custom state at the next step.
*
* Importantly, the sent state can differ from the core graph's state,
* allowing for flexible and dynamic workflow management.
*
* One such example is a "map-reduce" workflow where your graph invokes
* the same node multiple times in parallel with different states,
* before aggregating the results back into the main graph's state.
*
* @example
* ```typescript
* import { Annotation, Send, StateGraph } from "@langchain/langgraph";
*
* const ChainState = Annotation.Root({
*   subjects: Annotation<string[]>,
*   jokes: Annotation<string[]>({
*     reducer: (a, b) => a.concat(b),
*   }),
* });
*
* const continueToJokes = async (state: typeof ChainState.State) => {
*   return state.subjects.map((subject) => {
*     return new Send("generate_joke", { subjects: [subject] });
*   });
* };
*
* @remarks
* A per-task timeout can be supplied via the third argument's `timeout` option
* to override the target node's configured timeout for this specific pushed task:
*
* ```typescript
* new Send("generate_joke", { subjects: [subject] }, { timeout: { idleTimeout: 5000 } });
* ```
*
* const graph = new StateGraph(ChainState)
*   .addNode("generate_joke", (state) => ({
*     jokes: [`Joke about ${state.subjects}`],
*   }))
*   .addConditionalEdges("__start__", continueToJokes)
*   .addEdge("generate_joke", "__end__")
*   .compile();
*
* const res = await graph.invoke({ subjects: ["cats", "dogs"] });
* console.log(res);
*
* // Invoking with two subjects results in a generated joke for each
* // { subjects: ["cats", "dogs"], jokes: [`Joke about cats`, `Joke about dogs`] }
* ```
*/
var Send = class {
	lg_name = "Send";
	node;
	args;
	/**
	* Optional per-task timeout policy that overrides the target node's timeout
	* for this specific pushed task. A bare number is treated as a hard
	* `runTimeout` (in milliseconds).
	*/
	timeout;
	constructor(node, args, options) {
		this.node = node;
		this.args = _deserializeCommandSendObjectGraph(args);
		this.timeout = require_timeout.coerceTimeoutPolicy(options?.timeout);
	}
	toJSON() {
		return {
			lg_name: this.lg_name,
			node: this.node,
			args: this.args,
			timeout: this.timeout
		};
	}
};
function _isSend(x) {
	return x instanceof Send;
}
const OVERWRITE = "__overwrite__";
/**
* Bypass a reducer and write the wrapped value directly to a
* {@link BinaryOperatorAggregate} channel.
*
* Receiving multiple `Overwrite` values for the same channel in a single
* super-step will raise an {@link InvalidUpdateError}.
*
* @example
* ```typescript
* import { Annotation, StateGraph, Overwrite } from "@langchain/langgraph";
*
* const State = Annotation.Root({
*   messages: Annotation<string[]>({
*     reducer: (a, b) => a.concat(b),
*     default: () => [],
*   }),
* });
*
* const replaceMessages = (_state: typeof State.State) => {
*   return { messages: new Overwrite(["replacement"]) };
* };
* ```
*/
var Overwrite = class {
	lg_name = "Overwrite";
	[OVERWRITE];
	constructor(value) {
		this[OVERWRITE] = value;
	}
	get value() {
		return this[OVERWRITE];
	}
	toJSON() {
		return { [OVERWRITE]: this[OVERWRITE] };
	}
	static isInstance(value) {
		if (!value || typeof value !== "object") return false;
		if ("__overwrite__" in value) return true;
		if ("lg_name" in value && value.lg_name === "Overwrite") return true;
		return false;
	}
};
/**
* Helper function to detect and extract the value from an Overwrite wrapper,
* supporting both the Overwrite class instance and the serialized object format.
*
* Use to check if a provided value represents an Overwrite: returns the
* unwrapped value if so, or undefined otherwise.
*
* - If the value is an Overwrite instance (preferred API), return its `.value`.
* - If the value is a wire-format object ({ [OVERWRITE]: value }), extract it.
* - If the value is the discriminator form ({ type: OVERWRITE, value }) that
*   results from JSON-serializing a typed `Overwrite` in another runtime (e.g.
*   a Python dataclass routed through the LangGraph API server, where the typed
*   instance is erased), extract it. Keeps Overwrite semantics intact across
*   cross-runtime JSON boundaries.
* - Otherwise, returns undefined.
*
* @template ValueType - The expected type of the Overwrite value.
* @param value - The value to check (may be anything).
* @returns The unwrapped value if value is an Overwrite, or undefined otherwise.
* @internal
*/
function _getOverwriteValue(value) {
	if (typeof value === "object" && value !== null) {
		if ("__overwrite__" in value) return [true, value[OVERWRITE]];
		const rec = value;
		if (rec.type === "__overwrite__" && "value" in rec) return [true, rec.value];
	}
	return [false, void 0];
}
/**
* Type guard to check if a value is an Overwrite value -- either the class
* instance or the wire format object.
*
* @template ValueType - The expected type of the Overwrite value.
* @param value - The value to check (may be anything).
* @returns `true` if the value is an Overwrite value, `false` otherwise.
* @internal
*/
function _isOverwriteValue(value) {
	return _getOverwriteValue(value)[0];
}
/**
* Checks if the given graph invoke / stream chunk contains interrupt.
*
* @example
* ```ts
* import { INTERRUPT, isInterrupted } from "@langchain/langgraph";
*
* const values = await graph.invoke({ foo: "bar" });
* if (isInterrupted<string>(values)) {
*   const interrupt = values[INTERRUPT][0].value;
* }
* ```
*
* @param values - The values to check.
* @returns `true` if the values contain an interrupt, `false` otherwise.
*/
function isInterrupted(values) {
	if (!values || typeof values !== "object") return false;
	if (!("__interrupt__" in values)) return false;
	return Array.isArray(values[INTERRUPT]);
}
/**
* One or more commands to update the graph's state and send messages to nodes.
* Can be used to combine routing logic with state updates in lieu of conditional edges
*
* @example
* ```ts
* import { Annotation, Command } from "@langchain/langgraph";
*
* // Define graph state
* const StateAnnotation = Annotation.Root({
*   foo: Annotation<string>,
* });
*
* // Define the nodes
* const nodeA = async (_state: typeof StateAnnotation.State) => {
*   console.log("Called A");
*   // this is a replacement for a real conditional edge function
*   const goto = Math.random() > .5 ? "nodeB" : "nodeC";
*   // note how Command allows you to BOTH update the graph state AND route to the next node
*   return new Command({
*     // this is the state update
*     update: {
*       foo: "a",
*     },
*     // this is a replacement for an edge
*     goto,
*   });
* };
*
* // Nodes B and C are unchanged
* const nodeB = async (state: typeof StateAnnotation.State) => {
*   console.log("Called B");
*   return {
*     foo: state.foo + "|b",
*   };
* }
*
* const nodeC = async (state: typeof StateAnnotation.State) => {
*   console.log("Called C");
*   return {
*     foo: state.foo + "|c",
*   };
* }
* 
* import { StateGraph } from "@langchain/langgraph";

* // NOTE: there are no edges between nodes A, B and C!
* const graph = new StateGraph(StateAnnotation)
*   .addNode("nodeA", nodeA, {
*     ends: ["nodeB", "nodeC"],
*   })
*   .addNode("nodeB", nodeB)
*   .addNode("nodeC", nodeC)
*   .addEdge("__start__", "nodeA")
*   .compile();
* 
* await graph.invoke({ foo: "" });
*
* // Randomly oscillates between
* // { foo: 'a|c' } and { foo: 'a|b' }
* ```
*/
var Command = class extends CommandInstance {
	lg_name = "Command";
	lc_direct_tool_output = true;
	/**
	* Graph to send the command to. Supported values are:
	*   - None: the current graph (default)
	*   - The specific name of the graph to send the command to
	*   - {@link Command.PARENT}: closest parent graph (only supported when returned from a node in a subgraph)
	*/
	graph;
	/**
	* Update to apply to the graph's state as a result of executing the node that is returning the command.
	* Written to the state as if the node had simply returned this value instead of the Command object.
	*/
	update;
	/**
	* Value to resume execution with. To be used together with {@link interrupt}.
	*/
	resume;
	/**
	* Can be one of the following:
	*   - name of the node to navigate to next (any node that belongs to the specified `graph`)
	*   - sequence of node names to navigate to next
	*   - {@link Send} object (to execute a node with the exact input provided in the {@link Send} object)
	*   - sequence of {@link Send} objects
	*/
	goto = [];
	static PARENT = "__parent__";
	constructor(args) {
		super(args);
		this.resume = args.resume;
		this.graph = args.graph;
		this.update = args.update;
		if (args.goto) this.goto = Array.isArray(args.goto) ? _deserializeCommandSendObjectGraph(args.goto) : [_deserializeCommandSendObjectGraph(args.goto)];
	}
	/**
	* Convert the update field to a list of {@link PendingWrite} tuples
	* @returns List of {@link PendingWrite} tuples of the form `[channelKey, value]`.
	* @internal
	*/
	_updateAsTuples() {
		if (this.update && typeof this.update === "object" && !Array.isArray(this.update)) return Object.entries(this.update);
		else if (Array.isArray(this.update) && this.update.every((t) => Array.isArray(t) && t.length === 2 && typeof t[0] === "string")) return this.update;
		else return [["__root__", this.update]];
	}
	toJSON() {
		let serializedGoto;
		if (typeof this.goto === "string") serializedGoto = this.goto;
		else if (_isSend(this.goto)) serializedGoto = this.goto.toJSON();
		else serializedGoto = this.goto?.map((innerGoto) => {
			if (typeof innerGoto === "string") return innerGoto;
			else return innerGoto.toJSON();
		});
		return {
			lg_name: this.lg_name,
			update: this.update,
			resume: this.resume,
			goto: serializedGoto
		};
	}
};
/**
* A type guard to check if the given value is a {@link Command}.
*
* Useful for type narrowing when working with the {@link Command} object.
*
* @param x - The value to check.
* @returns `true` if the value is a {@link Command}, `false` otherwise.
*/
function isCommand(x) {
	if (typeof x !== "object") return false;
	if (x === null || x === void 0) return false;
	if ("lg_name" in x && x.lg_name === "Command") return true;
	return false;
}
function isPlainObject(value) {
	const prototype = Object.getPrototypeOf(value);
	return prototype === Object.prototype || prototype === null;
}
/**
* Reconstructs Command and Send objects from a deeply nested tree of anonymous objects
* matching their interfaces.
*
* This is only exported for testing purposes. It is NOT intended to be used outside of
* the Command and Send classes.
*
* @internal
*
* @param x - The command send tree to convert.
* @param seen - A map of seen objects to avoid infinite loops.
* @returns The converted command send tree.
*/
function _deserializeCommandSendObjectGraph(x, seen = /* @__PURE__ */ new Map()) {
	if (x !== void 0 && x !== null && typeof x === "object") {
		if (seen.has(x)) return seen.get(x);
		let result;
		if (Array.isArray(x)) {
			result = [];
			seen.set(x, result);
			x.forEach((item, index) => {
				result[index] = _deserializeCommandSendObjectGraph(item, seen);
			});
		} else if (x instanceof Command || x instanceof Send || !isPlainObject(x)) {
			result = x;
			seen.set(x, result);
		} else if (isCommand(x)) {
			result = new Command(x);
			seen.set(x, result);
		} else if (_isSendInterface(x)) {
			result = new Send(x.node, x.args, x.timeout !== void 0 ? { timeout: x.timeout } : void 0);
			seen.set(x, result);
		} else if ("lc_serializable" in x && x.lc_serializable) {
			result = x;
			seen.set(x, result);
		} else {
			result = {};
			seen.set(x, result);
			for (const [key, value] of Object.entries(x)) result[key] = _deserializeCommandSendObjectGraph(value, seen);
		}
		return result;
	}
	return x;
}
//#endregion
exports.CACHE_NS_WRITES = CACHE_NS_WRITES;
exports.COMMAND_SYMBOL = COMMAND_SYMBOL;
exports.CONFIG_KEY_ABORT_SIGNALS = CONFIG_KEY_ABORT_SIGNALS;
exports.CONFIG_KEY_CALL = CONFIG_KEY_CALL;
exports.CONFIG_KEY_CHECKPOINTER = CONFIG_KEY_CHECKPOINTER;
exports.CONFIG_KEY_CHECKPOINT_ID = CONFIG_KEY_CHECKPOINT_ID;
exports.CONFIG_KEY_CHECKPOINT_MAP = CONFIG_KEY_CHECKPOINT_MAP;
exports.CONFIG_KEY_CHECKPOINT_NS = CONFIG_KEY_CHECKPOINT_NS;
exports.CONFIG_KEY_DURABILITY = CONFIG_KEY_DURABILITY;
exports.CONFIG_KEY_NODE_ERROR = CONFIG_KEY_NODE_ERROR;
exports.CONFIG_KEY_NODE_FINISHED = CONFIG_KEY_NODE_FINISHED;
exports.CONFIG_KEY_PREVIOUS_STATE = CONFIG_KEY_PREVIOUS_STATE;
exports.CONFIG_KEY_READ = CONFIG_KEY_READ;
exports.CONFIG_KEY_REPLAY_STATE = CONFIG_KEY_REPLAY_STATE;
exports.CONFIG_KEY_RESUME_MAP = CONFIG_KEY_RESUME_MAP;
exports.CONFIG_KEY_RESUMING = CONFIG_KEY_RESUMING;
exports.CONFIG_KEY_SCRATCHPAD = CONFIG_KEY_SCRATCHPAD;
exports.CONFIG_KEY_SEND = CONFIG_KEY_SEND;
exports.CONFIG_KEY_STREAM = CONFIG_KEY_STREAM;
exports.CONFIG_KEY_TASK_ID = CONFIG_KEY_TASK_ID;
exports.COPY = COPY;
exports.Command = Command;
exports.CommandInstance = CommandInstance;
exports.END = END;
exports.ERROR = ERROR;
exports.ERROR_SOURCE_NODE = ERROR_SOURCE_NODE;
exports.INPUT = INPUT;
exports.INTERRUPT = INTERRUPT;
exports.NO_WRITES = NO_WRITES;
exports.NULL_TASK_ID = NULL_TASK_ID;
exports.OVERWRITE = OVERWRITE;
exports.Overwrite = Overwrite;
exports.PREVIOUS = PREVIOUS;
exports.PULL = PULL;
exports.PUSH = PUSH;
exports.RESERVED = RESERVED;
exports.RESUME = RESUME;
exports.RETURN = RETURN;
exports.SELF = SELF;
exports.START = START;
exports.Send = Send;
exports.TAG_HIDDEN = TAG_HIDDEN;
exports.TAG_NOSTREAM = TAG_NOSTREAM;
exports.TASKS = TASKS;
exports._getOverwriteValue = _getOverwriteValue;
exports._isOverwriteValue = _isOverwriteValue;
exports._isSend = _isSend;
exports._isSendInterface = _isSendInterface;
exports.getDeltaMaxSuperstepsSinceSnapshot = getDeltaMaxSuperstepsSinceSnapshot;
exports.isCommand = isCommand;
exports.isInterrupted = isInterrupted;

//# sourceMappingURL=constants.cjs.map