@effect-agent/storage-memory 0.1.0-beta.37 → 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.
@@ -1,2 +1,2 @@
1
- import { ConversationStoreConformanceCase, ConversationStoreConformanceFailure, ConversationStoreConformanceViolation, ScheduleStoreConformanceCase, ScheduleStoreConformanceFailure, ScheduleStoreConformanceViolation, SubmissionLedgerConformanceCase, SubmissionLedgerConformanceFailure, SubmissionLedgerConformanceViolation, conversationStoreConformanceCases, scheduleStoreConformanceCases, submissionLedgerConformanceCases } from "@effect-agent/session/testing";
2
- export { type ConversationStoreConformanceCase, type ConversationStoreConformanceFailure, ConversationStoreConformanceViolation, type ScheduleStoreConformanceCase, type ScheduleStoreConformanceFailure, ScheduleStoreConformanceViolation, type SubmissionLedgerConformanceCase, type SubmissionLedgerConformanceFailure, SubmissionLedgerConformanceViolation, conversationStoreConformanceCases, scheduleStoreConformanceCases, submissionLedgerConformanceCases };
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 { ConversationStoreConformanceViolation, ScheduleStoreConformanceViolation, SubmissionLedgerConformanceViolation, conversationStoreConformanceCases, scheduleStoreConformanceCases, submissionLedgerConformanceCases } from "@effect-agent/session/testing";
2
- export { ConversationStoreConformanceViolation, ScheduleStoreConformanceViolation, SubmissionLedgerConformanceViolation, conversationStoreConformanceCases, scheduleStoreConformanceCases, submissionLedgerConformanceCases };
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.37",
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.37",
16
- "@effect-agent/session": "0.1.0-beta.37",
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
- "description": "In-memory Conversation store and submission ledger reference adapters for Effect Agent tests and conformance suites.",
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
@@ -1,3 +1,4 @@
1
1
  export * from "./memory-ledger.ts";
2
2
  export * from "./memory-schedule-store.ts";
3
+ export * from "./memory-subscription-store.ts";
3
4
  export * from "./memory-storage.ts";
@@ -4,7 +4,7 @@ import {
4
4
  ReceiptId,
5
5
  SubmissionId,
6
6
  type AgentId,
7
- type ConversationId,
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/session";
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 conversationId: ConversationId;
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<ConversationId, LaneState>;
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
- conversationId: ConversationId,
251
+ threadId: ThreadId,
252
252
  principal: Principal,
253
253
  idempotencyKey: IdempotencyKey,
254
- ): string => `${conversationId}\u001f${principal}\u001f${idempotencyKey}`;
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
- conversationId: row.conversationId,
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, conversationId: ConversationId): number =>
305
- state.lanes.get(conversationId)?.producerEpoch ?? 0;
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.conversationId)),
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.conversationId !== conversationId || stored.row.state === "settled") continue;
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
- conversationId: request.conversationId,
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.conversationId) ?? {
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
- conversationId: request.conversationId,
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.conversationId, {
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.conversationId, request.principal, request.idempotencyKey),
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.conversationId, request.principal, request.idempotencyKey),
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.conversationId);
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.conversationId);
605
+ const lane = current.lanes.get(request.threadId);
613
606
  if (lane === undefined) {
614
607
  return [
615
- failure(ledgerError("claim", "Claimable head without a Conversation lane")),
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.conversationId, {
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.conversationId !== request.conversationId) {
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 Conversation ${request.conversationId}`,
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.conversationId === request.conversationId &&
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.conversationId < right.row.conversationId
2062
+ left.row.threadId < right.row.threadId
2070
2063
  ? -1
2071
- : left.row.conversationId > right.row.conversationId
2064
+ : left.row.threadId > right.row.threadId
2072
2065
  ? 1
2073
2066
  : left.row.queueSequence - right.row.queueSequence,
2074
2067
  )
@@ -20,7 +20,7 @@ import {
20
20
  scheduleKeyString,
21
21
  scheduleKeyOf,
22
22
  scheduleOwnerKey,
23
- } from "@effect-agent/session";
23
+ } from "@effect-agent/thread";
24
24
  import { Effect, Layer, Ref, Result, Schema } from "effect";
25
25
 
26
26
  interface MemoryScheduleState {