UNPKG

@langchain/langgraph

Version:

LangGraph

306 lines (304 loc) 11.6 kB
import { PendingWrite } from "@langchain/langgraph-checkpoint"; /** Special reserved node name denoting the start of a graph. */ export declare const START = "__start__"; /** Special reserved node name denoting the end of a graph. */ export declare const END = "__end__"; export declare const INPUT = "__input__"; export declare const COPY = "__copy__"; export declare const ERROR = "__error__"; /** Special reserved cache namespaces */ export declare const CACHE_NS_WRITES = "__pregel_ns_writes"; export declare const CONFIG_KEY_SEND = "__pregel_send"; /** config key containing function used to call a node (push task) */ export declare const CONFIG_KEY_CALL = "__pregel_call"; export declare const CONFIG_KEY_READ = "__pregel_read"; export declare const CONFIG_KEY_CHECKPOINTER = "__pregel_checkpointer"; export declare const CONFIG_KEY_RESUMING = "__pregel_resuming"; export declare const CONFIG_KEY_TASK_ID = "__pregel_task_id"; export declare const CONFIG_KEY_STREAM = "__pregel_stream"; export declare const CONFIG_KEY_RESUME_VALUE = "__pregel_resume_value"; export declare const CONFIG_KEY_SCRATCHPAD = "__pregel_scratchpad"; /** config key containing state from previous invocation of graph for the given thread */ export declare const CONFIG_KEY_PREVIOUS_STATE = "__pregel_previous"; export declare const CONFIG_KEY_CHECKPOINT_ID = "checkpoint_id"; export declare const CONFIG_KEY_CHECKPOINT_NS = "checkpoint_ns"; export declare const CONFIG_KEY_NODE_FINISHED = "__pregel_node_finished"; export declare const CONFIG_KEY_CHECKPOINT_MAP = "checkpoint_map"; export declare const CONFIG_KEY_ABORT_SIGNALS = "__pregel_abort_signals"; /** Special channel reserved for graph interrupts */ export declare const INTERRUPT = "__interrupt__"; /** Special channel reserved for graph resume */ export declare const RESUME = "__resume__"; /** Special channel reserved for cases when a task exits without any writes */ export declare const NO_WRITES = "__no_writes__"; /** Special channel reserved for graph return */ export declare const RETURN = "__return__"; /** Special channel reserved for graph previous state */ export declare const PREVIOUS = "__previous__"; export declare const RUNTIME_PLACEHOLDER = "__pregel_runtime_placeholder__"; export declare const RECURSION_LIMIT_DEFAULT = 25; export declare const TAG_HIDDEN = "langsmith:hidden"; export declare const TAG_NOSTREAM = "langsmith:nostream"; export declare const SELF = "__self__"; export declare const TASKS = "__pregel_tasks"; export declare const PUSH = "__pregel_push"; export declare const PULL = "__pregel_pull"; export declare const TASK_NAMESPACE = "6ba7b831-9dad-11d1-80b4-00c04fd430c8"; export declare const NULL_TASK_ID = "00000000-0000-0000-0000-000000000000"; export declare const RESERVED: string[]; export declare const CHECKPOINT_NAMESPACE_SEPARATOR = "|"; export declare const CHECKPOINT_NAMESPACE_END = ":"; export interface SendInterface<Node extends string = string, Args = any> { node: Node; args: Args; } export declare function _isSendInterface(x: unknown): x is SendInterface; /** * * 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] }); * }); * }; * * 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`] } * ``` */ export declare class Send<Node extends string = string, Args = any> implements SendInterface<Node, Args> { lg_name: string; node: Node; args: Args; constructor(node: Node, args: Args); toJSON(): { lg_name: string; node: Node; args: Args; }; } export declare function _isSend(x: unknown): x is Send; export type Interrupt<Value = any> = { value?: Value; when: "during" | (string & {}); resumable?: boolean; ns?: string[]; }; /** * 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. */ export declare function isInterrupted<Value = unknown>(values: unknown): values is { [INTERRUPT]: Interrupt<Value>[]; }; export type CommandParams<Resume = unknown, Update extends Record<string, unknown> = Record<string, unknown>, Nodes extends string = string> = { /** * A discriminator field used to identify the type of object. Must be populated when serializing. * * Optional because it's not required to specify this when directly constructing a {@link Command} * object. */ lg_name?: "Command"; /** * Value to resume execution with. To be used together with {@link interrupt}. */ resume?: Resume; /** * 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?: string; /** * Update to apply to the graph's state. */ update?: Update | [string, unknown][]; /** * 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 * - `Send` object (to execute a node with the input provided) * - sequence of `Send` objects */ goto?: Nodes | SendInterface<Nodes> | (Nodes | SendInterface<Nodes>)[]; }; /** * 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' } * ``` */ export declare class Command<Resume = unknown, Update extends Record<string, unknown> = Record<string, unknown>, Nodes extends string = string> { readonly lg_name = "Command"; lc_direct_tool_output: boolean; /** * 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?: string; /** * 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?: Update | [string, unknown][]; /** * Value to resume execution with. To be used together with {@link interrupt}. */ resume?: 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?: Nodes | Send<Nodes> | (Nodes | Send<Nodes>)[]; static PARENT: string; constructor(args: CommandParams<Resume, Update, Nodes>); /** * Convert the update field to a list of {@link PendingWrite} tuples * @returns List of {@link PendingWrite} tuples of the form `[channelKey, value]`. * @internal */ _updateAsTuples(): PendingWrite[]; toJSON(): { lg_name: string; update: Update | [string, unknown][] | undefined; resume: Resume | undefined; goto: Nodes | { lg_name: string; node: Nodes; args: any; } | (Nodes | { lg_name: string; node: Nodes; args: any; })[] | undefined; }; } /** * 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. */ export declare function isCommand(x: unknown): x is Command; /** * 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. */ export declare function _deserializeCommandSendObjectGraph(x: unknown, seen?: Map<object, unknown>): unknown;