@langchain/langgraph-checkpoint-redis 0.0.2 → 1.0.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shallow.cjs","names":["sortedObj: Record<string, any>","sorted: Record<string, any>","BaseCheckpointSaver","prevCheckpointData: any","prevCheckpointId: string | null","jsonDoc: any","pendingWrites: Array<[string, string, any]> | undefined","queryParts: string[]","error: any","limit","writeKeys: string[]","zaddArgs: Record<string, number>","pendingWrites: Array<[string, string, any]>","sanitized: any"],"sources":["../src/shallow.ts"],"sourcesContent":["import {\n BaseCheckpointSaver,\n ChannelVersions,\n Checkpoint,\n CheckpointListOptions,\n CheckpointMetadata,\n CheckpointTuple,\n PendingWrite,\n uuid6,\n} from \"@langchain/langgraph-checkpoint\";\nimport { RunnableConfig } from \"@langchain/core/runnables\";\nimport { createClient } from \"redis\";\n\nexport interface TTLConfig {\n defaultTTL?: number; // TTL in minutes\n refreshOnRead?: boolean; // Whether to refresh TTL when reading\n}\n\n// Helper function for deterministic object comparison\nfunction deterministicStringify(obj: any): string {\n if (obj === null || typeof obj !== \"object\") {\n return JSON.stringify(obj);\n }\n if (Array.isArray(obj)) {\n return JSON.stringify(obj.map((item) => deterministicStringify(item)));\n }\n const sortedObj: Record<string, any> = {};\n const sortedKeys = Object.keys(obj).sort();\n for (const key of sortedKeys) {\n sortedObj[key] = obj[key];\n }\n return JSON.stringify(sortedObj, (_, value) => {\n if (value !== null && typeof value === \"object\" && !Array.isArray(value)) {\n const sorted: Record<string, any> = {};\n const keys = Object.keys(value).sort();\n for (const k of keys) {\n sorted[k] = value[k];\n }\n return sorted;\n }\n return value;\n });\n}\n\nconst SCHEMAS = [\n {\n index: \"checkpoints\",\n prefix: \"checkpoint:\",\n schema: {\n \"$.thread_id\": { type: \"TAG\", AS: \"thread_id\" },\n \"$.checkpoint_ns\": { type: \"TAG\", AS: \"checkpoint_ns\" },\n \"$.checkpoint_id\": { type: \"TAG\", AS: \"checkpoint_id\" },\n \"$.parent_checkpoint_id\": { type: \"TAG\", AS: \"parent_checkpoint_id\" },\n \"$.checkpoint_ts\": { type: \"NUMERIC\", AS: \"checkpoint_ts\" },\n \"$.has_writes\": { type: \"TAG\", AS: \"has_writes\" },\n \"$.source\": { type: \"TAG\", AS: \"source\" },\n \"$.step\": { type: \"NUMERIC\", AS: \"step\" },\n },\n },\n {\n index: \"checkpoint_writes\",\n prefix: \"checkpoint_write:\",\n schema: {\n \"$.thread_id\": { type: \"TAG\", AS: \"thread_id\" },\n \"$.checkpoint_ns\": { type: \"TAG\", AS: \"checkpoint_ns\" },\n \"$.checkpoint_id\": { type: \"TAG\", AS: \"checkpoint_id\" },\n \"$.task_id\": { type: \"TAG\", AS: \"task_id\" },\n \"$.idx\": { type: \"NUMERIC\", AS: \"idx\" },\n \"$.channel\": { type: \"TAG\", AS: \"channel\" },\n \"$.type\": { type: \"TAG\", AS: \"type\" },\n },\n },\n];\n\n/**\n * ShallowRedisSaver - A Redis checkpoint saver that only keeps the latest checkpoint per thread.\n *\n * This is a memory-optimized variant that:\n * - Only stores the most recent checkpoint for each thread\n * - Stores channel values inline (no separate blob storage)\n * - Automatically cleans up old checkpoints and writes when new ones are added\n * - Reduces storage usage for applications that don't need checkpoint history\n */\nexport class ShallowRedisSaver extends BaseCheckpointSaver {\n private client: any;\n private ttlConfig?: TTLConfig;\n\n constructor(client: any, ttlConfig?: TTLConfig) {\n super();\n this.client = client;\n this.ttlConfig = ttlConfig;\n }\n\n static async fromUrl(\n url: string,\n ttlConfig?: TTLConfig\n ): Promise<ShallowRedisSaver> {\n const client = createClient({ url });\n await client.connect();\n const saver = new ShallowRedisSaver(client, ttlConfig);\n await saver.ensureIndexes();\n return saver;\n }\n\n async get(config: RunnableConfig): Promise<Checkpoint | undefined> {\n const tuple = await this.getTuple(config);\n return tuple?.checkpoint;\n }\n\n async put(\n config: RunnableConfig,\n checkpoint: Checkpoint,\n metadata: CheckpointMetadata,\n _newVersions: ChannelVersions\n ): Promise<RunnableConfig> {\n await this.ensureIndexes();\n\n const threadId = config.configurable?.thread_id;\n const checkpointNs = config.configurable?.checkpoint_ns ?? \"\";\n const parentCheckpointId = config.configurable?.checkpoint_id;\n\n if (!threadId) {\n throw new Error(\"thread_id is required\");\n }\n\n const checkpointId = checkpoint.id || uuid6(0);\n\n // In shallow mode, we use a single key per thread (no checkpoint_id in key)\n const key = `checkpoint:${threadId}:${checkpointNs}:shallow`;\n\n // Get the previous checkpoint to know what to clean up\n let prevCheckpointData: any = null;\n let prevCheckpointId: string | null = null;\n try {\n prevCheckpointData = await this.client.json.get(key);\n if (prevCheckpointData && typeof prevCheckpointData === \"object\") {\n prevCheckpointId = prevCheckpointData.checkpoint_id;\n }\n } catch (error) {\n // Key doesn't exist yet, that's fine\n }\n\n // Clean up old checkpoint and related data if it exists\n if (prevCheckpointId && prevCheckpointId !== checkpointId) {\n await this.cleanupOldCheckpoint(threadId, checkpointNs, prevCheckpointId);\n }\n\n // Store channel values inline - no blob storage in shallow mode\n const checkpointCopy = {\n ...checkpoint,\n channel_values: checkpoint.channel_values || {},\n // Remove channel_blobs if present\n channel_blobs: undefined,\n };\n\n // Structure matching Python implementation\n const jsonDoc: any = {\n thread_id: threadId,\n checkpoint_ns: checkpointNs,\n checkpoint_id: checkpointId,\n parent_checkpoint_id: parentCheckpointId || null,\n checkpoint: checkpointCopy,\n metadata: this.sanitizeMetadata(metadata),\n checkpoint_ts: Date.now(),\n has_writes: \"false\",\n };\n\n // Store metadata fields at top-level for searching\n this.addSearchableMetadataFields(jsonDoc, metadata);\n\n // Use Redis JSON commands\n await this.client.json.set(key, \"$\", jsonDoc);\n\n // Apply TTL if configured\n if (this.ttlConfig?.defaultTTL) {\n await this.applyTTL(key);\n }\n\n return {\n configurable: {\n thread_id: threadId,\n checkpoint_ns: checkpointNs,\n checkpoint_id: checkpointId,\n },\n };\n }\n\n async getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined> {\n const threadId = config.configurable?.thread_id;\n const checkpointNs = config.configurable?.checkpoint_ns ?? \"\";\n const checkpointId = config.configurable?.checkpoint_id;\n\n if (!threadId) {\n return undefined;\n }\n\n // In shallow mode, we use a single key per thread\n const key = `checkpoint:${threadId}:${checkpointNs}:shallow`;\n const jsonDoc = await this.client.json.get(key);\n\n if (!jsonDoc) {\n return undefined;\n }\n\n // If a specific checkpoint_id was requested, check if it matches\n if (checkpointId && jsonDoc.checkpoint_id !== checkpointId) {\n return undefined;\n }\n\n // Refresh TTL if configured\n if (this.ttlConfig?.refreshOnRead && this.ttlConfig?.defaultTTL) {\n await this.applyTTL(key);\n }\n\n // Channel values are stored inline in shallow mode\n const checkpoint = {\n ...jsonDoc.checkpoint,\n channel_values: jsonDoc.checkpoint.channel_values || {},\n };\n\n // Load pending writes if they exist\n let pendingWrites: Array<[string, string, any]> | undefined;\n if (jsonDoc.has_writes === \"true\") {\n pendingWrites = await this.loadPendingWrites(\n jsonDoc.thread_id,\n jsonDoc.checkpoint_ns,\n jsonDoc.checkpoint_id\n );\n }\n\n return this.createCheckpointTuple(jsonDoc, checkpoint, pendingWrites);\n }\n\n async *list(\n config: RunnableConfig | null,\n options?: CheckpointListOptions & { filter?: CheckpointMetadata }\n ): AsyncGenerator<CheckpointTuple> {\n await this.ensureIndexes();\n\n // In shallow mode, we only return the latest checkpoint per thread\n if (config?.configurable?.thread_id) {\n // Single thread case\n const tuple = await this.getTuple(config);\n if (tuple) {\n // Apply filter if provided\n if (options?.filter) {\n if (this.checkMetadataFilterMatch(tuple.metadata, options.filter)) {\n yield tuple;\n }\n } else {\n yield tuple;\n }\n }\n } else {\n // All threads case - use search\n const queryParts: string[] = [];\n\n // Add metadata filters\n if (options?.filter) {\n for (const [key, value] of Object.entries(options.filter)) {\n if (value === undefined) {\n // Skip undefined filters\n } else if (value === null) {\n // Skip null values for RediSearch query, will handle in post-processing\n } else if (typeof value === \"string\") {\n queryParts.push(`(@${key}:{${value}})`);\n } else if (typeof value === \"number\") {\n queryParts.push(`(@${key}:[${value} ${value}])`);\n }\n }\n }\n\n if (queryParts.length === 0) {\n queryParts.push(\"*\");\n }\n\n const query = queryParts.join(\" \");\n const limit = options?.limit ?? 10;\n\n try {\n const results = await this.client.ft.search(\"checkpoints\", query, {\n LIMIT: { from: 0, size: limit * 2 }, // Get more since we'll deduplicate\n SORTBY: { BY: \"checkpoint_ts\", DIRECTION: \"DESC\" },\n });\n\n // In shallow mode, deduplicate by thread_id\n const seenThreads = new Set<string>();\n let yieldCount = 0;\n\n for (const doc of results.documents) {\n if (yieldCount >= limit) break;\n\n const jsonDoc = doc.value;\n const threadKey = `${jsonDoc.thread_id}:${jsonDoc.checkpoint_ns}`;\n\n // Skip if we've already seen this thread\n if (seenThreads.has(threadKey)) {\n continue;\n }\n seenThreads.add(threadKey);\n\n // Check null filters manually if needed\n if (options?.filter) {\n if (\n !this.checkMetadataFilterMatch(jsonDoc.metadata, options.filter)\n ) {\n continue;\n }\n }\n\n // Channel values are inline in shallow mode\n const checkpoint = {\n ...jsonDoc.checkpoint,\n channel_values: jsonDoc.checkpoint.channel_values || {},\n };\n\n yield this.createCheckpointTuple(jsonDoc, checkpoint);\n yieldCount++;\n }\n } catch (error: any) {\n if (error.message?.includes(\"no such index\")) {\n // Index doesn't exist yet, fall back to scanning all shallow checkpoints\n const pattern = `checkpoint:*:*:shallow`;\n const keys = await this.client.keys(pattern);\n\n if (keys.length === 0) {\n return;\n }\n\n // Sort keys to have consistent ordering\n keys.sort().reverse();\n\n // Get unique threads\n const seenThreads = new Set<string>();\n let yieldCount = 0;\n const limit = options?.limit ?? 10;\n\n for (const key of keys) {\n if (yieldCount >= limit) break;\n\n const jsonDoc = await this.client.json.get(key);\n if (!jsonDoc) continue;\n\n const threadKey = `${jsonDoc.thread_id}:${jsonDoc.checkpoint_ns}`;\n\n // Skip if we've already seen this thread\n if (seenThreads.has(threadKey)) {\n continue;\n }\n seenThreads.add(threadKey);\n\n // Check filter if provided\n if (options?.filter) {\n if (\n !this.checkMetadataFilterMatch(jsonDoc.metadata, options.filter)\n ) {\n continue;\n }\n }\n\n // Channel values are inline in shallow mode\n const checkpoint = {\n ...jsonDoc.checkpoint,\n channel_values: jsonDoc.checkpoint.channel_values || {},\n };\n\n yield this.createCheckpointTuple(jsonDoc, checkpoint);\n yieldCount++;\n }\n return;\n }\n throw error;\n }\n }\n }\n\n async putWrites(\n config: RunnableConfig,\n writes: PendingWrite[],\n taskId: string\n ): Promise<void> {\n await this.ensureIndexes();\n\n const threadId = config.configurable?.thread_id;\n const checkpointNs = config.configurable?.checkpoint_ns ?? \"\";\n const checkpointId = config.configurable?.checkpoint_id;\n\n if (!threadId || !checkpointId) {\n throw new Error(\"thread_id and checkpoint_id are required\");\n }\n\n // In shallow mode, we overwrite all writes for the task\n // First, clean up old writes for this task\n const writePattern = `checkpoint_write:${threadId}:${checkpointNs}:${checkpointId}:${taskId}:*`;\n const oldWriteKeys = await this.client.keys(writePattern);\n if (oldWriteKeys.length > 0) {\n await this.client.del(oldWriteKeys);\n }\n\n // Store new writes\n const writeKeys: string[] = [];\n for (let idx = 0; idx < writes.length; idx++) {\n const [channel, value] = writes[idx];\n const writeKey = `checkpoint_write:${threadId}:${checkpointNs}:${checkpointId}:${taskId}:${idx}`;\n writeKeys.push(writeKey);\n\n const writeDoc = {\n thread_id: threadId,\n checkpoint_ns: checkpointNs,\n checkpoint_id: checkpointId,\n task_id: taskId,\n idx: idx,\n channel: channel,\n type: typeof value === \"object\" ? \"json\" : \"string\",\n value: value,\n };\n\n await this.client.json.set(writeKey, \"$\", writeDoc);\n }\n\n // Register write keys in sorted set for efficient retrieval\n if (writeKeys.length > 0) {\n const zsetKey = `write_keys_zset:${threadId}:${checkpointNs}:${checkpointId}`;\n\n // Clear existing entries for this task and add new ones\n const zaddArgs: Record<string, number> = {};\n writeKeys.forEach((key, idx) => {\n zaddArgs[key] = idx;\n });\n await this.client.zAdd(\n zsetKey,\n Object.entries(zaddArgs).map(([key, score]) => ({ score, value: key }))\n );\n\n // Apply TTL to write keys and zset if configured\n if (this.ttlConfig?.defaultTTL) {\n await this.applyTTL(...writeKeys, zsetKey);\n }\n }\n\n // Update checkpoint to indicate it has writes\n const checkpointKey = `checkpoint:${threadId}:${checkpointNs}:shallow`;\n const checkpointExists = await this.client.exists(checkpointKey);\n if (checkpointExists) {\n const currentDoc = await this.client.json.get(checkpointKey);\n if (currentDoc) {\n currentDoc.has_writes = \"true\";\n await this.client.json.set(checkpointKey, \"$\", currentDoc);\n }\n }\n }\n\n async deleteThread(threadId: string): Promise<void> {\n // Delete shallow checkpoints\n const checkpointPattern = `checkpoint:${threadId}:*:shallow`;\n const checkpointKeys = await this.client.keys(checkpointPattern);\n\n if (checkpointKeys.length > 0) {\n await this.client.del(checkpointKeys);\n }\n\n // Delete writes\n const writesPattern = `checkpoint_write:${threadId}:*`;\n const writesKeys = await this.client.keys(writesPattern);\n\n if (writesKeys.length > 0) {\n await this.client.del(writesKeys);\n }\n\n // Delete write registries\n const zsetPattern = `write_keys_zset:${threadId}:*`;\n const zsetKeys = await this.client.keys(zsetPattern);\n\n if (zsetKeys.length > 0) {\n await this.client.del(zsetKeys);\n }\n }\n\n async end(): Promise<void> {\n await this.client.quit();\n }\n\n // Helper method to add searchable metadata fields\n private addSearchableMetadataFields(\n jsonDoc: any,\n metadata?: CheckpointMetadata\n ): void {\n if (!metadata) return;\n\n // Add common searchable fields at top level\n if (\"source\" in metadata) {\n jsonDoc.source = metadata.source;\n }\n if (\"step\" in metadata) {\n jsonDoc.step = metadata.step;\n }\n if (\"writes\" in metadata) {\n // Writes field needs to be JSON stringified for TAG search\n jsonDoc.writes =\n typeof metadata.writes === \"object\"\n ? JSON.stringify(metadata.writes)\n : metadata.writes;\n }\n if (\"score\" in metadata) {\n jsonDoc.score = metadata.score;\n }\n }\n\n // Helper method to create checkpoint tuple from json document\n private createCheckpointTuple(\n jsonDoc: any,\n checkpoint: Checkpoint,\n pendingWrites?: Array<[string, string, any]>\n ): CheckpointTuple {\n return {\n config: {\n configurable: {\n thread_id: jsonDoc.thread_id,\n checkpoint_ns: jsonDoc.checkpoint_ns,\n checkpoint_id: jsonDoc.checkpoint_id,\n },\n },\n checkpoint,\n metadata: jsonDoc.metadata,\n parentConfig: jsonDoc.parent_checkpoint_id\n ? {\n configurable: {\n thread_id: jsonDoc.thread_id,\n checkpoint_ns: jsonDoc.checkpoint_ns,\n checkpoint_id: jsonDoc.parent_checkpoint_id,\n },\n }\n : undefined,\n pendingWrites,\n };\n }\n\n // Helper method to apply TTL to keys\n private async applyTTL(...keys: string[]): Promise<void> {\n if (!this.ttlConfig?.defaultTTL) return;\n\n const ttlSeconds = Math.floor(this.ttlConfig.defaultTTL * 60);\n const results = await Promise.allSettled(\n keys.map((key) => this.client.expire(key, ttlSeconds))\n );\n\n // Log any failures but don't throw - TTL is best effort\n for (let i = 0; i < results.length; i++) {\n if (results[i].status === \"rejected\") {\n console.warn(\n `Failed to set TTL for key ${keys[i]}:`,\n (results[i] as PromiseRejectedResult).reason\n );\n }\n }\n }\n\n // Helper method to load pending writes\n private async loadPendingWrites(\n threadId: string,\n checkpointNs: string,\n checkpointId: string\n ): Promise<Array<[string, string, any]> | undefined> {\n const zsetKey = `write_keys_zset:${threadId}:${checkpointNs}:${checkpointId}`;\n const writeKeys = await this.client.zRange(zsetKey, 0, -1);\n\n if (writeKeys.length === 0) {\n return undefined;\n }\n\n const pendingWrites: Array<[string, string, any]> = [];\n for (const writeKey of writeKeys) {\n const writeDoc = await this.client.json.get(writeKey);\n if (writeDoc) {\n pendingWrites.push([\n writeDoc.task_id,\n writeDoc.channel,\n writeDoc.value,\n ]);\n }\n }\n\n return pendingWrites;\n }\n\n // Helper method to check metadata filter matches\n private checkMetadataFilterMatch(\n metadata: any,\n filter: CheckpointMetadata\n ): boolean {\n for (const [key, value] of Object.entries(filter)) {\n const metadataValue = metadata?.[key];\n if (value === null) {\n if (!(key in (metadata || {})) || metadataValue !== null) {\n return false;\n }\n } else if (typeof value === \"object\" && !Array.isArray(value)) {\n // Deep comparison for objects with deterministic key ordering\n if (typeof metadataValue !== \"object\" || metadataValue === null) {\n return false;\n }\n if (\n deterministicStringify(value) !==\n deterministicStringify(metadataValue)\n ) {\n return false;\n }\n } else if (metadataValue !== value) {\n return false;\n }\n }\n return true;\n }\n\n private async cleanupOldCheckpoint(\n threadId: string,\n checkpointNs: string,\n oldCheckpointId: string\n ): Promise<void> {\n // Clean up old writes\n const writePattern = `checkpoint_write:${threadId}:${checkpointNs}:${oldCheckpointId}:*`;\n const oldWriteKeys = await this.client.keys(writePattern);\n if (oldWriteKeys.length > 0) {\n await this.client.del(oldWriteKeys);\n }\n\n // Clean up write registry\n const zsetKey = `write_keys_zset:${threadId}:${checkpointNs}:${oldCheckpointId}`;\n await this.client.del(zsetKey);\n\n // Note: We don't clean up blob keys in shallow mode since we store inline\n // But for completeness, clean up any legacy blob keys if they exist\n const blobPattern = `checkpoint_blob:${threadId}:${checkpointNs}:${oldCheckpointId}:*`;\n const oldBlobKeys = await this.client.keys(blobPattern);\n if (oldBlobKeys.length > 0) {\n await this.client.del(oldBlobKeys);\n }\n }\n\n private sanitizeMetadata(metadata: CheckpointMetadata): CheckpointMetadata {\n if (!metadata) return {} as CheckpointMetadata;\n\n const sanitized: any = {};\n for (const [key, value] of Object.entries(metadata)) {\n // Remove null characters from keys and string values\n // eslint-disable-next-line no-control-regex\n const sanitizedKey = key.replace(/\\x00/g, \"\");\n sanitized[sanitizedKey] =\n // eslint-disable-next-line no-control-regex\n typeof value === \"string\" ? value.replace(/\\x00/g, \"\") : value;\n }\n return sanitized as CheckpointMetadata;\n }\n\n private async ensureIndexes(): Promise<void> {\n for (const schema of SCHEMAS) {\n try {\n // Try to create the index\n await this.client.ft.create(schema.index, schema.schema, {\n ON: \"JSON\",\n PREFIX: schema.prefix,\n });\n } catch (error: any) {\n // Ignore if index already exists\n if (!error.message?.includes(\"Index already exists\")) {\n console.error(\n `Failed to create index ${schema.index}:`,\n error.message\n );\n }\n }\n }\n }\n}\n"],"mappings":";;;;;AAmBA,SAAS,uBAAuB,KAAkB;AAChD,KAAI,QAAQ,QAAQ,OAAO,QAAQ,SACjC,QAAO,KAAK,UAAU;AAExB,KAAI,MAAM,QAAQ,KAChB,QAAO,KAAK,UAAU,IAAI,KAAK,SAAS,uBAAuB;CAEjE,MAAMA,YAAiC;CACvC,MAAM,aAAa,OAAO,KAAK,KAAK;AACpC,MAAK,MAAM,OAAO,WAChB,WAAU,OAAO,IAAI;AAEvB,QAAO,KAAK,UAAU,YAAY,GAAG,UAAU;AAC7C,MAAI,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,QAAQ;GACxE,MAAMC,SAA8B;GACpC,MAAM,OAAO,OAAO,KAAK,OAAO;AAChC,QAAK,MAAM,KAAK,KACd,QAAO,KAAK,MAAM;AAEpB,UAAO;;AAET,SAAO;;;AAIX,MAAM,UAAU,CACd;CACE,OAAO;CACP,QAAQ;CACR,QAAQ;EACN,eAAe;GAAE,MAAM;GAAO,IAAI;;EAClC,mBAAmB;GAAE,MAAM;GAAO,IAAI;;EACtC,mBAAmB;GAAE,MAAM;GAAO,IAAI;;EACtC,0BAA0B;GAAE,MAAM;GAAO,IAAI;;EAC7C,mBAAmB;GAAE,MAAM;GAAW,IAAI;;EAC1C,gBAAgB;GAAE,MAAM;GAAO,IAAI;;EACnC,YAAY;GAAE,MAAM;GAAO,IAAI;;EAC/B,UAAU;GAAE,MAAM;GAAW,IAAI;;;GAGrC;CACE,OAAO;CACP,QAAQ;CACR,QAAQ;EACN,eAAe;GAAE,MAAM;GAAO,IAAI;;EAClC,mBAAmB;GAAE,MAAM;GAAO,IAAI;;EACtC,mBAAmB;GAAE,MAAM;GAAO,IAAI;;EACtC,aAAa;GAAE,MAAM;GAAO,IAAI;;EAChC,SAAS;GAAE,MAAM;GAAW,IAAI;;EAChC,aAAa;GAAE,MAAM;GAAO,IAAI;;EAChC,UAAU;GAAE,MAAM;GAAO,IAAI;;;;;;;;;;;;;AAcnC,IAAa,oBAAb,MAAa,0BAA0BC,qDAAoB;CACzD,AAAQ;CACR,AAAQ;CAER,YAAY,QAAa,WAAuB;AAC9C;AACA,OAAK,SAAS;AACd,OAAK,YAAY;;CAGnB,aAAa,QACX,KACA,WAC4B;EAC5B,MAAM,iCAAsB,EAAE;AAC9B,QAAM,OAAO;EACb,MAAM,QAAQ,IAAI,kBAAkB,QAAQ;AAC5C,QAAM,MAAM;AACZ,SAAO;;CAGT,MAAM,IAAI,QAAyD;EACjE,MAAM,QAAQ,MAAM,KAAK,SAAS;AAClC,SAAO,OAAO;;CAGhB,MAAM,IACJ,QACA,YACA,UACA,cACyB;AACzB,QAAM,KAAK;EAEX,MAAM,WAAW,OAAO,cAAc;EACtC,MAAM,eAAe,OAAO,cAAc,iBAAiB;EAC3D,MAAM,qBAAqB,OAAO,cAAc;AAEhD,MAAI,CAAC,SACH,OAAM,IAAI,MAAM;EAGlB,MAAM,eAAe,WAAW,kDAAY;EAG5C,MAAM,MAAM,cAAc,SAAS,GAAG,aAAa;EAGnD,IAAIC,qBAA0B;EAC9B,IAAIC,mBAAkC;AACtC,MAAI;AACF,wBAAqB,MAAM,KAAK,OAAO,KAAK,IAAI;AAChD,OAAI,sBAAsB,OAAO,uBAAuB,SACtD,oBAAmB,mBAAmB;WAEjC,OAAO;AAKhB,MAAI,oBAAoB,qBAAqB,aAC3C,OAAM,KAAK,qBAAqB,UAAU,cAAc;EAI1D,MAAM,iBAAiB;GACrB,GAAG;GACH,gBAAgB,WAAW,kBAAkB;GAE7C,eAAe;;EAIjB,MAAMC,UAAe;GACnB,WAAW;GACX,eAAe;GACf,eAAe;GACf,sBAAsB,sBAAsB;GAC5C,YAAY;GACZ,UAAU,KAAK,iBAAiB;GAChC,eAAe,KAAK;GACpB,YAAY;;AAId,OAAK,4BAA4B,SAAS;AAG1C,QAAM,KAAK,OAAO,KAAK,IAAI,KAAK,KAAK;AAGrC,MAAI,KAAK,WAAW,WAClB,OAAM,KAAK,SAAS;AAGtB,SAAO,EACL,cAAc;GACZ,WAAW;GACX,eAAe;GACf,eAAe;;;CAKrB,MAAM,SAAS,QAA8D;EAC3E,MAAM,WAAW,OAAO,cAAc;EACtC,MAAM,eAAe,OAAO,cAAc,iBAAiB;EAC3D,MAAM,eAAe,OAAO,cAAc;AAE1C,MAAI,CAAC,SACH,QAAO;EAIT,MAAM,MAAM,cAAc,SAAS,GAAG,aAAa;EACnD,MAAM,UAAU,MAAM,KAAK,OAAO,KAAK,IAAI;AAE3C,MAAI,CAAC,QACH,QAAO;AAIT,MAAI,gBAAgB,QAAQ,kBAAkB,aAC5C,QAAO;AAIT,MAAI,KAAK,WAAW,iBAAiB,KAAK,WAAW,WACnD,OAAM,KAAK,SAAS;EAItB,MAAM,aAAa;GACjB,GAAG,QAAQ;GACX,gBAAgB,QAAQ,WAAW,kBAAkB;;EAIvD,IAAIC;AACJ,MAAI,QAAQ,eAAe,OACzB,iBAAgB,MAAM,KAAK,kBACzB,QAAQ,WACR,QAAQ,eACR,QAAQ;AAIZ,SAAO,KAAK,sBAAsB,SAAS,YAAY;;CAGzD,OAAO,KACL,QACA,SACiC;AACjC,QAAM,KAAK;AAGX,MAAI,QAAQ,cAAc,WAAW;GAEnC,MAAM,QAAQ,MAAM,KAAK,SAAS;AAClC,OAAI,MAEF,KAAI,SAAS,QACX;QAAI,KAAK,yBAAyB,MAAM,UAAU,QAAQ,QACxD,OAAM;SAGR,OAAM;SAGL;GAEL,MAAMC,aAAuB;AAG7B,OAAI,SAAS,QACX;SAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,QAChD,KAAI,UAAU,QAAW,YAEd,UAAU,MAAM,YAEhB,OAAO,UAAU,SAC1B,YAAW,KAAK,KAAK,IAAI,IAAI,MAAM;aAC1B,OAAO,UAAU,SAC1B,YAAW,KAAK,KAAK,IAAI,IAAI,MAAM,GAAG,MAAM;;AAKlD,OAAI,WAAW,WAAW,EACxB,YAAW,KAAK;GAGlB,MAAM,QAAQ,WAAW,KAAK;GAC9B,MAAM,QAAQ,SAAS,SAAS;AAEhC,OAAI;IACF,MAAM,UAAU,MAAM,KAAK,OAAO,GAAG,OAAO,eAAe,OAAO;KAChE,OAAO;MAAE,MAAM;MAAG,MAAM,QAAQ;;KAChC,QAAQ;MAAE,IAAI;MAAiB,WAAW;;;IAI5C,MAAM,8BAAc,IAAI;IACxB,IAAI,aAAa;AAEjB,SAAK,MAAM,OAAO,QAAQ,WAAW;AACnC,SAAI,cAAc,MAAO;KAEzB,MAAM,UAAU,IAAI;KACpB,MAAM,YAAY,GAAG,QAAQ,UAAU,GAAG,QAAQ;AAGlD,SAAI,YAAY,IAAI,WAClB;AAEF,iBAAY,IAAI;AAGhB,SAAI,SAAS,QACX;UACE,CAAC,KAAK,yBAAyB,QAAQ,UAAU,QAAQ,QAEzD;;KAKJ,MAAM,aAAa;MACjB,GAAG,QAAQ;MACX,gBAAgB,QAAQ,WAAW,kBAAkB;;AAGvD,WAAM,KAAK,sBAAsB,SAAS;AAC1C;;YAEKC,OAAY;AACnB,QAAI,MAAM,SAAS,SAAS,kBAAkB;KAE5C,MAAM,UAAU;KAChB,MAAM,OAAO,MAAM,KAAK,OAAO,KAAK;AAEpC,SAAI,KAAK,WAAW,EAClB;AAIF,UAAK,OAAO;KAGZ,MAAM,8BAAc,IAAI;KACxB,IAAI,aAAa;KACjB,MAAMC,UAAQ,SAAS,SAAS;AAEhC,UAAK,MAAM,OAAO,MAAM;AACtB,UAAI,cAAcA,QAAO;MAEzB,MAAM,UAAU,MAAM,KAAK,OAAO,KAAK,IAAI;AAC3C,UAAI,CAAC,QAAS;MAEd,MAAM,YAAY,GAAG,QAAQ,UAAU,GAAG,QAAQ;AAGlD,UAAI,YAAY,IAAI,WAClB;AAEF,kBAAY,IAAI;AAGhB,UAAI,SAAS,QACX;WACE,CAAC,KAAK,yBAAyB,QAAQ,UAAU,QAAQ,QAEzD;;MAKJ,MAAM,aAAa;OACjB,GAAG,QAAQ;OACX,gBAAgB,QAAQ,WAAW,kBAAkB;;AAGvD,YAAM,KAAK,sBAAsB,SAAS;AAC1C;;AAEF;;AAEF,UAAM;;;;CAKZ,MAAM,UACJ,QACA,QACA,QACe;AACf,QAAM,KAAK;EAEX,MAAM,WAAW,OAAO,cAAc;EACtC,MAAM,eAAe,OAAO,cAAc,iBAAiB;EAC3D,MAAM,eAAe,OAAO,cAAc;AAE1C,MAAI,CAAC,YAAY,CAAC,aAChB,OAAM,IAAI,MAAM;EAKlB,MAAM,eAAe,oBAAoB,SAAS,GAAG,aAAa,GAAG,aAAa,GAAG,OAAO;EAC5F,MAAM,eAAe,MAAM,KAAK,OAAO,KAAK;AAC5C,MAAI,aAAa,SAAS,EACxB,OAAM,KAAK,OAAO,IAAI;EAIxB,MAAMC,YAAsB;AAC5B,OAAK,IAAI,MAAM,GAAG,MAAM,OAAO,QAAQ,OAAO;GAC5C,MAAM,CAAC,SAAS,SAAS,OAAO;GAChC,MAAM,WAAW,oBAAoB,SAAS,GAAG,aAAa,GAAG,aAAa,GAAG,OAAO,GAAG;AAC3F,aAAU,KAAK;GAEf,MAAM,WAAW;IACf,WAAW;IACX,eAAe;IACf,eAAe;IACf,SAAS;IACJ;IACI;IACT,MAAM,OAAO,UAAU,WAAW,SAAS;IACpC;;AAGT,SAAM,KAAK,OAAO,KAAK,IAAI,UAAU,KAAK;;AAI5C,MAAI,UAAU,SAAS,GAAG;GACxB,MAAM,UAAU,mBAAmB,SAAS,GAAG,aAAa,GAAG;GAG/D,MAAMC,WAAmC;AACzC,aAAU,SAAS,KAAK,QAAQ;AAC9B,aAAS,OAAO;;AAElB,SAAM,KAAK,OAAO,KAChB,SACA,OAAO,QAAQ,UAAU,KAAK,CAAC,KAAK,YAAY;IAAE;IAAO,OAAO;;AAIlE,OAAI,KAAK,WAAW,WAClB,OAAM,KAAK,SAAS,GAAG,WAAW;;EAKtC,MAAM,gBAAgB,cAAc,SAAS,GAAG,aAAa;EAC7D,MAAM,mBAAmB,MAAM,KAAK,OAAO,OAAO;AAClD,MAAI,kBAAkB;GACpB,MAAM,aAAa,MAAM,KAAK,OAAO,KAAK,IAAI;AAC9C,OAAI,YAAY;AACd,eAAW,aAAa;AACxB,UAAM,KAAK,OAAO,KAAK,IAAI,eAAe,KAAK;;;;CAKrD,MAAM,aAAa,UAAiC;EAElD,MAAM,oBAAoB,cAAc,SAAS;EACjD,MAAM,iBAAiB,MAAM,KAAK,OAAO,KAAK;AAE9C,MAAI,eAAe,SAAS,EAC1B,OAAM,KAAK,OAAO,IAAI;EAIxB,MAAM,gBAAgB,oBAAoB,SAAS;EACnD,MAAM,aAAa,MAAM,KAAK,OAAO,KAAK;AAE1C,MAAI,WAAW,SAAS,EACtB,OAAM,KAAK,OAAO,IAAI;EAIxB,MAAM,cAAc,mBAAmB,SAAS;EAChD,MAAM,WAAW,MAAM,KAAK,OAAO,KAAK;AAExC,MAAI,SAAS,SAAS,EACpB,OAAM,KAAK,OAAO,IAAI;;CAI1B,MAAM,MAAqB;AACzB,QAAM,KAAK,OAAO;;CAIpB,AAAQ,4BACN,SACA,UACM;AACN,MAAI,CAAC,SAAU;AAGf,MAAI,YAAY,SACd,SAAQ,SAAS,SAAS;AAE5B,MAAI,UAAU,SACZ,SAAQ,OAAO,SAAS;AAE1B,MAAI,YAAY,SAEd,SAAQ,SACN,OAAO,SAAS,WAAW,WACvB,KAAK,UAAU,SAAS,UACxB,SAAS;AAEjB,MAAI,WAAW,SACb,SAAQ,QAAQ,SAAS;;CAK7B,AAAQ,sBACN,SACA,YACA,eACiB;AACjB,SAAO;GACL,QAAQ,EACN,cAAc;IACZ,WAAW,QAAQ;IACnB,eAAe,QAAQ;IACvB,eAAe,QAAQ;;GAG3B;GACA,UAAU,QAAQ;GAClB,cAAc,QAAQ,uBAClB,EACE,cAAc;IACZ,WAAW,QAAQ;IACnB,eAAe,QAAQ;IACvB,eAAe,QAAQ;SAG3B;GACJ;;;CAKJ,MAAc,SAAS,GAAG,MAA+B;AACvD,MAAI,CAAC,KAAK,WAAW,WAAY;EAEjC,MAAM,aAAa,KAAK,MAAM,KAAK,UAAU,aAAa;EAC1D,MAAM,UAAU,MAAM,QAAQ,WAC5B,KAAK,KAAK,QAAQ,KAAK,OAAO,OAAO,KAAK;AAI5C,OAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,IAClC,KAAI,QAAQ,GAAG,WAAW,WACxB,SAAQ,KACN,6BAA6B,KAAK,GAAG,IACpC,QAAQ,GAA6B;;CAO9C,MAAc,kBACZ,UACA,cACA,cACmD;EACnD,MAAM,UAAU,mBAAmB,SAAS,GAAG,aAAa,GAAG;EAC/D,MAAM,YAAY,MAAM,KAAK,OAAO,OAAO,SAAS,GAAG;AAEvD,MAAI,UAAU,WAAW,EACvB,QAAO;EAGT,MAAMC,gBAA8C;AACpD,OAAK,MAAM,YAAY,WAAW;GAChC,MAAM,WAAW,MAAM,KAAK,OAAO,KAAK,IAAI;AAC5C,OAAI,SACF,eAAc,KAAK;IACjB,SAAS;IACT,SAAS;IACT,SAAS;;;AAKf,SAAO;;CAIT,AAAQ,yBACN,UACA,QACS;AACT,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,SAAS;GACjD,MAAM,gBAAgB,WAAW;AACjC,OAAI,UAAU,MACZ;QAAI,EAAE,QAAQ,YAAY,QAAQ,kBAAkB,KAClD,QAAO;cAEA,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,QAAQ;AAE7D,QAAI,OAAO,kBAAkB,YAAY,kBAAkB,KACzD,QAAO;AAET,QACE,uBAAuB,WACvB,uBAAuB,eAEvB,QAAO;cAEA,kBAAkB,MAC3B,QAAO;;AAGX,SAAO;;CAGT,MAAc,qBACZ,UACA,cACA,iBACe;EAEf,MAAM,eAAe,oBAAoB,SAAS,GAAG,aAAa,GAAG,gBAAgB;EACrF,MAAM,eAAe,MAAM,KAAK,OAAO,KAAK;AAC5C,MAAI,aAAa,SAAS,EACxB,OAAM,KAAK,OAAO,IAAI;EAIxB,MAAM,UAAU,mBAAmB,SAAS,GAAG,aAAa,GAAG;AAC/D,QAAM,KAAK,OAAO,IAAI;EAItB,MAAM,cAAc,mBAAmB,SAAS,GAAG,aAAa,GAAG,gBAAgB;EACnF,MAAM,cAAc,MAAM,KAAK,OAAO,KAAK;AAC3C,MAAI,YAAY,SAAS,EACvB,OAAM,KAAK,OAAO,IAAI;;CAI1B,AAAQ,iBAAiB,UAAkD;AACzE,MAAI,CAAC,SAAU,QAAO;EAEtB,MAAMC,YAAiB;AACvB,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,WAAW;GAGnD,MAAM,eAAe,IAAI,QAAQ,SAAS;AAC1C,aAAU,gBAER,OAAO,UAAU,WAAW,MAAM,QAAQ,SAAS,MAAM;;AAE7D,SAAO;;CAGT,MAAc,gBAA+B;AAC3C,OAAK,MAAM,UAAU,QACnB,KAAI;AAEF,SAAM,KAAK,OAAO,GAAG,OAAO,OAAO,OAAO,OAAO,QAAQ;IACvD,IAAI;IACJ,QAAQ,OAAO;;WAEVL,OAAY;AAEnB,OAAI,CAAC,MAAM,SAAS,SAAS,wBAC3B,SAAQ,MACN,0BAA0B,OAAO,MAAM,IACvC,MAAM"}
@@ -0,0 +1,46 @@
1
+ import { BaseCheckpointSaver, ChannelVersions, Checkpoint, CheckpointListOptions, CheckpointMetadata, CheckpointTuple, PendingWrite } from "@langchain/langgraph-checkpoint";
2
+ import { RunnableConfig } from "@langchain/core/runnables";
3
+
4
+ //#region src/shallow.d.ts
5
+ interface TTLConfig {
6
+ defaultTTL?: number; // TTL in minutes
7
+ refreshOnRead?: boolean; // Whether to refresh TTL when reading
8
+ }
9
+ /**
10
+ * ShallowRedisSaver - A Redis checkpoint saver that only keeps the latest checkpoint per thread.
11
+ *
12
+ * This is a memory-optimized variant that:
13
+ * - Only stores the most recent checkpoint for each thread
14
+ * - Stores channel values inline (no separate blob storage)
15
+ * - Automatically cleans up old checkpoints and writes when new ones are added
16
+ * - Reduces storage usage for applications that don't need checkpoint history
17
+ */
18
+ declare class ShallowRedisSaver extends BaseCheckpointSaver {
19
+ private client;
20
+ private ttlConfig?;
21
+ constructor(client: any, ttlConfig?: TTLConfig);
22
+ static fromUrl(url: string, ttlConfig?: TTLConfig): Promise<ShallowRedisSaver>;
23
+ get(config: RunnableConfig): Promise<Checkpoint | undefined>;
24
+ put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata, _newVersions: ChannelVersions): Promise<RunnableConfig>;
25
+ getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined>;
26
+ list(config: RunnableConfig | null, options?: CheckpointListOptions & {
27
+ filter?: CheckpointMetadata;
28
+ }): AsyncGenerator<CheckpointTuple>;
29
+ putWrites(config: RunnableConfig, writes: PendingWrite[], taskId: string): Promise<void>;
30
+ deleteThread(threadId: string): Promise<void>;
31
+ end(): Promise<void>;
32
+ // Helper method to add searchable metadata fields
33
+ private addSearchableMetadataFields;
34
+ // Helper method to create checkpoint tuple from json document
35
+ private createCheckpointTuple;
36
+ private applyTTL;
37
+ private loadPendingWrites;
38
+ // Helper method to check metadata filter matches
39
+ private checkMetadataFilterMatch;
40
+ private cleanupOldCheckpoint;
41
+ private sanitizeMetadata;
42
+ private ensureIndexes;
43
+ }
44
+ //#endregion
45
+ export { ShallowRedisSaver, TTLConfig };
46
+ //# sourceMappingURL=shallow.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shallow.d.cts","names":["BaseCheckpointSaver","ChannelVersions","Checkpoint","CheckpointListOptions","CheckpointMetadata","CheckpointTuple","PendingWrite","RunnableConfig","TTLConfig","ShallowRedisSaver","Promise","AsyncGenerator"],"sources":["../src/shallow.d.ts"],"sourcesContent":["import { BaseCheckpointSaver, ChannelVersions, Checkpoint, CheckpointListOptions, CheckpointMetadata, CheckpointTuple, PendingWrite } from \"@langchain/langgraph-checkpoint\";\nimport { RunnableConfig } from \"@langchain/core/runnables\";\nexport interface TTLConfig {\n defaultTTL?: number; // TTL in minutes\n refreshOnRead?: boolean; // Whether to refresh TTL when reading\n}\n/**\n * ShallowRedisSaver - A Redis checkpoint saver that only keeps the latest checkpoint per thread.\n *\n * This is a memory-optimized variant that:\n * - Only stores the most recent checkpoint for each thread\n * - Stores channel values inline (no separate blob storage)\n * - Automatically cleans up old checkpoints and writes when new ones are added\n * - Reduces storage usage for applications that don't need checkpoint history\n */\nexport declare class ShallowRedisSaver extends BaseCheckpointSaver {\n private client;\n private ttlConfig?;\n constructor(client: any, ttlConfig?: TTLConfig);\n static fromUrl(url: string, ttlConfig?: TTLConfig): Promise<ShallowRedisSaver>;\n get(config: RunnableConfig): Promise<Checkpoint | undefined>;\n put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata, _newVersions: ChannelVersions): Promise<RunnableConfig>;\n getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined>;\n list(config: RunnableConfig | null, options?: CheckpointListOptions & {\n filter?: CheckpointMetadata;\n }): AsyncGenerator<CheckpointTuple>;\n putWrites(config: RunnableConfig, writes: PendingWrite[], taskId: string): Promise<void>;\n deleteThread(threadId: string): Promise<void>;\n end(): Promise<void>;\n // Helper method to add searchable metadata fields\n private addSearchableMetadataFields;\n // Helper method to create checkpoint tuple from json document\n private createCheckpointTuple;\n private applyTTL;\n private loadPendingWrites;\n // Helper method to check metadata filter matches\n private checkMetadataFilterMatch;\n private cleanupOldCheckpoint;\n private sanitizeMetadata;\n private ensureIndexes;\n}\n//# sourceMappingURL=shallow.d.ts.map"],"mappings":";;;;UAEiBQ,SAAAA;;EAAAA,aAAS,CAAA,EAAA,OAAA,CAAA,CAAA;AAa1B;;;;;;;;;;AAM4CN,cANvBO,iBAAAA,SAA0BT,mBAAAA,CAMHE;UAAsBE,MAAAA;UAAkCH,SAAAA;aAA0BM,CAAAA,MAAAA,EAAAA,GAAAA,EAAAA,SAAAA,CAAAA,EAHrFC,SAGqFD;SAARG,OAAAA,CAAAA,GAAAA,EAAAA,MAAAA,EAAAA,SAAAA,CAAAA,EAF1EF,SAE0EE,CAAAA,EAF9DA,OAE8DA,CAFtDD,iBAEsDC,CAAAA;KACjGH,CAAAA,MAAAA,EAFLA,cAEKA,CAAAA,EAFYG,OAEZH,CAFoBL,UAEpBK,GAAAA,SAAAA,CAAAA;KAAyBF,CAAAA,MAAAA,EAD9BE,cAC8BF,EAAAA,UAAAA,EADFH,UACEG,EAAAA,QAAAA,EADoBD,kBACpBC,EAAAA,YAAAA,EADsDJ,eACtDI,CAAAA,EADwEK,OACxEL,CADgFE,cAChFF,CAAAA;UAARK,CAAAA,MAAAA,EAAjBH,cAAiBG,CAAAA,EAAAA,OAAAA,CAAQL,eAARK,GAAAA,SAAAA,CAAAA;MACrBH,CAAAA,MAAAA,EAAAA,cAAAA,GAAAA,IAAAA,EAAAA,QAAAA,EAAiCJ,qBAAjCI,GAAAA;IAAiCJ,MAAAA,CAAAA,EACjCC,kBADiCD;MAE1CQ,cADSP,CACMC,eADND,CAAAA;WACMC,CAAAA,MAAAA,EACDE,cADCF,EAAAA,MAAAA,EACuBC,YADvBD,EAAAA,EAAAA,MAAAA,EAAAA,MAAAA,CAAAA,EACwDK,OADxDL,CAAAA,IAAAA,CAAAA;cAAfM,CAAAA,QAAAA,EAAAA,MAAAA,CAAAA,EAE4BD,OAF5BC,CAAAA,IAAAA,CAAAA;KACcJ,CAAAA,CAAAA,EAEXG,OAFWH,CAAAA,IAAAA,CAAAA;;UAAyDG,2BAAAA;;UAEpEA,qBAAAA;UAboCV,QAAAA"}
package/dist/shallow.d.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  import { BaseCheckpointSaver, ChannelVersions, Checkpoint, CheckpointListOptions, CheckpointMetadata, CheckpointTuple, PendingWrite } from "@langchain/langgraph-checkpoint";
2
2
  import { RunnableConfig } from "@langchain/core/runnables";
3
- export interface TTLConfig {
4
- defaultTTL?: number;
5
- refreshOnRead?: boolean;
3
+
4
+ //#region src/shallow.d.ts
5
+ interface TTLConfig {
6
+ defaultTTL?: number; // TTL in minutes
7
+ refreshOnRead?: boolean; // Whether to refresh TTL when reading
6
8
  }
7
9
  /**
8
10
  * ShallowRedisSaver - A Redis checkpoint saver that only keeps the latest checkpoint per thread.
@@ -13,27 +15,32 @@ export interface TTLConfig {
13
15
  * - Automatically cleans up old checkpoints and writes when new ones are added
14
16
  * - Reduces storage usage for applications that don't need checkpoint history
15
17
  */
16
- export declare class ShallowRedisSaver extends BaseCheckpointSaver {
17
- private client;
18
- private ttlConfig?;
19
- constructor(client: any, ttlConfig?: TTLConfig);
20
- static fromUrl(url: string, ttlConfig?: TTLConfig): Promise<ShallowRedisSaver>;
21
- get(config: RunnableConfig): Promise<Checkpoint | undefined>;
22
- put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata, _newVersions: ChannelVersions): Promise<RunnableConfig>;
23
- getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined>;
24
- list(config: RunnableConfig | null, options?: CheckpointListOptions & {
25
- filter?: CheckpointMetadata;
26
- }): AsyncGenerator<CheckpointTuple>;
27
- putWrites(config: RunnableConfig, writes: PendingWrite[], taskId: string): Promise<void>;
28
- deleteThread(threadId: string): Promise<void>;
29
- end(): Promise<void>;
30
- private addSearchableMetadataFields;
31
- private createCheckpointTuple;
32
- private applyTTL;
33
- private loadPendingWrites;
34
- private checkMetadataFilterMatch;
35
- private cleanupOldCheckpoint;
36
- private sanitizeMetadata;
37
- private ensureIndexes;
18
+ declare class ShallowRedisSaver extends BaseCheckpointSaver {
19
+ private client;
20
+ private ttlConfig?;
21
+ constructor(client: any, ttlConfig?: TTLConfig);
22
+ static fromUrl(url: string, ttlConfig?: TTLConfig): Promise<ShallowRedisSaver>;
23
+ get(config: RunnableConfig): Promise<Checkpoint | undefined>;
24
+ put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata, _newVersions: ChannelVersions): Promise<RunnableConfig>;
25
+ getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined>;
26
+ list(config: RunnableConfig | null, options?: CheckpointListOptions & {
27
+ filter?: CheckpointMetadata;
28
+ }): AsyncGenerator<CheckpointTuple>;
29
+ putWrites(config: RunnableConfig, writes: PendingWrite[], taskId: string): Promise<void>;
30
+ deleteThread(threadId: string): Promise<void>;
31
+ end(): Promise<void>;
32
+ // Helper method to add searchable metadata fields
33
+ private addSearchableMetadataFields;
34
+ // Helper method to create checkpoint tuple from json document
35
+ private createCheckpointTuple;
36
+ private applyTTL;
37
+ private loadPendingWrites;
38
+ // Helper method to check metadata filter matches
39
+ private checkMetadataFilterMatch;
40
+ private cleanupOldCheckpoint;
41
+ private sanitizeMetadata;
42
+ private ensureIndexes;
38
43
  }
44
+ //#endregion
45
+ export { ShallowRedisSaver, TTLConfig };
39
46
  //# sourceMappingURL=shallow.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"shallow.d.ts","sourceRoot":"","sources":["../src/shallow.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,UAAU,EACV,qBAAqB,EACrB,kBAAkB,EAClB,eAAe,EACf,YAAY,EAEb,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAG3D,MAAM,WAAW,SAAS;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AA0DD;;;;;;;;GAQG;AACH,qBAAa,iBAAkB,SAAQ,mBAAmB;IACxD,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,SAAS,CAAC,CAAY;gBAElB,MAAM,EAAE,GAAG,EAAE,SAAS,CAAC,EAAE,SAAS;WAMjC,OAAO,CAClB,GAAG,EAAE,MAAM,EACX,SAAS,CAAC,EAAE,SAAS,GACpB,OAAO,CAAC,iBAAiB,CAAC;IAQvB,GAAG,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAK5D,GAAG,CACP,MAAM,EAAE,cAAc,EACtB,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,kBAAkB,EAC5B,YAAY,EAAE,eAAe,GAC5B,OAAO,CAAC,cAAc,CAAC;IAyEpB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;IA8CrE,IAAI,CACT,MAAM,EAAE,cAAc,GAAG,IAAI,EAC7B,OAAO,CAAC,EAAE,qBAAqB,GAAG;QAAE,MAAM,CAAC,EAAE,kBAAkB,CAAA;KAAE,GAChE,cAAc,CAAC,eAAe,CAAC;IA4I5B,SAAS,CACb,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,YAAY,EAAE,EACtB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC;IAwEV,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0B7C,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAK1B,OAAO,CAAC,2BAA2B;IA0BnC,OAAO,CAAC,qBAAqB;YA6Bf,QAAQ;YAoBR,iBAAiB;IA4B/B,OAAO,CAAC,wBAAwB;YA4BlB,oBAAoB;IAyBlC,OAAO,CAAC,gBAAgB;YAeV,aAAa;CAmB5B"}
1
+ {"version":3,"file":"shallow.d.ts","names":["BaseCheckpointSaver","ChannelVersions","Checkpoint","CheckpointListOptions","CheckpointMetadata","CheckpointTuple","PendingWrite","RunnableConfig","TTLConfig","ShallowRedisSaver","Promise","AsyncGenerator"],"sources":["../src/shallow.d.ts"],"sourcesContent":["import { BaseCheckpointSaver, ChannelVersions, Checkpoint, CheckpointListOptions, CheckpointMetadata, CheckpointTuple, PendingWrite } from \"@langchain/langgraph-checkpoint\";\nimport { RunnableConfig } from \"@langchain/core/runnables\";\nexport interface TTLConfig {\n defaultTTL?: number; // TTL in minutes\n refreshOnRead?: boolean; // Whether to refresh TTL when reading\n}\n/**\n * ShallowRedisSaver - A Redis checkpoint saver that only keeps the latest checkpoint per thread.\n *\n * This is a memory-optimized variant that:\n * - Only stores the most recent checkpoint for each thread\n * - Stores channel values inline (no separate blob storage)\n * - Automatically cleans up old checkpoints and writes when new ones are added\n * - Reduces storage usage for applications that don't need checkpoint history\n */\nexport declare class ShallowRedisSaver extends BaseCheckpointSaver {\n private client;\n private ttlConfig?;\n constructor(client: any, ttlConfig?: TTLConfig);\n static fromUrl(url: string, ttlConfig?: TTLConfig): Promise<ShallowRedisSaver>;\n get(config: RunnableConfig): Promise<Checkpoint | undefined>;\n put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata, _newVersions: ChannelVersions): Promise<RunnableConfig>;\n getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined>;\n list(config: RunnableConfig | null, options?: CheckpointListOptions & {\n filter?: CheckpointMetadata;\n }): AsyncGenerator<CheckpointTuple>;\n putWrites(config: RunnableConfig, writes: PendingWrite[], taskId: string): Promise<void>;\n deleteThread(threadId: string): Promise<void>;\n end(): Promise<void>;\n // Helper method to add searchable metadata fields\n private addSearchableMetadataFields;\n // Helper method to create checkpoint tuple from json document\n private createCheckpointTuple;\n private applyTTL;\n private loadPendingWrites;\n // Helper method to check metadata filter matches\n private checkMetadataFilterMatch;\n private cleanupOldCheckpoint;\n private sanitizeMetadata;\n private ensureIndexes;\n}\n//# sourceMappingURL=shallow.d.ts.map"],"mappings":";;;;UAEiBQ,SAAAA;;EAAAA,aAAS,CAAA,EAAA,OAAA,CAAA,CAAA;AAa1B;;;;;;;;;;AAM4CN,cANvBO,iBAAAA,SAA0BT,mBAAAA,CAMHE;UAAsBE,MAAAA;UAAkCH,SAAAA;aAA0BM,CAAAA,MAAAA,EAAAA,GAAAA,EAAAA,SAAAA,CAAAA,EAHrFC,SAGqFD;SAARG,OAAAA,CAAAA,GAAAA,EAAAA,MAAAA,EAAAA,SAAAA,CAAAA,EAF1EF,SAE0EE,CAAAA,EAF9DA,OAE8DA,CAFtDD,iBAEsDC,CAAAA;KACjGH,CAAAA,MAAAA,EAFLA,cAEKA,CAAAA,EAFYG,OAEZH,CAFoBL,UAEpBK,GAAAA,SAAAA,CAAAA;KAAyBF,CAAAA,MAAAA,EAD9BE,cAC8BF,EAAAA,UAAAA,EADFH,UACEG,EAAAA,QAAAA,EADoBD,kBACpBC,EAAAA,YAAAA,EADsDJ,eACtDI,CAAAA,EADwEK,OACxEL,CADgFE,cAChFF,CAAAA;UAARK,CAAAA,MAAAA,EAAjBH,cAAiBG,CAAAA,EAAAA,OAAAA,CAAQL,eAARK,GAAAA,SAAAA,CAAAA;MACrBH,CAAAA,MAAAA,EAAAA,cAAAA,GAAAA,IAAAA,EAAAA,QAAAA,EAAiCJ,qBAAjCI,GAAAA;IAAiCJ,MAAAA,CAAAA,EACjCC,kBADiCD;MAE1CQ,cADSP,CACMC,eADND,CAAAA;WACMC,CAAAA,MAAAA,EACDE,cADCF,EAAAA,MAAAA,EACuBC,YADvBD,EAAAA,EAAAA,MAAAA,EAAAA,MAAAA,CAAAA,EACwDK,OADxDL,CAAAA,IAAAA,CAAAA;cAAfM,CAAAA,QAAAA,EAAAA,MAAAA,CAAAA,EAE4BD,OAF5BC,CAAAA,IAAAA,CAAAA;KACcJ,CAAAA,CAAAA,EAEXG,OAFWH,CAAAA,IAAAA,CAAAA;;UAAyDG,2BAAAA;;UAEpEA,qBAAAA;UAboCV,QAAAA"}