@effect-agent/storage-memory 0.1.0-beta.38 → 0.1.0-beta.39
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/dist/index.d.mts +9 -6
- package/dist/index.mjs +752 -160
- package/dist/index.mjs.map +1 -1
- package/dist/testing.d.mts +2 -2
- package/dist/testing.mjs +2 -2
- package/package.json +8 -5
- package/src/index.ts +1 -0
- package/src/memory-ledger.ts +28 -35
- package/src/memory-schedule-store.ts +1 -1
- package/src/memory-storage.ts +336 -366
- package/src/memory-subscription-store.ts +921 -0
- package/src/testing.ts +7 -6
package/dist/testing.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { type
|
|
1
|
+
import { ScheduleStoreConformanceCase, ScheduleStoreConformanceFailure, ScheduleStoreConformanceViolation, SubmissionLedgerConformanceCase, SubmissionLedgerConformanceFailure, SubmissionLedgerConformanceViolation, ThreadStoreConformanceCase, ThreadStoreConformanceFailure, ThreadStoreConformanceViolation, scheduleStoreConformanceCases, submissionLedgerConformanceCases, threadCheckpointConformanceCases, threadStoreConformanceCases } from "@effect-agent/thread/testing";
|
|
2
|
+
export { type ScheduleStoreConformanceCase, type ScheduleStoreConformanceFailure, ScheduleStoreConformanceViolation, type SubmissionLedgerConformanceCase, type SubmissionLedgerConformanceFailure, SubmissionLedgerConformanceViolation, type ThreadStoreConformanceCase, type ThreadStoreConformanceFailure, ThreadStoreConformanceViolation, scheduleStoreConformanceCases, submissionLedgerConformanceCases, threadCheckpointConformanceCases, threadStoreConformanceCases };
|
package/dist/testing.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { ScheduleStoreConformanceViolation, SubmissionLedgerConformanceViolation, ThreadStoreConformanceViolation, scheduleStoreConformanceCases, submissionLedgerConformanceCases, threadCheckpointConformanceCases, threadStoreConformanceCases } from "@effect-agent/thread/testing";
|
|
2
|
+
export { ScheduleStoreConformanceViolation, SubmissionLedgerConformanceViolation, ThreadStoreConformanceViolation, scheduleStoreConformanceCases, submissionLedgerConformanceCases, threadCheckpointConformanceCases, threadStoreConformanceCases };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effect-agent/storage-memory",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.39",
|
|
4
4
|
"exports": {
|
|
5
5
|
".": {
|
|
6
6
|
"types": "./dist/index.d.mts",
|
|
@@ -12,11 +12,13 @@
|
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@effect-agent/core": "0.1.0-beta.
|
|
16
|
-
"@effect-agent/
|
|
17
|
-
"effect": "4.0.0-rc.111"
|
|
15
|
+
"@effect-agent/core": "0.1.0-beta.39",
|
|
16
|
+
"@effect-agent/thread": "0.1.0-beta.39"
|
|
18
17
|
},
|
|
19
|
-
"
|
|
18
|
+
"peerDependencies": {
|
|
19
|
+
"effect": "^4.0.0-rc.111"
|
|
20
|
+
},
|
|
21
|
+
"description": "In-memory Thread store and submission ledger reference adapters for Effect Agent tests and conformance suites.",
|
|
20
22
|
"license": "MIT",
|
|
21
23
|
"repository": {
|
|
22
24
|
"type": "git",
|
|
@@ -39,6 +41,7 @@
|
|
|
39
41
|
"devDependencies": {
|
|
40
42
|
"@effect/platform-node": "4.0.0-rc.111",
|
|
41
43
|
"@effect/vitest": "4.0.0-rc.111",
|
|
44
|
+
"effect": "4.0.0-rc.111",
|
|
42
45
|
"typescript": "7.0.2",
|
|
43
46
|
"vite-plus": "0.2.6"
|
|
44
47
|
}
|
package/src/index.ts
CHANGED
package/src/memory-ledger.ts
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
ReceiptId,
|
|
5
5
|
SubmissionId,
|
|
6
6
|
type AgentId,
|
|
7
|
-
type
|
|
7
|
+
type ThreadId,
|
|
8
8
|
type SettlementId,
|
|
9
9
|
} from "@effect-agent/core";
|
|
10
10
|
import {
|
|
@@ -86,7 +86,7 @@ import {
|
|
|
86
86
|
type SubmissionState,
|
|
87
87
|
type SuspensionOutcome,
|
|
88
88
|
type SuspensionReason,
|
|
89
|
-
} from "@effect-agent/
|
|
89
|
+
} from "@effect-agent/thread";
|
|
90
90
|
import { Clock, DateTime, Duration, Effect, Layer, Option, Ref, Schema, Stream } from "effect";
|
|
91
91
|
|
|
92
92
|
const MAX_SUBMISSIONS = 65_536;
|
|
@@ -111,7 +111,7 @@ const STATE_RANK: Record<SubmissionState, number> = {
|
|
|
111
111
|
|
|
112
112
|
interface SubmissionRow {
|
|
113
113
|
readonly submissionId: SubmissionId;
|
|
114
|
-
readonly
|
|
114
|
+
readonly threadId: ThreadId;
|
|
115
115
|
readonly queueSequence: QueueSequence;
|
|
116
116
|
readonly principal: Principal;
|
|
117
117
|
readonly idempotencyKey: IdempotencyKey;
|
|
@@ -207,7 +207,7 @@ interface StoredChildReservation {
|
|
|
207
207
|
interface LedgerState {
|
|
208
208
|
readonly submissions: ReadonlyMap<SubmissionId, StoredSubmission>;
|
|
209
209
|
readonly admissionIndex: ReadonlyMap<string, SubmissionId>;
|
|
210
|
-
readonly lanes: ReadonlyMap<
|
|
210
|
+
readonly lanes: ReadonlyMap<ThreadId, LaneState>;
|
|
211
211
|
readonly childReservations: ReadonlyMap<ChildReservationId, StoredChildReservation>;
|
|
212
212
|
readonly mintCounter: number;
|
|
213
213
|
}
|
|
@@ -248,15 +248,15 @@ const equivalentUnknownResolution = Schema.toEquivalence(UnknownResolution);
|
|
|
248
248
|
const utc = (millis: number): DateTime.Utc => DateTime.toUtc(DateTime.makeUnsafe(millis));
|
|
249
249
|
|
|
250
250
|
const admissionKey = (
|
|
251
|
-
|
|
251
|
+
threadId: ThreadId,
|
|
252
252
|
principal: Principal,
|
|
253
253
|
idempotencyKey: IdempotencyKey,
|
|
254
|
-
): string => `${
|
|
254
|
+
): string => `${threadId}\u001f${principal}\u001f${idempotencyKey}`;
|
|
255
255
|
|
|
256
256
|
const toSnapshot = (row: SubmissionRow): SubmissionSnapshot =>
|
|
257
257
|
SubmissionSnapshot.make({
|
|
258
258
|
submissionId: row.submissionId,
|
|
259
|
-
|
|
259
|
+
threadId: row.threadId,
|
|
260
260
|
queueSequence: row.queueSequence,
|
|
261
261
|
principal: row.principal,
|
|
262
262
|
idempotencyKey: row.idempotencyKey,
|
|
@@ -301,13 +301,13 @@ const sameParentLinkage = (
|
|
|
301
301
|
left.parentSubmissionId === right.parentSubmissionId &&
|
|
302
302
|
left.parentToolCallId === right.parentToolCallId;
|
|
303
303
|
|
|
304
|
-
const laneEpoch = (state: LedgerState,
|
|
305
|
-
state.lanes.get(
|
|
304
|
+
const laneEpoch = (state: LedgerState, threadId: ThreadId): number =>
|
|
305
|
+
state.lanes.get(threadId)?.producerEpoch ?? 0;
|
|
306
306
|
|
|
307
307
|
const ownershipLost = (state: LedgerState, stored: StoredSubmission): OwnershipLost =>
|
|
308
308
|
OwnershipLost.make({
|
|
309
309
|
submissionId: stored.row.submissionId,
|
|
310
|
-
actualEpoch: decodeProducerEpoch(laneEpoch(state, stored.row.
|
|
310
|
+
actualEpoch: decodeProducerEpoch(laneEpoch(state, stored.row.threadId)),
|
|
311
311
|
});
|
|
312
312
|
|
|
313
313
|
/** The presented token owns the lane only while it matches the live ownership record. */
|
|
@@ -327,13 +327,10 @@ const withChildReservation = (
|
|
|
327
327
|
childReservations: new Map(state.childReservations).set(reservation.reservationId, reservation),
|
|
328
328
|
});
|
|
329
329
|
|
|
330
|
-
const findHead = (
|
|
331
|
-
state: LedgerState,
|
|
332
|
-
conversationId: ConversationId,
|
|
333
|
-
): StoredSubmission | undefined => {
|
|
330
|
+
const findHead = (state: LedgerState, threadId: ThreadId): StoredSubmission | undefined => {
|
|
334
331
|
let head: StoredSubmission | undefined;
|
|
335
332
|
for (const stored of state.submissions.values()) {
|
|
336
|
-
if (stored.row.
|
|
333
|
+
if (stored.row.threadId !== threadId || stored.row.state === "settled") continue;
|
|
337
334
|
if (head === undefined || stored.row.queueSequence < head.row.queueSequence) head = stored;
|
|
338
335
|
}
|
|
339
336
|
return head;
|
|
@@ -399,11 +396,7 @@ const makeSubmissionLedger = (options: MemorySubmissionLedgerOptions = {}) =>
|
|
|
399
396
|
Decision<AdmissionResult, AdmissionConflict | LedgerError>,
|
|
400
397
|
LedgerState,
|
|
401
398
|
] => {
|
|
402
|
-
const key = admissionKey(
|
|
403
|
-
request.conversationId,
|
|
404
|
-
request.principal,
|
|
405
|
-
request.idempotencyKey,
|
|
406
|
-
);
|
|
399
|
+
const key = admissionKey(request.threadId, request.principal, request.idempotencyKey);
|
|
407
400
|
const existingId = current.admissionIndex.get(key);
|
|
408
401
|
if (existingId !== undefined) {
|
|
409
402
|
const existing = current.submissions.get(existingId);
|
|
@@ -424,7 +417,7 @@ const makeSubmissionLedger = (options: MemorySubmissionLedgerOptions = {}) =>
|
|
|
424
417
|
return [
|
|
425
418
|
failure(
|
|
426
419
|
AdmissionConflict.make({
|
|
427
|
-
|
|
420
|
+
threadId: request.threadId,
|
|
428
421
|
principal: request.principal,
|
|
429
422
|
idempotencyKey: request.idempotencyKey,
|
|
430
423
|
existingInputDigest: existing.row.inputDigest,
|
|
@@ -455,14 +448,14 @@ const makeSubmissionLedger = (options: MemorySubmissionLedgerOptions = {}) =>
|
|
|
455
448
|
current,
|
|
456
449
|
];
|
|
457
450
|
}
|
|
458
|
-
const lane = current.lanes.get(request.
|
|
451
|
+
const lane = current.lanes.get(request.threadId) ?? {
|
|
459
452
|
nextQueueSequence: 1,
|
|
460
453
|
producerEpoch: 0,
|
|
461
454
|
};
|
|
462
455
|
const mintCounter = current.mintCounter + 1;
|
|
463
456
|
const row: SubmissionRow = {
|
|
464
457
|
submissionId: decodeSubmissionId(`submission-memory-${mintCounter}`),
|
|
465
|
-
|
|
458
|
+
threadId: request.threadId,
|
|
466
459
|
queueSequence: decodeQueueSequence(lane.nextQueueSequence),
|
|
467
460
|
principal: request.principal,
|
|
468
461
|
idempotencyKey: request.idempotencyKey,
|
|
@@ -491,7 +484,7 @@ const makeSubmissionLedger = (options: MemorySubmissionLedgerOptions = {}) =>
|
|
|
491
484
|
unknownResolutions: new Map<ToolCallId, StoredUnknownResolution>(),
|
|
492
485
|
});
|
|
493
486
|
const admissionIndex = new Map(current.admissionIndex).set(key, row.submissionId);
|
|
494
|
-
const lanes = new Map(current.lanes).set(request.
|
|
487
|
+
const lanes = new Map(current.lanes).set(request.threadId, {
|
|
495
488
|
nextQueueSequence: lane.nextQueueSequence + 1,
|
|
496
489
|
producerEpoch: lane.producerEpoch,
|
|
497
490
|
});
|
|
@@ -554,7 +547,7 @@ const makeSubmissionLedger = (options: MemorySubmissionLedgerOptions = {}) =>
|
|
|
554
547
|
request._tag === "SubmissionLookupById"
|
|
555
548
|
? request.submissionId
|
|
556
549
|
: current.admissionIndex.get(
|
|
557
|
-
admissionKey(request.
|
|
550
|
+
admissionKey(request.threadId, request.principal, request.idempotencyKey),
|
|
558
551
|
);
|
|
559
552
|
const stored =
|
|
560
553
|
submissionId === undefined ? undefined : current.submissions.get(submissionId);
|
|
@@ -577,7 +570,7 @@ const makeSubmissionLedger = (options: MemorySubmissionLedgerOptions = {}) =>
|
|
|
577
570
|
}
|
|
578
571
|
const current = yield* Ref.get(state);
|
|
579
572
|
const submissionId = current.admissionIndex.get(
|
|
580
|
-
admissionKey(request.
|
|
573
|
+
admissionKey(request.threadId, request.principal, request.idempotencyKey),
|
|
581
574
|
);
|
|
582
575
|
const stored =
|
|
583
576
|
submissionId === undefined ? undefined : current.submissions.get(submissionId);
|
|
@@ -595,7 +588,7 @@ const makeSubmissionLedger = (options: MemorySubmissionLedgerOptions = {}) =>
|
|
|
595
588
|
const decision = yield* Ref.modify(
|
|
596
589
|
state,
|
|
597
590
|
(current): readonly [Decision<Option.Option<Claim>, LedgerError>, LedgerState] => {
|
|
598
|
-
const head = findHead(current, request.
|
|
591
|
+
const head = findHead(current, request.threadId);
|
|
599
592
|
if (head === undefined) return [success(Option.none()), current];
|
|
600
593
|
if (
|
|
601
594
|
BLOCKED_HEAD_STATES.has(head.row.state) ||
|
|
@@ -609,10 +602,10 @@ const makeSubmissionLedger = (options: MemorySubmissionLedgerOptions = {}) =>
|
|
|
609
602
|
) {
|
|
610
603
|
return [success(Option.none()), current];
|
|
611
604
|
}
|
|
612
|
-
const lane = current.lanes.get(request.
|
|
605
|
+
const lane = current.lanes.get(request.threadId);
|
|
613
606
|
if (lane === undefined) {
|
|
614
607
|
return [
|
|
615
|
-
failure(ledgerError("claim", "Claimable head without a
|
|
608
|
+
failure(ledgerError("claim", "Claimable head without a Thread lane")),
|
|
616
609
|
current,
|
|
617
610
|
];
|
|
618
611
|
}
|
|
@@ -628,7 +621,7 @@ const makeSubmissionLedger = (options: MemorySubmissionLedgerOptions = {}) =>
|
|
|
628
621
|
const row: SubmissionRow =
|
|
629
622
|
head.row.state === "ready" ? { ...head.row, state: "running" } : head.row;
|
|
630
623
|
const next = withSubmission(current, { ...head, row, ownership });
|
|
631
|
-
const lanes = new Map(next.lanes).set(request.
|
|
624
|
+
const lanes = new Map(next.lanes).set(request.threadId, {
|
|
632
625
|
nextQueueSequence: lane.nextQueueSequence,
|
|
633
626
|
producerEpoch: lane.producerEpoch + 1,
|
|
634
627
|
});
|
|
@@ -1071,12 +1064,12 @@ const makeSubmissionLedger = (options: MemorySubmissionLedgerOptions = {}) =>
|
|
|
1071
1064
|
current,
|
|
1072
1065
|
];
|
|
1073
1066
|
}
|
|
1074
|
-
if (host.row.
|
|
1067
|
+
if (host.row.threadId !== request.threadId) {
|
|
1075
1068
|
return [
|
|
1076
1069
|
failure(
|
|
1077
1070
|
ledgerError(
|
|
1078
1071
|
"claimJoining",
|
|
1079
|
-
`Host Submission ${request.hostSubmissionId} does not belong to
|
|
1072
|
+
`Host Submission ${request.hostSubmissionId} does not belong to Thread ${request.threadId}`,
|
|
1080
1073
|
),
|
|
1081
1074
|
),
|
|
1082
1075
|
current,
|
|
@@ -1088,7 +1081,7 @@ const makeSubmissionLedger = (options: MemorySubmissionLedgerOptions = {}) =>
|
|
|
1088
1081
|
const later = [...current.submissions.values()]
|
|
1089
1082
|
.filter(
|
|
1090
1083
|
(stored) =>
|
|
1091
|
-
stored.row.
|
|
1084
|
+
stored.row.threadId === request.threadId &&
|
|
1092
1085
|
stored.row.queueSequence > host.row.queueSequence,
|
|
1093
1086
|
)
|
|
1094
1087
|
.sort((left, right) => left.row.queueSequence - right.row.queueSequence);
|
|
@@ -2066,9 +2059,9 @@ const makeSubmissionLedger = (options: MemorySubmissionLedgerOptions = {}) =>
|
|
|
2066
2059
|
const snapshots = [...current.submissions.values()]
|
|
2067
2060
|
.filter((stored) => stored.row.state !== "settled")
|
|
2068
2061
|
.sort((left, right) =>
|
|
2069
|
-
left.row.
|
|
2062
|
+
left.row.threadId < right.row.threadId
|
|
2070
2063
|
? -1
|
|
2071
|
-
: left.row.
|
|
2064
|
+
: left.row.threadId > right.row.threadId
|
|
2072
2065
|
? 1
|
|
2073
2066
|
: left.row.queueSequence - right.row.queueSequence,
|
|
2074
2067
|
)
|