@farukada/aws-langgraph-dynamodb-ts 0.3.1 → 0.4.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.
- package/README.md +12 -5
- package/dist/checkpointer/actions/delete-thread.js +1 -1
- package/dist/checkpointer/actions/delete-thread.js.map +1 -1
- package/dist/checkpointer/actions/get-tuple.js.map +1 -1
- package/dist/checkpointer/actions/list.d.ts.map +1 -1
- package/dist/checkpointer/actions/list.js +3 -1
- package/dist/checkpointer/actions/list.js.map +1 -1
- package/dist/checkpointer/actions/put-writes.d.ts +6 -0
- package/dist/checkpointer/actions/put-writes.d.ts.map +1 -1
- package/dist/checkpointer/actions/put-writes.js +77 -10
- package/dist/checkpointer/actions/put-writes.js.map +1 -1
- package/dist/checkpointer/actions/put.js.map +1 -1
- package/dist/checkpointer/internal/assemble.js.map +1 -1
- package/dist/checkpointer/internal/configurable.js.map +1 -1
- package/dist/checkpointer/internal/fetch.js.map +1 -1
- package/dist/checkpointer/internal/filter-match.d.ts.map +1 -1
- package/dist/checkpointer/internal/filter-match.js.map +1 -1
- package/dist/checkpointer/internal/item-reader.js.map +1 -1
- package/dist/checkpointer/internal/item-writer.d.ts +13 -2
- package/dist/checkpointer/internal/item-writer.d.ts.map +1 -1
- package/dist/checkpointer/internal/item-writer.js +15 -3
- package/dist/checkpointer/internal/item-writer.js.map +1 -1
- package/dist/checkpointer/internal/keys.js.map +1 -1
- package/dist/checkpointer/internal/query.d.ts +5 -1
- package/dist/checkpointer/internal/query.d.ts.map +1 -1
- package/dist/checkpointer/internal/query.js +5 -2
- package/dist/checkpointer/internal/query.js.map +1 -1
- package/dist/checkpointer/internal/setup.d.ts.map +1 -1
- package/dist/checkpointer/internal/setup.js +8 -1
- package/dist/checkpointer/internal/setup.js.map +1 -1
- package/dist/checkpointer/internal/validation.js.map +1 -1
- package/dist/checkpointer/saver.d.ts +9 -0
- package/dist/checkpointer/saver.d.ts.map +1 -1
- package/dist/checkpointer/saver.js +14 -0
- package/dist/checkpointer/saver.js.map +1 -1
- package/dist/factory/factory.d.ts +4 -4
- package/dist/factory/factory.d.ts.map +1 -1
- package/dist/factory/factory.js +4 -6
- package/dist/factory/factory.js.map +1 -1
- package/dist/history/actions/add-messages.d.ts.map +1 -1
- package/dist/history/actions/add-messages.js +4 -3
- package/dist/history/actions/add-messages.js.map +1 -1
- package/dist/history/actions/clear.d.ts +6 -3
- package/dist/history/actions/clear.d.ts.map +1 -1
- package/dist/history/actions/clear.js +28 -15
- package/dist/history/actions/clear.js.map +1 -1
- package/dist/history/actions/get-messages.d.ts.map +1 -1
- package/dist/history/actions/get-messages.js +2 -0
- package/dist/history/actions/get-messages.js.map +1 -1
- package/dist/history/actions/list-sessions.d.ts +4 -1
- package/dist/history/actions/list-sessions.d.ts.map +1 -1
- package/dist/history/actions/list-sessions.js +3 -1
- package/dist/history/actions/list-sessions.js.map +1 -1
- package/dist/history/actions/reconcile-count.d.ts +4 -1
- package/dist/history/actions/reconcile-count.d.ts.map +1 -1
- package/dist/history/actions/reconcile-count.js +21 -9
- package/dist/history/actions/reconcile-count.js.map +1 -1
- package/dist/history/chat-message-history.d.ts +13 -1
- package/dist/history/chat-message-history.d.ts.map +1 -1
- package/dist/history/chat-message-history.js +16 -2
- package/dist/history/chat-message-history.js.map +1 -1
- package/dist/history/internal/append-saga.d.ts +6 -3
- package/dist/history/internal/append-saga.d.ts.map +1 -1
- package/dist/history/internal/append-saga.js +28 -14
- package/dist/history/internal/append-saga.js.map +1 -1
- package/dist/history/internal/item-mapper.js.map +1 -1
- package/dist/history/internal/keys.js.map +1 -1
- package/dist/history/internal/message-chunker.js.map +1 -1
- package/dist/history/internal/message-transaction.d.ts +4 -0
- package/dist/history/internal/message-transaction.d.ts.map +1 -1
- package/dist/history/internal/message-transaction.js +6 -0
- package/dist/history/internal/message-transaction.js.map +1 -1
- package/dist/history/internal/query.js.map +1 -1
- package/dist/history/internal/session-update.d.ts +6 -1
- package/dist/history/internal/session-update.d.ts.map +1 -1
- package/dist/history/internal/session-update.js +6 -2
- package/dist/history/internal/session-update.js.map +1 -1
- package/dist/history/internal/setup.d.ts.map +1 -1
- package/dist/history/internal/setup.js +8 -1
- package/dist/history/internal/setup.js.map +1 -1
- package/dist/history/internal/title-generator.js.map +1 -1
- package/dist/history/internal/ttl-anchor.d.ts +20 -7
- package/dist/history/internal/ttl-anchor.d.ts.map +1 -1
- package/dist/history/internal/ttl-anchor.js +19 -7
- package/dist/history/internal/ttl-anchor.js.map +1 -1
- package/dist/history/session-adapter.d.ts.map +1 -1
- package/dist/history/session-adapter.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/shared/clock.js.map +1 -1
- package/dist/shared/codec/codec.js.map +1 -1
- package/dist/shared/codec/compression.js.map +1 -1
- package/dist/shared/codec/descriptor-keys.js.map +1 -1
- package/dist/shared/codec/s3/client.d.ts +7 -1
- package/dist/shared/codec/s3/client.d.ts.map +1 -1
- package/dist/shared/codec/s3/client.js +8 -2
- package/dist/shared/codec/s3/client.js.map +1 -1
- package/dist/shared/codec/s3/config.d.ts +9 -1
- package/dist/shared/codec/s3/config.d.ts.map +1 -1
- package/dist/shared/codec/s3/config.js +14 -2
- package/dist/shared/codec/s3/config.js.map +1 -1
- package/dist/shared/codec/s3/delete.js.map +1 -1
- package/dist/shared/codec/s3/lifecycle.js.map +1 -1
- package/dist/shared/codec/s3/offloader.d.ts +2 -1
- package/dist/shared/codec/s3/offloader.d.ts.map +1 -1
- package/dist/shared/codec/s3/offloader.js +15 -8
- package/dist/shared/codec/s3/offloader.js.map +1 -1
- package/dist/shared/codec/s3/orphans.d.ts +4 -2
- package/dist/shared/codec/s3/orphans.d.ts.map +1 -1
- package/dist/shared/codec/s3/orphans.js +8 -23
- package/dist/shared/codec/s3/orphans.js.map +1 -1
- package/dist/shared/codec/s3/read-write.d.ts.map +1 -1
- package/dist/shared/codec/s3/read-write.js +14 -13
- package/dist/shared/codec/s3/read-write.js.map +1 -1
- package/dist/shared/codec/s3/retry.d.ts +5 -0
- package/dist/shared/codec/s3/retry.d.ts.map +1 -0
- package/dist/shared/codec/s3/retry.js +25 -0
- package/dist/shared/codec/s3/retry.js.map +1 -0
- package/dist/shared/constants.d.ts +12 -0
- package/dist/shared/constants.d.ts.map +1 -1
- package/dist/shared/constants.js +13 -1
- package/dist/shared/constants.js.map +1 -1
- package/dist/shared/dynamodb/backoff.js.map +1 -1
- package/dist/shared/dynamodb/batch-write.d.ts +5 -2
- package/dist/shared/dynamodb/batch-write.d.ts.map +1 -1
- package/dist/shared/dynamodb/batch-write.js +19 -3
- package/dist/shared/dynamodb/batch-write.js.map +1 -1
- package/dist/shared/dynamodb/client.js +1 -1
- package/dist/shared/dynamodb/client.js.map +1 -1
- package/dist/shared/dynamodb/drain-unprocessed.js.map +1 -1
- package/dist/shared/dynamodb/paginate-core.js.map +1 -1
- package/dist/shared/dynamodb/paginate.js.map +1 -1
- package/dist/shared/dynamodb/retry-classifier.d.ts.map +1 -1
- package/dist/shared/dynamodb/retry-classifier.js +3 -0
- package/dist/shared/dynamodb/retry-classifier.js.map +1 -1
- package/dist/shared/dynamodb/retry.js.map +1 -1
- package/dist/shared/dynamodb/scan.js.map +1 -1
- package/dist/shared/errors/base-error.d.ts.map +1 -1
- package/dist/shared/errors/base-error.js.map +1 -1
- package/dist/shared/errors/error-code.js.map +1 -1
- package/dist/shared/errors/errors.d.ts +13 -0
- package/dist/shared/errors/errors.d.ts.map +1 -1
- package/dist/shared/errors/errors.js +22 -1
- package/dist/shared/errors/errors.js.map +1 -1
- package/dist/shared/errors/wrap-error.js.map +1 -1
- package/dist/shared/logging/logger.js.map +1 -1
- package/dist/shared/logging/redaction.d.ts.map +1 -1
- package/dist/shared/logging/redaction.js +13 -8
- package/dist/shared/logging/redaction.js.map +1 -1
- package/dist/shared/ulid.js.map +1 -1
- package/dist/shared/validation/primitives.js.map +1 -1
- package/dist/shared/validation/ttl.d.ts +5 -0
- package/dist/shared/validation/ttl.d.ts.map +1 -1
- package/dist/shared/validation/ttl.js +8 -0
- package/dist/shared/validation/ttl.js.map +1 -1
- package/dist/store/actions/get.js.map +1 -1
- package/dist/store/actions/list-namespaces.js.map +1 -1
- package/dist/store/actions/put.d.ts +6 -4
- package/dist/store/actions/put.d.ts.map +1 -1
- package/dist/store/actions/put.js +32 -13
- package/dist/store/actions/put.js.map +1 -1
- package/dist/store/actions/reconcile-vector-index.js.map +1 -1
- package/dist/store/actions/search.d.ts.map +1 -1
- package/dist/store/actions/search.js +29 -9
- package/dist/store/actions/search.js.map +1 -1
- package/dist/store/internal/filter.d.ts.map +1 -1
- package/dist/store/internal/filter.js +12 -8
- package/dist/store/internal/filter.js.map +1 -1
- package/dist/store/internal/index-reconcile.d.ts.map +1 -1
- package/dist/store/internal/index-reconcile.js +5 -5
- package/dist/store/internal/index-reconcile.js.map +1 -1
- package/dist/store/internal/index-sync.js.map +1 -1
- package/dist/store/internal/item-mapper.d.ts +2 -1
- package/dist/store/internal/item-mapper.d.ts.map +1 -1
- package/dist/store/internal/item-mapper.js +1 -1
- package/dist/store/internal/item-mapper.js.map +1 -1
- package/dist/store/internal/keys.js.map +1 -1
- package/dist/store/internal/namespace-match.js.map +1 -1
- package/dist/store/internal/query.js.map +1 -1
- package/dist/store/internal/ranker.d.ts.map +1 -1
- package/dist/store/internal/ranker.js +3 -1
- package/dist/store/internal/ranker.js.map +1 -1
- package/dist/store/internal/semantic-search.js.map +1 -1
- package/dist/store/internal/setup.d.ts +1 -0
- package/dist/store/internal/setup.d.ts.map +1 -1
- package/dist/store/internal/setup.js +8 -1
- package/dist/store/internal/setup.js.map +1 -1
- package/dist/store/internal/validation.js.map +1 -1
- package/dist/store/store.d.ts +9 -0
- package/dist/store/store.d.ts.map +1 -1
- package/dist/store/store.js +14 -0
- package/dist/store/store.js.map +1 -1
- package/dist/store/types.d.ts +2 -0
- package/dist/store/types.d.ts.map +1 -1
- package/package.json +28 -26
package/README.md
CHANGED
|
@@ -192,16 +192,21 @@ All adapters share a common base. Provide **either** a prebuilt `client` (which
|
|
|
192
192
|
| `index` | `IndexConfig` | store only | `{ dims, embeddings, fields? }` for semantic search |
|
|
193
193
|
| `vectorBackend` | `VectorBackend` | store only | delegate similarity search to an external index; DynamoDB keeps the canonical item |
|
|
194
194
|
| `maxSearchCandidates` | `number` | store only | cap for the in-DB ranker before it errors (default 1000) |
|
|
195
|
+
| `maxScanItems` | `number` | store only | cap on items scanned into memory during a plain (non-semantic) `search()` before it errors (default 10000, the shared in-memory cap used by every paginated read) |
|
|
195
196
|
|
|
196
197
|
`S3OffloadConfig`: `{ bucketName, keyPrefix?, thresholdBytes?, serverSideEncryption?, sseKmsKeyId?, clientConfig? }`.
|
|
197
198
|
|
|
199
|
+
When `keyPrefix` is omitted, each adapter defaults to its own sub-prefix under the shared base (`langgraph-checkpoints/store/`, `langgraph-checkpoints/checkpointer/`, `langgraph-checkpoints/history/`) so that multiple adapters can safely share one bucket — their offloaded object keys and `ensureS3LifecycleRule()` TTL rules never collide. An explicit `keyPrefix` is always honored verbatim, including across adapters if you want them to share one; at that point avoiding a lifecycle-rule collision (e.g. by giving them the same TTL) is your responsibility, same as with any other explicit override.
|
|
200
|
+
|
|
198
201
|
## Features
|
|
199
202
|
|
|
200
203
|
**Gzip compression** — set `compression: { enabled: true }`. Payloads at or above `minSizeBytes` (default 1 KB) are gzipped transparently; decompression auto-detects on read and is guarded against decompression-bomb expansion (`maxDecompressedBytes`, default 50 MiB).
|
|
201
204
|
|
|
202
|
-
**S3 offloading** — set `s3: { bucketName }`. Any serialized payload at or above `thresholdBytes` (default 350 KB) is written to S3, with only a reference stored in DynamoDB; reads rehydrate transparently. Requires the optional `@aws-sdk/client-s3` peer. When a `ttl` is also configured
|
|
205
|
+
**S3 offloading** — set `s3: { bucketName }`. Any serialized payload at or above `thresholdBytes` (default 350 KB) is written to S3, with only a reference stored in DynamoDB; reads rehydrate transparently. Requires the optional `@aws-sdk/client-s3` peer. Deleting a checkpoint thread / chat session also best-effort deletes its offloaded objects. When a `ttl` is also configured, call `ensureS3LifecycleRule()` once (e.g. during deployment) to best-effort install a matching S3 lifecycle expiration rule (logged, never fatal) — this is opt-in rather than automatic, since it requires the broader `s3:PutLifecycleConfiguration` bucket-level permission and is not safe to fire on every adapter construction. If you configure `ttl` + `s3` but never call it, nothing reclaims objects that best-effort cleanup misses (a failed delete, or a write that lost the checkpointer's first-write-wins race) — they stay in the bucket until you remove them or add a lifecycle rule yourself. The store has an analogous, smaller-scale race: two concurrent `put`s to the same key that both read the previous descriptor before either commits each upload to their own distinct (nonced) key and each then try to clean up that same previous descriptor — the loser's own upload becomes an orphan (bounded at one per race), the same class of leak, reclaimed the same way.
|
|
206
|
+
|
|
207
|
+
**TTL expiry** — set `ttl: { days }` or `ttl: { seconds }`. The `ttl` attribute is written as a Unix-epoch-seconds timestamp; enable DynamoDB TTL on the `ttl` attribute for automatic deletion. Chat history anchors a single **uniform whole-conversation TTL** on the session's metadata row, shared by every message: normally it's set once, at session creation, via `if_not_exists`; but if the previously-stored anchor is ever found missing or already expired (DynamoDB's own TTL sweep can lag up to ~48h), the next append heals it with a plain overwrite instead of staying stuck. Every message written at any point in time shares whatever the current anchor is; expired messages are also filtered out on read.
|
|
203
208
|
|
|
204
|
-
**
|
|
209
|
+
**Plain (metadata) search** (store) — a `search()` call with no `query` (or with a `query` but no `index`/`vectorBackend` configured) decodes every row under the `namespacePrefix` — applying `filter` in-process — before slicing to `offset`/`limit`. That full-namespace decode is bounded by `maxScanItems` (default 10,000, the same in-memory cap shared by every other paginated read in the library); exceeding it throws rather than silently returning a partial result. This is a different cap from `maxSearchCandidates` below: `maxScanItems` gates the plain in-memory scan, `maxSearchCandidates` gates the in-DB semantic ranker. Raise `maxScanItems` for a one-off oversized namespace, but for namespaces that routinely exceed the default, prefer a `vectorBackend` or a narrower `namespacePrefix` over raising the cap indefinitely.
|
|
205
210
|
|
|
206
211
|
**Semantic search** (store) — provide `index` with a LangChain `Embeddings` implementation. On `put`, the configured `fields` are embedded; on `search` with a `query`, results are ranked by cosine similarity. By default the embedding is stored on the item and ranking happens in-process over the scoped candidate set (bounded by `maxSearchCandidates`, default 1000 — exceeding it throws, steering you to an external index). For large corpora, pass a `vectorBackend`: the embedding is sent there instead, similarity search is delegated to it, and DynamoDB still holds the canonical item. Per-item indexing can be overridden via the `index` argument to `put` (`false` to skip, or a `string[]` of fields).
|
|
207
212
|
|
|
@@ -225,7 +230,9 @@ try {
|
|
|
225
230
|
}
|
|
226
231
|
```
|
|
227
232
|
|
|
228
|
-
`ErrorCode` values: `VALIDATION`, `CONDITION_CONFLICT`, `RETRY_EXHAUSTED`, `BATCH_WRITE_INCOMPLETE`, `COMPRESSION_LIMIT`, `S3_OFFLOAD_FAILED`, `ABORTED`. Typed subclasses are exported where callers commonly branch: `ValidationError`, `ConflictError`, `RetryExhaustedError`, `BatchWriteIncompleteError`, `AbortError`.
|
|
233
|
+
`ErrorCode` values: `VALIDATION`, `CONDITION_CONFLICT`, `RETRY_EXHAUSTED`, `BATCH_WRITE_INCOMPLETE`, `COMPRESSION_LIMIT`, `S3_OFFLOAD_FAILED`, `ABORTED`. Typed subclasses are exported where callers commonly branch: `ValidationError`, `ConflictError`, `RetryExhaustedError`, `BatchWriteIncompleteError`, `BatchWriteAllIncompleteError`, `AbortError`.
|
|
234
|
+
|
|
235
|
+
`BatchWriteAllIncompleteError` is thrown by `deleteThread`, `clearSession`, `putWrites`, and the history append rollback path when a multi-chunk `BatchWriteItem` sequence doesn't fully drain. It carries `succeededChunks` / `totalChunks` / `failedChunks` so a caller can tell how much of the batch actually persisted before the failure, rather than just seeing the first chunk's raw error.
|
|
229
236
|
|
|
230
237
|
## Logging
|
|
231
238
|
|
|
@@ -322,10 +329,10 @@ When S3 offloading is enabled, on the bucket/objects: `s3:GetObject`, `s3:PutObj
|
|
|
322
329
|
## Production notes
|
|
323
330
|
|
|
324
331
|
- **Sharing one table** across all three adapters is supported — their key spaces don't collide, and table-wide reads filter to their own items. Checkpointer, chat-history, and *scoped* store reads are all partition-scoped (`Query`/`GetItem`).
|
|
325
|
-
- **Scoped reads are `Query`s.** `store.search`/`store.listNamespaces` with a concrete namespace prefix and `history.getMessages` are native `Query`s. Only a rootless `store.search([])` / unprefixed `listNamespaces` and `history.listSessions` fall back to `Scan` (cost scales with table size) — keep those rare or use a dedicated table.
|
|
332
|
+
- **Scoped reads are `Query`s.** `store.search`/`store.listNamespaces` with a concrete namespace prefix and `history.getMessages` are native `Query`s. Only a rootless `store.search([])` / unprefixed `listNamespaces` and `history.listSessions` fall back to `Scan` (cost scales with table size) — keep those rare or use a dedicated table. `listSessions` accepts an optional `{ maxIterations }` override for tables where non-session rows dominate the scan.
|
|
326
333
|
- **Hot partitions.** The store's partition key is `namespace[0]` and chat history's is `sessionId`. A single partition tops out around ~1000 WCU / 3000 RCU, so avoid funneling very high write throughput through one tenant/session id; spread load across scope roots (e.g. include a tenant id as `namespace[0]`).
|
|
327
334
|
- **Very large vector corpora** outgrow the in-DB ranker (`maxSearchCandidates`). Configure a `vectorBackend` (OpenSearch, pgvector, …) — the library keeps DynamoDB as the source of truth and only delegates similarity ranking.
|
|
328
|
-
- **TTL deletion timing** is governed by DynamoDB (typically within 48 h of expiry) and S3 lifecycle expiry is day-granular — the library writes the correct expiry timestamp
|
|
335
|
+
- **TTL deletion timing** is governed by DynamoDB (typically within 48 h of expiry) and S3 lifecycle expiry is day-granular — the library writes the correct expiry timestamp (and filters expired chat messages on read) but does not guarantee instant deletion. The matching S3 lifecycle rule is not written automatically: it is installed only when you call `ensureS3LifecycleRule()`.
|
|
329
336
|
|
|
330
337
|
## Testing
|
|
331
338
|
|
|
@@ -37,7 +37,7 @@ async function flushBuffer(context, buffer) {
|
|
|
37
37
|
*/
|
|
38
38
|
async function deleteThread(context, threadId) {
|
|
39
39
|
(0, primitives_1.validateNonEmptyString)(threadId, 'threadId');
|
|
40
|
-
const params = (0, query_1.partitionQuery)(context.tableName, (0, keys_1.partitionKey)(threadId));
|
|
40
|
+
const params = (0, query_1.partitionQuery)(context.tableName, (0, keys_1.partitionKey)(threadId), { consistent: true });
|
|
41
41
|
const buffer = { keys: [], descriptors: [] };
|
|
42
42
|
const pages = (0, paginate_1.paginateQuery)({
|
|
43
43
|
client: context.client,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete-thread.js","sourceRoot":"","sources":["../../../src/checkpointer/actions/delete-thread.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"delete-thread.js","sourceRoot":"","sources":["../../../src/checkpointer/actions/delete-thread.ts"],"names":[],"mappings":";;;AACA,wEAAmE;AACnE,2DAAiE;AACjE,sDAAyD;AACzD,mEAAkE;AAClE,6DAA+D;AAC/D,mEAA4E;AAC5E,2CAAgD;AAChD,6CAAmD;AAiBnD,uFAAuF;AACvF,SAAS,UAAU,CAAC,MAAoB,EAAE,IAAmB;IAC3D,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IAC/C,KAAK,MAAM,UAAU,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACtE,IAAI,UAAU;YAAE,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACtD,CAAC;AACH,CAAC;AAED,sFAAsF;AACtF,KAAK,UAAU,WAAW,CAAC,OAA4B,EAAE,MAAoB;IAC3E,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IACrC,MAAM,IAAA,2BAAa,EACjB,OAAO,CAAC,MAAM,EACd,OAAO,CAAC,SAAS,EACjB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,aAAa,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CACvD,CAAC;IACF,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACtB,MAAM,IAAA,0BAAgB,EACpB,OAAO,CAAC,SAAS,EACjB,IAAA,+BAAa,EAAC,MAAM,CAAC,WAAW,CAAC,EACjC,cAAc,EACd,OAAO,CAAC,MAAM,CACf,CAAC;IACJ,CAAC;IACD,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;IACjB,MAAM,CAAC,WAAW,GAAG,EAAE,CAAC;AAC1B,CAAC;AAED;;;;;;GAMG;AACI,KAAK,uBAAuB,OAA4B,EAAE,QAAgB;IAC/E,IAAA,mCAAsB,EAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,IAAA,sBAAc,EAAC,OAAO,CAAC,SAAS,EAAE,IAAA,mBAAY,EAAC,QAAQ,CAAC,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/F,MAAM,MAAM,GAAiB,EAAE,IAAI,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;IAC3D,MAAM,KAAK,GAAG,IAAA,wBAAa,EAAC;QAC1B,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM;QACN,QAAQ,EAAE,MAAM,CAAC,iBAAiB;QAClC,aAAa,EAAE,MAAM,CAAC,iBAAiB;KACxC,CAAC,CAAC;IACH,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QAC9B,UAAU,CAAC,MAAM,EAAE,GAAoB,CAAC,CAAC;QACzC,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,2BAAe;YAAE,MAAM,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAChF,CAAC;IACD,MAAM,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AACrC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-tuple.js","sourceRoot":"","sources":["../../../src/checkpointer/actions/get-tuple.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"get-tuple.js","sourceRoot":"","sources":["../../../src/checkpointer/actions/get-tuple.ts"],"names":[],"mappings":";;;AAGA,mDAAqD;AACrD,2DAA4D;AAC5D,6CAAoD;AAGpD;;;;GAIG;AACI,KAAK,6BACV,OAA4B,EAC5B,MAAsB;IAEtB,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,IAAA,+BAAgB,EAAC,MAAM,CAAC,CAAC;IAC1E,MAAM,IAAI,GAAG,MAAM,IAAA,uBAAe,EAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;IAClF,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,OAAO,IAAA,wBAAa,EAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;AAC9D,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/actions/list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAS9F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AA2B7D;;;;GAIG;AACH,wBAAuB,eAAe,CACpC,OAAO,EAAE,mBAAmB,EAC5B,MAAM,EAAE,cAAc,EACtB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,cAAc,CAAC,eAAe,CAAC,
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/actions/list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAS9F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AA2B7D;;;;GAIG;AACH,wBAAuB,eAAe,CACpC,OAAO,EAAE,mBAAmB,EAC5B,MAAM,EAAE,cAAc,EACtB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,cAAc,CAAC,eAAe,CAAC,CAqBjC"}
|
|
@@ -29,7 +29,7 @@ async function passesMetadataFilter(context, meta, filter) {
|
|
|
29
29
|
* (metadata equality), and `options.limit` (max tuples yielded).
|
|
30
30
|
*/
|
|
31
31
|
async function* listCheckpoints(context, config, options) {
|
|
32
|
-
const { threadId, checkpointNs } = (0, configurable_1.readConfigurable)(config);
|
|
32
|
+
const { threadId, checkpointNs, checkpointId } = (0, configurable_1.readConfigurable)(config);
|
|
33
33
|
const { before, filter, limit } = readListOptions(options);
|
|
34
34
|
const params = (0, query_1.beginsWithQuery)(context.tableName, (0, keys_1.partitionKey)(threadId), (0, keys_1.metaSortKeyPrefix)(checkpointNs));
|
|
35
35
|
let yielded = 0;
|
|
@@ -37,6 +37,8 @@ async function* listCheckpoints(context, config, options) {
|
|
|
37
37
|
if (limit !== undefined && yielded >= limit)
|
|
38
38
|
return;
|
|
39
39
|
const meta = raw;
|
|
40
|
+
if (checkpointId !== undefined && meta.checkpointId !== checkpointId)
|
|
41
|
+
continue;
|
|
40
42
|
if (before !== undefined && meta.checkpointId >= before)
|
|
41
43
|
continue;
|
|
42
44
|
if (!(await passesMetadataFilter(context, meta, filter)))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/checkpointer/actions/list.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/checkpointer/actions/list.ts"],"names":[],"mappings":";;;AAGA,6DAA+D;AAC/D,mDAAqD;AACrD,2DAA4D;AAC5D,2DAA2E;AAC3E,yDAAuD;AACvD,2CAAmE;AACnE,6CAAoD;AAIpD,kDAAkD;AAClD,SAAS,eAAe,CAAC,OAA+B;IAKtD,OAAO;QACL,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,aAAmC;QAC1E,MAAM,EAAE,OAAO,EAAE,MAAiD;QAClE,KAAK,EAAE,OAAO,EAAE,KAAK;KACtB,CAAC;AACJ,CAAC;AAED,uEAAuE;AACvE,KAAK,UAAU,oBAAoB,CACjC,OAA4B,EAC5B,IAAwB,EACxB,MAA+C;IAE/C,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,MAAM,QAAQ,GAAG,CAAC,MAAM,IAAA,0BAAY,EAAC,OAAO,EAAE,IAAI,CAAC,CAAgC,CAAC;IACpF,OAAO,IAAA,4BAAa,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AACzC,CAAC;AAED;;;;GAIG;AACI,KAAK,SAAS,CAAC,iBACpB,OAA4B,EAC5B,MAAsB,EACtB,OAA+B;IAE/B,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,IAAA,+BAAgB,EAAC,MAAM,CAAC,CAAC;IAC1E,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,IAAA,uBAAe,EAC5B,OAAO,CAAC,SAAS,EACjB,IAAA,mBAAY,EAAC,QAAQ,CAAC,EACtB,IAAA,wBAAiB,EAAC,YAAY,CAAC,CAChC,CAAC;IACF,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,IAAA,wBAAa,EAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QAC1E,IAAI,KAAK,KAAK,SAAS,IAAI,OAAO,IAAI,KAAK;YAAE,OAAO;QACpD,MAAM,IAAI,GAAG,GAAyB,CAAC;QACvC,IAAI,YAAY,KAAK,SAAS,IAAI,IAAI,CAAC,YAAY,KAAK,YAAY;YAAE,SAAS;QAC/E,IAAI,MAAM,KAAK,SAAS,IAAI,IAAI,CAAC,YAAY,IAAI,MAAM;YAAE,SAAS;QAClE,IAAI,CAAC,CAAC,MAAM,oBAAoB,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YAAE,SAAS;QACnE,MAAM,KAAK,GAAG,MAAM,IAAA,wBAAa,EAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;QACzE,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,KAAK,CAAC;YACZ,OAAO,IAAI,CAAC,CAAC;QACf,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -4,6 +4,12 @@ import type { CheckpointerContext } from '../internal/setup';
|
|
|
4
4
|
/**
|
|
5
5
|
* Persist a task's intermediate writes for a checkpoint as one item per write.
|
|
6
6
|
* Requires `checkpoint_id` in the config — writes always attach to a checkpoint.
|
|
7
|
+
* Regular writes are first-write-wins (matching the reference checkpointer
|
|
8
|
+
* contract); special negative-index writes always overwrite (see
|
|
9
|
+
* {@link writeSpecialItems}). Failure cleanup only ever targets regular items
|
|
10
|
+
* known never to have committed (see {@link RegularWriteOutcome}) — never a
|
|
11
|
+
* special item or a lost guard, so an upload can leak but a live row can
|
|
12
|
+
* never be stranded pointing at a deleted object.
|
|
7
13
|
*/
|
|
8
14
|
export declare function putWrites(context: CheckpointerContext, config: RunnableConfig, writes: PendingWrite[], taskId: string): Promise<void>;
|
|
9
15
|
//# sourceMappingURL=put-writes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"put-writes.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/actions/put-writes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"put-writes.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/actions/put-writes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAUpE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AA6F7D;;;;;;;;;GASG;AACH,wBAAsB,SAAS,CAC7B,OAAO,EAAE,mBAAmB,EAC5B,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,YAAY,EAAE,EACtB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CA4Bf"}
|
|
@@ -1,17 +1,82 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.putWrites = putWrites;
|
|
4
|
+
const node_crypto_1 = require("node:crypto");
|
|
4
5
|
const descriptor_keys_1 = require("../../shared/codec/descriptor-keys");
|
|
5
6
|
const orphans_1 = require("../../shared/codec/s3/orphans");
|
|
6
7
|
const batch_write_1 = require("../../shared/dynamodb/batch-write");
|
|
8
|
+
const retry_1 = require("../../shared/dynamodb/retry");
|
|
7
9
|
const errors_1 = require("../../shared/errors/errors");
|
|
8
10
|
const ttl_1 = require("../../shared/validation/ttl");
|
|
9
11
|
const configurable_1 = require("../internal/configurable");
|
|
10
12
|
const item_writer_1 = require("../internal/item-writer");
|
|
11
13
|
const validation_1 = require("../internal/validation");
|
|
14
|
+
/**
|
|
15
|
+
* True when the first-write-wins guard rejected a write — NOT evidence a
|
|
16
|
+
* *competitor* wrote that row. A `PutCommand` retried after its response was
|
|
17
|
+
* lost (`ETIMEDOUT`/`NetworkingError`/`ECONNRESET`) re-hits the row it
|
|
18
|
+
* committed itself and fails identically; the two cases are indistinguishable.
|
|
19
|
+
*/
|
|
20
|
+
function isConditionalCheckFailed(error) {
|
|
21
|
+
return error.name === 'ConditionalCheckFailedException';
|
|
22
|
+
}
|
|
23
|
+
/** Best-effort delete `items`' offloaded S3 objects, if an offloader is configured. */
|
|
24
|
+
async function cleanUpItems(context, items) {
|
|
25
|
+
if (!context.offloader)
|
|
26
|
+
return;
|
|
27
|
+
await (0, orphans_1.cleanUpS3Orphans)(context.offloader, (0, descriptor_keys_1.collectS3Keys)(items.map((item) => item.value)), 'putWrites', context.logger);
|
|
28
|
+
}
|
|
29
|
+
/** Dedup by sort key (last-write-wins), matching LangGraph's special-write semantics. */
|
|
30
|
+
function dedupeBySortKey(items) {
|
|
31
|
+
return [...new Map(items.map((item) => [item.SK, item])).values()];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Write special (negative-index) items unconditionally — overwrite is correct
|
|
35
|
+
* there, matching every reference checkpointer implementation. Their key is
|
|
36
|
+
* deterministic, so a failed batch never triggers S3 cleanup here either: the
|
|
37
|
+
* next write to the same channel overwrites the same key (self-healing);
|
|
38
|
+
* deleting now could strand a row a previous call already committed.
|
|
39
|
+
*/
|
|
40
|
+
async function writeSpecialItems(context, items) {
|
|
41
|
+
if (items.length === 0)
|
|
42
|
+
return;
|
|
43
|
+
await (0, batch_write_1.batchWriteAll)(context.client, context.tableName, items.map((item) => ({ PutRequest: { Item: item } })));
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Write regular items with a first-write-wins guard. Every `PutCommand` fully
|
|
47
|
+
* settles (`Promise.allSettled`) before this resolves and never rejects; a
|
|
48
|
+
* genuine failure is reported via `error`, not thrown.
|
|
49
|
+
*/
|
|
50
|
+
async function writeRegularItems(context, items) {
|
|
51
|
+
const failed = [];
|
|
52
|
+
let error;
|
|
53
|
+
const results = await Promise.allSettled(items.map((item) => (0, retry_1.withDynamoDBRetry)(() => context.client.put({
|
|
54
|
+
TableName: context.tableName,
|
|
55
|
+
Item: item,
|
|
56
|
+
ConditionExpression: 'attribute_not_exists(PK)',
|
|
57
|
+
}))));
|
|
58
|
+
results.forEach((result, index) => {
|
|
59
|
+
if (result.status === 'fulfilled')
|
|
60
|
+
return;
|
|
61
|
+
const reason = result.reason;
|
|
62
|
+
if (isConditionalCheckFailed(reason)) {
|
|
63
|
+
context.logger.debug('putWrites: lost the guard', { sortKey: items[index].SK });
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
failed.push(items[index]);
|
|
67
|
+
error = error ?? reason;
|
|
68
|
+
});
|
|
69
|
+
return { failed, error };
|
|
70
|
+
}
|
|
12
71
|
/**
|
|
13
72
|
* Persist a task's intermediate writes for a checkpoint as one item per write.
|
|
14
73
|
* Requires `checkpoint_id` in the config — writes always attach to a checkpoint.
|
|
74
|
+
* Regular writes are first-write-wins (matching the reference checkpointer
|
|
75
|
+
* contract); special negative-index writes always overwrite (see
|
|
76
|
+
* {@link writeSpecialItems}). Failure cleanup only ever targets regular items
|
|
77
|
+
* known never to have committed (see {@link RegularWriteOutcome}) — never a
|
|
78
|
+
* special item or a lost guard, so an upload can leak but a live row can
|
|
79
|
+
* never be stranded pointing at a deleted object.
|
|
15
80
|
*/
|
|
16
81
|
async function putWrites(context, config, writes, taskId) {
|
|
17
82
|
(0, validation_1.validateTaskId)(taskId);
|
|
@@ -22,15 +87,17 @@ async function putWrites(context, config, writes, taskId) {
|
|
|
22
87
|
if (writes.length === 0)
|
|
23
88
|
return;
|
|
24
89
|
const ttlTimestamp = context.ttl ? (0, ttl_1.calculateTtlTimestamp)(context.ttl) : undefined;
|
|
25
|
-
const items = await (0, item_writer_1.buildWriteItems)(context, threadId, checkpointNs, checkpointId, taskId, writes, ttlTimestamp);
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
90
|
+
const items = await (0, item_writer_1.buildWriteItems)(context, threadId, checkpointNs, checkpointId, taskId, writes, (0, node_crypto_1.randomUUID)(), ttlTimestamp);
|
|
91
|
+
const special = dedupeBySortKey(items.filter((item) => item.index < 0));
|
|
92
|
+
const regular = items.filter((item) => item.index >= 0);
|
|
93
|
+
const [specialError, regularOutcome] = await Promise.all([
|
|
94
|
+
writeSpecialItems(context, special).catch((error) => error),
|
|
95
|
+
writeRegularItems(context, regular),
|
|
96
|
+
]);
|
|
97
|
+
const firstError = specialError ?? regularOutcome.error;
|
|
98
|
+
if (!firstError)
|
|
99
|
+
return;
|
|
100
|
+
await cleanUpItems(context, regularOutcome.failed);
|
|
101
|
+
throw firstError;
|
|
35
102
|
}
|
|
36
103
|
//# sourceMappingURL=put-writes.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"put-writes.js","sourceRoot":"","sources":["../../../src/checkpointer/actions/put-writes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"put-writes.js","sourceRoot":"","sources":["../../../src/checkpointer/actions/put-writes.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"put.js","sourceRoot":"","sources":["../../../src/checkpointer/actions/put.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"put.js","sourceRoot":"","sources":["../../../src/checkpointer/actions/put.ts"],"names":[],"mappings":";;;AAGA,wEAAmE;AACnE,2DAAiE;AACjE,uDAAgE;AAChE,qDAAoE;AACpE,2DAA4D;AAC5D,yDAA+D;AAG/D;;;;GAIG;AACI,KAAK,wBACV,OAA4B,EAC5B,MAAsB,EACtB,UAAsB,EACtB,QAA4B;IAE5B,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,GAAG,IAAA,+BAAgB,EAAC,MAAM,CAAC,CAAC;IAC9F,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAA,2BAAqB,EAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAClF,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,IAAA,kCAAoB,EAClD,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,kBAAkB,EAClB,YAAY,CACb,CAAC;IACF,IAAI,CAAC;QACH,MAAM,IAAA,yBAAiB,EAAC,GAAG,EAAE,CAC3B,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC;YAC3B,aAAa,EAAE;gBACb,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;gBACrD,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;aACzD;SACF,CAAC,CACH,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;YACtB,MAAM,IAAA,0BAAgB,EACpB,OAAO,CAAC,SAAS,EACjB,IAAA,+BAAa,EAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,EAClD,KAAK,EACL,OAAO,CAAC,MAAM,CACf,CAAC;QACJ,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;IACD,OAAO;QACL,YAAY,EAAE;YACZ,SAAS,EAAE,QAAQ;YACnB,aAAa,EAAE,YAAY;YAC3B,aAAa,EAAE,UAAU,CAAC,EAAE;SAC7B;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assemble.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/assemble.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"assemble.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/assemble.ts"],"names":[],"mappings":";;;AAIA,mCAA2D;AAC3D,+CAA6D;AAG7D,2DAA2D;AAC3D,SAAS,SAAS,CAAC,QAAgB,EAAE,YAAoB,EAAE,YAAoB;IAC7E,OAAO;QACL,YAAY,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE;KAChG,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACI,KAAK,wBACV,OAA4B,EAC5B,QAAgB,EAChB,YAAoB,EACpB,IAAwB;IAExB,MAAM,OAAO,GAAG,MAAM,IAAA,oBAAY,EAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IACvF,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAC/B,MAAM,CAAC,UAAU,EAAE,QAAQ,EAAE,aAAa,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC9D,IAAA,4BAAc,EAAC,OAAO,EAAE,OAAO,CAAC;QAChC,IAAA,0BAAY,EAAC,OAAO,EAAE,IAAI,CAAC;QAC3B,IAAA,0BAAkB,EAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC;KACvE,CAAC,CAAC;IACH,MAAM,KAAK,GAAoB;QAC7B,MAAM,EAAE,SAAS,CAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC;QAC5D,UAAU;QACV,QAAQ;QACR,aAAa;KACd,CAAC;IACF,IAAI,IAAI,CAAC,kBAAkB,KAAK,SAAS,EAAE,CAAC;QAC1C,KAAK,CAAC,YAAY,GAAG,SAAS,CAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAClF,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configurable.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/configurable.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"configurable.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/configurable.ts"],"names":[],"mappings":";;;AAGA,6CAA4F;AAS5F;;;GAGG;AACH,0BAAiC,MAAsB;IACrD,MAAM,YAAY,GAAG,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,CAA2B,CAAC;IAC3E,IAAA,6BAAgB,EAAC,YAAY,CAAC,SAAS,CAAC,CAAC;IACzC,MAAM,YAAY,GAAG,YAAY,CAAC,aAAa,IAAI,EAAE,CAAC;IACtD,IAAA,iCAAoB,EAAC,YAAY,CAAC,CAAC;IACnC,IAAI,YAAY,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;QAC7C,IAAA,iCAAoB,EAAC,YAAY,CAAC,aAAa,CAAC,CAAC;IACnD,CAAC;IACD,OAAO;QACL,QAAQ,EAAE,YAAY,CAAC,SAAS;QAChC,YAAY;QACZ,YAAY,EAAE,YAAY,CAAC,aAAa;KACzC,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/fetch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/fetch.ts"],"names":[],"mappings":";;;;;AAEA,6DAA+D;AAC/D,uDAAgE;AAEhE,+CAAgD;AAChD,iCAMgB;AAChB,mCAA0C;AAG1C,sFAAsF;AAC/E,KAAK,0BACV,OAA4B,EAC5B,QAAgB,EAChB,YAAoB,EACpB,YAAqB;IAErB,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,MAAM,IAAA,yBAAiB,EAAC,GAAG,EAAE,CAC1C,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC;YACjB,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,GAAG,EAAE,EAAE,EAAE,EAAE,IAAA,mBAAY,EAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,IAAA,kBAAW,EAAC,YAAY,EAAE,YAAY,CAAC,EAAE;YAChF,cAAc,EAAE,IAAI;SACrB,CAAC,CACH,CAAC;QACF,OAAO,MAAM,CAAC,IAAsC,CAAC;IACvD,CAAC;IACD,MAAM,MAAM,GAAG,IAAA,uBAAe,EAC5B,OAAO,CAAC,SAAS,EACjB,IAAA,mBAAY,EAAC,QAAQ,CAAC,EACtB,IAAA,wBAAiB,EAAC,YAAY,CAAC,EAC/B;QACE,KAAK,EAAE,CAAC;QACR,UAAU,EAAE,IAAI;KACjB,CACF,CAAC;IACF,MAAM,MAAM,GAAG,MAAM,IAAA,yBAAiB,EAAC,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3E,OAAO,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAmC,CAAC;AAC7D,CAAC;AAED,+CAA+C;AACxC,KAAK,uBACV,OAA4B,EAC5B,QAAgB,EAChB,YAAoB,EACpB,YAAoB;IAEpB,MAAM,MAAM,GAAG,MAAM,IAAA,yBAAiB,EAAC,GAAG,EAAE,CAC1C,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC;QACjB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,GAAG,EAAE,EAAE,EAAE,EAAE,IAAA,mBAAY,EAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,IAAA,qBAAc,EAAC,YAAY,EAAE,YAAY,CAAC,EAAE;QACnF,cAAc,EAAE,IAAI;KACrB,CAAC,CACH,CAAC;IACF,OAAO,MAAM,CAAC,IAAyC,CAAC;AAC1D,CAAC;AAED,6EAA6E;AACtE,KAAK,6BACV,OAA4B,EAC5B,QAAgB,EAChB,YAAoB,EACpB,YAAoB;IAEpB,MAAM,MAAM,GAAG,IAAA,uBAAe,EAC5B,OAAO,CAAC,SAAS,EACjB,IAAA,mBAAY,EAAC,QAAQ,CAAC,EACtB,IAAA,yBAAkB,EAAC,YAAY,EAAE,YAAY,CAAC,EAC9C,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CACtC,CAAC;IACF,MAAM,KAAK,GAA0B,EAAE,CAAC;IACxC,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,IAAA,wBAAa,EAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QAC3E,KAAK,CAAC,IAAI,CAAC,IAA2B,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,IAAA,6BAAe,EAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter-match.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/internal/filter-match.ts"],"names":[],"mappings":"AAEA,wDAAwD;AACxD,MAAM,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"filter-match.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/internal/filter-match.ts"],"names":[],"mappings":"AAEA,wDAAwD;AACxD,MAAM,MAAM,WAAW,GACrB,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,WAAW,EAAE,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAAA;CAAE,CAAC;AAEpF;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACrC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GAClC,OAAO,CAET"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter-match.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/filter-match.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"filter-match.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/filter-match.ts"],"names":[],"mappings":";;;AAAA,yCAA8C;AAM9C;;;;;GAKG;AACH,uBACE,QAAqC,EACrC,MAAmC;IAEnC,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,IAAA,6BAAiB,EAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;AACjG,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"item-reader.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/item-reader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"item-reader.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/item-reader.ts"],"names":[],"mappings":";;;;;AAMA,oDAAyD;AAEzD,+CAA0C;AAG1C,sDAAsD;AAC/C,KAAK,yBACV,OAA4B,EAC5B,IAA2B;IAE3B,OAAO,IAAA,qBAAa,EAAa,IAAI,CAAC,UAAU,EAAE,IAAA,uBAAS,EAAC,OAAO,CAAC,CAAC,CAAC;AACxE,CAAC;AAED,iDAAiD;AAC1C,KAAK,uBACV,OAA4B,EAC5B,IAAwB;IAExB,OAAO,IAAA,qBAAa,EAAqB,IAAI,CAAC,QAAQ,EAAE,IAAA,uBAAS,EAAC,OAAO,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED,+EAA+E;AACxE,KAAK,0BACV,OAA4B,EAC5B,KAA4B;IAE5B,MAAM,IAAI,GAAG,IAAA,uBAAS,EAAC,OAAO,CAAC,CAAC;IAChC,MAAM,OAAO,GAA6B,EAAE,CAAC;IAC7C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,MAAM,IAAA,qBAAa,EAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -9,6 +9,17 @@ export declare function buildCheckpointItems(context: CheckpointerContext, threa
|
|
|
9
9
|
meta: CheckpointMetaItem;
|
|
10
10
|
payload: CheckpointPayloadItem;
|
|
11
11
|
}>;
|
|
12
|
-
/**
|
|
13
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Encode a task's pending writes into one item per write. `nonce` must be
|
|
14
|
+
* unique per `putWrites` *call* (not per write) and is appended to the S3
|
|
15
|
+
* offload keyParts of **regular (non-negative-index) writes only** — the ones
|
|
16
|
+
* written conditionally, first-write-wins. There, repeated/concurrent attempts
|
|
17
|
+
* for the same (thread, checkpoint, task, index) must never share an S3
|
|
18
|
+
* location, so a failed attempt's cleanup can only ever delete its own upload.
|
|
19
|
+
* Special (negative-index) writes are overwritten in place, so their key stays
|
|
20
|
+
* deterministic: nonce'ing it would strand the previous upload — referenced by
|
|
21
|
+
* nothing, tracked by nothing, cleaned up by nothing — on every rewrite of the
|
|
22
|
+
* same special channel.
|
|
23
|
+
*/
|
|
24
|
+
export declare function buildWriteItems(context: CheckpointerContext, threadId: string, checkpointNs: string, checkpointId: string, taskId: string, writes: PendingWrite[], nonce: string, ttlTimestamp?: number): Promise<CheckpointWriteItem[]>;
|
|
14
25
|
//# sourceMappingURL=item-writer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"item-writer.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/internal/item-writer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAGpG,OAAO,EAAE,KAAK,SAAS,EAAiB,MAAM,0BAA0B,CAAC;AACzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAE/F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEnD,gDAAgD;AAChD,wBAAgB,SAAS,CAAC,OAAO,EAAE,mBAAmB,GAAG,SAAS,CAEjE;AAOD,sEAAsE;AACtE,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,mBAAmB,EAC5B,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,kBAAkB,EAC5B,kBAAkB,CAAC,EAAE,MAAM,EAC3B,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,OAAO,EAAE,qBAAqB,CAAA;CAAE,CAAC,CAwBvE;AAED
|
|
1
|
+
{"version":3,"file":"item-writer.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/internal/item-writer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAGpG,OAAO,EAAE,KAAK,SAAS,EAAiB,MAAM,0BAA0B,CAAC;AACzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAE/F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEnD,gDAAgD;AAChD,wBAAgB,SAAS,CAAC,OAAO,EAAE,mBAAmB,GAAG,SAAS,CAEjE;AAOD,sEAAsE;AACtE,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,mBAAmB,EAC5B,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,kBAAkB,EAC5B,kBAAkB,CAAC,EAAE,MAAM,EAC3B,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,OAAO,EAAE,qBAAqB,CAAA;CAAE,CAAC,CAwBvE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,mBAAmB,EAC5B,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,YAAY,EAAE,EACtB,KAAK,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAsBhC"}
|
|
@@ -42,16 +42,28 @@ async function buildCheckpointItems(context, threadId, checkpointNs, checkpoint,
|
|
|
42
42
|
};
|
|
43
43
|
return { meta: withTtl(meta, ttlTimestamp), payload: withTtl(payload, ttlTimestamp) };
|
|
44
44
|
}
|
|
45
|
-
/**
|
|
46
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Encode a task's pending writes into one item per write. `nonce` must be
|
|
47
|
+
* unique per `putWrites` *call* (not per write) and is appended to the S3
|
|
48
|
+
* offload keyParts of **regular (non-negative-index) writes only** — the ones
|
|
49
|
+
* written conditionally, first-write-wins. There, repeated/concurrent attempts
|
|
50
|
+
* for the same (thread, checkpoint, task, index) must never share an S3
|
|
51
|
+
* location, so a failed attempt's cleanup can only ever delete its own upload.
|
|
52
|
+
* Special (negative-index) writes are overwritten in place, so their key stays
|
|
53
|
+
* deterministic: nonce'ing it would strand the previous upload — referenced by
|
|
54
|
+
* nothing, tracked by nothing, cleaned up by nothing — on every rewrite of the
|
|
55
|
+
* same special channel.
|
|
56
|
+
*/
|
|
57
|
+
async function buildWriteItems(context, threadId, checkpointNs, checkpointId, taskId, writes, nonce, ttlTimestamp) {
|
|
47
58
|
const deps = codecDeps(context);
|
|
48
59
|
const pk = (0, keys_1.partitionKey)(threadId);
|
|
49
60
|
const items = [];
|
|
50
61
|
for (let positional = 0; positional < writes.length; positional++) {
|
|
51
62
|
const [channel, value] = writes[positional];
|
|
52
63
|
const index = langgraph_checkpoint_1.WRITES_IDX_MAP[channel] ?? positional;
|
|
64
|
+
const baseKeyParts = [threadId, checkpointNs, checkpointId, taskId, `write-${index}`];
|
|
53
65
|
const descriptor = await (0, codec_1.encodePayload)(value, deps, {
|
|
54
|
-
keyParts:
|
|
66
|
+
keyParts: index < 0 ? baseKeyParts : [...baseKeyParts, nonce],
|
|
55
67
|
});
|
|
56
68
|
const item = {
|
|
57
69
|
PK: pk,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"item-writer.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/item-writer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"item-writer.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/item-writer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/keys.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/keys.ts"],"names":[],"mappings":";;;;;;;;;AAAA,kFAAkF;AACrE,QAAA,kBAAkB,GAAG,GAAG,CAAC;AAEtC,4EAA4E;AAC5E,MAAM,qBAAqB,GAAG,EAAE,CAAC;AAEjC;;;;GAIG;AACH,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAE7B,6EAA6E;AAC7E,IAAK,kBAIJ;AAJD,WAAK,kBAAkB;IACrB,mCAAa,CAAA;IACb,yCAAmB,CAAA;IACnB,qCAAe,CAAA;AACjB,CAAC,EAJI,kBAAkB,KAAlB,kBAAkB,QAItB;AAED,wDAAwD;AACxD,sBAA6B,QAAgB;IAC3C,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,6DAA6D;AAC7D,qBAA4B,YAAoB,EAAE,YAAoB;IACpE,OAAO,GAAG,kBAAkB,CAAC,IAAI,GAAG,QAAA,kBAAkB,GAAG,YAAY,GAAG,QAAA,kBAAkB,GAAG,YAAY,EAAE,CAAC;AAC9G,CAAC;AAED,gFAAgF;AAChF,2BAAkC,YAAoB;IACpD,OAAO,GAAG,kBAAkB,CAAC,IAAI,GAAG,QAAA,kBAAkB,GAAG,YAAY,GAAG,QAAA,kBAAkB,EAAE,CAAC;AAC/F,CAAC;AAED,sDAAsD;AACtD,wBAA+B,YAAoB,EAAE,YAAoB;IACvE,OAAO,GAAG,kBAAkB,CAAC,OAAO,GAAG,QAAA,kBAAkB,GAAG,YAAY,GAAG,QAAA,kBAAkB,GAAG,YAAY,EAAE,CAAC;AACjH,CAAC;AAED,2CAA2C;AAC3C,sBACE,YAAoB,EACpB,YAAoB,EACpB,MAAc,EACd,KAAa;IAEb,MAAM,WAAW,GAAG,CAAC,KAAK,GAAG,kBAAkB,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qBAAqB,EAAE,GAAG,CAAC,CAAC;IACjG,OAAO,CAAC,kBAAkB,CAAC,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,IAAI,CACrF,QAAA,kBAAkB,CACnB,CAAC;AACJ,CAAC;AAED,0EAA0E;AAC1E,4BAAmC,YAAoB,EAAE,YAAoB;IAC3E,OAAO,GAAG,kBAAkB,CAAC,KAAK,GAAG,QAAA,kBAAkB,GAAG,YAAY,GAAG,QAAA,kBAAkB,GAAG,YAAY,GAAG,QAAA,kBAAkB,EAAE,CAAC;AACpI,CAAC"}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import type { QueryCommandInput } from '@aws-sdk/lib-dynamodb';
|
|
2
|
+
/** Options for {@link partitionQuery}. */
|
|
3
|
+
export interface PartitionQueryOptions {
|
|
4
|
+
consistent?: boolean;
|
|
5
|
+
}
|
|
2
6
|
/** Options for {@link beginsWithQuery}. */
|
|
3
7
|
export interface BeginsWithQueryOptions {
|
|
4
8
|
limit?: number;
|
|
@@ -6,7 +10,7 @@ export interface BeginsWithQueryOptions {
|
|
|
6
10
|
consistent?: boolean;
|
|
7
11
|
}
|
|
8
12
|
/** Build a Query input selecting every item in a partition (all sort keys). */
|
|
9
|
-
export declare function partitionQuery(tableName: string, partition: string): QueryCommandInput;
|
|
13
|
+
export declare function partitionQuery(tableName: string, partition: string, options?: PartitionQueryOptions): QueryCommandInput;
|
|
10
14
|
/**
|
|
11
15
|
* Build a Query input selecting items whose partition equals `partition` and
|
|
12
16
|
* whose sort key begins with `skPrefix`. Names are aliased so reserved words
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/internal/query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,2CAA2C;AAC3C,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/internal/query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,0CAA0C;AAC1C,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,2CAA2C;AAC3C,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,qBAA0B,GAClC,iBAAiB,CASnB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,sBAA2B,GACnC,iBAAiB,CAWnB"}
|
|
@@ -3,13 +3,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.partitionQuery = partitionQuery;
|
|
4
4
|
exports.beginsWithQuery = beginsWithQuery;
|
|
5
5
|
/** Build a Query input selecting every item in a partition (all sort keys). */
|
|
6
|
-
function partitionQuery(tableName, partition) {
|
|
7
|
-
|
|
6
|
+
function partitionQuery(tableName, partition, options = {}) {
|
|
7
|
+
const params = {
|
|
8
8
|
TableName: tableName,
|
|
9
9
|
KeyConditionExpression: '#pk = :pk',
|
|
10
10
|
ExpressionAttributeNames: { '#pk': 'PK' },
|
|
11
11
|
ExpressionAttributeValues: { ':pk': partition },
|
|
12
12
|
};
|
|
13
|
+
if (options.consistent)
|
|
14
|
+
params.ConsistentRead = true;
|
|
15
|
+
return params;
|
|
13
16
|
}
|
|
14
17
|
/**
|
|
15
18
|
* Build a Query input selecting items whose partition equals `partition` and
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/query.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"query.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/query.ts"],"names":[],"mappings":";;;;AAcA,+EAA+E;AAC/E,wBACE,SAAiB,EACjB,SAAiB,EACjB,OAAO,GAA0B,EAAE;IAEnC,MAAM,MAAM,GAAsB;QAChC,SAAS,EAAE,SAAS;QACpB,sBAAsB,EAAE,WAAW;QACnC,wBAAwB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE;QACzC,yBAAyB,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE;KAChD,CAAC;IACF,IAAI,OAAO,CAAC,UAAU;QAAE,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC;IACrD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,yBACE,SAAiB,EACjB,SAAiB,EACjB,QAAgB,EAChB,OAAO,GAA2B,EAAE;IAEpC,MAAM,MAAM,GAAsB;QAChC,SAAS,EAAE,SAAS;QACpB,sBAAsB,EAAE,2CAA2C;QACnE,wBAAwB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;QACtD,yBAAyB,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE;QACtE,gBAAgB,EAAE,OAAO,CAAC,SAAS,IAAI,KAAK;KAC7C,CAAC;IACF,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS;QAAE,MAAM,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC9D,IAAI,OAAO,CAAC,UAAU;QAAE,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC;IACrD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/internal/setup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAE1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/internal/setup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAE1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAExE,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAG9D,OAAO,EAAE,KAAK,MAAM,EAAiB,MAAM,6BAA6B,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAErD,kEAAkE;AAClE,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,gBAAgB,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,kBAAkB,CAAC;IAC1B,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,2DAA2D;AAC3D,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,mBAAmB,CAAC;IAC7B,SAAS,EAAE,cAAc,GAAG,SAAS,CAAC;IACtC,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,oBAAoB,EAC7B,KAAK,EAAE,kBAAkB,GACxB,iBAAiB,CAsBnB"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.setUpCheckpointer = setUpCheckpointer;
|
|
4
|
+
const config_1 = require("../../shared/codec/s3/config");
|
|
4
5
|
const offloader_1 = require("../../shared/codec/s3/offloader");
|
|
6
|
+
const constants_1 = require("../../shared/constants");
|
|
5
7
|
const client_1 = require("../../shared/dynamodb/client");
|
|
6
8
|
const logger_1 = require("../../shared/logging/logger");
|
|
7
9
|
/**
|
|
@@ -11,7 +13,12 @@ const logger_1 = require("../../shared/logging/logger");
|
|
|
11
13
|
*/
|
|
12
14
|
function setUpCheckpointer(options, serde) {
|
|
13
15
|
const resolved = (0, client_1.resolveDynamoDBClient)(options);
|
|
14
|
-
const offloader = options.s3
|
|
16
|
+
const offloader = options.s3
|
|
17
|
+
? new offloader_1.S3Offloader({
|
|
18
|
+
...options.s3,
|
|
19
|
+
keyPrefix: options.s3.keyPrefix ?? (0, config_1.defaultAdapterKeyPrefix)(constants_1.DEFAULT_S3_KEY_PREFIX, 'checkpointer'),
|
|
20
|
+
})
|
|
21
|
+
: undefined;
|
|
15
22
|
return {
|
|
16
23
|
context: {
|
|
17
24
|
client: resolved.client,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/setup.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/setup.ts"],"names":[],"mappings":";;;AAKA,yDAAuE;AACvE,+DAA8D;AAC9D,sDAA+D;AAC/D,yDAAqE;AACrE,wDAAyE;AAsBzE;;;;GAIG;AACH,2BACE,OAA6B,EAC7B,KAAyB;IAEzB,MAAM,QAAQ,GAAG,IAAA,8BAAqB,EAAC,OAAO,CAAC,CAAC;IAChD,MAAM,SAAS,GAAG,OAAO,CAAC,EAAE;QAC1B,CAAC,CAAC,IAAI,uBAAW,CAAC;YACd,GAAG,OAAO,CAAC,EAAE;YACb,SAAS,EACP,OAAO,CAAC,EAAE,CAAC,SAAS,IAAI,IAAA,gCAAuB,EAAC,iCAAqB,EAAE,cAAc,CAAC;SACzF,CAAC;QACJ,CAAC,CAAC,SAAS,CAAC;IACd,OAAO;QACL,OAAO,EAAE;YACP,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,KAAK;YACL,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,SAAS;YACT,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,MAAM,EAAE,IAAA,sBAAa,EAAC,OAAO,CAAC,MAAM,CAAC;SACtC;QACD,SAAS,EAAE,QAAQ,CAAC,SAAS;QAC7B,UAAU,EAAE,QAAQ,CAAC,UAAU;KAChC,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/validation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/validation.ts"],"names":[],"mappings":";;;;;;AAAA,mEAA+F;AAC/F,iCAA4C;AAE5C,kEAAkE;AAClE,0BAAiC,QAAgB;IAC/C,IAAA,mCAAsB,EAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IAC9C,IAAA,8BAAiB,EAAC,QAAQ,EAAE,yBAAkB,EAAE,WAAW,CAAC,CAAC;AAC/D,CAAC;AAED,uFAAuF;AACvF,8BAAqC,YAAoB;IACvD,IAAA,8BAAiB,EAAC,YAAY,EAAE,yBAAkB,EAAE,eAAe,CAAC,CAAC;AACvE,CAAC;AAED,sEAAsE;AACtE,8BAAqC,YAAoB;IACvD,IAAA,mCAAsB,EAAC,YAAY,EAAE,eAAe,CAAC,CAAC;IACtD,IAAA,8BAAiB,EAAC,YAAY,EAAE,yBAAkB,EAAE,eAAe,CAAC,CAAC;AACvE,CAAC;AAED,gEAAgE;AAChE,wBAA+B,MAAc;IAC3C,IAAA,mCAAsB,EAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACzC,IAAA,8BAAiB,EAAC,MAAM,EAAE,yBAAkB,EAAE,QAAQ,CAAC,CAAC;AAC1D,CAAC"}
|
|
@@ -17,5 +17,14 @@ export declare class DynamoDBSaver extends BaseCheckpointSaver {
|
|
|
17
17
|
deleteThread(threadId: string): Promise<void>;
|
|
18
18
|
/** Release owned resources (the underlying client and any S3 client). */
|
|
19
19
|
destroy(): void;
|
|
20
|
+
/**
|
|
21
|
+
* Best-effort provision an S3 lifecycle expiration rule matching the
|
|
22
|
+
* configured TTL, so offloaded objects don't outlive their DynamoDB item
|
|
23
|
+
* forever. No-ops when S3 offload or TTL isn't configured. Requires the
|
|
24
|
+
* `s3:GetLifecycleConfiguration`/`s3:PutLifecycleConfiguration` bucket-level
|
|
25
|
+
* permissions (broader than the object-level CRUD the rest of S3 offload
|
|
26
|
+
* needs) — call this once during deployment/provisioning, not per-request.
|
|
27
|
+
*/
|
|
28
|
+
ensureS3LifecycleRule(): Promise<void>;
|
|
20
29
|
}
|
|
21
30
|
//# sourceMappingURL=saver.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"saver.d.ts","sourceRoot":"","sources":["../../src/checkpointer/saver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EACL,mBAAmB,EACnB,KAAK,UAAU,EACf,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,YAAY,EAClB,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"saver.d.ts","sourceRoot":"","sources":["../../src/checkpointer/saver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EACL,mBAAmB,EACnB,KAAK,UAAU,EACf,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,YAAY,EAClB,MAAM,iCAAiC,CAAC;AASzC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAEpD;;;GAGG;AACH,qBAAa,aAAc,SAAQ,mBAAmB;IACpD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAU;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoD;IAE9E,YAAY,OAAO,EAAE,oBAAoB,EAMxC;IAEK,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAE3E;IAED,IAAI,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,cAAc,CAAC,eAAe,CAAC,CAE7F;IAEK,GAAG,CACP,MAAM,EAAE,cAAc,EACtB,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,kBAAkB,GAC3B,OAAO,CAAC,cAAc,CAAC,CAEzB;IAEK,SAAS,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE7F;IAEK,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAElD;IAED,yEAAyE;IACzE,OAAO,IAAI,IAAI,CAGd;IAED;;;;;;;OAOG;IACG,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAG3C;CACF"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DynamoDBSaver = void 0;
|
|
4
4
|
const langgraph_checkpoint_1 = require("@langchain/langgraph-checkpoint");
|
|
5
|
+
const ttl_1 = require("../shared/validation/ttl");
|
|
5
6
|
const delete_thread_1 = require("./actions/delete-thread");
|
|
6
7
|
const get_tuple_1 = require("./actions/get-tuple");
|
|
7
8
|
const list_1 = require("./actions/list");
|
|
@@ -44,6 +45,19 @@ class DynamoDBSaver extends langgraph_checkpoint_1.BaseCheckpointSaver {
|
|
|
44
45
|
if (this.ownsClient)
|
|
45
46
|
this.ddbClient?.destroy();
|
|
46
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Best-effort provision an S3 lifecycle expiration rule matching the
|
|
50
|
+
* configured TTL, so offloaded objects don't outlive their DynamoDB item
|
|
51
|
+
* forever. No-ops when S3 offload or TTL isn't configured. Requires the
|
|
52
|
+
* `s3:GetLifecycleConfiguration`/`s3:PutLifecycleConfiguration` bucket-level
|
|
53
|
+
* permissions (broader than the object-level CRUD the rest of S3 offload
|
|
54
|
+
* needs) — call this once during deployment/provisioning, not per-request.
|
|
55
|
+
*/
|
|
56
|
+
async ensureS3LifecycleRule() {
|
|
57
|
+
if (!this.context.offloader || !this.context.ttl)
|
|
58
|
+
return;
|
|
59
|
+
await this.context.offloader.ensureLifecycleRule((0, ttl_1.resolveTtlDaysCeil)(this.context.ttl));
|
|
60
|
+
}
|
|
47
61
|
}
|
|
48
62
|
exports.DynamoDBSaver = DynamoDBSaver;
|
|
49
63
|
//# sourceMappingURL=saver.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"saver.js","sourceRoot":"","sources":["../../src/checkpointer/saver.ts"],"names":[],"mappings":";;;AACA,0EAOyC;AAEzC,2DAA6E;AAC7E,mDAAyD;AACzD,yCAAiD;AACjD,uCAA8C;AAC9C,qDAAoE;AACpE,4CAA+E;AAG/E;;;GAGG;AACH,
|
|
1
|
+
{"version":3,"file":"saver.js","sourceRoot":"","sources":["../../src/checkpointer/saver.ts"],"names":[],"mappings":";;;AACA,0EAOyC;AAEzC,kDAA8D;AAC9D,2DAA6E;AAC7E,mDAAyD;AACzD,yCAAiD;AACjD,uCAA8C;AAC9C,qDAAoE;AACpE,4CAA+E;AAG/E;;;GAGG;AACH,mBAA2B,SAAQ,0CAAmB;IACnC,OAAO,CAAsB;IAC7B,UAAU,CAAU;IACpB,SAAS,CAAoD;IAE9E,YAAY,OAA6B;QACvC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACrB,MAAM,KAAK,GAAG,IAAA,yBAAiB,EAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QACrD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QAC7B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,MAAsB;QACnC,OAAO,IAAA,8BAAkB,EAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAClD,CAAC;IAED,IAAI,CAAC,MAAsB,EAAE,OAA+B;QAC1D,OAAO,IAAA,sBAAe,EAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,GAAG,CACP,MAAsB,EACtB,UAAsB,EACtB,QAA4B;QAE5B,OAAO,IAAA,mBAAa,EAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;IACnE,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,MAAsB,EAAE,MAAsB,EAAE,MAAc;QAC5E,OAAO,IAAA,sBAAe,EAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/D,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,QAAgB;QACjC,OAAO,IAAA,4BAAkB,EAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACpD,CAAC;IAED,yEAAyE;IACzE,OAAO;QACL,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,UAAU;YAAE,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC;IACjD,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,qBAAqB;QACzB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG;YAAE,OAAO;QACzD,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,mBAAmB,CAAC,IAAA,wBAAkB,EAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IACzF,CAAC;CACF"}
|