@langchain/langgraph 1.4.15 → 1.4.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/dist/callbacks.cjs +29 -0
  2. package/dist/callbacks.cjs.map +1 -0
  3. package/dist/callbacks.d.cts +46 -0
  4. package/dist/callbacks.d.cts.map +1 -0
  5. package/dist/callbacks.d.ts +46 -0
  6. package/dist/callbacks.d.ts.map +1 -0
  7. package/dist/callbacks.js +29 -0
  8. package/dist/callbacks.js.map +1 -0
  9. package/dist/constants.cjs.map +1 -1
  10. package/dist/constants.d.cts +6 -0
  11. package/dist/constants.d.cts.map +1 -1
  12. package/dist/constants.d.ts +6 -0
  13. package/dist/constants.d.ts.map +1 -1
  14. package/dist/constants.js.map +1 -1
  15. package/dist/index.cjs +2 -0
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.d.cts +3 -2
  18. package/dist/index.d.ts +3 -2
  19. package/dist/index.js +2 -1
  20. package/dist/index.js.map +1 -1
  21. package/dist/interrupt.cjs +19 -7
  22. package/dist/interrupt.cjs.map +1 -1
  23. package/dist/interrupt.d.cts +20 -3
  24. package/dist/interrupt.d.cts.map +1 -1
  25. package/dist/interrupt.d.ts +20 -3
  26. package/dist/interrupt.d.ts.map +1 -1
  27. package/dist/interrupt.js +19 -7
  28. package/dist/interrupt.js.map +1 -1
  29. package/dist/pregel/callbacks.cjs +25 -0
  30. package/dist/pregel/callbacks.cjs.map +1 -0
  31. package/dist/pregel/callbacks.js +25 -0
  32. package/dist/pregel/callbacks.js.map +1 -0
  33. package/dist/pregel/index.cjs +8 -2
  34. package/dist/pregel/index.cjs.map +1 -1
  35. package/dist/pregel/index.d.cts.map +1 -1
  36. package/dist/pregel/index.d.ts.map +1 -1
  37. package/dist/pregel/index.js +8 -2
  38. package/dist/pregel/index.js.map +1 -1
  39. package/dist/pregel/loop.cjs +18 -1
  40. package/dist/pregel/loop.cjs.map +1 -1
  41. package/dist/pregel/loop.js +18 -1
  42. package/dist/pregel/loop.js.map +1 -1
  43. package/dist/pregel/messages-v2.cjs +1 -1
  44. package/dist/pregel/messages-v2.js +1 -1
  45. package/dist/pregel/messages.cjs +1 -1
  46. package/dist/pregel/messages.js +1 -1
  47. package/dist/pregel/runner.cjs +1 -1
  48. package/dist/pregel/runner.cjs.map +1 -1
  49. package/dist/pregel/runner.js +2 -2
  50. package/dist/pregel/runner.js.map +1 -1
  51. package/dist/pregel/stream.cjs +1 -1
  52. package/dist/pregel/stream.d.cts +1 -0
  53. package/dist/pregel/stream.d.cts.map +1 -1
  54. package/dist/pregel/stream.d.ts +1 -1
  55. package/dist/pregel/stream.js +1 -1
  56. package/dist/web.cjs +2 -0
  57. package/dist/web.d.cts +3 -2
  58. package/dist/web.d.ts +3 -2
  59. package/dist/web.js +2 -1
  60. package/package.json +2 -2
package/dist/index.d.ts CHANGED
@@ -35,7 +35,7 @@ import { DeltaValue, DeltaValueInit } from "./state/values/delta.js";
35
35
  import { AnyStateSchema, InferStateSchemaUpdate, InferStateSchemaValue, StateSchema, StateSchemaField, StateSchemaFieldToChannel, StateSchemaFields, StateSchemaFieldsToStateDefinition } from "./state/schema.js";
36
36
  import { ConditionalEdgeRouter, ConditionalEdgeRouterTypes, ContextSchemaInit, ExtractStateType, ExtractUpdateType, GraphNode, GraphNodeReturnValue, GraphNodeTypes, StateDefinitionInit, StateGraphInit, StateGraphOptions, ToStateDefinition } from "./graph/types.js";
37
37
  import { AddNodeOptions, CompiledGraph, CompiledGraphType, Graph, NodeSpec } from "./graph/graph.js";
38
- import { InferInterruptInputType, InferInterruptResumeType, interrupt } from "./interrupt.js";
38
+ import { InferInterruptInputType, InferInterruptResumeType, InterruptOptions, interrupt } from "./interrupt.js";
39
39
  import { InferWriterType, writer } from "./writer.js";
40
40
  import { CompiledStateGraph, NodePolicyOptions, StateGraph, StateGraphAddNodeOptions, StateGraphArgs, StateGraphArgsWithInputOutputSchemas, StateGraphArgsWithStateSchema, StateGraphNodeSpec } from "./graph/state.js";
41
41
  import { Messages, REMOVE_ALL_MESSAGES, messagesDeltaReducer, messagesStateReducer } from "./graph/messages_reducer.js";
@@ -45,5 +45,6 @@ import { MessagesAnnotation, MessagesZodMeta, MessagesZodState } from "./graph/m
45
45
  import { getJsonSchemaFromSchema, getSchemaDefaultGetter } from "./state/adapter.js";
46
46
  import { MessagesDeltaValue, MessagesValue } from "./state/prebuilt/messages.js";
47
47
  import { getConfig, getCurrentTaskInput, getStore, getWriter } from "./pregel/utils/config.js";
48
+ import { GraphCallbackHandler, GraphInterruptEvent, GraphLifecycleEvent, GraphLifecycleStatus, GraphResumeEvent } from "./callbacks.js";
48
49
  import { AsyncBatchedStore, BaseCheckpointSaver, BaseStore, Checkpoint, CheckpointMetadata, CheckpointTuple, GetOperation, InMemoryStore, Item, ListNamespacesOperation, MatchCondition, MemorySaver, NameSpacePath, NamespaceMatchType, Operation, OperationResults, PutOperation, SearchOperation, copyCheckpoint, emptyCheckpoint } from "./web.js";
49
- export { AddNodeOptions, AgentStatus, Annotation, AnnotationRoot, AnyStateSchema, AnyValue, AsyncBatchedStore, BaseChannel, BaseCheckpointSaver, BaseLangGraphError, BaseLangGraphErrorFields, BaseStore, BinaryOperator, BinaryOperatorAggregate, COMMAND_SYMBOL, CachePolicy, ChatModelStream, ChatModelStreamImpl, Checkpoint, CheckpointMetadata, CheckpointTuple, Command, CommandInstance, CommandParams, CompiledGraph, CompiledGraphType, CompiledStateGraph, ConditionalEdgeRouter, ConditionalEdgeRouterTypes, ContextSchemaInit, ConvertToProtocolEventOptions, CreateGraphRunStreamOptions, DeltaChannel, DeltaReducer, DeltaValue, DeltaValueInit, DynamicBarrierValue, END, EmptyChannelError, EmptyInputError, EntrypointOptions, EphemeralValue, StreamChannel as EventLog, ExecutionInfo, ExtractStateType, ExtractUpdateType, GetOperation, GetStateOptions, Graph, GraphBubbleUp, GraphDrained, GraphInterrupt, GraphNode, GraphNodeReturnValue, GraphNodeTypes, GraphRecursionError, GraphRunStream, GraphValueError, INTERRUPT, InMemoryStore, InferExtensions, InferInterruptInputType, InferInterruptResumeType, InferStateSchemaUpdate, InferStateSchemaValue, InferWriterType, Interrupt, InterruptPayload, InvalidUpdateError, Item, LangGraphRunnableConfig, LastValue, LifecycleCause, LifecycleData, LifecycleEntry, LifecycleProjection, LifecycleTransformerOptions, ListNamespacesOperation, MatchCondition, MemorySaver, MessageGraph, Messages, MessagesAnnotation, MessagesDeltaValue, MessagesEventData, MessagesValue, MessagesZodMeta, MessagesZodState, MultipleChannelSubscriptionOptions, MultipleSubgraphsError, NameSpacePath, NamedBarrierValue, Namespace, NamespaceMatchType, NativeStreamTransformer, NodeError, NodeInterrupt, NodePolicyOptions, NodeSpec, NodeTimeoutError, NodeType, Operation, OperationResults, Overwrite, OverwriteValue, ParentCommand, Pregel, PregelNode, PregelOptions, PregelParams, ProtocolEvent, PutOperation, REMOVE_ALL_MESSAGES, ReducedValue, ReducedValueInit, RemoteException, RetryPolicy, RunControl, Runtime, START, STREAM_EVENTS_V3_MODES, SearchOperation, Send, SendOptions, ServerInfo, SingleChannelSubscriptionOptions, SingleReducer, StateDefinition, StateDefinitionInit, StateGraph, StateGraphAddNodeOptions, StateGraphArgs, StateGraphArgsWithInputOutputSchemas, StateGraphArgsWithStateSchema, StateGraphInit, StateGraphInputError, StateGraphNodeSpec, StateGraphOptions, StateSchema, StateSchemaField, StateSchemaFieldToChannel, StateSchemaFields, StateSchemaFieldsToStateDefinition, StateSnapshot, StateType, StreamChannel, StreamEmitter, StreamMode, StreamOutputMap, StreamTransformer, SubgraphDiscoveryProjection, SubgraphDiscoveryTransformerOptions, SubgraphRunStream, TaskOptions, TimeoutPolicy, ToStateDefinition, ToolCallStatus, ToolCallStream, ToolsEventData, Topic, UnreachableNodeError, UntrackedValue, UntrackedValueChannel, UntrackedValueInit, UpdateType, UpdatesEventData, UsageInfo, WaitForNames, messagesStateReducer as addMessages, convertToProtocolEvent, copyCheckpoint, createGraphRunStream, createLifecycleTransformer, createMessagesTransformer, createSubgraphDiscoveryTransformer, createValuesTransformer, emptyCheckpoint, entrypoint, filterLifecycleEntries, filterSubgraphHandles, getConfig, getCurrentTaskInput, getJsonSchemaFromSchema, getPreviousState, getSchemaDefaultGetter, getStore, getSubgraphsSeenSet, getWriter, interrupt, isCheckpointEnvelope, isCommand, isGraphBubbleUp, isGraphDrained, isGraphInterrupt, isInterrupted, isNativeTransformer, isNodeError, isNodeTimeoutError, isParentCommand, isSerializableSchema, isStandardSchema, messagesDeltaReducer, messagesStateReducer, pushMessage, task, writer };
50
+ export { AddNodeOptions, AgentStatus, Annotation, AnnotationRoot, AnyStateSchema, AnyValue, AsyncBatchedStore, BaseChannel, BaseCheckpointSaver, BaseLangGraphError, BaseLangGraphErrorFields, BaseStore, BinaryOperator, BinaryOperatorAggregate, COMMAND_SYMBOL, CachePolicy, ChatModelStream, ChatModelStreamImpl, Checkpoint, CheckpointMetadata, CheckpointTuple, Command, CommandInstance, CommandParams, CompiledGraph, CompiledGraphType, CompiledStateGraph, ConditionalEdgeRouter, ConditionalEdgeRouterTypes, ContextSchemaInit, ConvertToProtocolEventOptions, CreateGraphRunStreamOptions, DeltaChannel, DeltaReducer, DeltaValue, DeltaValueInit, DynamicBarrierValue, END, EmptyChannelError, EmptyInputError, EntrypointOptions, EphemeralValue, StreamChannel as EventLog, ExecutionInfo, ExtractStateType, ExtractUpdateType, GetOperation, GetStateOptions, Graph, GraphBubbleUp, GraphCallbackHandler, GraphDrained, GraphInterrupt, GraphInterruptEvent, GraphLifecycleEvent, GraphLifecycleStatus, GraphNode, GraphNodeReturnValue, GraphNodeTypes, GraphRecursionError, GraphResumeEvent, GraphRunStream, GraphValueError, INTERRUPT, InMemoryStore, InferExtensions, InferInterruptInputType, InferInterruptResumeType, InferStateSchemaUpdate, InferStateSchemaValue, InferWriterType, Interrupt, InterruptOptions, InterruptPayload, InvalidUpdateError, Item, LangGraphRunnableConfig, LastValue, LifecycleCause, LifecycleData, LifecycleEntry, LifecycleProjection, LifecycleTransformerOptions, ListNamespacesOperation, MatchCondition, MemorySaver, MessageGraph, Messages, MessagesAnnotation, MessagesDeltaValue, MessagesEventData, MessagesValue, MessagesZodMeta, MessagesZodState, MultipleChannelSubscriptionOptions, MultipleSubgraphsError, NameSpacePath, NamedBarrierValue, Namespace, NamespaceMatchType, NativeStreamTransformer, NodeError, NodeInterrupt, NodePolicyOptions, NodeSpec, NodeTimeoutError, NodeType, Operation, OperationResults, Overwrite, OverwriteValue, ParentCommand, Pregel, PregelNode, PregelOptions, PregelParams, ProtocolEvent, PutOperation, REMOVE_ALL_MESSAGES, ReducedValue, ReducedValueInit, RemoteException, RetryPolicy, RunControl, Runtime, START, STREAM_EVENTS_V3_MODES, SearchOperation, Send, SendOptions, ServerInfo, SingleChannelSubscriptionOptions, SingleReducer, StateDefinition, StateDefinitionInit, StateGraph, StateGraphAddNodeOptions, StateGraphArgs, StateGraphArgsWithInputOutputSchemas, StateGraphArgsWithStateSchema, StateGraphInit, StateGraphInputError, StateGraphNodeSpec, StateGraphOptions, StateSchema, StateSchemaField, StateSchemaFieldToChannel, StateSchemaFields, StateSchemaFieldsToStateDefinition, StateSnapshot, StateType, StreamChannel, StreamEmitter, StreamMode, StreamOutputMap, StreamTransformer, SubgraphDiscoveryProjection, SubgraphDiscoveryTransformerOptions, SubgraphRunStream, TaskOptions, TimeoutPolicy, ToStateDefinition, ToolCallStatus, ToolCallStream, ToolsEventData, Topic, UnreachableNodeError, UntrackedValue, UntrackedValueChannel, UntrackedValueInit, UpdateType, UpdatesEventData, UsageInfo, WaitForNames, messagesStateReducer as addMessages, convertToProtocolEvent, copyCheckpoint, createGraphRunStream, createLifecycleTransformer, createMessagesTransformer, createSubgraphDiscoveryTransformer, createValuesTransformer, emptyCheckpoint, entrypoint, filterLifecycleEntries, filterSubgraphHandles, getConfig, getCurrentTaskInput, getJsonSchemaFromSchema, getPreviousState, getSchemaDefaultGetter, getStore, getSubgraphsSeenSet, getWriter, interrupt, isCheckpointEnvelope, isCommand, isGraphBubbleUp, isGraphDrained, isGraphInterrupt, isInterrupted, isNativeTransformer, isNodeError, isNodeTimeoutError, isParentCommand, isSerializableSchema, isStandardSchema, messagesDeltaReducer, messagesStateReducer, pushMessage, task, writer };
package/dist/index.js CHANGED
@@ -5,6 +5,7 @@ import { BaseChannel } from "./channels/base.js";
5
5
  import { BinaryOperatorAggregate } from "./channels/binop.js";
6
6
  import { Annotation } from "./graph/annotation.js";
7
7
  import { getConfig, getCurrentTaskInput, getStore, getWriter } from "./pregel/utils/config.js";
8
+ import { GraphCallbackHandler } from "./callbacks.js";
8
9
  import { RunControl } from "./pregel/runtime.js";
9
10
  import { STREAM_EVENTS_V3_MODES, convertToProtocolEvent, isCheckpointEnvelope } from "./stream/convert.js";
10
11
  import { StreamChannel } from "./stream/stream-channel.js";
@@ -36,6 +37,6 @@ import { AsyncBatchedStore, BaseCheckpointSaver, BaseStore, InMemoryStore, Memor
36
37
  //#region src/index.ts
37
38
  initializeAsyncLocalStorageSingleton();
38
39
  //#endregion
39
- export { Annotation, AsyncBatchedStore, BaseChannel, BaseCheckpointSaver, BaseLangGraphError, BaseStore, BinaryOperatorAggregate, COMMAND_SYMBOL, ChatModelStreamImpl, Command, CommandInstance, CompiledStateGraph, DeltaChannel, DeltaValue, END, EmptyChannelError, EmptyInputError, StreamChannel as EventLog, Graph, GraphBubbleUp, GraphDrained, GraphInterrupt, GraphRecursionError, GraphRunStream, GraphValueError, INTERRUPT, InMemoryStore, InvalidUpdateError, MemorySaver, MessageGraph, MessagesAnnotation, MessagesDeltaValue, MessagesValue, MessagesZodMeta, MessagesZodState, MultipleSubgraphsError, NodeError, NodeInterrupt, NodeTimeoutError, Overwrite, ParentCommand, REMOVE_ALL_MESSAGES, ReducedValue, RemoteException, RunControl, START, STREAM_EVENTS_V3_MODES, Send, StateGraph, StateGraphInputError, StateSchema, StreamChannel, SubgraphRunStream, UnreachableNodeError, UntrackedValue, UntrackedValueChannel, messagesStateReducer as addMessages, convertToProtocolEvent, copyCheckpoint, createGraphRunStream, createLifecycleTransformer, createMessagesTransformer, createSubgraphDiscoveryTransformer, createValuesTransformer, emptyCheckpoint, entrypoint, filterLifecycleEntries, filterSubgraphHandles, getConfig, getCurrentTaskInput, getJsonSchemaFromSchema, getPreviousState, getSchemaDefaultGetter, getStore, getSubgraphsSeenSet, getWriter, interrupt, isCheckpointEnvelope, isCommand, isGraphBubbleUp, isGraphDrained, isGraphInterrupt, isInterrupted, isNativeTransformer, isNodeError, isNodeTimeoutError, isParentCommand, isSerializableSchema, isStandardSchema, messagesDeltaReducer, messagesStateReducer, pushMessage, task, writer };
40
+ export { Annotation, AsyncBatchedStore, BaseChannel, BaseCheckpointSaver, BaseLangGraphError, BaseStore, BinaryOperatorAggregate, COMMAND_SYMBOL, ChatModelStreamImpl, Command, CommandInstance, CompiledStateGraph, DeltaChannel, DeltaValue, END, EmptyChannelError, EmptyInputError, StreamChannel as EventLog, Graph, GraphBubbleUp, GraphCallbackHandler, GraphDrained, GraphInterrupt, GraphRecursionError, GraphRunStream, GraphValueError, INTERRUPT, InMemoryStore, InvalidUpdateError, MemorySaver, MessageGraph, MessagesAnnotation, MessagesDeltaValue, MessagesValue, MessagesZodMeta, MessagesZodState, MultipleSubgraphsError, NodeError, NodeInterrupt, NodeTimeoutError, Overwrite, ParentCommand, REMOVE_ALL_MESSAGES, ReducedValue, RemoteException, RunControl, START, STREAM_EVENTS_V3_MODES, Send, StateGraph, StateGraphInputError, StateSchema, StreamChannel, SubgraphRunStream, UnreachableNodeError, UntrackedValue, UntrackedValueChannel, messagesStateReducer as addMessages, convertToProtocolEvent, copyCheckpoint, createGraphRunStream, createLifecycleTransformer, createMessagesTransformer, createSubgraphDiscoveryTransformer, createValuesTransformer, emptyCheckpoint, entrypoint, filterLifecycleEntries, filterSubgraphHandles, getConfig, getCurrentTaskInput, getJsonSchemaFromSchema, getPreviousState, getSchemaDefaultGetter, getStore, getSubgraphsSeenSet, getWriter, interrupt, isCheckpointEnvelope, isCommand, isGraphBubbleUp, isGraphDrained, isGraphInterrupt, isInterrupted, isNativeTransformer, isNodeError, isNodeTimeoutError, isParentCommand, isSerializableSchema, isStandardSchema, messagesDeltaReducer, messagesStateReducer, pushMessage, task, writer };
40
41
 
41
42
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\nimport { initializeAsyncLocalStorageSingleton } from \"./node.js\";\n\n// Initialize global async local storage instance for tracing\ninitializeAsyncLocalStorageSingleton();\n\nexport * from \"./web.js\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,sCAAsC"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\nimport { initializeAsyncLocalStorageSingleton } from \"./node.js\";\n\n// Initialize global async local storage instance for tracing\ninitializeAsyncLocalStorageSingleton();\n\nexport * from \"./web.js\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,sCAAsC"}
@@ -2,6 +2,8 @@ const require_constants = require("./constants.cjs");
2
2
  const require_errors = require("./errors.cjs");
3
3
  const require_hash = require("./hash.cjs");
4
4
  let _langchain_core_singletons = require("@langchain/core/singletons");
5
+ let _langchain_core_utils_json_schema = require("@langchain/core/utils/json_schema");
6
+ let _langchain_core_utils_types = require("@langchain/core/utils/types");
5
7
  //#region src/interrupt.ts
6
8
  /**
7
9
  * Interrupts the execution of a graph node.
@@ -19,7 +21,10 @@ let _langchain_core_singletons = require("@langchain/core/singletons");
19
21
  * or if you do, ensure that the `GraphInterrupt` error is thrown again within your `catch` block.
20
22
  *
21
23
  * @param value - The value to include in the interrupt. This will be available in task.interrupts[].value
22
- * @returns The `resume` value provided when the graph is re-invoked with a Command
24
+ * @param options - Optional settings. `responseSchema` describes the expected resume value and is
25
+ * available in task.interrupts[].response_schema as JSON Schema; a Zod schema also validates the resume value.
26
+ * @returns The `resume` value provided when the graph is re-invoked with a Command, parsed by
27
+ * `responseSchema` when it is a Zod schema
23
28
  *
24
29
  * @example
25
30
  * ```typescript
@@ -45,32 +50,39 @@ let _langchain_core_singletons = require("@langchain/core/singletons");
45
50
  *
46
51
  * @throws {Error} If called outside the context of a graph
47
52
  * @throws {GraphInterrupt} When no resume value is available
53
+ * @throws {ZodError} When the resume value does not match a Zod `responseSchema`
48
54
  */
49
- function interrupt(value) {
55
+ function interrupt(value, options) {
50
56
  const config = _langchain_core_singletons.AsyncLocalStorageProviderSingleton.getRunnableConfig();
51
57
  if (!config) throw new Error("Called interrupt() outside the context of a graph.");
52
58
  const conf = config.configurable;
53
59
  if (!conf) throw new Error("No configurable found in config");
54
60
  if (!conf["__pregel_checkpointer"]) throw new require_errors.GraphValueError("No checkpointer set", { lc_error_code: "MISSING_CHECKPOINTER" });
61
+ const schema = options?.responseSchema;
62
+ const parseResume = (resume) => schema !== void 0 && (0, _langchain_core_utils_types.isInteropZodSchema)(schema) ? (0, _langchain_core_utils_types.interopParse)(schema, resume) : resume;
55
63
  const scratchpad = conf[require_constants.CONFIG_KEY_SCRATCHPAD];
56
64
  scratchpad.interruptCounter += 1;
57
65
  const idx = scratchpad.interruptCounter;
58
66
  if (scratchpad.resume.length > 0 && idx < scratchpad.resume.length) {
59
- conf[require_constants.CONFIG_KEY_SEND]?.([[require_constants.RESUME, scratchpad.resume]]);
60
- return scratchpad.resume[idx];
67
+ const parsed = parseResume(scratchpad.resume[idx]);
68
+ conf[require_constants.CONFIG_KEY_SEND]?.([[require_constants.RESUME, scratchpad.resume.slice(0, idx + 1)]]);
69
+ return parsed;
61
70
  }
62
71
  if (scratchpad.nullResume !== void 0) {
63
72
  if (scratchpad.resume.length !== idx) throw new Error(`Resume length mismatch: ${scratchpad.resume.length} !== ${idx}`);
64
73
  const v = scratchpad.consumeNullResume();
74
+ const parsed = parseResume(v);
65
75
  scratchpad.resume.push(v);
66
76
  conf[require_constants.CONFIG_KEY_SEND]?.([[require_constants.RESUME, scratchpad.resume]]);
67
- return v;
77
+ return parsed;
68
78
  }
69
79
  const ns = conf[require_constants.CONFIG_KEY_CHECKPOINT_NS]?.split("|");
70
- throw new require_errors.GraphInterrupt([{
80
+ const pending = {
71
81
  id: ns ? require_hash.XXH3(ns.join("|")) : void 0,
72
82
  value
73
- }]);
83
+ };
84
+ if (schema !== void 0) pending.response_schema = (0, _langchain_core_utils_json_schema.toJsonSchema)(schema);
85
+ throw new require_errors.GraphInterrupt([pending]);
74
86
  }
75
87
  //#endregion
76
88
  exports.interrupt = interrupt;
@@ -1 +1 @@
1
- {"version":3,"file":"interrupt.cjs","names":["AsyncLocalStorageProviderSingleton","GraphValueError","CONFIG_KEY_SCRATCHPAD","CONFIG_KEY_SEND","RESUME","CONFIG_KEY_CHECKPOINT_NS","GraphInterrupt","XXH3"],"sources":["../src/interrupt.ts"],"sourcesContent":["import { AsyncLocalStorageProviderSingleton } from \"@langchain/core/singletons\";\nimport { RunnableConfig } from \"@langchain/core/runnables\";\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} from \"./constants.js\";\nimport { PregelScratchpad } from \"./pregel/types.js\";\nimport { XXH3 } from \"./hash.js\";\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 * @returns The `resume` value provided when the graph is re-invoked with a Command\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 */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function interrupt<I = unknown, R = any>(value: I): 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 // 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 conf[CONFIG_KEY_SEND]?.([[RESUME, scratchpad.resume] as PendingWrite]);\n return scratchpad.resume[idx] as R;\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 scratchpad.resume.push(v);\n conf[CONFIG_KEY_SEND]?.([[RESUME, scratchpad.resume] as PendingWrite]);\n return v as R;\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 throw new GraphInterrupt([{ id, value }]);\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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8DA,SAAgB,UAAgC,OAAa;CAC3D,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;CAIJ,MAAM,aAA+B,KAAKC,kBAAAA;AAC1C,YAAW,oBAAoB;CAC/B,MAAM,MAAM,WAAW;AAGvB,KAAI,WAAW,OAAO,SAAS,KAAK,MAAM,WAAW,OAAO,QAAQ;AAClE,OAAKC,kBAAAA,mBAAmB,CAAC,CAACC,kBAAAA,QAAQ,WAAW,OAAO,CAAiB,CAAC;AACtE,SAAO,WAAW,OAAO;;AAI3B,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;AACxC,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;AAGD,OAAM,IAAIC,eAAAA,eAAe,CAAC;EAAE,IADjB,KAAKC,aAAAA,KAAK,GAAG,KAAA,IAAoC,CAAC,GAAG,KAAA;EAChC;EAAO,CAAC,CAAC"}
1
+ {"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"}
@@ -1,4 +1,17 @@
1
+ import { JSONSchema } from "@langchain/core/utils/json_schema";
2
+ import { InteropZodType } from "@langchain/core/utils/types";
3
+
1
4
  //#region src/interrupt.d.ts
5
+ interface InterruptOptions {
6
+ /**
7
+ * Schema for the value expected when the graph is resumed, surfaced to
8
+ * clients on `Interrupt.response_schema` (as JSON Schema) so they can render
9
+ * a typed input form. A Zod schema also parses the resume value, and the
10
+ * parsed value is what `interrupt` returns; a JSON Schema object is passed
11
+ * through to clients without validating the resume value.
12
+ */
13
+ responseSchema?: InteropZodType | JSONSchema;
14
+ }
2
15
  /**
3
16
  * Interrupts the execution of a graph node.
4
17
  * This function can be used to pause execution of a node, and return the value of the `resume`
@@ -15,7 +28,10 @@
15
28
  * or if you do, ensure that the `GraphInterrupt` error is thrown again within your `catch` block.
16
29
  *
17
30
  * @param value - The value to include in the interrupt. This will be available in task.interrupts[].value
18
- * @returns The `resume` value provided when the graph is re-invoked with a Command
31
+ * @param options - Optional settings. `responseSchema` describes the expected resume value and is
32
+ * available in task.interrupts[].response_schema as JSON Schema; a Zod schema also validates the resume value.
33
+ * @returns The `resume` value provided when the graph is re-invoked with a Command, parsed by
34
+ * `responseSchema` when it is a Zod schema
19
35
  *
20
36
  * @example
21
37
  * ```typescript
@@ -41,8 +57,9 @@
41
57
  *
42
58
  * @throws {Error} If called outside the context of a graph
43
59
  * @throws {GraphInterrupt} When no resume value is available
60
+ * @throws {ZodError} When the resume value does not match a Zod `responseSchema`
44
61
  */
45
- declare function interrupt<I = unknown, R = any>(value: I): R;
62
+ declare function interrupt<I = unknown, R = any>(value: I, options?: InterruptOptions): R;
46
63
  type FilterAny<X> = (<T>() => T extends X ? 1 : 2) extends (<T>() => (T extends any ? 1 : 2)) ? never : X;
47
64
  type InferInterruptInputType<T> = T extends typeof interrupt<infer I, unknown> ? I : T extends {
48
65
  [key: string]: typeof interrupt<any, any>;
@@ -51,5 +68,5 @@ type InferInterruptResumeType<T, TInner = false> = T extends typeof interrupt<ne
51
68
  [key: string]: typeof interrupt<any, any>;
52
69
  } ? { [K in keyof T]: InferInterruptResumeType<T[K], true> }[keyof T] : unknown;
53
70
  //#endregion
54
- export { InferInterruptInputType, InferInterruptResumeType, interrupt };
71
+ export { InferInterruptInputType, InferInterruptResumeType, InterruptOptions, interrupt };
55
72
  //# sourceMappingURL=interrupt.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"interrupt.d.cts","names":[],"sources":["../src/interrupt.ts"],"mappings":";;AA8DA;;;;;;;;;;;AAkDC;;;;;;;;;;;;;;;;;;AAUD;;;;;;;;;;;;;iBA5DgB,SAAA,sBAAA,CAAgC,KAAA,EAAO,CAAA,GAAI,CAAA;AAAA,KAoDtD,SAAA,gBACO,CAAA,SAAU,CAAA,6BAGb,CAAA,iCAEH,CAAA;AAAA,KAEM,uBAAA,MAA6B,CAAA,gBAAiB,SAAA,qBAItD,CAAA,GAEA,CAAA;EAAA,CAAa,GAAA,kBAAqB,SAAA;AAAA,kBAClB,CAAA,GAAI,uBAAA,CAAwB,CAAA,CAAE,CAAA,WAAY,CAAA;AAAA,KAGlD,wBAAA,sBAGR,CAAA,gBAAiB,SAAA,mBACjB,MAAA,gBACE,SAAA,CAAU,CAAA,IACV,CAAA,GAEF,CAAA;EAAA,CAAa,GAAA,kBAAqB,SAAA;AAAA,kBAClB,CAAA,GAAI,wBAAA,CAAyB,CAAA,CAAE,CAAA,iBAAkB,CAAA"}
1
+ {"version":3,"file":"interrupt.d.cts","names":[],"sources":["../src/interrupt.ts"],"mappings":";;;;UA4BiB,gBAAA;;AAAjB;;;;;;EAQE,cAAA,GAAiB,cAAA,GAAiB,UAAA;AAAA;;AAmDpC;;;;;;;;;;;;;;;;;AAsEC;;;;;;;;;;;;;;;;;;AAUD;;;;;;;;;;;iBAhFgB,SAAA,sBAAA,CACd,KAAA,EAAO,CAAA,EACP,OAAA,GAAU,gBAAA,GACT,CAAA;AAAA,KAqEE,SAAA,gBACO,CAAA,SAAU,CAAA,6BAGb,CAAA,iCAEH,CAAA;AAAA,KAEM,uBAAA,MAA6B,CAAA,gBAAiB,SAAA,qBAItD,CAAA,GAEA,CAAA;EAAA,CAAa,GAAA,kBAAqB,SAAA;AAAA,kBAClB,CAAA,GAAI,uBAAA,CAAwB,CAAA,CAAE,CAAA,WAAY,CAAA;AAAA,KAGlD,wBAAA,sBAGR,CAAA,gBAAiB,SAAA,mBACjB,MAAA,gBACE,SAAA,CAAU,CAAA,IACV,CAAA,GAEF,CAAA;EAAA,CAAa,GAAA,kBAAqB,SAAA;AAAA,kBAClB,CAAA,GAAI,wBAAA,CAAyB,CAAA,CAAE,CAAA,iBAAkB,CAAA"}
@@ -1,4 +1,17 @@
1
+ import { JSONSchema } from "@langchain/core/utils/json_schema";
2
+ import { InteropZodType } from "@langchain/core/utils/types";
3
+
1
4
  //#region src/interrupt.d.ts
5
+ interface InterruptOptions {
6
+ /**
7
+ * Schema for the value expected when the graph is resumed, surfaced to
8
+ * clients on `Interrupt.response_schema` (as JSON Schema) so they can render
9
+ * a typed input form. A Zod schema also parses the resume value, and the
10
+ * parsed value is what `interrupt` returns; a JSON Schema object is passed
11
+ * through to clients without validating the resume value.
12
+ */
13
+ responseSchema?: InteropZodType | JSONSchema;
14
+ }
2
15
  /**
3
16
  * Interrupts the execution of a graph node.
4
17
  * This function can be used to pause execution of a node, and return the value of the `resume`
@@ -15,7 +28,10 @@
15
28
  * or if you do, ensure that the `GraphInterrupt` error is thrown again within your `catch` block.
16
29
  *
17
30
  * @param value - The value to include in the interrupt. This will be available in task.interrupts[].value
18
- * @returns The `resume` value provided when the graph is re-invoked with a Command
31
+ * @param options - Optional settings. `responseSchema` describes the expected resume value and is
32
+ * available in task.interrupts[].response_schema as JSON Schema; a Zod schema also validates the resume value.
33
+ * @returns The `resume` value provided when the graph is re-invoked with a Command, parsed by
34
+ * `responseSchema` when it is a Zod schema
19
35
  *
20
36
  * @example
21
37
  * ```typescript
@@ -41,8 +57,9 @@
41
57
  *
42
58
  * @throws {Error} If called outside the context of a graph
43
59
  * @throws {GraphInterrupt} When no resume value is available
60
+ * @throws {ZodError} When the resume value does not match a Zod `responseSchema`
44
61
  */
45
- declare function interrupt<I = unknown, R = any>(value: I): R;
62
+ declare function interrupt<I = unknown, R = any>(value: I, options?: InterruptOptions): R;
46
63
  type FilterAny<X> = (<T>() => T extends X ? 1 : 2) extends (<T>() => (T extends any ? 1 : 2)) ? never : X;
47
64
  type InferInterruptInputType<T> = T extends typeof interrupt<infer I, unknown> ? I : T extends {
48
65
  [key: string]: typeof interrupt<any, any>;
@@ -51,5 +68,5 @@ type InferInterruptResumeType<T, TInner = false> = T extends typeof interrupt<ne
51
68
  [key: string]: typeof interrupt<any, any>;
52
69
  } ? { [K in keyof T]: InferInterruptResumeType<T[K], true> }[keyof T] : unknown;
53
70
  //#endregion
54
- export { InferInterruptInputType, InferInterruptResumeType, interrupt };
71
+ export { InferInterruptInputType, InferInterruptResumeType, InterruptOptions, interrupt };
55
72
  //# sourceMappingURL=interrupt.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"interrupt.d.ts","names":[],"sources":["../src/interrupt.ts"],"mappings":";;AA8DA;;;;;;;;;;;AAkDC;;;;;;;;;;;;;;;;;;AAUD;;;;;;;;;;;;;iBA5DgB,SAAA,sBAAA,CAAgC,KAAA,EAAO,CAAA,GAAI,CAAA;AAAA,KAoDtD,SAAA,gBACO,CAAA,SAAU,CAAA,6BAGb,CAAA,iCAEH,CAAA;AAAA,KAEM,uBAAA,MAA6B,CAAA,gBAAiB,SAAA,qBAItD,CAAA,GAEA,CAAA;EAAA,CAAa,GAAA,kBAAqB,SAAA;AAAA,kBAClB,CAAA,GAAI,uBAAA,CAAwB,CAAA,CAAE,CAAA,WAAY,CAAA;AAAA,KAGlD,wBAAA,sBAGR,CAAA,gBAAiB,SAAA,mBACjB,MAAA,gBACE,SAAA,CAAU,CAAA,IACV,CAAA,GAEF,CAAA;EAAA,CAAa,GAAA,kBAAqB,SAAA;AAAA,kBAClB,CAAA,GAAI,wBAAA,CAAyB,CAAA,CAAE,CAAA,iBAAkB,CAAA"}
1
+ {"version":3,"file":"interrupt.d.ts","names":[],"sources":["../src/interrupt.ts"],"mappings":";;;;UA4BiB,gBAAA;;AAAjB;;;;;;EAQE,cAAA,GAAiB,cAAA,GAAiB,UAAA;AAAA;;AAmDpC;;;;;;;;;;;;;;;;;AAsEC;;;;;;;;;;;;;;;;;;AAUD;;;;;;;;;;;iBAhFgB,SAAA,sBAAA,CACd,KAAA,EAAO,CAAA,EACP,OAAA,GAAU,gBAAA,GACT,CAAA;AAAA,KAqEE,SAAA,gBACO,CAAA,SAAU,CAAA,6BAGb,CAAA,iCAEH,CAAA;AAAA,KAEM,uBAAA,MAA6B,CAAA,gBAAiB,SAAA,qBAItD,CAAA,GAEA,CAAA;EAAA,CAAa,GAAA,kBAAqB,SAAA;AAAA,kBAClB,CAAA,GAAI,uBAAA,CAAwB,CAAA,CAAE,CAAA,WAAY,CAAA;AAAA,KAGlD,wBAAA,sBAGR,CAAA,gBAAiB,SAAA,mBACjB,MAAA,gBACE,SAAA,CAAU,CAAA,IACV,CAAA,GAEF,CAAA;EAAA,CAAa,GAAA,kBAAqB,SAAA;AAAA,kBAClB,CAAA,GAAI,wBAAA,CAAyB,CAAA,CAAE,CAAA,iBAAkB,CAAA"}
package/dist/interrupt.js CHANGED
@@ -2,6 +2,8 @@ import { CONFIG_KEY_CHECKPOINT_NS, CONFIG_KEY_SCRATCHPAD, CONFIG_KEY_SEND, RESUM
2
2
  import { GraphInterrupt, GraphValueError } from "./errors.js";
3
3
  import { XXH3 } from "./hash.js";
4
4
  import { AsyncLocalStorageProviderSingleton } from "@langchain/core/singletons";
5
+ import { toJsonSchema } from "@langchain/core/utils/json_schema";
6
+ import { interopParse, isInteropZodSchema } from "@langchain/core/utils/types";
5
7
  //#region src/interrupt.ts
6
8
  /**
7
9
  * Interrupts the execution of a graph node.
@@ -19,7 +21,10 @@ import { AsyncLocalStorageProviderSingleton } from "@langchain/core/singletons";
19
21
  * or if you do, ensure that the `GraphInterrupt` error is thrown again within your `catch` block.
20
22
  *
21
23
  * @param value - The value to include in the interrupt. This will be available in task.interrupts[].value
22
- * @returns The `resume` value provided when the graph is re-invoked with a Command
24
+ * @param options - Optional settings. `responseSchema` describes the expected resume value and is
25
+ * available in task.interrupts[].response_schema as JSON Schema; a Zod schema also validates the resume value.
26
+ * @returns The `resume` value provided when the graph is re-invoked with a Command, parsed by
27
+ * `responseSchema` when it is a Zod schema
23
28
  *
24
29
  * @example
25
30
  * ```typescript
@@ -45,32 +50,39 @@ import { AsyncLocalStorageProviderSingleton } from "@langchain/core/singletons";
45
50
  *
46
51
  * @throws {Error} If called outside the context of a graph
47
52
  * @throws {GraphInterrupt} When no resume value is available
53
+ * @throws {ZodError} When the resume value does not match a Zod `responseSchema`
48
54
  */
49
- function interrupt(value) {
55
+ function interrupt(value, options) {
50
56
  const config = AsyncLocalStorageProviderSingleton.getRunnableConfig();
51
57
  if (!config) throw new Error("Called interrupt() outside the context of a graph.");
52
58
  const conf = config.configurable;
53
59
  if (!conf) throw new Error("No configurable found in config");
54
60
  if (!conf["__pregel_checkpointer"]) throw new GraphValueError("No checkpointer set", { lc_error_code: "MISSING_CHECKPOINTER" });
61
+ const schema = options?.responseSchema;
62
+ const parseResume = (resume) => schema !== void 0 && isInteropZodSchema(schema) ? interopParse(schema, resume) : resume;
55
63
  const scratchpad = conf[CONFIG_KEY_SCRATCHPAD];
56
64
  scratchpad.interruptCounter += 1;
57
65
  const idx = scratchpad.interruptCounter;
58
66
  if (scratchpad.resume.length > 0 && idx < scratchpad.resume.length) {
59
- conf[CONFIG_KEY_SEND]?.([[RESUME, scratchpad.resume]]);
60
- return scratchpad.resume[idx];
67
+ const parsed = parseResume(scratchpad.resume[idx]);
68
+ conf[CONFIG_KEY_SEND]?.([[RESUME, scratchpad.resume.slice(0, idx + 1)]]);
69
+ return parsed;
61
70
  }
62
71
  if (scratchpad.nullResume !== void 0) {
63
72
  if (scratchpad.resume.length !== idx) throw new Error(`Resume length mismatch: ${scratchpad.resume.length} !== ${idx}`);
64
73
  const v = scratchpad.consumeNullResume();
74
+ const parsed = parseResume(v);
65
75
  scratchpad.resume.push(v);
66
76
  conf[CONFIG_KEY_SEND]?.([[RESUME, scratchpad.resume]]);
67
- return v;
77
+ return parsed;
68
78
  }
69
79
  const ns = conf[CONFIG_KEY_CHECKPOINT_NS]?.split("|");
70
- throw new GraphInterrupt([{
80
+ const pending = {
71
81
  id: ns ? XXH3(ns.join("|")) : void 0,
72
82
  value
73
- }]);
83
+ };
84
+ if (schema !== void 0) pending.response_schema = toJsonSchema(schema);
85
+ throw new GraphInterrupt([pending]);
74
86
  }
75
87
  //#endregion
76
88
  export { interrupt };
@@ -1 +1 @@
1
- {"version":3,"file":"interrupt.js","names":[],"sources":["../src/interrupt.ts"],"sourcesContent":["import { AsyncLocalStorageProviderSingleton } from \"@langchain/core/singletons\";\nimport { RunnableConfig } from \"@langchain/core/runnables\";\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} from \"./constants.js\";\nimport { PregelScratchpad } from \"./pregel/types.js\";\nimport { XXH3 } from \"./hash.js\";\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 * @returns The `resume` value provided when the graph is re-invoked with a Command\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 */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function interrupt<I = unknown, R = any>(value: I): 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 // 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 conf[CONFIG_KEY_SEND]?.([[RESUME, scratchpad.resume] as PendingWrite]);\n return scratchpad.resume[idx] as R;\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 scratchpad.resume.push(v);\n conf[CONFIG_KEY_SEND]?.([[RESUME, scratchpad.resume] as PendingWrite]);\n return v as R;\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 throw new GraphInterrupt([{ id, value }]);\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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8DA,SAAgB,UAAgC,OAAa;CAC3D,MAAM,SACJ,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,IAAI,gBAAgB,uBAAuB,EAC/C,eAAe,wBAChB,CAAC;CAIJ,MAAM,aAA+B,KAAK;AAC1C,YAAW,oBAAoB;CAC/B,MAAM,MAAM,WAAW;AAGvB,KAAI,WAAW,OAAO,SAAS,KAAK,MAAM,WAAW,OAAO,QAAQ;AAClE,OAAK,mBAAmB,CAAC,CAAC,QAAQ,WAAW,OAAO,CAAiB,CAAC;AACtE,SAAO,WAAW,OAAO;;AAI3B,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;AACxC,aAAW,OAAO,KAAK,EAAE;AACzB,OAAK,mBAAmB,CAAC,CAAC,QAAQ,WAAW,OAAO,CAAiB,CAAC;AACtE,SAAO;;CAIT,MAAM,KAA2B,KAAK,2BAA2B,MAAA,IAEhE;AAGD,OAAM,IAAI,eAAe,CAAC;EAAE,IADjB,KAAK,KAAK,GAAG,KAAA,IAAoC,CAAC,GAAG,KAAA;EAChC;EAAO,CAAC,CAAC"}
1
+ {"version":3,"file":"interrupt.js","names":[],"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,SACJ,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,IAAI,gBAAgB,uBAAuB,EAC/C,eAAe,wBAChB,CAAC;CAGJ,MAAM,SAAS,SAAS;CACxB,MAAM,eAAe,WAClB,WAAW,KAAA,KAAa,mBAAmB,OAAO,GAC/C,aAAa,QAAQ,OAAO,GAC5B;CAGN,MAAM,aAA+B,KAAK;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,OAAK,mBAAmB,CACtB,CAAC,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,OAAK,mBAAmB,CAAC,CAAC,QAAQ,WAAW,OAAO,CAAiB,CAAC;AACtE,SAAO;;CAIT,MAAM,KAA2B,KAAK,2BAA2B,MAAA,IAEhE;CAGD,MAAM,UAAwB;EAAE,IADrB,KAAK,KAAK,GAAG,KAAA,IAAoC,CAAC,GAAG,KAAA;EAC5B;EAAO;AAC3C,KAAI,WAAW,KAAA,EACb,SAAQ,kBAAkB,aAAa,OAAO;AAEhD,OAAM,IAAI,eAAe,CAAC,QAAQ,CAAC"}
@@ -0,0 +1,25 @@
1
+ const require_callbacks = require("../callbacks.cjs");
2
+ //#region src/pregel/callbacks.ts
3
+ function getGraphCallbackDispatcher(manager) {
4
+ const handlers = manager?.handlers.filter(require_callbacks.GraphCallbackHandler.isInstance);
5
+ if (!handlers?.length) return void 0;
6
+ return async (events) => {
7
+ while (events?.length) {
8
+ const event = events.shift();
9
+ for (const handler of handlers) {
10
+ const method = "interrupts" in event ? "handleInterrupt" : "handleResume";
11
+ try {
12
+ if ("interrupts" in event) await handler.handleInterrupt?.(event);
13
+ else await handler.handleResume?.(event);
14
+ } catch (error) {
15
+ (handler.raiseError ? console.error : console.warn)(`Error in handler ${handler.constructor.name}, ${method}: ${error}`);
16
+ if (handler.raiseError) throw error;
17
+ }
18
+ }
19
+ }
20
+ };
21
+ }
22
+ //#endregion
23
+ exports.getGraphCallbackDispatcher = getGraphCallbackDispatcher;
24
+
25
+ //# sourceMappingURL=callbacks.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"callbacks.cjs","names":["GraphCallbackHandler"],"sources":["../../src/pregel/callbacks.ts"],"sourcesContent":["import type { CallbackManagerForChainRun } from \"@langchain/core/callbacks/manager\";\nimport {\n GraphCallbackHandler,\n type GraphLifecycleEvent,\n} from \"../callbacks.js\";\n\nexport function getGraphCallbackDispatcher(\n manager: CallbackManagerForChainRun | undefined\n) {\n const handlers = manager?.handlers.filter(GraphCallbackHandler.isInstance);\n if (!handlers?.length) return undefined;\n\n return async (events: GraphLifecycleEvent[] | undefined) => {\n while (events?.length) {\n const event = events.shift()!;\n for (const handler of handlers) {\n const method =\n \"interrupts\" in event ? \"handleInterrupt\" : \"handleResume\";\n try {\n if (\"interrupts\" in event) {\n await handler.handleInterrupt?.(event);\n } else {\n await handler.handleResume?.(event);\n }\n } catch (error) {\n (handler.raiseError ? console.error : console.warn)(\n `Error in handler ${handler.constructor.name}, ${method}: ${error}`\n );\n if (handler.raiseError) throw error;\n }\n }\n }\n };\n}\n"],"mappings":";;AAMA,SAAgB,2BACd,SACA;CACA,MAAM,WAAW,SAAS,SAAS,OAAOA,kBAAAA,qBAAqB,WAAW;AAC1E,KAAI,CAAC,UAAU,OAAQ,QAAO,KAAA;AAE9B,QAAO,OAAO,WAA8C;AAC1D,SAAO,QAAQ,QAAQ;GACrB,MAAM,QAAQ,OAAO,OAAO;AAC5B,QAAK,MAAM,WAAW,UAAU;IAC9B,MAAM,SACJ,gBAAgB,QAAQ,oBAAoB;AAC9C,QAAI;AACF,SAAI,gBAAgB,MAClB,OAAM,QAAQ,kBAAkB,MAAM;SAEtC,OAAM,QAAQ,eAAe,MAAM;aAE9B,OAAO;AACd,MAAC,QAAQ,aAAa,QAAQ,QAAQ,QAAQ,MAC5C,oBAAoB,QAAQ,YAAY,KAAK,IAAI,OAAO,IAAI,QAC7D;AACD,SAAI,QAAQ,WAAY,OAAM"}
@@ -0,0 +1,25 @@
1
+ import { GraphCallbackHandler } from "../callbacks.js";
2
+ //#region src/pregel/callbacks.ts
3
+ function getGraphCallbackDispatcher(manager) {
4
+ const handlers = manager?.handlers.filter(GraphCallbackHandler.isInstance);
5
+ if (!handlers?.length) return void 0;
6
+ return async (events) => {
7
+ while (events?.length) {
8
+ const event = events.shift();
9
+ for (const handler of handlers) {
10
+ const method = "interrupts" in event ? "handleInterrupt" : "handleResume";
11
+ try {
12
+ if ("interrupts" in event) await handler.handleInterrupt?.(event);
13
+ else await handler.handleResume?.(event);
14
+ } catch (error) {
15
+ (handler.raiseError ? console.error : console.warn)(`Error in handler ${handler.constructor.name}, ${method}: ${error}`);
16
+ if (handler.raiseError) throw error;
17
+ }
18
+ }
19
+ }
20
+ };
21
+ }
22
+ //#endregion
23
+ export { getGraphCallbackDispatcher };
24
+
25
+ //# sourceMappingURL=callbacks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"callbacks.js","names":[],"sources":["../../src/pregel/callbacks.ts"],"sourcesContent":["import type { CallbackManagerForChainRun } from \"@langchain/core/callbacks/manager\";\nimport {\n GraphCallbackHandler,\n type GraphLifecycleEvent,\n} from \"../callbacks.js\";\n\nexport function getGraphCallbackDispatcher(\n manager: CallbackManagerForChainRun | undefined\n) {\n const handlers = manager?.handlers.filter(GraphCallbackHandler.isInstance);\n if (!handlers?.length) return undefined;\n\n return async (events: GraphLifecycleEvent[] | undefined) => {\n while (events?.length) {\n const event = events.shift()!;\n for (const handler of handlers) {\n const method =\n \"interrupts\" in event ? \"handleInterrupt\" : \"handleResume\";\n try {\n if (\"interrupts\" in event) {\n await handler.handleInterrupt?.(event);\n } else {\n await handler.handleResume?.(event);\n }\n } catch (error) {\n (handler.raiseError ? console.error : console.warn)(\n `Error in handler ${handler.constructor.name}, ${method}: ${error}`\n );\n if (handler.raiseError) throw error;\n }\n }\n }\n };\n}\n"],"mappings":";;AAMA,SAAgB,2BACd,SACA;CACA,MAAM,WAAW,SAAS,SAAS,OAAO,qBAAqB,WAAW;AAC1E,KAAI,CAAC,UAAU,OAAQ,QAAO,KAAA;AAE9B,QAAO,OAAO,WAA8C;AAC1D,SAAO,QAAQ,QAAQ;GACrB,MAAM,QAAQ,OAAO,OAAO;AAC5B,QAAK,MAAM,WAAW,UAAU;IAC9B,MAAM,SACJ,gBAAgB,QAAQ,oBAAoB;AAC9C,QAAI;AACF,SAAI,gBAAgB,MAClB,OAAM,QAAQ,kBAAkB,MAAM;SAEtC,OAAM,QAAQ,eAAe,MAAM;aAE9B,OAAO;AACd,MAAC,QAAQ,aAAa,QAAQ,QAAQ,QAAQ,MAC5C,oBAAoB,QAAQ,YAAY,KAAK,IAAI,OAAO,IAAI,QAC7D;AACD,SAAI,QAAQ,WAAY,OAAM"}
@@ -6,6 +6,7 @@ const require_config = require("./utils/config.cjs");
6
6
  const require_utils = require("../utils.cjs");
7
7
  const require_write = require("./write.cjs");
8
8
  const require_read = require("./read.cjs");
9
+ const require_callbacks = require("./callbacks.cjs");
9
10
  const require_runtime = require("./runtime.cjs");
10
11
  const require_io = require("./io.cjs");
11
12
  const require_index = require("./utils/index.cjs");
@@ -1061,6 +1062,7 @@ var Pregel = class extends PartialRunnable {
1061
1062
  config.control ??= new require_runtime.RunControl();
1062
1063
  const callbackManagerOptions = { tracerInheritableMetadata: _getTracingMetadataDefaults(config) };
1063
1064
  const runManager = await (await _langchain_core_callbacks_manager.CallbackManager._configureSync(config?.callbacks, void 0, config?.tags, void 0, config?.metadata, void 0, callbackManagerOptions))?.handleChainStart(this.toJSON(), require_index._coerceToDict(input, "input"), runId, void 0, void 0, void 0, config?.runName ?? this.getName());
1065
+ const dispatchGraphCallbacks = require_callbacks.getGraphCallbackDispatcher(runManager);
1064
1066
  const channelSpecs = require_base.getOnlyChannels(this.channels);
1065
1067
  let loop;
1066
1068
  let loopError;
@@ -1088,6 +1090,7 @@ var Pregel = class extends PartialRunnable {
1088
1090
  interruptAfter,
1089
1091
  interruptBefore,
1090
1092
  manager: runManager,
1093
+ hasGraphCallbacks: dispatchGraphCallbacks !== void 0,
1091
1094
  debug: this.debug,
1092
1095
  triggerToNodes: this.triggerToNodes,
1093
1096
  durability
@@ -1104,7 +1107,8 @@ var Pregel = class extends PartialRunnable {
1104
1107
  loop,
1105
1108
  runner,
1106
1109
  debug,
1107
- config
1110
+ config,
1111
+ emitLifecycleEvents: dispatchGraphCallbacks
1108
1112
  });
1109
1113
  if (durability === "sync") await Promise.all(loop?.checkpointerPromises ?? []);
1110
1114
  } catch (e) {
@@ -1199,10 +1203,11 @@ var Pregel = class extends PartialRunnable {
1199
1203
  return chunks;
1200
1204
  }
1201
1205
  async _runLoop(params) {
1202
- const { loop, runner, debug, config } = params;
1206
+ const { loop, runner, debug, config, emitLifecycleEvents } = params;
1203
1207
  let tickError;
1204
1208
  try {
1205
1209
  while (await loop.tick({ inputKeys: this.inputChannels })) {
1210
+ if (emitLifecycleEvents) await emitLifecycleEvents(loop.lifecycleEvents);
1206
1211
  for (const { task } of await loop._matchCachedWrites()) loop._outputWrites(task.id, task.writes, true);
1207
1212
  if (debug) require_debug.printStepCheckpoint(loop.checkpointMetadata.step, loop.channels, this.streamChannelsList);
1208
1213
  if (debug) require_debug.printStepTasks(loop.step, Object.values(loop.tasks));
@@ -1230,6 +1235,7 @@ var Pregel = class extends PartialRunnable {
1230
1235
  if (!await loop.finishAndHandleError(tickError)) throw e;
1231
1236
  } finally {
1232
1237
  if (tickError === void 0) await loop.finishAndHandleError();
1238
+ if (emitLifecycleEvents) await emitLifecycleEvents(loop.lifecycleEvents);
1233
1239
  }
1234
1240
  }
1235
1241
  async clearCache() {