{"version":3,"file":"memory.cjs","names":["BaseCheckpointSaver","TASKS","maxChannelVersion","getCheckpointId","copyCheckpoint","WRITES_IDX_MAP"],"sources":["../src/memory.ts"],"sourcesContent":["import type { RunnableConfig } from \"@langchain/core/runnables\";\nimport {\n  BaseCheckpointSaver,\n  Checkpoint,\n  CheckpointListOptions,\n  CheckpointTuple,\n  copyCheckpoint,\n  getCheckpointId,\n  maxChannelVersion,\n  WRITES_IDX_MAP,\n} from \"./base.js\";\nimport { SerializerProtocol } from \"./serde/base.js\";\nimport {\n  CheckpointMetadata,\n  CheckpointPendingWrite,\n  DeltaChannelHistory,\n  PendingWrite,\n} from \"./types.js\";\nimport { TASKS } from \"./serde/types.js\";\n\n/**\n * Keys that, when written into a plain JavaScript object via bracket\n * notation, traverse the prototype chain and mutate `Object.prototype`\n * (or the constructor) instead of creating a new own property. Any of\n * the three reaches `Object.prototype` and pollutes every object in\n * the running process. CWE-1321 (Prototype Pollution).\n */\nconst POLLUTION_KEYS = new Set([\"__proto__\", \"constructor\", \"prototype\"]);\n\n/**\n * Asserts that a value sourced from {@link RunnableConfig.configurable} (or\n * any other caller-influenced position) is safe to use as a property key\n * on the in-memory checkpoint store.\n *\n * `MemorySaver` keeps state in two nested plain objects (`storage` and\n * `writes`) and writes to them with bracket notation:\n *\n *     this.storage[threadId][checkpointNamespace][checkpoint.id] = ...\n *\n * Without this guard a `threadId` of `\"__proto__\"` (or `\"constructor\"`)\n * resolves through the prototype chain, and the subsequent assignment\n * mutates `Object.prototype`. From that point every plain object in the\n * process inherits the injected property: `for...in` loops over unrelated\n * objects iterate it, framework code that does `if (obj[x])` short-circuits\n * unexpectedly, and downstream serializers may emit it. In a Node.js\n * server this is a stepping stone to remote code execution.\n *\n * `MemorySaver` is the default saver used by every quickstart, every\n * tutorial, and most test fixtures, so this guard runs in the hot path\n * for the most common LangGraph configuration.\n *\n * @param field Name of the configurable field, used in the error message.\n * @param value Value to validate. Must be a non-empty string that is not\n *              one of the three prototype-pollution keys.\n * @param options.allowEmpty When true the empty string is accepted, used\n *                            for the documented empty `checkpoint_ns`\n *                            default; otherwise an empty string is\n *                            rejected the same way as a non-string.\n */\nfunction assertSafeStorageKey(\n  field: string,\n  value: unknown,\n  options: { allowEmpty?: boolean } = {}\n): asserts value is string {\n  const { allowEmpty = false } = options;\n  if (typeof value !== \"string\") {\n    const observed =\n      value === null\n        ? \"null\"\n        : value === undefined\n          ? \"undefined\"\n          : Array.isArray(value)\n            ? \"array\"\n            : typeof value;\n    throw new Error(\n      `Invalid configurable value for key \"${field}\": expected a string identifier (got ${observed}). This guard protects MemorySaver from prototype pollution.`\n    );\n  }\n  if (!allowEmpty && value === \"\") {\n    throw new Error(\n      `Invalid configurable value for key \"${field}\": empty string is not permitted as an in-memory storage key.`\n    );\n  }\n  if (POLLUTION_KEYS.has(value)) {\n    throw new Error(\n      `Invalid configurable value for key \"${field}\": value \"${value}\" is reserved (would mutate Object.prototype). This guard protects MemorySaver from prototype pollution.`\n    );\n  }\n}\n\nfunction _generateKey(\n  threadId: string,\n  checkpointNamespace: string,\n  checkpointId: string\n) {\n  return JSON.stringify([threadId, checkpointNamespace, checkpointId]);\n}\n\nfunction _parseKey(key: string) {\n  const [threadId, checkpointNamespace, checkpointId] = JSON.parse(key);\n  return { threadId, checkpointNamespace, checkpointId };\n}\n\nexport class MemorySaver extends BaseCheckpointSaver {\n  // thread ID ->  checkpoint namespace -> checkpoint ID -> checkpoint mapping\n  //\n  // Defense in depth against prototype pollution: the backing\n  // objects (and every nested level created below) use a null prototype, so\n  // even if a malicious key bypassed `assertSafeStorageKey` it could not reach\n  // `Object.prototype`. The guard remains the primary control; this is the\n  // structural safety net.\n  storage: Record<\n    string,\n    Record<string, Record<string, [Uint8Array, Uint8Array, string | undefined]>>\n  > = Object.create(null);\n\n  writes: Record<string, Record<string, [string, string, Uint8Array]>> =\n    Object.create(null);\n\n  constructor(serde?: SerializerProtocol) {\n    super(serde);\n  }\n\n  /** @internal */\n  async _migratePendingSends(\n    mutableCheckpoint: Checkpoint,\n    threadId: string,\n    checkpointNs: string,\n    parentCheckpointId: string\n  ) {\n    const deseriablizableCheckpoint = mutableCheckpoint;\n    const parentKey = _generateKey(threadId, checkpointNs, parentCheckpointId);\n\n    const pendingSends = await Promise.all(\n      Object.values(this.writes[parentKey] ?? {})\n        .filter(([_taskId, channel]) => channel === TASKS)\n        .map(\n          async ([_taskId, _channel, writes]) =>\n            await this.serde.loadsTyped(\"json\", writes)\n        )\n    );\n\n    deseriablizableCheckpoint.channel_values ??= {};\n    deseriablizableCheckpoint.channel_values[TASKS] = pendingSends;\n\n    deseriablizableCheckpoint.channel_versions ??= {};\n    deseriablizableCheckpoint.channel_versions[TASKS] =\n      Object.keys(deseriablizableCheckpoint.channel_versions).length > 0\n        ? maxChannelVersion(\n            ...Object.values(deseriablizableCheckpoint.channel_versions)\n          )\n        : this.getNextVersion(undefined);\n  }\n\n  async getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined> {\n    const thread_id = config.configurable?.thread_id;\n    const checkpoint_ns = config.configurable?.checkpoint_ns ?? \"\";\n    let checkpoint_id = getCheckpointId(config);\n\n    // Defense in depth: every public entry that mutates state already\n    // validates these, but read paths must not return data sourced from\n    // prototype-chain lookups when an attacker passes the magic keys.\n    // `checkpoint_id` is intentionally allowed to be empty / undefined\n    // here because the downstream `if (checkpoint_id)` branch treats\n    // both as \"fetch the latest checkpoint\" rather than as a lookup key.\n    if (thread_id !== undefined) {\n      assertSafeStorageKey(\"thread_id\", thread_id);\n    }\n    assertSafeStorageKey(\"checkpoint_ns\", checkpoint_ns, { allowEmpty: true });\n    if (checkpoint_id) {\n      assertSafeStorageKey(\"checkpoint_id\", checkpoint_id);\n    }\n\n    if (checkpoint_id) {\n      const saved = this.storage[thread_id]?.[checkpoint_ns]?.[checkpoint_id];\n      if (saved !== undefined) {\n        const [checkpoint, metadata, parentCheckpointId] = saved;\n        const key = _generateKey(thread_id, checkpoint_ns, checkpoint_id);\n        const deserializedCheckpoint: Checkpoint = await this.serde.loadsTyped(\n          \"json\",\n          checkpoint\n        );\n\n        if (deserializedCheckpoint.v < 4 && parentCheckpointId !== undefined) {\n          await this._migratePendingSends(\n            deserializedCheckpoint,\n            thread_id,\n            checkpoint_ns,\n            parentCheckpointId\n          );\n        }\n\n        const pendingWrites: CheckpointPendingWrite[] = await Promise.all(\n          Object.values(this.writes[key] || {}).map(\n            async ([taskId, channel, value]) => {\n              return [\n                taskId,\n                channel,\n                await this.serde.loadsTyped(\"json\", value),\n              ];\n            }\n          )\n        );\n        const checkpointTuple: CheckpointTuple = {\n          config,\n          checkpoint: deserializedCheckpoint,\n          metadata: (await this.serde.loadsTyped(\n            \"json\",\n            metadata\n          )) as CheckpointMetadata,\n          pendingWrites,\n        };\n        if (parentCheckpointId !== undefined) {\n          checkpointTuple.parentConfig = {\n            configurable: {\n              thread_id,\n              checkpoint_ns,\n              checkpoint_id: parentCheckpointId,\n            },\n          };\n        }\n        return checkpointTuple;\n      }\n    } else {\n      const checkpoints = this.storage[thread_id]?.[checkpoint_ns];\n      if (checkpoints !== undefined) {\n        // eslint-disable-next-line prefer-destructuring\n        checkpoint_id = Object.keys(checkpoints).sort((a, b) =>\n          b.localeCompare(a)\n        )[0];\n        const saved = checkpoints[checkpoint_id];\n        const [checkpoint, metadata, parentCheckpointId] = saved;\n        const key = _generateKey(thread_id, checkpoint_ns, checkpoint_id);\n        const deserializedCheckpoint: Checkpoint = await this.serde.loadsTyped(\n          \"json\",\n          checkpoint\n        );\n\n        if (deserializedCheckpoint.v < 4 && parentCheckpointId !== undefined) {\n          await this._migratePendingSends(\n            deserializedCheckpoint,\n            thread_id,\n            checkpoint_ns,\n            parentCheckpointId\n          );\n        }\n\n        const pendingWrites: CheckpointPendingWrite[] = await Promise.all(\n          Object.values(this.writes[key] || {}).map(\n            async ([taskId, channel, value]) => {\n              return [\n                taskId,\n                channel,\n                await this.serde.loadsTyped(\"json\", value),\n              ];\n            }\n          )\n        );\n        const checkpointTuple: CheckpointTuple = {\n          config: {\n            configurable: {\n              thread_id,\n              checkpoint_id,\n              checkpoint_ns,\n            },\n          },\n          checkpoint: deserializedCheckpoint,\n          metadata: (await this.serde.loadsTyped(\n            \"json\",\n            metadata\n          )) as CheckpointMetadata,\n          pendingWrites,\n        };\n        if (parentCheckpointId !== undefined) {\n          checkpointTuple.parentConfig = {\n            configurable: {\n              thread_id,\n              checkpoint_ns,\n              checkpoint_id: parentCheckpointId,\n            },\n          };\n        }\n        return checkpointTuple;\n      }\n    }\n\n    return undefined;\n  }\n\n  async *list(\n    config: RunnableConfig,\n    options?: CheckpointListOptions\n  ): AsyncGenerator<CheckpointTuple> {\n    // eslint-disable-next-line prefer-const\n    let { before, limit, filter } = options ?? {};\n    if (config.configurable?.thread_id !== undefined) {\n      assertSafeStorageKey(\"thread_id\", config.configurable.thread_id);\n    }\n    if (config.configurable?.checkpoint_ns !== undefined) {\n      assertSafeStorageKey(\"checkpoint_ns\", config.configurable.checkpoint_ns, {\n        allowEmpty: true,\n      });\n    }\n    if (config.configurable?.checkpoint_id) {\n      assertSafeStorageKey(\"checkpoint_id\", config.configurable.checkpoint_id);\n    }\n    if (before?.configurable?.checkpoint_id) {\n      assertSafeStorageKey(\"checkpoint_id\", before.configurable.checkpoint_id);\n    }\n    const threadIds = config.configurable?.thread_id\n      ? [config.configurable?.thread_id]\n      : Object.keys(this.storage);\n    const configCheckpointNamespace = config.configurable?.checkpoint_ns;\n    const configCheckpointId = config.configurable?.checkpoint_id;\n\n    for (const threadId of threadIds) {\n      for (const checkpointNamespace of Object.keys(\n        this.storage[threadId] ?? {}\n      )) {\n        if (\n          configCheckpointNamespace !== undefined &&\n          checkpointNamespace !== configCheckpointNamespace\n        ) {\n          continue;\n        }\n        const checkpoints = this.storage[threadId]?.[checkpointNamespace] ?? {};\n        const sortedCheckpoints = Object.entries(checkpoints).sort((a, b) =>\n          b[0].localeCompare(a[0])\n        );\n\n        for (const [\n          checkpointId,\n          [checkpoint, metadataStr, parentCheckpointId],\n        ] of sortedCheckpoints) {\n          // Filter by checkpoint ID from config\n          if (configCheckpointId && checkpointId !== configCheckpointId) {\n            continue;\n          }\n\n          // Filter by checkpoint ID from before config\n          if (\n            before &&\n            before.configurable?.checkpoint_id &&\n            checkpointId >= before.configurable.checkpoint_id\n          ) {\n            continue;\n          }\n\n          // Parse metadata\n          const metadata = (await this.serde.loadsTyped(\n            \"json\",\n            metadataStr\n          )) as CheckpointMetadata;\n\n          if (\n            filter &&\n            !Object.entries(filter).every(\n              ([key, value]) =>\n                (metadata as unknown as Record<string, unknown>)[key] === value\n            )\n          ) {\n            continue;\n          }\n\n          // Limit search results\n          if (limit !== undefined) {\n            if (limit <= 0) break;\n            limit -= 1;\n          }\n\n          const key = _generateKey(threadId, checkpointNamespace, checkpointId);\n          const writes = Object.values(this.writes[key] || {});\n\n          const pendingWrites: CheckpointPendingWrite[] = await Promise.all(\n            writes.map(async ([taskId, channel, value]) => {\n              return [\n                taskId,\n                channel,\n                await this.serde.loadsTyped(\"json\", value),\n              ];\n            })\n          );\n\n          const deserializedCheckpoint = await this.serde.loadsTyped(\n            \"json\",\n            checkpoint\n          );\n\n          if (\n            deserializedCheckpoint.v < 4 &&\n            parentCheckpointId !== undefined\n          ) {\n            await this._migratePendingSends(\n              deserializedCheckpoint,\n              threadId,\n              checkpointNamespace,\n              parentCheckpointId\n            );\n          }\n\n          const checkpointTuple: CheckpointTuple = {\n            config: {\n              configurable: {\n                thread_id: threadId,\n                checkpoint_ns: checkpointNamespace,\n                checkpoint_id: checkpointId,\n              },\n            },\n            checkpoint: deserializedCheckpoint,\n            metadata,\n            pendingWrites,\n          };\n          if (parentCheckpointId !== undefined) {\n            checkpointTuple.parentConfig = {\n              configurable: {\n                thread_id: threadId,\n                checkpoint_ns: checkpointNamespace,\n                checkpoint_id: parentCheckpointId,\n              },\n            };\n          }\n          yield checkpointTuple;\n        }\n      }\n    }\n  }\n\n  async put(\n    config: RunnableConfig,\n    checkpoint: Checkpoint,\n    metadata: CheckpointMetadata\n  ): Promise<RunnableConfig> {\n    const preparedCheckpoint: Partial<Checkpoint> = copyCheckpoint(checkpoint);\n    const threadId = config.configurable?.thread_id;\n    const checkpointNamespace = config.configurable?.checkpoint_ns ?? \"\";\n    if (threadId === undefined) {\n      throw new Error(\n        `Failed to put checkpoint. The passed RunnableConfig is missing a required \"thread_id\" field in its \"configurable\" property. ` +\n          `When using a checkpointer, you must pass a \"thread_id\" so the checkpointer knows which conversation thread to persist state for. ` +\n          `Example: graph.stream(input, { configurable: { thread_id: \"my-thread-id\" } })`\n      );\n    }\n\n    assertSafeStorageKey(\"thread_id\", threadId);\n    assertSafeStorageKey(\"checkpoint_ns\", checkpointNamespace, {\n      allowEmpty: true,\n    });\n    assertSafeStorageKey(\"checkpoint_id\", checkpoint.id);\n\n    if (!this.storage[threadId]) {\n      this.storage[threadId] = Object.create(null);\n    }\n    if (!this.storage[threadId][checkpointNamespace]) {\n      this.storage[threadId][checkpointNamespace] = Object.create(null);\n    }\n\n    const [[, serializedCheckpoint], [, serializedMetadata]] =\n      await Promise.all([\n        this.serde.dumpsTyped(preparedCheckpoint),\n        this.serde.dumpsTyped(metadata),\n      ]);\n\n    this.storage[threadId][checkpointNamespace][checkpoint.id] = [\n      serializedCheckpoint,\n      serializedMetadata,\n      config.configurable?.checkpoint_id, // parent\n    ];\n\n    return {\n      configurable: {\n        thread_id: threadId,\n        checkpoint_ns: checkpointNamespace,\n        checkpoint_id: checkpoint.id,\n      },\n    };\n  }\n\n  async putWrites(\n    config: RunnableConfig,\n    writes: PendingWrite[],\n    taskId: string\n  ): Promise<void> {\n    const threadId = config.configurable?.thread_id;\n    const checkpointNamespace = config.configurable?.checkpoint_ns;\n    const checkpointId = config.configurable?.checkpoint_id;\n    if (threadId === undefined) {\n      throw new Error(\n        `Failed to put writes. The passed RunnableConfig is missing a required \"thread_id\" field in its \"configurable\" property. ` +\n          `When using a checkpointer, you must pass a \"thread_id\" so the checkpointer knows which conversation thread to persist state for. ` +\n          `Example: graph.stream(input, { configurable: { thread_id: \"my-thread-id\" } })`\n      );\n    }\n    if (checkpointId === undefined) {\n      throw new Error(\n        `Failed to put writes. The passed RunnableConfig is missing a required \"checkpoint_id\" field in its \"configurable\" property.`\n      );\n    }\n    assertSafeStorageKey(\"thread_id\", threadId);\n    assertSafeStorageKey(\"checkpoint_ns\", checkpointNamespace, {\n      allowEmpty: true,\n    });\n    assertSafeStorageKey(\"checkpoint_id\", checkpointId);\n    assertSafeStorageKey(\"task_id\", taskId);\n    const outerKey = _generateKey(threadId, checkpointNamespace, checkpointId);\n    const outerWrites_ = this.writes[outerKey];\n    if (this.writes[outerKey] === undefined) {\n      this.writes[outerKey] = Object.create(null);\n    }\n\n    await Promise.all(\n      writes.map(async ([channel, value], idx) => {\n        const [, serializedValue] = await this.serde.dumpsTyped(value);\n        const innerKey: [string, number] = [\n          taskId,\n          WRITES_IDX_MAP[channel] || idx,\n        ];\n        const innerKeyStr = `${innerKey[0]},${innerKey[1]}`;\n        if (innerKey[1] >= 0 && outerWrites_ && innerKeyStr in outerWrites_) {\n          return;\n        }\n        this.writes[outerKey][innerKeyStr] = [taskId, channel, serializedValue];\n      })\n    );\n  }\n\n  async deleteThread(threadId: string): Promise<void> {\n    assertSafeStorageKey(\"thread_id\", threadId);\n    delete this.storage[threadId];\n    for (const key of Object.keys(this.writes)) {\n      if (_parseKey(key).threadId === threadId) delete this.writes[key];\n    }\n  }\n\n  /**\n   * Override: walk the parent chain ONCE for all requested channels using\n   * direct storage access.\n   *\n   * Each channel terminates independently at the nearest ancestor whose\n   * stored `channel_values[ch]` is populated. Other channels keep walking\n   * until they find their own terminator or hit the root.\n   *\n   * The seed value (whether a `DeltaSnapshot` or a plain pre-delta migration\n   * blob) is the value AT that ancestor, prior to its own pending writes that\n   * produce the child. Those on-path writes — including the ones stored on the\n   * terminating ancestor — are always collected and replayed on top of the\n   * seed, so a thread migrated from a pre-delta channel does not drop the\n   * writes saved under the migration boundary checkpoint.\n   *\n   * @remarks Beta. See {@link BaseCheckpointSaver.getDeltaChannelHistory}.\n   */\n  async getDeltaChannelHistory(options: {\n    config: RunnableConfig;\n    channels: string[];\n  }): Promise<Record<string, DeltaChannelHistory>> {\n    const { config, channels } = options;\n    if (channels.length === 0) return {};\n\n    const threadId = config.configurable?.thread_id;\n    const checkpointNs = config.configurable?.checkpoint_ns ?? \"\";\n    const checkpointId = getCheckpointId(config);\n\n    if (threadId !== undefined) assertSafeStorageKey(\"thread_id\", threadId);\n    assertSafeStorageKey(\"checkpoint_ns\", checkpointNs, { allowEmpty: true });\n\n    const nsStorage = this.storage[threadId]?.[checkpointNs] ?? {};\n\n    // Build the parent chain starting at the target's parent (the target's\n    // own pending writes are for the next super-step and excluded).\n    const chain: string[] = [];\n    const targetEntry = checkpointId ? nsStorage[checkpointId] : undefined;\n    let current: string | undefined = targetEntry?.[2];\n    while (current !== undefined) {\n      const entry = nsStorage[current];\n      if (entry === undefined) break;\n      chain.push(current);\n      current = entry[2];\n    }\n\n    const collectedByCh: Record<string, CheckpointPendingWrite[]> = {};\n    const seedByCh: Record<string, unknown> = {};\n    const remaining = new Set(channels);\n    for (const ch of channels) collectedByCh[ch] = [];\n\n    for (const cpId of chain) {\n      if (remaining.size === 0) break;\n      const entry = nsStorage[cpId];\n      const ckpt: Checkpoint | undefined =\n        entry !== undefined\n          ? await this.serde.loadsTyped(\"json\", entry[0])\n          : undefined;\n\n      const blobValueByCh: Record<string, unknown> = {};\n      const terminatedHere = new Set<string>();\n      if (ckpt !== undefined) {\n        for (const ch of remaining) {\n          if (\n            Object.prototype.hasOwnProperty.call(ckpt.channel_values, ch) &&\n            ckpt.channel_values[ch] !== undefined\n          ) {\n            blobValueByCh[ch] = ckpt.channel_values[ch];\n            terminatedHere.add(ch);\n          }\n        }\n      }\n\n      const stepWritesKey = _generateKey(threadId, checkpointNs, cpId);\n      const stepWrites = Object.entries(this.writes[stepWritesKey] ?? {});\n      // Sort by [taskId, idx] descending to mirror the Python walk order;\n      // the full list is reversed once at the end to get oldest→newest.\n      stepWrites.sort(([a], [b]) => {\n        const [aTask, aIdx] = a.split(\",\");\n        const [bTask, bIdx] = b.split(\",\");\n        if (aTask !== bTask) return aTask < bTask ? 1 : -1;\n        return Number(bIdx) - Number(aIdx);\n      });\n      for (const [, [tid, ch, serialized]] of stepWrites) {\n        if (!remaining.has(ch)) continue;\n        // Collect on-path writes regardless of seed type. A plain (pre-delta\n        // migration) blob is the settled value AT that ancestor; its own\n        // pending writes produce the child and must still be replayed, just\n        // like a `DeltaSnapshot` seed. Skipping them would drop post-migration\n        // writes saved under the migration boundary checkpoint.\n        collectedByCh[ch].push([\n          tid,\n          ch,\n          await this.serde.loadsTyped(\"json\", serialized),\n        ]);\n      }\n\n      for (const ch of terminatedHere) {\n        seedByCh[ch] = blobValueByCh[ch];\n        remaining.delete(ch);\n      }\n    }\n\n    const result: Record<string, DeltaChannelHistory> = {};\n    for (const ch of channels) {\n      const entryH: DeltaChannelHistory = {\n        writes: collectedByCh[ch].slice().reverse(),\n      };\n      if (Object.prototype.hasOwnProperty.call(seedByCh, ch)) {\n        entryH.seed = seedByCh[ch];\n      }\n      result[ch] = entryH;\n    }\n    return result;\n  }\n}\n"],"mappings":"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"}