@farukada/aws-langgraph-dynamodb-ts 0.7.0 → 0.9.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 +52 -9
- package/dist/checkpointer/actions/delete-thread.d.ts +3 -4
- package/dist/checkpointer/actions/delete-thread.d.ts.map +1 -1
- package/dist/checkpointer/actions/delete-thread.js +21 -41
- package/dist/checkpointer/actions/delete-thread.js.map +1 -1
- package/dist/checkpointer/actions/list.d.ts.map +1 -1
- package/dist/checkpointer/actions/list.js +38 -4
- package/dist/checkpointer/actions/list.js.map +1 -1
- package/dist/checkpointer/actions/put-writes.d.ts.map +1 -1
- package/dist/checkpointer/actions/put-writes.js +15 -24
- package/dist/checkpointer/actions/put-writes.js.map +1 -1
- package/dist/checkpointer/internal/item-reader.d.ts +45 -0
- package/dist/checkpointer/internal/item-reader.d.ts.map +1 -1
- package/dist/checkpointer/internal/item-reader.js +63 -1
- package/dist/checkpointer/internal/item-reader.js.map +1 -1
- package/dist/checkpointer/internal/item-writer.d.ts +0 -8
- package/dist/checkpointer/internal/item-writer.d.ts.map +1 -1
- package/dist/checkpointer/internal/item-writer.js +16 -21
- package/dist/checkpointer/internal/item-writer.js.map +1 -1
- package/dist/checkpointer/internal/keys.d.ts +19 -3
- package/dist/checkpointer/internal/keys.d.ts.map +1 -1
- package/dist/checkpointer/internal/keys.js +41 -6
- package/dist/checkpointer/internal/keys.js.map +1 -1
- package/dist/checkpointer/internal/special-write-cas.d.ts +30 -0
- package/dist/checkpointer/internal/special-write-cas.d.ts.map +1 -0
- package/dist/checkpointer/internal/special-write-cas.js +104 -0
- package/dist/checkpointer/internal/special-write-cas.js.map +1 -0
- package/dist/checkpointer/internal/special-write-cleanup.d.ts +18 -12
- package/dist/checkpointer/internal/special-write-cleanup.d.ts.map +1 -1
- package/dist/checkpointer/internal/special-write-cleanup.js +31 -86
- package/dist/checkpointer/internal/special-write-cleanup.js.map +1 -1
- package/dist/checkpointer/internal/special-write-verify.d.ts +54 -0
- package/dist/checkpointer/internal/special-write-verify.d.ts.map +1 -0
- package/dist/checkpointer/internal/special-write-verify.js +65 -0
- package/dist/checkpointer/internal/special-write-verify.js.map +1 -0
- package/dist/checkpointer/internal/validation.d.ts +8 -4
- package/dist/checkpointer/internal/validation.d.ts.map +1 -1
- package/dist/checkpointer/internal/validation.js +12 -10
- package/dist/checkpointer/internal/validation.js.map +1 -1
- package/dist/checkpointer/internal/write-guard.d.ts +13 -0
- package/dist/checkpointer/internal/write-guard.d.ts.map +1 -0
- package/dist/checkpointer/internal/write-guard.js +39 -0
- package/dist/checkpointer/internal/write-guard.js.map +1 -0
- package/dist/checkpointer/internal/write-index.d.ts +37 -0
- package/dist/checkpointer/internal/write-index.d.ts.map +1 -0
- package/dist/checkpointer/internal/write-index.js +42 -0
- package/dist/checkpointer/internal/write-index.js.map +1 -0
- package/dist/checkpointer/types.d.ts +8 -0
- package/dist/checkpointer/types.d.ts.map +1 -1
- package/dist/history/actions/add-messages.d.ts.map +1 -1
- package/dist/history/actions/add-messages.js +24 -4
- package/dist/history/actions/add-messages.js.map +1 -1
- package/dist/history/actions/clear.d.ts +4 -6
- package/dist/history/actions/clear.d.ts.map +1 -1
- package/dist/history/actions/clear.js +18 -33
- package/dist/history/actions/clear.js.map +1 -1
- package/dist/history/actions/get-messages.d.ts +2 -1
- package/dist/history/actions/get-messages.d.ts.map +1 -1
- package/dist/history/actions/get-messages.js +28 -2
- package/dist/history/actions/get-messages.js.map +1 -1
- package/dist/history/actions/list-sessions.d.ts +2 -1
- package/dist/history/actions/list-sessions.d.ts.map +1 -1
- package/dist/history/actions/list-sessions.js +21 -2
- package/dist/history/actions/list-sessions.js.map +1 -1
- package/dist/history/actions/reconcile-count.d.ts.map +1 -1
- package/dist/history/actions/reconcile-count.js +2 -2
- package/dist/history/actions/reconcile-count.js.map +1 -1
- package/dist/history/internal/append-saga.d.ts.map +1 -1
- package/dist/history/internal/append-saga.js +2 -78
- package/dist/history/internal/append-saga.js.map +1 -1
- package/dist/history/internal/compensation.d.ts +21 -0
- package/dist/history/internal/compensation.d.ts.map +1 -0
- package/dist/history/internal/compensation.js +84 -0
- package/dist/history/internal/compensation.js.map +1 -0
- package/dist/history/internal/keys.d.ts +9 -1
- package/dist/history/internal/keys.d.ts.map +1 -1
- package/dist/history/internal/keys.js +21 -4
- package/dist/history/internal/keys.js.map +1 -1
- package/dist/history/internal/message-chunker.d.ts.map +1 -1
- package/dist/history/internal/message-chunker.js +13 -5
- package/dist/history/internal/message-chunker.js.map +1 -1
- package/dist/history/internal/session-count.d.ts +21 -0
- package/dist/history/internal/session-count.d.ts.map +1 -1
- package/dist/history/internal/session-count.js +51 -0
- package/dist/history/internal/session-count.js.map +1 -1
- package/dist/history/internal/session-title.d.ts +20 -0
- package/dist/history/internal/session-title.d.ts.map +1 -0
- package/dist/history/internal/session-title.js +44 -0
- package/dist/history/internal/session-title.js.map +1 -0
- package/dist/history/internal/setup.d.ts +2 -1
- package/dist/history/internal/setup.d.ts.map +1 -1
- package/dist/history/internal/setup.js +1 -0
- package/dist/history/internal/setup.js.map +1 -1
- package/dist/history/internal/title-generator.d.ts +8 -2
- package/dist/history/internal/title-generator.d.ts.map +1 -1
- package/dist/history/internal/title-generator.js +12 -3
- package/dist/history/internal/title-generator.js.map +1 -1
- package/dist/history/internal/validation.d.ts +9 -0
- package/dist/history/internal/validation.d.ts.map +1 -0
- package/dist/history/internal/validation.js +16 -0
- package/dist/history/internal/validation.js.map +1 -0
- package/dist/history/types.d.ts +12 -0
- package/dist/history/types.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/shared/codec/s3/offloader.d.ts +7 -1
- package/dist/shared/codec/s3/offloader.d.ts.map +1 -1
- package/dist/shared/codec/s3/offloader.js +14 -1
- package/dist/shared/codec/s3/offloader.js.map +1 -1
- package/dist/shared/constants.d.ts +15 -0
- package/dist/shared/constants.d.ts.map +1 -1
- package/dist/shared/constants.js +16 -1
- package/dist/shared/constants.js.map +1 -1
- package/dist/shared/dynamodb/conditional-put.d.ts +51 -0
- package/dist/shared/dynamodb/conditional-put.d.ts.map +1 -0
- package/dist/shared/dynamodb/conditional-put.js +59 -0
- package/dist/shared/dynamodb/conditional-put.js.map +1 -0
- package/dist/shared/dynamodb/partition-delete.d.ts +33 -0
- package/dist/shared/dynamodb/partition-delete.d.ts.map +1 -0
- package/dist/shared/dynamodb/partition-delete.js +70 -0
- package/dist/shared/dynamodb/partition-delete.js.map +1 -0
- package/dist/shared/dynamodb/retry-classifier.d.ts.map +1 -1
- package/dist/shared/dynamodb/retry-classifier.js +9 -1
- package/dist/shared/dynamodb/retry-classifier.js.map +1 -1
- package/dist/shared/logging/redaction-walk.d.ts +23 -0
- package/dist/shared/logging/redaction-walk.d.ts.map +1 -0
- package/dist/shared/logging/redaction-walk.js +92 -0
- package/dist/shared/logging/redaction-walk.js.map +1 -0
- package/dist/shared/logging/redaction.d.ts +26 -17
- package/dist/shared/logging/redaction.d.ts.map +1 -1
- package/dist/shared/logging/redaction.js +24 -48
- package/dist/shared/logging/redaction.js.map +1 -1
- package/dist/shared/logging/secret-patterns.d.ts +74 -0
- package/dist/shared/logging/secret-patterns.d.ts.map +1 -0
- package/dist/shared/logging/secret-patterns.js +107 -0
- package/dist/shared/logging/secret-patterns.js.map +1 -0
- package/dist/shared/validation/primitives.d.ts +9 -1
- package/dist/shared/validation/primitives.d.ts.map +1 -1
- package/dist/shared/validation/primitives.js +13 -0
- package/dist/shared/validation/primitives.js.map +1 -1
- package/dist/store/actions/get.d.ts.map +1 -1
- package/dist/store/actions/get.js +15 -1
- package/dist/store/actions/get.js.map +1 -1
- package/dist/store/actions/list-namespaces.d.ts.map +1 -1
- package/dist/store/actions/list-namespaces.js +1 -0
- package/dist/store/actions/list-namespaces.js.map +1 -1
- package/dist/store/actions/put.d.ts.map +1 -1
- package/dist/store/actions/put.js +24 -18
- package/dist/store/actions/put.js.map +1 -1
- package/dist/store/actions/search.d.ts.map +1 -1
- package/dist/store/actions/search.js +4 -35
- package/dist/store/actions/search.js.map +1 -1
- package/dist/store/internal/backend-search.d.ts +5 -0
- package/dist/store/internal/backend-search.d.ts.map +1 -0
- package/dist/store/internal/backend-search.js +68 -0
- package/dist/store/internal/backend-search.js.map +1 -0
- package/dist/store/internal/filter.d.ts.map +1 -1
- package/dist/store/internal/filter.js +46 -5
- 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 +41 -5
- package/dist/store/internal/index-reconcile.js.map +1 -1
- package/dist/store/internal/item-mapper.d.ts +1 -0
- package/dist/store/internal/item-mapper.d.ts.map +1 -1
- package/dist/store/internal/item-mapper.js +2 -0
- package/dist/store/internal/item-mapper.js.map +1 -1
- package/dist/store/internal/keys.d.ts +1 -1
- package/dist/store/internal/keys.d.ts.map +1 -1
- package/dist/store/internal/keys.js +8 -2
- package/dist/store/internal/keys.js.map +1 -1
- package/dist/store/internal/overwrite-swap.d.ts +33 -0
- package/dist/store/internal/overwrite-swap.d.ts.map +1 -0
- package/dist/store/internal/overwrite-swap.js +62 -0
- package/dist/store/internal/overwrite-swap.js.map +1 -0
- package/dist/store/internal/persist.d.ts +22 -6
- package/dist/store/internal/persist.d.ts.map +1 -1
- package/dist/store/internal/persist.js +41 -20
- package/dist/store/internal/persist.js.map +1 -1
- package/dist/store/internal/read-existing.d.ts +19 -0
- package/dist/store/internal/read-existing.d.ts.map +1 -0
- package/dist/store/internal/read-existing.js +29 -0
- package/dist/store/internal/read-existing.js.map +1 -0
- package/dist/store/internal/score-direction.d.ts +32 -0
- package/dist/store/internal/score-direction.d.ts.map +1 -0
- package/dist/store/internal/score-direction.js +39 -0
- package/dist/store/internal/score-direction.js.map +1 -0
- package/dist/store/internal/search-filter.d.ts +4 -0
- package/dist/store/internal/search-filter.d.ts.map +1 -0
- package/dist/store/internal/search-filter.js +11 -0
- package/dist/store/internal/search-filter.js.map +1 -0
- package/dist/store/internal/setup.d.ts +13 -1
- package/dist/store/internal/setup.d.ts.map +1 -1
- package/dist/store/internal/setup.js +57 -1
- package/dist/store/internal/setup.js.map +1 -1
- package/dist/store/internal/validation.d.ts +8 -2
- package/dist/store/internal/validation.d.ts.map +1 -1
- package/dist/store/internal/validation.js +15 -6
- package/dist/store/internal/validation.js.map +1 -1
- package/dist/store/internal/write-verify.d.ts +31 -6
- package/dist/store/internal/write-verify.d.ts.map +1 -1
- package/dist/store/internal/write-verify.js +48 -8
- package/dist/store/internal/write-verify.js.map +1 -1
- package/dist/store/types.d.ts +16 -0
- package/dist/store/types.d.ts.map +1 -1
- package/dist/store/vector-backend.d.ts +17 -0
- package/dist/store/vector-backend.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SPECIAL_REVISION_ATTRIBUTE = void 0;
|
|
4
|
+
exports.readSpecialRow = readSpecialRow;
|
|
5
|
+
exports.verifyAfterFailure = verifyAfterFailure;
|
|
6
|
+
const retry_1 = require("../../shared/dynamodb/retry");
|
|
7
|
+
/**
|
|
8
|
+
* A special row already carries a per-call ULID in `writeGroup`, so it needs no
|
|
9
|
+
* extra revision attribute to compare and swap on.
|
|
10
|
+
*/
|
|
11
|
+
exports.SPECIAL_REVISION_ATTRIBUTE = 'writeGroup';
|
|
12
|
+
/** Read a special row's current descriptor and the writeGroup guarding it. */
|
|
13
|
+
async function readSpecialRow(context, item) {
|
|
14
|
+
const result = await (0, retry_1.withDynamoDBRetry)(() => context.client.get({
|
|
15
|
+
TableName: context.tableName,
|
|
16
|
+
Key: { PK: item.PK, SK: item.SK },
|
|
17
|
+
ConsistentRead: true,
|
|
18
|
+
ProjectionExpression: '#v, #g',
|
|
19
|
+
ExpressionAttributeNames: { '#v': 'value', '#g': exports.SPECIAL_REVISION_ATTRIBUTE },
|
|
20
|
+
}));
|
|
21
|
+
if (!result.Item)
|
|
22
|
+
return { exists: false };
|
|
23
|
+
return {
|
|
24
|
+
exists: true,
|
|
25
|
+
value: result.Item.value,
|
|
26
|
+
revision: result.Item[exports.SPECIAL_REVISION_ATTRIBUTE],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Read the row back after a put failed, and report what that failure actually
|
|
31
|
+
* did — never assuming it did nothing.
|
|
32
|
+
*
|
|
33
|
+
* No rejection is proof of a non-commit. `withDynamoDBRetry` re-issues a put
|
|
34
|
+
* whose response was lost, and those re-issues can time out at the transport
|
|
35
|
+
* without ever reaching DynamoDB, so the budget is spent on a
|
|
36
|
+
* `RetryExhaustedError` and never on a `ConditionalCheckFailedException` — yet
|
|
37
|
+
* the row is committed. Reporting that as a confirmed non-commit let
|
|
38
|
+
* `writeSpecialItemsWithCleanup` delete the S3 object the live row points at,
|
|
39
|
+
* so every later `getTuple()` on that checkpoint failed with `NoSuchKey`,
|
|
40
|
+
* permanently.
|
|
41
|
+
*
|
|
42
|
+
* Three answers are possible:
|
|
43
|
+
* - the row holds this item's own `writeGroup`: the write landed, and the
|
|
44
|
+
* descriptor this attempt pinned is the dead one.
|
|
45
|
+
* - the row holds some other group: the write is confirmed not to be what is
|
|
46
|
+
* live, so this item's own upload is the dead one. `observed` is returned so
|
|
47
|
+
* a rejected compare-and-swap can re-pin and try again.
|
|
48
|
+
* - the read itself fails: nothing is confirmed, so the outcome still reports a
|
|
49
|
+
* commit and keeps the originating error. That leaks one S3 object at worst
|
|
50
|
+
* (reclaimed by `ensureS3LifecycleRule`) where the alternative strands a live
|
|
51
|
+
* row — the same trade `store/internal/persist.ts` makes.
|
|
52
|
+
*/
|
|
53
|
+
async function verifyAfterFailure(context, item, attempted, error) {
|
|
54
|
+
try {
|
|
55
|
+
const observed = await readSpecialRow(context, item);
|
|
56
|
+
if (observed.revision === item.writeGroup) {
|
|
57
|
+
return { outcome: { committed: true, superseded: attempted.value } };
|
|
58
|
+
}
|
|
59
|
+
return { outcome: { committed: false, error }, observed };
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return { outcome: { committed: true, error } };
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=special-write-verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"special-write-verify.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/special-write-verify.ts"],"names":[],"mappings":";;;;;AACA,uDAAgE;AAIhE;;;GAGG;AACU,QAAA,0BAA0B,GAAG,YAAY,CAAC;AAuBvD,8EAA8E;AACvE,KAAK,yBACV,OAA4B,EAC5B,IAAyB;IAEzB,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,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;QACjC,cAAc,EAAE,IAAI;QACpB,oBAAoB,EAAE,QAAQ;QAC9B,wBAAwB,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAA,0BAA0B,EAAE;KAC9E,CAAC,CACH,CAAC;IACF,IAAI,CAAC,MAAM,CAAC,IAAI;QAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC3C,OAAO;QACL,MAAM,EAAE,IAAI;QACZ,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAsC;QACzD,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,QAAA,0BAA0B,CAAuB;KACxE,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACI,KAAK,6BACV,OAA4B,EAC5B,IAAyB,EACzB,SAA0B,EAC1B,KAAY;IAEZ,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACrD,IAAI,QAAQ,CAAC,QAAQ,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;YAC1C,OAAO,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,KAAK,EAAE,EAAE,CAAC;QACvE,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;IACjD,CAAC;AACH,CAAC"}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
/** Validate a thread id is a non-empty, separator-free string. */
|
|
1
|
+
/** Validate a thread id is a non-empty, separator- and control-char-free string. */
|
|
2
2
|
export declare function validateThreadId(threadId: string): void;
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* Validate a checkpoint namespace. Unlike the other identifiers an empty value
|
|
5
|
+
* is legal — it is the root namespace — so only the separator and
|
|
6
|
+
* control-character rules apply.
|
|
7
|
+
*/
|
|
4
8
|
export declare function validateCheckpointNs(checkpointNs: string): void;
|
|
5
|
-
/** Validate a checkpoint id is a non-empty, separator-free string. */
|
|
9
|
+
/** Validate a checkpoint id is a non-empty, separator- and control-char-free string. */
|
|
6
10
|
export declare function validateCheckpointId(checkpointId: string): void;
|
|
7
|
-
/** Validate a task id is a non-empty, separator-free string. */
|
|
11
|
+
/** Validate a task id is a non-empty, separator- and control-char-free string. */
|
|
8
12
|
export declare function validateTaskId(taskId: string): void;
|
|
9
13
|
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/internal/validation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/internal/validation.ts"],"names":[],"mappings":"AAOA,oFAAoF;AACpF,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAEvD;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAG/D;AAED,wFAAwF;AACxF,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAE/D;AAED,kFAAkF;AAClF,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAEnD"}
|
|
@@ -6,23 +6,25 @@ exports.validateCheckpointId = validateCheckpointId;
|
|
|
6
6
|
exports.validateTaskId = validateTaskId;
|
|
7
7
|
const primitives_1 = require("../../shared/validation/primitives");
|
|
8
8
|
const keys_1 = require("./keys");
|
|
9
|
-
/** Validate a thread id is a non-empty, separator-free string. */
|
|
9
|
+
/** Validate a thread id is a non-empty, separator- and control-char-free string. */
|
|
10
10
|
function validateThreadId(threadId) {
|
|
11
|
-
(0, primitives_1.
|
|
12
|
-
(0, primitives_1.assertNoSeparator)(threadId, keys_1.SORT_KEY_SEPARATOR, 'thread_id');
|
|
11
|
+
(0, primitives_1.validateIdentifier)(threadId, keys_1.SORT_KEY_SEPARATOR, 'thread_id');
|
|
13
12
|
}
|
|
14
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* Validate a checkpoint namespace. Unlike the other identifiers an empty value
|
|
15
|
+
* is legal — it is the root namespace — so only the separator and
|
|
16
|
+
* control-character rules apply.
|
|
17
|
+
*/
|
|
15
18
|
function validateCheckpointNs(checkpointNs) {
|
|
16
19
|
(0, primitives_1.assertNoSeparator)(checkpointNs, keys_1.SORT_KEY_SEPARATOR, 'checkpoint_ns');
|
|
20
|
+
(0, primitives_1.assertNoControlChars)(checkpointNs, 'checkpoint_ns');
|
|
17
21
|
}
|
|
18
|
-
/** Validate a checkpoint id is a non-empty, separator-free string. */
|
|
22
|
+
/** Validate a checkpoint id is a non-empty, separator- and control-char-free string. */
|
|
19
23
|
function validateCheckpointId(checkpointId) {
|
|
20
|
-
(0, primitives_1.
|
|
21
|
-
(0, primitives_1.assertNoSeparator)(checkpointId, keys_1.SORT_KEY_SEPARATOR, 'checkpoint_id');
|
|
24
|
+
(0, primitives_1.validateIdentifier)(checkpointId, keys_1.SORT_KEY_SEPARATOR, 'checkpoint_id');
|
|
22
25
|
}
|
|
23
|
-
/** Validate a task id is a non-empty, separator-free string. */
|
|
26
|
+
/** Validate a task id is a non-empty, separator- and control-char-free string. */
|
|
24
27
|
function validateTaskId(taskId) {
|
|
25
|
-
(0, primitives_1.
|
|
26
|
-
(0, primitives_1.assertNoSeparator)(taskId, keys_1.SORT_KEY_SEPARATOR, 'taskId');
|
|
28
|
+
(0, primitives_1.validateIdentifier)(taskId, keys_1.SORT_KEY_SEPARATOR, 'taskId');
|
|
27
29
|
}
|
|
28
30
|
//# sourceMappingURL=validation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/validation.ts"],"names":[],"mappings":";;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/validation.ts"],"names":[],"mappings":";;;;;;AAAA,mEAI4C;AAC5C,iCAA4C;AAE5C,oFAAoF;AACpF,0BAAiC,QAAgB;IAC/C,IAAA,+BAAkB,EAAC,QAAQ,EAAE,yBAAkB,EAAE,WAAW,CAAC,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,8BAAqC,YAAoB;IACvD,IAAA,8BAAiB,EAAC,YAAY,EAAE,yBAAkB,EAAE,eAAe,CAAC,CAAC;IACrE,IAAA,iCAAoB,EAAC,YAAY,EAAE,eAAe,CAAC,CAAC;AACtD,CAAC;AAED,wFAAwF;AACxF,8BAAqC,YAAoB;IACvD,IAAA,+BAAkB,EAAC,YAAY,EAAE,yBAAkB,EAAE,eAAe,CAAC,CAAC;AACxE,CAAC;AAED,kFAAkF;AAClF,wBAA+B,MAAc;IAC3C,IAAA,+BAAkB,EAAC,MAAM,EAAE,yBAAkB,EAAE,QAAQ,CAAC,CAAC;AAC3D,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { CheckpointWriteItem } from '../types';
|
|
2
|
+
import type { CheckpointerContext } from './setup';
|
|
3
|
+
/**
|
|
4
|
+
* Report a guard rejection. Sort keys carry their channel, so a rejection
|
|
5
|
+
* normally means this exact (task, channel, occurrence) row is already
|
|
6
|
+
* committed — a genuine duplicate, and the expected outcome of a retry. A row
|
|
7
|
+
* held by a *different* channel is not something this adapter can produce, so
|
|
8
|
+
* it is reported at `warn`: the write was not persisted and something else
|
|
9
|
+
* wrote to this key space. No attributes returned means the outcome cannot be
|
|
10
|
+
* told apart, so it is treated as the ordinary duplicate.
|
|
11
|
+
*/
|
|
12
|
+
export declare function reportGuardRejection(context: CheckpointerContext, item: CheckpointWriteItem, error: Error): void;
|
|
13
|
+
//# sourceMappingURL=write-guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-guard.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/internal/write-guard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAcnD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,mBAAmB,EAC5B,IAAI,EAAE,mBAAmB,EACzB,KAAK,EAAE,KAAK,GACX,IAAI,CAcN"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.reportGuardRejection = reportGuardRejection;
|
|
4
|
+
/**
|
|
5
|
+
* The channel recorded on the row that turned a write away, or undefined when
|
|
6
|
+
* the service returned no attributes. `ReturnValuesOnConditionCheckFailure:
|
|
7
|
+
* 'ALL_OLD'` attaches the existing item to the exception at no extra round
|
|
8
|
+
* trip, but — verified against real DynamoDB — the document client does not
|
|
9
|
+
* unmarshall an *error* payload the way it unmarshalls a response, so the
|
|
10
|
+
* attribute arrives in raw AttributeValue form.
|
|
11
|
+
*/
|
|
12
|
+
function rejectedChannel(error) {
|
|
13
|
+
return error.Item?.channel?.S;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Report a guard rejection. Sort keys carry their channel, so a rejection
|
|
17
|
+
* normally means this exact (task, channel, occurrence) row is already
|
|
18
|
+
* committed — a genuine duplicate, and the expected outcome of a retry. A row
|
|
19
|
+
* held by a *different* channel is not something this adapter can produce, so
|
|
20
|
+
* it is reported at `warn`: the write was not persisted and something else
|
|
21
|
+
* wrote to this key space. No attributes returned means the outcome cannot be
|
|
22
|
+
* told apart, so it is treated as the ordinary duplicate.
|
|
23
|
+
*/
|
|
24
|
+
function reportGuardRejection(context, item, error) {
|
|
25
|
+
const found = rejectedChannel(error);
|
|
26
|
+
if (found !== undefined && found !== item.channel) {
|
|
27
|
+
context.logger.warn('putWrites: write row held by an unexpected channel; write not persisted', {
|
|
28
|
+
sortKey: item.SK,
|
|
29
|
+
expected: item.channel,
|
|
30
|
+
found,
|
|
31
|
+
});
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
context.logger.debug('putWrites: skipped a write already committed for this task and channel', {
|
|
35
|
+
sortKey: item.SK,
|
|
36
|
+
channel: item.channel,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=write-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-guard.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/write-guard.ts"],"names":[],"mappings":";;;AAGA;;;;;;;GAOG;AACH,SAAS,eAAe,CAAC,KAAY;IACnC,OAAQ,KAAiD,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;AAC7E,CAAC;AAED;;;;;;;;GAQG;AACH,8BACE,OAA4B,EAC5B,IAAyB,EACzB,KAAY;IAEZ,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACrC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;QAClD,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,yEAAyE,EAAE;YAC7F,OAAO,EAAE,IAAI,CAAC,EAAE;YAChB,QAAQ,EAAE,IAAI,CAAC,OAAO;YACtB,KAAK;SACN,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wEAAwE,EAAE;QAC7F,OAAO,EAAE,IAAI,CAAC,EAAE;QAChB,OAAO,EAAE,IAAI,CAAC,OAAO;KACtB,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { PendingWrite, PendingWriteValue } from '@langchain/langgraph-checkpoint';
|
|
2
|
+
/** One write with its sort-key index resolved exactly once. */
|
|
3
|
+
export interface ResolvedWrite {
|
|
4
|
+
channel: string;
|
|
5
|
+
value: PendingWriteValue;
|
|
6
|
+
index: number;
|
|
7
|
+
/**
|
|
8
|
+
* How many earlier writes in this same call already used this channel. A
|
|
9
|
+
* retry that emits a channel *more* often than the original call produces a
|
|
10
|
+
* row at an occurrence no earlier call ever wrote — it collides with nothing
|
|
11
|
+
* and commits cleanly, so the read-side dedup must not mistake it for a
|
|
12
|
+
* superseding duplicate.
|
|
13
|
+
*/
|
|
14
|
+
occurrence: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Assign every write in one `putWrites` call its sort-key index, in a single
|
|
18
|
+
* pass — nothing recomputes it downstream, which is what used to let the
|
|
19
|
+
* deduped array's positions disagree with the ones the caller's array
|
|
20
|
+
* produced.
|
|
21
|
+
*
|
|
22
|
+
* A regular write's index is its position in the caller's array, exactly as
|
|
23
|
+
* the reference `MemorySaver` computes it: that is what makes stored writes
|
|
24
|
+
* replay in the order the task emitted them. A special channel takes its
|
|
25
|
+
* fixed `WRITES_IDX_MAP` slot instead, and a later duplicate replaces an
|
|
26
|
+
* earlier one (last-write-wins, again matching the reference).
|
|
27
|
+
*
|
|
28
|
+
* Positions are not stable across calls, which is why the *sort key* also
|
|
29
|
+
* carries the channel and each call stamps its rows with a shared
|
|
30
|
+
* `writeGroup` — see {@link buildWriteItems} and `dropSupersededWrites`.
|
|
31
|
+
*
|
|
32
|
+
* `Object.hasOwn` guards WRITES_IDX_MAP's own `Object.prototype` chain — a
|
|
33
|
+
* channel literally named `constructor`/`toString`/etc. must be treated as
|
|
34
|
+
* regular, not resolve to an inherited function reference.
|
|
35
|
+
*/
|
|
36
|
+
export declare function resolveWriteIndices(writes: PendingWrite[]): ResolvedWrite[];
|
|
37
|
+
//# sourceMappingURL=write-index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-index.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/internal/write-index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAGvF,+DAA+D;AAC/D,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,iBAAiB,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,aAAa,EAAE,CAgB3E"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveWriteIndices = resolveWriteIndices;
|
|
4
|
+
const langgraph_checkpoint_1 = require("@langchain/langgraph-checkpoint");
|
|
5
|
+
/**
|
|
6
|
+
* Assign every write in one `putWrites` call its sort-key index, in a single
|
|
7
|
+
* pass — nothing recomputes it downstream, which is what used to let the
|
|
8
|
+
* deduped array's positions disagree with the ones the caller's array
|
|
9
|
+
* produced.
|
|
10
|
+
*
|
|
11
|
+
* A regular write's index is its position in the caller's array, exactly as
|
|
12
|
+
* the reference `MemorySaver` computes it: that is what makes stored writes
|
|
13
|
+
* replay in the order the task emitted them. A special channel takes its
|
|
14
|
+
* fixed `WRITES_IDX_MAP` slot instead, and a later duplicate replaces an
|
|
15
|
+
* earlier one (last-write-wins, again matching the reference).
|
|
16
|
+
*
|
|
17
|
+
* Positions are not stable across calls, which is why the *sort key* also
|
|
18
|
+
* carries the channel and each call stamps its rows with a shared
|
|
19
|
+
* `writeGroup` — see {@link buildWriteItems} and `dropSupersededWrites`.
|
|
20
|
+
*
|
|
21
|
+
* `Object.hasOwn` guards WRITES_IDX_MAP's own `Object.prototype` chain — a
|
|
22
|
+
* channel literally named `constructor`/`toString`/etc. must be treated as
|
|
23
|
+
* regular, not resolve to an inherited function reference.
|
|
24
|
+
*/
|
|
25
|
+
function resolveWriteIndices(writes) {
|
|
26
|
+
const bySpecialIndex = new Map();
|
|
27
|
+
const regular = [];
|
|
28
|
+
const occurrences = new Map();
|
|
29
|
+
writes.forEach(([channel, value], positional) => {
|
|
30
|
+
if (Object.hasOwn(langgraph_checkpoint_1.WRITES_IDX_MAP, channel)) {
|
|
31
|
+
const index = langgraph_checkpoint_1.WRITES_IDX_MAP[channel];
|
|
32
|
+
/** Last write wins per special channel, so a call holds exactly one. */
|
|
33
|
+
bySpecialIndex.set(index, { channel, value, index, occurrence: 0 });
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const occurrence = occurrences.get(channel) ?? 0;
|
|
37
|
+
occurrences.set(channel, occurrence + 1);
|
|
38
|
+
regular.push({ channel, value, index: positional, occurrence });
|
|
39
|
+
});
|
|
40
|
+
return [...bySpecialIndex.values(), ...regular];
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=write-index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-index.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/write-index.ts"],"names":[],"mappings":";;;AACA,0EAAiE;AAiBjE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,6BAAoC,MAAsB;IACxD,MAAM,cAAc,GAAG,IAAI,GAAG,EAAyB,CAAC;IACxD,MAAM,OAAO,GAAoB,EAAE,CAAC;IACpC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC9C,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,UAAU,EAAE,EAAE;QAC9C,IAAI,MAAM,CAAC,MAAM,CAAC,qCAAc,EAAE,OAAO,CAAC,EAAE,CAAC;YAC3C,MAAM,KAAK,GAAG,qCAAc,CAAC,OAAO,CAAC,CAAC;YACtC,wEAAwE;YACxE,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;YACpE,OAAO;QACT,CAAC;QACD,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACjD,WAAW,CAAC,GAAG,CAAC,OAAO,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC;QACzC,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,cAAc,CAAC,MAAM,EAAE,EAAE,GAAG,OAAO,CAAC,CAAC;AAClD,CAAC"}
|
|
@@ -37,6 +37,14 @@ export interface CheckpointWriteItem {
|
|
|
37
37
|
taskId: string;
|
|
38
38
|
index: number;
|
|
39
39
|
channel: string;
|
|
40
|
+
/** Identifies the `putWrites` call that produced this row (see item-writer). */
|
|
41
|
+
writeGroup: string;
|
|
42
|
+
/**
|
|
43
|
+
* How many earlier writes in the same call already used this channel.
|
|
44
|
+
* Optional: rows written before 0.9.0 carry none and read back as 0, which
|
|
45
|
+
* is exactly the identity they were stored under.
|
|
46
|
+
*/
|
|
47
|
+
occurrence?: number;
|
|
40
48
|
value: PayloadDescriptor;
|
|
41
49
|
ttl?: number;
|
|
42
50
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/checkpointer/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAE1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE1E,yCAAyC;AACzC,MAAM,MAAM,oBAAoB,GAAG,kBAAkB,GACnD,YAAY,GAAG;IACb,8EAA8E;IAC9E,KAAK,CAAC,EAAE,kBAAkB,CAAC;CAC5B,CAAC;AAEJ,2EAA2E;AAC3E,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,6EAA6E;AAC7E,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,4DAA4D;AAC5D,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,iBAAiB,CAAC;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,gEAAgE;AAChE,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,iBAAiB,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/checkpointer/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAE1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE1E,yCAAyC;AACzC,MAAM,MAAM,oBAAoB,GAAG,kBAAkB,GACnD,YAAY,GAAG;IACb,8EAA8E;IAC9E,KAAK,CAAC,EAAE,kBAAkB,CAAC;CAC5B,CAAC;AAEJ,2EAA2E;AAC3E,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,6EAA6E;AAC7E,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,4DAA4D;AAC5D,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,iBAAiB,CAAC;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,gEAAgE;AAChE,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,gFAAgF;IAChF,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,iBAAiB,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-messages.d.ts","sourceRoot":"","sources":["../../../src/history/actions/add-messages.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAGjB,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"add-messages.d.ts","sourceRoot":"","sources":["../../../src/history/actions/add-messages.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAGjB,MAAM,0BAA0B,CAAC;AASlC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAmDxD;;;;;;;;;;;GAWG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,WAAW,EAAE,GACtB,OAAO,CAAC,IAAI,CAAC,CAef"}
|
|
@@ -3,13 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.addMessages = addMessages;
|
|
4
4
|
const messages_1 = require("@langchain/core/messages");
|
|
5
5
|
const clock_1 = require("../../shared/clock");
|
|
6
|
-
const
|
|
6
|
+
const descriptor_keys_1 = require("../../shared/codec/descriptor-keys");
|
|
7
|
+
const orphans_1 = require("../../shared/codec/s3/orphans");
|
|
7
8
|
const ttl_1 = require("../../shared/validation/ttl");
|
|
8
9
|
const append_saga_1 = require("../internal/append-saga");
|
|
9
10
|
const item_mapper_1 = require("../internal/item-mapper");
|
|
10
11
|
const message_chunker_1 = require("../internal/message-chunker");
|
|
11
12
|
const title_generator_1 = require("../internal/title-generator");
|
|
12
13
|
const ttl_anchor_1 = require("../internal/ttl-anchor");
|
|
14
|
+
const validation_1 = require("../internal/validation");
|
|
13
15
|
/** Message Puts per append transaction: the 100-item limit, less the metadata Update. */
|
|
14
16
|
const MAX_MESSAGES_PER_TRANSACTION = 99;
|
|
15
17
|
/**
|
|
@@ -18,10 +20,28 @@ const MAX_MESSAGES_PER_TRANSACTION = 99;
|
|
|
18
20
|
* `ITEM_OVERHEAD_BYTES`) cannot push a chunk over the real limit at commit time.
|
|
19
21
|
*/
|
|
20
22
|
const MAX_TRANSACTION_BYTES = 3_500_000;
|
|
23
|
+
/**
|
|
24
|
+
* Encode every message, cleaning up after itself if one fails partway.
|
|
25
|
+
*
|
|
26
|
+
* Offloaded messages upload sequentially here, *before* the append saga's
|
|
27
|
+
* compensation machinery is ever reached, so a failure on message N used to
|
|
28
|
+
* strand messages 1..N-1's already-uploaded S3 objects with no cleanup path —
|
|
29
|
+
* the one gap in this subsystem's otherwise complete no-orphan guarantee.
|
|
30
|
+
* Nothing will ever reference those objects, so they are safe to delete
|
|
31
|
+
* unconditionally on the way out.
|
|
32
|
+
*/
|
|
21
33
|
async function buildItems(context, sessionId, stored, ttlTimestamp) {
|
|
22
34
|
const items = [];
|
|
23
|
-
|
|
24
|
-
|
|
35
|
+
try {
|
|
36
|
+
for (const message of stored) {
|
|
37
|
+
items.push(await (0, item_mapper_1.buildMessageItem)(context, sessionId, context.ulid(), message, ttlTimestamp));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
if (context.offloader) {
|
|
42
|
+
await (0, orphans_1.cleanUpS3Orphans)(context.offloader, (0, descriptor_keys_1.collectS3Keys)(items.map((item) => item.message)), 'history.addMessages.encode', context.logger);
|
|
43
|
+
}
|
|
44
|
+
throw error;
|
|
25
45
|
}
|
|
26
46
|
return items;
|
|
27
47
|
}
|
|
@@ -38,7 +58,7 @@ async function buildItems(context, sessionId, stored, ttlTimestamp) {
|
|
|
38
58
|
* large payloads become small descriptors and stay well under the limits.
|
|
39
59
|
*/
|
|
40
60
|
async function addMessages(context, sessionId, messages) {
|
|
41
|
-
(0,
|
|
61
|
+
(0, validation_1.validateSessionId)(sessionId);
|
|
42
62
|
if (messages.length === 0)
|
|
43
63
|
return;
|
|
44
64
|
const stored = (0, messages_1.mapChatMessagesToStoredMessages)(messages);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-messages.js","sourceRoot":"","sources":["../../../src/history/actions/add-messages.ts"],"names":[],"mappings":";;;AAAA,uDAIkC;AAElC,8CAA4C;AAC5C,
|
|
1
|
+
{"version":3,"file":"add-messages.js","sourceRoot":"","sources":["../../../src/history/actions/add-messages.ts"],"names":[],"mappings":";;;AAAA,uDAIkC;AAElC,8CAA4C;AAC5C,wEAAmE;AACnE,2DAAiE;AACjE,qDAAoE;AACpE,yDAAuD;AACvD,yDAA2D;AAC3D,iEAA0D;AAE1D,iEAA0D;AAC1D,uDAA0D;AAC1D,uDAA2D;AAG3D,yFAAyF;AACzF,MAAM,4BAA4B,GAAG,EAAE,CAAC;AAExC;;;;GAIG;AACH,MAAM,qBAAqB,GAAG,SAAS,CAAC;AAExC;;;;;;;;;GASG;AACH,KAAK,UAAU,UAAU,CACvB,OAAuB,EACvB,SAAiB,EACjB,MAAuB,EACvB,YAAqB;IAErB,MAAM,KAAK,GAAsB,EAAE,CAAC;IACpC,IAAI,CAAC;QACH,KAAK,MAAM,OAAO,IAAI,MAAM,EAAE,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,MAAM,IAAA,8BAAgB,EAAC,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;QAChG,CAAC;IACH,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,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAChD,4BAA4B,EAC5B,OAAO,CAAC,MAAM,CACf,CAAC;QACJ,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;GAWG;AACI,KAAK,sBACV,OAAuB,EACvB,SAAiB,EACjB,QAAuB;IAEvB,IAAA,8BAAiB,EAAC,SAAS,CAAC,CAAC;IAC7B,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAClC,MAAM,MAAM,GAAG,IAAA,0CAA+B,EAAC,QAAQ,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG;QACxB,CAAC,CAAC,MAAM,IAAA,6BAAgB,EAAC,OAAO,EAAE,SAAS,EAAE,IAAA,2BAAqB,EAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChF,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;IACjF,MAAM,MAAM,GAAG,IAAA,6BAAW,EAAC,KAAK,EAAE,4BAA4B,EAAE,qBAAqB,CAAC,CAAC;IACvF,MAAM,IAAA,0BAAY,EAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE;QAC7C,GAAG,EAAE,IAAA,cAAM,GAAE;QACb,KAAK,EAAE,IAAA,6BAAW,EAAC,MAAM,CAAC;QAC1B,YAAY,EAAE,MAAM,EAAE,YAAY;QAClC,eAAe,EAAE,MAAM,EAAE,OAAO;KACjC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import type { HistoryContext } from '../internal/setup';
|
|
2
2
|
/**
|
|
3
|
-
* Delete a whole session: every message item plus the metadata item,
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* the in-memory page caps, and never discards already-flushed progress if a
|
|
8
|
-
* later batch fails.
|
|
3
|
+
* Delete a whole session: every message item plus the metadata item, best-effort
|
|
4
|
+
* deleting any offloaded S3 objects. Rows this adapter does not own are left in
|
|
5
|
+
* place and logged, so a shared-table partition holding a foreign row is never
|
|
6
|
+
* collaterally wiped.
|
|
9
7
|
*/
|
|
10
8
|
export declare function clearSession(context: HistoryContext, sessionId: string): Promise<void>;
|
|
11
9
|
//# sourceMappingURL=clear.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clear.d.ts","sourceRoot":"","sources":["../../../src/history/actions/clear.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"clear.d.ts","sourceRoot":"","sources":["../../../src/history/actions/clear.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAQxD;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAY5F"}
|
|
@@ -1,46 +1,31 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.clearSession = clearSession;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const constants_1 = require("../../shared/constants");
|
|
7
|
-
const batch_write_1 = require("../../shared/dynamodb/batch-write");
|
|
8
|
-
const paginate_1 = require("../../shared/dynamodb/paginate");
|
|
4
|
+
const partition_delete_1 = require("../../shared/dynamodb/partition-delete");
|
|
5
|
+
const keys_1 = require("../internal/keys");
|
|
9
6
|
const query_1 = require("../internal/query");
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
if (context.offloader) {
|
|
15
|
-
await (0, orphans_1.cleanUpS3Orphans)(context.offloader, (0, descriptor_keys_1.collectS3Keys)(buffer.descriptors), 'history.clear', context.logger);
|
|
16
|
-
}
|
|
17
|
-
buffer.keys = [];
|
|
18
|
-
buffer.descriptors = [];
|
|
7
|
+
const validation_1 = require("../internal/validation");
|
|
8
|
+
/** The offloaded payload a chat-history row can reference. */
|
|
9
|
+
function descriptorsOf(row) {
|
|
10
|
+
return [row.message];
|
|
19
11
|
}
|
|
20
12
|
/**
|
|
21
|
-
* Delete a whole session: every message item plus the metadata item,
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* the in-memory page caps, and never discards already-flushed progress if a
|
|
26
|
-
* later batch fails.
|
|
13
|
+
* Delete a whole session: every message item plus the metadata item, best-effort
|
|
14
|
+
* deleting any offloaded S3 objects. Rows this adapter does not own are left in
|
|
15
|
+
* place and logged, so a shared-table partition holding a foreign row is never
|
|
16
|
+
* collaterally wiped.
|
|
27
17
|
*/
|
|
28
18
|
async function clearSession(context, sessionId) {
|
|
29
|
-
|
|
30
|
-
|
|
19
|
+
(0, validation_1.validateSessionId)(sessionId);
|
|
20
|
+
await (0, partition_delete_1.deletePartitionRows)({
|
|
31
21
|
client: context.client,
|
|
22
|
+
tableName: context.tableName,
|
|
32
23
|
params: (0, query_1.sessionItemsQuery)(context.tableName, sessionId, { consistent: true }),
|
|
33
|
-
|
|
34
|
-
|
|
24
|
+
logger: context.logger,
|
|
25
|
+
offloader: context.offloader,
|
|
26
|
+
operation: 'history.clear',
|
|
27
|
+
ownsSortKey: keys_1.isHistorySortKey,
|
|
28
|
+
descriptorsOf,
|
|
35
29
|
});
|
|
36
|
-
for await (const raw of pages) {
|
|
37
|
-
const item = raw;
|
|
38
|
-
buffer.keys.push({ PK: item.PK, SK: item.SK });
|
|
39
|
-
if (item.message)
|
|
40
|
-
buffer.descriptors.push(item.message);
|
|
41
|
-
if (buffer.keys.length >= constants_1.BATCH_WRITE_MAX)
|
|
42
|
-
await flushBuffer(context, buffer);
|
|
43
|
-
}
|
|
44
|
-
await flushBuffer(context, buffer);
|
|
45
30
|
}
|
|
46
31
|
//# sourceMappingURL=clear.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clear.js","sourceRoot":"","sources":["../../../src/history/actions/clear.ts"],"names":[],"mappings":";;;AACA,
|
|
1
|
+
{"version":3,"file":"clear.js","sourceRoot":"","sources":["../../../src/history/actions/clear.ts"],"names":[],"mappings":";;;AACA,6EAA6E;AAE7E,2CAAoD;AACpD,6CAAsD;AAEtD,uDAA2D;AAE3D,8DAA8D;AAC9D,SAAS,aAAa,CAAC,GAAY;IACjC,OAAO,CAAC,GAAG,CAAC,OAAwC,CAAC,CAAC;AACxD,CAAC;AAED;;;;;GAKG;AACI,KAAK,uBAAuB,OAAuB,EAAE,SAAiB;IAC3E,IAAA,8BAAiB,EAAC,SAAS,CAAC,CAAC;IAC7B,MAAM,IAAA,sCAAmB,EAAC;QACxB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,MAAM,EAAE,IAAA,yBAAiB,EAAC,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;QAC7E,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,SAAS,EAAE,eAAe;QAC1B,WAAW,EAAE,uBAAgB;QAC7B,aAAa;KACd,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -3,7 +3,8 @@ import type { HistoryContext } from '../internal/setup';
|
|
|
3
3
|
/**
|
|
4
4
|
* Return a session's messages in chronological order. Items past their TTL are
|
|
5
5
|
* filtered out on read (DynamoDB's background TTL sweep can lag by up to 48h),
|
|
6
|
-
* so the returned history is never stale.
|
|
6
|
+
* so the returned history is never stale. An item that cannot be decoded is
|
|
7
|
+
* handled per `onCorruptMessage` (see {@link decodeOrSkip}).
|
|
7
8
|
*/
|
|
8
9
|
export declare function getMessages(context: HistoryContext, sessionId: string): Promise<BaseMessage[]>;
|
|
9
10
|
//# sourceMappingURL=get-messages.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-messages.d.ts","sourceRoot":"","sources":["../../../src/history/actions/get-messages.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAGjB,MAAM,0BAA0B,CAAC;AAKlC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"get-messages.d.ts","sourceRoot":"","sources":["../../../src/history/actions/get-messages.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAGjB,MAAM,0BAA0B,CAAC;AAKlC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAgCxD;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,WAAW,EAAE,CAAC,CAgBxB"}
|
|
@@ -5,15 +5,39 @@ const messages_1 = require("@langchain/core/messages");
|
|
|
5
5
|
const paginate_1 = require("../../shared/dynamodb/paginate");
|
|
6
6
|
const item_mapper_1 = require("../internal/item-mapper");
|
|
7
7
|
const query_1 = require("../internal/query");
|
|
8
|
+
const validation_1 = require("../internal/validation");
|
|
8
9
|
function isExpired(item, nowSeconds) {
|
|
9
10
|
return item.ttl !== undefined && item.ttl <= nowSeconds;
|
|
10
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Decode one item, honouring the configured corrupt-message policy. Under the
|
|
14
|
+
* default `'skip'` an undecodable item is reported and dropped rather than
|
|
15
|
+
* taking the whole session down with it: one bad row used to throw out of
|
|
16
|
+
* `getMessages` entirely, making every other message in the session
|
|
17
|
+
* permanently unreadable with no API to remove just the bad one.
|
|
18
|
+
*/
|
|
19
|
+
async function decodeOrSkip(context, sessionId, item) {
|
|
20
|
+
try {
|
|
21
|
+
return await (0, item_mapper_1.decodeMessageItem)(context, item);
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
if (context.onCorruptMessage === 'throw')
|
|
25
|
+
throw error;
|
|
26
|
+
context.logger.error('getMessages: skipped a corrupt message item', {
|
|
27
|
+
sessionId,
|
|
28
|
+
sortKey: item.SK,
|
|
29
|
+
});
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
11
33
|
/**
|
|
12
34
|
* Return a session's messages in chronological order. Items past their TTL are
|
|
13
35
|
* filtered out on read (DynamoDB's background TTL sweep can lag by up to 48h),
|
|
14
|
-
* so the returned history is never stale.
|
|
36
|
+
* so the returned history is never stale. An item that cannot be decoded is
|
|
37
|
+
* handled per `onCorruptMessage` (see {@link decodeOrSkip}).
|
|
15
38
|
*/
|
|
16
39
|
async function getMessages(context, sessionId) {
|
|
40
|
+
(0, validation_1.validateSessionId)(sessionId);
|
|
17
41
|
const nowSeconds = Math.floor(Date.now() / 1000);
|
|
18
42
|
const stored = [];
|
|
19
43
|
for await (const raw of (0, paginate_1.paginateQuery)({
|
|
@@ -25,7 +49,9 @@ async function getMessages(context, sessionId) {
|
|
|
25
49
|
const item = raw;
|
|
26
50
|
if (isExpired(item, nowSeconds))
|
|
27
51
|
continue;
|
|
28
|
-
|
|
52
|
+
const message = await decodeOrSkip(context, sessionId, item);
|
|
53
|
+
if (message)
|
|
54
|
+
stored.push(message);
|
|
29
55
|
}
|
|
30
56
|
return (0, messages_1.mapStoredMessagesToChatMessages)(stored);
|
|
31
57
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-messages.js","sourceRoot":"","sources":["../../../src/history/actions/get-messages.ts"],"names":[],"mappings":";;;AAAA,uDAIkC;AAElC,6DAA+D;AAC/D,yDAA4D;AAC5D,6CAAiD;
|
|
1
|
+
{"version":3,"file":"get-messages.js","sourceRoot":"","sources":["../../../src/history/actions/get-messages.ts"],"names":[],"mappings":";;;AAAA,uDAIkC;AAElC,6DAA+D;AAC/D,yDAA4D;AAC5D,6CAAiD;AAEjD,uDAA2D;AAG3D,SAAS,SAAS,CAAC,IAAqB,EAAE,UAAkB;IAC1D,OAAO,IAAI,CAAC,GAAG,KAAK,SAAS,IAAI,IAAI,CAAC,GAAG,IAAI,UAAU,CAAC;AAC1D,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,YAAY,CACzB,OAAuB,EACvB,SAAiB,EACjB,IAAqB;IAErB,IAAI,CAAC;QACH,OAAO,MAAM,IAAA,+BAAiB,EAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAChD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,OAAO,CAAC,gBAAgB,KAAK,OAAO;YAAE,MAAM,KAAK,CAAC;QACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,6CAA6C,EAAE;YAClE,SAAS;YACT,OAAO,EAAE,IAAI,CAAC,EAAE;SACjB,CAAC,CAAC;QACH,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACI,KAAK,sBACV,OAAuB,EACvB,SAAiB;IAEjB,IAAA,8BAAiB,EAAC,SAAS,CAAC,CAAC;IAC7B,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IACjD,MAAM,MAAM,GAAoB,EAAE,CAAC;IACnC,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,IAAA,wBAAa,EAAC;QACpC,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM,EAAE,IAAA,oBAAY,EAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC;QAClD,QAAQ,EAAE,MAAM,CAAC,iBAAiB;QAClC,aAAa,EAAE,MAAM,CAAC,iBAAiB;KACxC,CAAC,EAAE,CAAC;QACH,MAAM,IAAI,GAAG,GAAsB,CAAC;QACpC,IAAI,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC;YAAE,SAAS;QAC1C,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;QAC7D,IAAI,OAAO;YAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,IAAA,0CAA+B,EAAC,MAAM,CAAC,CAAC;AACjD,CAAC"}
|
|
@@ -3,7 +3,8 @@ import type { SessionMetadata } from '../types';
|
|
|
3
3
|
/**
|
|
4
4
|
* List all sessions as metadata summaries, newest-updated first. The scan is
|
|
5
5
|
* filtered to session items so the adapter works on a table shared with the
|
|
6
|
-
* checkpointer/store; foreign rows are also skipped defensively
|
|
6
|
+
* checkpointer/store; foreign rows are also skipped defensively, and rows past
|
|
7
|
+
* their TTL are filtered out exactly as `getMessages` filters expired messages.
|
|
7
8
|
*/
|
|
8
9
|
export declare function listSessions(context: HistoryContext, options?: {
|
|
9
10
|
maxIterations?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-sessions.d.ts","sourceRoot":"","sources":["../../../src/history/actions/list-sessions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAmB,eAAe,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"list-sessions.d.ts","sourceRoot":"","sources":["../../../src/history/actions/list-sessions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAmB,eAAe,EAAE,MAAM,UAAU,CAAC;AAYjE;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GACtD,OAAO,CAAC,eAAe,EAAE,CAAC,CAiC5B"}
|