@langchain/langgraph
Version:
1 lines • 3.58 kB
Source Map (JSON)
{"version":3,"file":"replay.cjs","names":["#visitedNs","#isFirstVisit"],"sources":["../../src/pregel/replay.ts"],"sourcesContent":["import type {\n BaseCheckpointSaver,\n CheckpointTuple,\n} from \"@langchain/langgraph-checkpoint\";\nimport type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { CHECKPOINT_NAMESPACE_END } from \"../constants.js\";\n\n/**\n * Tracks subgraph checkpoint loading during parent-graph time travel.\n *\n * When a parent replays from a historical checkpoint, nested subgraphs must\n * load the checkpoint that existed *before* the replay point on their first\n * visit, then fall back to normal latest-checkpoint loading on later visits\n * within the same run.\n */\nexport class ReplayState {\n /** Parent checkpoint ID used as the `before` cursor for subgraph lookups. */\n checkpointId: string;\n\n #visitedNs: Set<string> = new Set();\n\n /**\n * @param checkpointId - Checkpoint ID from the parent graph at the replay point.\n */\n constructor(checkpointId: string) {\n this.checkpointId = checkpointId;\n }\n\n /**\n * Whether this is the first visit to a logical subgraph namespace in the run.\n *\n * Task-id suffixes are stripped so the same subgraph invoked across loop\n * iterations shares one visit record.\n *\n * @param checkpointNs - Subgraph checkpoint namespace.\n */\n #isFirstVisit(checkpointNs: string): boolean {\n const stableNs = checkpointNs.includes(CHECKPOINT_NAMESPACE_END)\n ? checkpointNs.slice(\n 0,\n checkpointNs.lastIndexOf(CHECKPOINT_NAMESPACE_END)\n )\n : checkpointNs;\n if (this.#visitedNs.has(stableNs)) {\n return false;\n }\n this.#visitedNs.add(stableNs);\n return true;\n }\n\n /**\n * Load the checkpoint tuple for a subgraph namespace during replay.\n *\n * On the first visit to `checkpointNs`, returns the latest checkpoint saved\n * before {@link ReplayState.checkpointId}. On subsequent visits, delegates to\n * `checkpointer.getTuple` for the current config.\n *\n * @param checkpointNs - Subgraph checkpoint namespace.\n * @param checkpointer - Checkpointer shared with the parent graph.\n * @param checkpointConfig - Runnable config for the subgraph lookup.\n * @returns The resolved checkpoint tuple, if any.\n */\n async getCheckpoint(\n checkpointNs: string,\n checkpointer: BaseCheckpointSaver,\n checkpointConfig: RunnableConfig\n ): Promise<CheckpointTuple | undefined> {\n if (this.#isFirstVisit(checkpointNs)) {\n const results: CheckpointTuple[] = [];\n for await (const saved of checkpointer.list(checkpointConfig, {\n before: {\n configurable: { checkpoint_id: this.checkpointId },\n },\n limit: 1,\n })) {\n results.push(saved);\n }\n return results.length > 0 ? results[0] : undefined;\n }\n return (await checkpointer.getTuple(checkpointConfig)) ?? undefined;\n }\n}\n"],"mappings":";;;;;;;;;;AAeA,IAAa,cAAb,MAAyB;;CAEvB;CAEA,6BAA0B,IAAI,KAAK;;;;CAKnC,YAAY,cAAsB;AAChC,OAAK,eAAe;;;;;;;;;;CAWtB,cAAc,cAA+B;EAC3C,MAAM,WAAW,aAAa,SAAA,IAAkC,GAC5D,aAAa,MACX,GACA,aAAa,YAAA,IAAqC,CACnD,GACD;AACJ,MAAI,MAAA,UAAgB,IAAI,SAAS,CAC/B,QAAO;AAET,QAAA,UAAgB,IAAI,SAAS;AAC7B,SAAO;;;;;;;;;;;;;;CAeT,MAAM,cACJ,cACA,cACA,kBACsC;AACtC,MAAI,MAAA,aAAmB,aAAa,EAAE;GACpC,MAAM,UAA6B,EAAE;AACrC,cAAW,MAAM,SAAS,aAAa,KAAK,kBAAkB;IAC5D,QAAQ,EACN,cAAc,EAAE,eAAe,KAAK,cAAc,EACnD;IACD,OAAO;IACR,CAAC,CACA,SAAQ,KAAK,MAAM;AAErB,UAAO,QAAQ,SAAS,IAAI,QAAQ,KAAK,KAAA;;AAE3C,SAAQ,MAAM,aAAa,SAAS,iBAAiB,IAAK,KAAA"}