{"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  PendingWrite,\n} from \"./types.js\";\nimport { TASKS } from \"./serde/types.js\";\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  storage: Record<\n    string,\n    Record<string, Record<string, [Uint8Array, Uint8Array, string | undefined]>>\n  > = {};\n\n  writes: Record<string, Record<string, [string, string, Uint8Array]>> = {};\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    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    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    if (!this.storage[threadId]) {\n      this.storage[threadId] = {};\n    }\n    if (!this.storage[threadId][checkpointNamespace]) {\n      this.storage[threadId][checkpointNamespace] = {};\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    const outerKey = _generateKey(threadId, checkpointNamespace, checkpointId);\n    const outerWrites_ = this.writes[outerKey];\n    if (this.writes[outerKey] === undefined) {\n      this.writes[outerKey] = {};\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    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"],"mappings":"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"}