{"version":3,"file":"interrupt.cjs","names":["AsyncLocalStorageProviderSingleton","GraphValueError","CONFIG_KEY_SCRATCHPAD","CONFIG_KEY_SEND","RESUME","CONFIG_KEY_CHECKPOINT_NS","XXH3","GraphInterrupt"],"sources":["../src/interrupt.ts"],"sourcesContent":["import { AsyncLocalStorageProviderSingleton } from \"@langchain/core/singletons\";\nimport { RunnableConfig } from \"@langchain/core/runnables\";\nimport {\n  type JSONSchema,\n  toJsonSchema,\n} from \"@langchain/core/utils/json_schema\";\nimport {\n  type InteropZodType,\n  interopParse,\n  isInteropZodSchema,\n} from \"@langchain/core/utils/types\";\nimport {\n  BaseCheckpointSaver,\n  type PendingWrite,\n} from \"@langchain/langgraph-checkpoint\";\nimport { GraphInterrupt, GraphValueError } from \"./errors.js\";\nimport {\n  CONFIG_KEY_CHECKPOINT_NS,\n  CONFIG_KEY_SCRATCHPAD,\n  CONFIG_KEY_SEND,\n  CONFIG_KEY_CHECKPOINTER,\n  CHECKPOINT_NAMESPACE_SEPARATOR,\n  RESUME,\n  type Interrupt,\n} from \"./constants.js\";\nimport { PregelScratchpad } from \"./pregel/types.js\";\nimport { XXH3 } from \"./hash.js\";\n\nexport interface InterruptOptions {\n  /**\n   * Schema for the value expected when the graph is resumed, surfaced to\n   * clients on `Interrupt.response_schema` (as JSON Schema) so they can render\n   * a typed input form. A Zod schema also parses the resume value, and the\n   * parsed value is what `interrupt` returns; a JSON Schema object is passed\n   * through to clients without validating the resume value.\n   */\n  responseSchema?: InteropZodType | JSONSchema;\n}\n\n/**\n * Interrupts the execution of a graph node.\n * This function can be used to pause execution of a node, and return the value of the `resume`\n * input when the graph is re-invoked using `Command`.\n * Multiple interrupts can be called within a single node, and each will be handled sequentially.\n *\n * When an interrupt is called:\n * 1. If there's a `resume` value available (from a previous `Command`), it returns that value.\n * 2. Otherwise, it throws a `GraphInterrupt` with the provided value\n * 3. The graph can be resumed by passing a `Command` with a `resume` value\n *\n * Because the `interrupt` function propagates by throwing a special `GraphInterrupt` error,\n * you should avoid using `try/catch` blocks around the `interrupt` function,\n * or if you do, ensure that the `GraphInterrupt` error is thrown again within your `catch` block.\n *\n * @param value - The value to include in the interrupt. This will be available in task.interrupts[].value\n * @param options - Optional settings. `responseSchema` describes the expected resume value and is\n *   available in task.interrupts[].response_schema as JSON Schema; a Zod schema also validates the resume value.\n * @returns The `resume` value provided when the graph is re-invoked with a Command, parsed by\n *   `responseSchema` when it is a Zod schema\n *\n * @example\n * ```typescript\n * // Define a node that uses multiple interrupts\n * const nodeWithInterrupts = () => {\n *   // First interrupt - will pause execution and include {value: 1} in task values\n *   const answer1 = interrupt({ value: 1 });\n *\n *   // Second interrupt - only called after first interrupt is resumed\n *   const answer2 = interrupt({ value: 2 });\n *\n *   // Use the resume values\n *   return { myKey: answer1 + \" \" + answer2 };\n * };\n *\n * // Resume the graph after first interrupt\n * await graph.stream(new Command({ resume: \"answer 1\" }));\n *\n * // Resume the graph after second interrupt\n * await graph.stream(new Command({ resume: \"answer 2\" }));\n * // Final result: { myKey: \"answer 1 answer 2\" }\n * ```\n *\n * @throws {Error} If called outside the context of a graph\n * @throws {GraphInterrupt} When no resume value is available\n * @throws {ZodError} When the resume value does not match a Zod `responseSchema`\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function interrupt<I = unknown, R = any>(\n  value: I,\n  options?: InterruptOptions\n): R {\n  const config: RunnableConfig | undefined =\n    AsyncLocalStorageProviderSingleton.getRunnableConfig();\n  if (!config) {\n    throw new Error(\"Called interrupt() outside the context of a graph.\");\n  }\n\n  const conf = config.configurable;\n  if (!conf) {\n    throw new Error(\"No configurable found in config\");\n  }\n\n  const checkpointer: BaseCheckpointSaver = conf[CONFIG_KEY_CHECKPOINTER];\n  if (!checkpointer) {\n    throw new GraphValueError(\"No checkpointer set\", {\n      lc_error_code: \"MISSING_CHECKPOINTER\",\n    });\n  }\n\n  const schema = options?.responseSchema;\n  const parseResume = (resume: unknown): R =>\n    (schema !== undefined && isInteropZodSchema(schema)\n      ? interopParse(schema, resume)\n      : resume) as R;\n\n  // Track interrupt index\n  const scratchpad: PregelScratchpad = conf[CONFIG_KEY_SCRATCHPAD];\n  scratchpad.interruptCounter += 1;\n  const idx = scratchpad.interruptCounter;\n\n  // Find previous resume values\n  if (scratchpad.resume.length > 0 && idx < scratchpad.resume.length) {\n    const parsed = parseResume(scratchpad.resume[idx]);\n    // Persist only through the interrupt being consumed. Values past `idx` belong\n    // to later interrupts and may be unvalidated mapped resumes; a failing one must\n    // not become durable, or its retry can never replace it.\n    conf[CONFIG_KEY_SEND]?.([\n      [RESUME, scratchpad.resume.slice(0, idx + 1)] as PendingWrite,\n    ]);\n    return parsed;\n  }\n\n  // Find current resume value\n  if (scratchpad.nullResume !== undefined) {\n    if (scratchpad.resume.length !== idx) {\n      throw new Error(\n        `Resume length mismatch: ${scratchpad.resume.length} !== ${idx}`\n      );\n    }\n    const v = scratchpad.consumeNullResume();\n    const parsed = parseResume(v);\n    scratchpad.resume.push(v);\n    conf[CONFIG_KEY_SEND]?.([[RESUME, scratchpad.resume] as PendingWrite]);\n    return parsed;\n  }\n\n  // No resume value found\n  const ns: string[] | undefined = conf[CONFIG_KEY_CHECKPOINT_NS]?.split(\n    CHECKPOINT_NAMESPACE_SEPARATOR\n  );\n\n  const id = ns ? XXH3(ns.join(CHECKPOINT_NAMESPACE_SEPARATOR)) : undefined;\n  const pending: Interrupt<I> = { id, value };\n  if (schema !== undefined) {\n    pending.response_schema = toJsonSchema(schema);\n  }\n  throw new GraphInterrupt([pending]);\n}\n\ntype FilterAny<X> =\n  (<T>() => T extends X ? 1 : 2) extends <\n    T,\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  >() => T extends any ? 1 : 2\n    ? never\n    : X;\n\nexport type InferInterruptInputType<T> = T extends typeof interrupt<\n  infer I,\n  unknown\n>\n  ? I\n  : // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    T extends { [key: string]: typeof interrupt<any, any> }\n    ? { [K in keyof T]: InferInterruptInputType<T[K]> }[keyof T]\n    : unknown;\n\nexport type InferInterruptResumeType<\n  T,\n  TInner = false,\n> = T extends typeof interrupt<never, infer R>\n  ? TInner extends true\n    ? FilterAny<R>\n    : R\n  : // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    T extends { [key: string]: typeof interrupt<any, any> }\n    ? { [K in keyof T]: InferInterruptResumeType<T[K], true> }[keyof T]\n    : unknown;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuFA,SAAgB,UACd,OACA,SACG;CACH,MAAM,SACJA,2BAAAA,mCAAmC,mBAAmB;AACxD,KAAI,CAAC,OACH,OAAM,IAAI,MAAM,qDAAqD;CAGvE,MAAM,OAAO,OAAO;AACpB,KAAI,CAAC,KACH,OAAM,IAAI,MAAM,kCAAkC;AAIpD,KAAI,CADsC,KAAA,yBAExC,OAAM,IAAIC,eAAAA,gBAAgB,uBAAuB,EAC/C,eAAe,wBAChB,CAAC;CAGJ,MAAM,SAAS,SAAS;CACxB,MAAM,eAAe,WAClB,WAAW,KAAA,MAAA,GAAA,4BAAA,oBAAgC,OAAO,IAAA,GAAA,4BAAA,cAClC,QAAQ,OAAO,GAC5B;CAGN,MAAM,aAA+B,KAAKC,kBAAAA;AAC1C,YAAW,oBAAoB;CAC/B,MAAM,MAAM,WAAW;AAGvB,KAAI,WAAW,OAAO,SAAS,KAAK,MAAM,WAAW,OAAO,QAAQ;EAClE,MAAM,SAAS,YAAY,WAAW,OAAO,KAAK;AAIlD,OAAKC,kBAAAA,mBAAmB,CACtB,CAACC,kBAAAA,QAAQ,WAAW,OAAO,MAAM,GAAG,MAAM,EAAE,CAAC,CAC9C,CAAC;AACF,SAAO;;AAIT,KAAI,WAAW,eAAe,KAAA,GAAW;AACvC,MAAI,WAAW,OAAO,WAAW,IAC/B,OAAM,IAAI,MACR,2BAA2B,WAAW,OAAO,OAAO,OAAO,MAC5D;EAEH,MAAM,IAAI,WAAW,mBAAmB;EACxC,MAAM,SAAS,YAAY,EAAE;AAC7B,aAAW,OAAO,KAAK,EAAE;AACzB,OAAKD,kBAAAA,mBAAmB,CAAC,CAACC,kBAAAA,QAAQ,WAAW,OAAO,CAAiB,CAAC;AACtE,SAAO;;CAIT,MAAM,KAA2B,KAAKC,kBAAAA,2BAA2B,MAAA,IAEhE;CAGD,MAAM,UAAwB;EAAE,IADrB,KAAKC,aAAAA,KAAK,GAAG,KAAA,IAAoC,CAAC,GAAG,KAAA;EAC5B;EAAO;AAC3C,KAAI,WAAW,KAAA,EACb,SAAQ,mBAAA,GAAA,kCAAA,cAA+B,OAAO;AAEhD,OAAM,IAAIC,eAAAA,eAAe,CAAC,QAAQ,CAAC"}