@langchain/langgraph-checkpoint
Version:
Library with base interfaces for LangGraph checkpoint savers.
96 lines • 3.13 kB
JavaScript
import { uuid6 } from "./id.js";
import { ERROR, INTERRUPT, RESUME, SCHEDULED, } from "./serde/types.js";
import { JsonPlusSerializer } from "./serde/jsonplus.js";
export function deepCopy(obj) {
if (typeof obj !== "object" || obj === null) {
return obj;
}
const newObj = Array.isArray(obj) ? [] : {};
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
newObj[key] = deepCopy(obj[key]);
}
}
return newObj;
}
/** @hidden */
export function emptyCheckpoint() {
return {
v: 1,
id: uuid6(-2),
ts: new Date().toISOString(),
channel_values: {},
channel_versions: {},
versions_seen: {},
pending_sends: [],
};
}
/** @hidden */
export function copyCheckpoint(checkpoint) {
return {
v: checkpoint.v,
id: checkpoint.id,
ts: checkpoint.ts,
channel_values: { ...checkpoint.channel_values },
channel_versions: { ...checkpoint.channel_versions },
versions_seen: deepCopy(checkpoint.versions_seen),
pending_sends: [...checkpoint.pending_sends],
};
}
export class BaseCheckpointSaver {
constructor(serde) {
Object.defineProperty(this, "serde", {
enumerable: true,
configurable: true,
writable: true,
value: new JsonPlusSerializer()
});
this.serde = serde || this.serde;
}
async get(config) {
const value = await this.getTuple(config);
return value ? value.checkpoint : undefined;
}
/**
* Generate the next version ID for a channel.
*
* Default is to use integer versions, incrementing by 1. If you override, you can use str/int/float versions,
* as long as they are monotonically increasing.
*/
getNextVersion(current, _channel) {
if (typeof current === "string") {
throw new Error("Please override this method to use string versions.");
}
return (current !== undefined && typeof current === "number" ? current + 1 : 1);
}
}
export function compareChannelVersions(a, b) {
if (typeof a === "number" && typeof b === "number") {
return Math.sign(a - b);
}
return String(a).localeCompare(String(b));
}
export function maxChannelVersion(...versions) {
return versions.reduce((max, version, idx) => {
if (idx === 0)
return version;
return compareChannelVersions(max, version) >= 0 ? max : version;
});
}
/**
* Mapping from error type to error index.
* Regular writes just map to their index in the list of writes being saved.
* Special writes (e.g. errors) map to negative indices, to avoid those writes from
* conflicting with regular writes.
* Each Checkpointer implementation should use this mapping in put_writes.
*/
export const WRITES_IDX_MAP = {
[ERROR]: -1,
[SCHEDULED]: -2,
[INTERRUPT]: -3,
[RESUME]: -4,
};
export function getCheckpointId(config) {
return (config.configurable?.checkpoint_id || config.configurable?.thread_ts || "");
}
//# sourceMappingURL=base.js.map