@yielded/agent-storage-memory 0.1.0-beta.172 → 0.1.0-beta.174

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/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@yielded/agent-storage-memory","version":"0.1.0-beta.172","dependencies":{"@yielded/agent":"0.1.0-beta.172"},"devDependencies":{"@effect/platform-node":"4.0.3","@effect/vitest":"4.0.3","effect":"4.0.3","typescript":"7.0.2","vite":"npm:@voidzero-dev/vite-plus-core@1.1.0","vite-plus":"1.1.0","vitest":"5.0.3"},"peerDependencies":{"effect":"^4.0.3"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./memory-message-delivery-store":{"types":"./dist/MemoryMessageDeliveryStore.d.mts","default":"./dist/MemoryMessageDeliveryStore.mjs"},"./memory-schedule-store":{"types":"./dist/MemoryScheduleStore.d.mts","default":"./dist/MemoryScheduleStore.mjs"},"./memory-semantic-index":{"types":"./dist/MemorySemanticIndex.d.mts","default":"./dist/MemorySemanticIndex.mjs"},"./memory-submission-ledger":{"types":"./dist/MemorySubmissionLedger.d.mts","default":"./dist/MemorySubmissionLedger.mjs"},"./memory-subscription-store":{"types":"./dist/MemorySubscriptionStore.d.mts","default":"./dist/MemorySubscriptionStore.mjs"},"./memory-thread-store":{"types":"./dist/MemoryThreadStore.d.mts","default":"./dist/MemoryThreadStore.mjs"}},"description":"In-memory Thread store and submission ledger reference adapters for Effect Agent tests and conformance suites.","license":"MIT","repository":{"type":"git","url":"git+https://github.com/yielded-dev/agent.git","directory":"packages/storage-memory"},"files":["dist","src"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json","test":"vp test --passWithNoTests"}}
1
+ {"name":"@yielded/agent-storage-memory","version":"0.1.0-beta.174","dependencies":{"@yielded/agent":"0.1.0-beta.174"},"devDependencies":{"@effect/platform-node":"4.0.3","@effect/vitest":"4.0.3","effect":"4.0.3","typescript":"7.0.2","vite":"npm:@voidzero-dev/vite-plus-core@1.1.0","vite-plus":"1.1.0","vitest":"5.0.3"},"peerDependencies":{"effect":"^4.0.3"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./memory-message-delivery-store":{"types":"./dist/MemoryMessageDeliveryStore.d.mts","default":"./dist/MemoryMessageDeliveryStore.mjs"},"./memory-schedule-store":{"types":"./dist/MemoryScheduleStore.d.mts","default":"./dist/MemoryScheduleStore.mjs"},"./memory-semantic-index":{"types":"./dist/MemorySemanticIndex.d.mts","default":"./dist/MemorySemanticIndex.mjs"},"./memory-submission-ledger":{"types":"./dist/MemorySubmissionLedger.d.mts","default":"./dist/MemorySubmissionLedger.mjs"},"./memory-subscription-store":{"types":"./dist/MemorySubscriptionStore.d.mts","default":"./dist/MemorySubscriptionStore.mjs"},"./memory-thread-store":{"types":"./dist/MemoryThreadStore.d.mts","default":"./dist/MemoryThreadStore.mjs"}},"description":"In-memory Thread store and submission ledger reference adapters for Effect Agent tests and conformance suites.","license":"MIT","repository":{"type":"git","url":"git+https://github.com/yielded-dev/agent.git","directory":"packages/storage-memory"},"files":["dist","src"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json","test":"vp test --passWithNoTests"}}
@@ -189,36 +189,35 @@ export const memoryMessageDeliveryStoreLayer = (
189
189
  };
190
190
  }),
191
191
  ),
192
- page: (threadId, after, limit) =>
193
- Effect.gen(function* () {
194
- const current = yield* Ref.get(state);
195
-
196
- const candidates = boundedWorkSelection<MessageDeliveryKey["messageId"]>(
197
- limit + 1,
198
- (id) => id,
199
- after,
200
- );
192
+ page: Effect.fnUntraced(function* (threadId, after, limit) {
193
+ const current = yield* Ref.get(state);
201
194
 
202
- for (const id of current.pending.get(threadId) ?? []) candidates.add(id);
203
- const ids = candidates.values;
195
+ const candidates = boundedWorkSelection<MessageDeliveryKey["messageId"]>(
196
+ limit + 1,
197
+ (id) => id,
198
+ after,
199
+ );
204
200
 
205
- const entries: Array<ThreadWorkEntry> = [];
201
+ for (const id of current.pending.get(threadId) ?? []) candidates.add(id);
202
+ const ids = candidates.values;
206
203
 
207
- for (const messageId of ids.slice(0, limit)) {
208
- const key = messageDeliveryKeyString({ ownerThreadId: threadId, messageId });
209
- const entry = current.work.get(key);
204
+ const entries: Array<ThreadWorkEntry> = [];
210
205
 
211
- if (entry === undefined || !current.records.has(key))
212
- return yield* ThreadStoreError.make({
213
- operation: "delivery work",
214
- message: "Pending delivery index is incomplete or corrupt",
215
- });
216
- entries.push(entry);
217
- }
218
- const next = ids.length > limit ? ids[limit - 1] : undefined;
206
+ for (const messageId of ids.slice(0, limit)) {
207
+ const key = messageDeliveryKeyString({ ownerThreadId: threadId, messageId });
208
+ const entry = current.work.get(key);
219
209
 
220
- return { entries, ...(next === undefined ? {} : { after: next }) };
221
- }),
210
+ if (entry === undefined || !current.records.has(key))
211
+ return yield* ThreadStoreError.make({
212
+ operation: "delivery work",
213
+ message: "Pending delivery index is incomplete or corrupt",
214
+ });
215
+ entries.push(entry);
216
+ }
217
+ const next = ids.length > limit ? ids[limit - 1] : undefined;
218
+
219
+ return { entries, ...(next === undefined ? {} : { after: next }) };
220
+ }),
222
221
  });
223
222
 
224
223
  const commitInto = (
@@ -662,19 +662,19 @@ function* threadRows(state: LedgerState, threadId: ThreadId, after = -1) {
662
662
  }
663
663
  }
664
664
 
665
- /**
666
- * Reference in-memory SubmissionLedger. Admission, ordered selection and canonical settlement
667
- * share the Memory kernel's mutation gate. The kernel Scope owns local Run capabilities;
668
- * selecting work does not write execution ownership into the ledger.
669
- *
670
- * Joining retains the contiguous ready prefix and exact host linkage. Canonical settlement
671
- * authorizes finalization and child wake repair, while bound sessions reject late commands.
672
- * Child wake checks read the child rows directly, without a separate notification marker.
673
- * Admission resolution is strongly consistent; resolveAdmissionFault injects the
674
- * Indeterminate outcome for existing caller conformance workflows.
675
- */
676
- const makeSubmissionLedger = (options: MemorySubmissionLedgerOptions = {}) =>
677
- Effect.gen(function* () {
665
+ const makeSubmissionLedger = Effect.fnUntraced(
666
+ /**
667
+ * Reference in-memory SubmissionLedger. Admission, ordered selection and canonical settlement
668
+ * share the Memory kernel's mutation gate. The kernel Scope owns local Run capabilities;
669
+ * selecting work does not write execution ownership into the ledger.
670
+ *
671
+ * Joining retains the contiguous ready prefix and exact host linkage. Canonical settlement
672
+ * authorizes finalization and child wake repair, while bound sessions reject late commands.
673
+ * Child wake checks read the child rows directly, without a separate notification marker.
674
+ * Admission resolution is strongly consistent; resolveAdmissionFault injects the
675
+ * Indeterminate outcome for existing caller conformance workflows.
676
+ */
677
+ function* (options: MemorySubmissionLedgerOptions = {}) {
678
678
  const journal = yield* MemoryThreadStoreKernel;
679
679
  const crypto = yield* Crypto.Crypto;
680
680
 
@@ -721,47 +721,46 @@ const makeSubmissionLedger = (options: MemorySubmissionLedgerOptions = {}) =>
721
721
  };
722
722
  }),
723
723
  ),
724
- page: (threadId, after, limit) =>
725
- Effect.gen(function* () {
726
- const current = yield* Ref.get(state);
724
+ page: Effect.fnUntraced(function* (threadId, after, limit) {
725
+ const current = yield* Ref.get(state);
727
726
 
728
- const candidates = boundedWorkSelection<SubmissionId>(limit + 1, (id) => id, after);
727
+ const candidates = boundedWorkSelection<SubmissionId>(limit + 1, (id) => id, after);
729
728
 
730
- for (const id of current.activeByThread.get(threadId) ?? []) candidates.add(id);
731
- const ids = candidates.values;
729
+ for (const id of current.activeByThread.get(threadId) ?? []) candidates.add(id);
730
+ const ids = candidates.values;
732
731
 
733
- const entries = [];
732
+ const entries = [];
734
733
 
735
- for (const id of ids.slice(0, limit)) {
736
- const stored = current.submissions.get(id);
734
+ for (const id of ids.slice(0, limit)) {
735
+ const stored = current.submissions.get(id);
737
736
 
738
- if (
739
- stored === undefined ||
740
- stored.row.threadId !== threadId ||
741
- stored.row.state === "settled"
742
- )
743
- return yield* ThreadStoreError.make({
744
- operation: "admission work",
745
- message: "Active admission index is incomplete or corrupt",
746
- });
747
- const entry = admissionWork(stored.row);
748
-
749
- entries.push(
750
- stored.suspension === undefined
751
- ? entry
752
- : {
753
- ...entry,
754
- wait:
755
- stored.suspension.reason._tag === "WaitingForChild"
756
- ? ("child" as const)
757
- : ("approval" as const),
758
- },
759
- );
760
- }
761
- const next = ids.length > limit ? ids[limit - 1] : undefined;
737
+ if (
738
+ stored === undefined ||
739
+ stored.row.threadId !== threadId ||
740
+ stored.row.state === "settled"
741
+ )
742
+ return yield* ThreadStoreError.make({
743
+ operation: "admission work",
744
+ message: "Active admission index is incomplete or corrupt",
745
+ });
746
+ const entry = admissionWork(stored.row);
747
+
748
+ entries.push(
749
+ stored.suspension === undefined
750
+ ? entry
751
+ : {
752
+ ...entry,
753
+ wait:
754
+ stored.suspension.reason._tag === "WaitingForChild"
755
+ ? ("child" as const)
756
+ : ("approval" as const),
757
+ },
758
+ );
759
+ }
760
+ const next = ids.length > limit ? ids[limit - 1] : undefined;
762
761
 
763
- return { entries, ...(next === undefined ? {} : { after: next }) };
764
- }),
762
+ return { entries, ...(next === undefined ? {} : { after: next }) };
763
+ }),
765
764
  });
766
765
 
767
766
  const admissionFence = yield* SubmissionAdmissionFence;
@@ -3521,7 +3520,8 @@ const makeSubmissionLedger = (options: MemorySubmissionLedgerOptions = {}) =>
3521
3520
  return Context.make(SubmissionLedger, ledger).pipe(
3522
3521
  Context.add(SettlementPublisher, { publish }),
3523
3522
  );
3524
- });
3523
+ },
3524
+ );
3525
3525
 
3526
3526
  /** Construction options for the in-memory reference SubmissionLedger. */
3527
3527
  export interface MemorySubmissionLedgerOptions {
@@ -225,7 +225,11 @@ const storedBytes = (thread: StoredThread, sequence: number) =>
225
225
  (sequence - 1) % RECORD_CHUNK_SIZE
226
226
  ];
227
227
 
228
- const storedPage = (thread: StoredThread, after: number, limit: number) => {
228
+ const storedPage = Effect.fnUntraced(function* (
229
+ thread: StoredThread,
230
+ after: number,
231
+ limit: number,
232
+ ) {
229
233
  const page: Array<CanonicalRecordEnvelope> = [];
230
234
  let bytes = 0;
231
235
 
@@ -236,7 +240,7 @@ const storedPage = (thread: StoredThread, after: number, limit: number) => {
236
240
  ) {
237
241
  const record = storedRecord(thread, sequence);
238
242
 
239
- if (record === undefined) throw new Error("Incomplete canonical chunk table");
243
+ if (record === undefined) return yield* storeError("read", "Incomplete canonical chunk table");
240
244
  const size = storedBytes(thread, sequence) ?? 0;
241
245
 
242
246
  if (bytes + size > 32 * 1024 * 1024) break;
@@ -245,7 +249,7 @@ const storedPage = (thread: StoredThread, after: number, limit: number) => {
245
249
  }
246
250
 
247
251
  return page;
248
- };
252
+ });
249
253
 
250
254
  const retainRecords = (thread: StoredThread, records: ReadonlyArray<CanonicalRecordEnvelope>) => {
251
255
  for (const entry of records) {
@@ -1533,7 +1537,7 @@ const makeThreadStore = Effect.gen(function* () {
1533
1537
  ) =>
1534
1538
  Ref.get(state).pipe(
1535
1539
  Effect.flatMap((current) => findThread(current, threadId)),
1536
- Effect.map((thread) => {
1540
+ Effect.flatMap((thread) => {
1537
1541
  // Append assigns gap-free sequences starting at 1, so the exclusive cursor is an index.
1538
1542
  const start = afterSequence ?? ZERO_CANONICAL_SEQUENCE;
1539
1543
 
@@ -1598,7 +1602,7 @@ const makeThreadStore = Effect.gen(function* () {
1598
1602
  { after: request.afterSequence ?? ZERO_CANONICAL_SEQUENCE, count: 0 },
1599
1603
  (cursor) =>
1600
1604
  Effect.gen(function* () {
1601
- const page = storedPage(
1605
+ const page = yield* storedPage(
1602
1606
  thread,
1603
1607
  cursor.after,
1604
1608
  Math.min(READ_PAGE_SIZE, request.limit - cursor.count),
@@ -2038,26 +2042,25 @@ const makeThreadStore = Effect.gen(function* () {
2038
2042
  const verificationPage: ThreadStore["Service"]["export"] = (request) =>
2039
2043
  exportThreadPage(request).pipe(Effect.provideService(ThreadExporterReader, verificationReader));
2040
2044
 
2041
- const exactRunRecords = (thread: StoredThread, runId: RunId) =>
2042
- Effect.gen(function* () {
2043
- const records: Array<CanonicalRecordEnvelope> = [];
2044
- let bytes = 0;
2045
- const facts = thread.runRecords.get(runId) ?? [];
2045
+ const exactRunRecords = Effect.fnUntraced(function* (thread: StoredThread, runId: RunId) {
2046
+ const records: Array<CanonicalRecordEnvelope> = [];
2047
+ let bytes = 0;
2048
+ const facts = thread.runRecords.get(runId) ?? [];
2046
2049
 
2047
- if (
2048
- facts.length >
2049
- MAX_RUN_EVIDENCE_RECORDS + RUN_TERMINAL_RESERVE_RECORDS + MAX_RUN_RECOVERY_SUFFIX_RECORDS
2050
- )
2051
- return yield* storeError("Run evidence", "Run record bounds exceeded");
2052
- for (const entry of facts) {
2053
- bytes += canonicalRecordBytes(entry.record);
2054
- if (bytes > MAX_RUN_EVIDENCE_BYTES + MAX_RUN_TERMINAL_BYTES + MAX_RUN_RECOVERY_SUFFIX_BYTES)
2055
- return yield* storeError("Run evidence", "Run byte bounds exceeded");
2056
- records.push(entry);
2057
- }
2050
+ if (
2051
+ facts.length >
2052
+ MAX_RUN_EVIDENCE_RECORDS + RUN_TERMINAL_RESERVE_RECORDS + MAX_RUN_RECOVERY_SUFFIX_RECORDS
2053
+ )
2054
+ return yield* storeError("Run evidence", "Run record bounds exceeded");
2055
+ for (const entry of facts) {
2056
+ bytes += canonicalRecordBytes(entry.record);
2057
+ if (bytes > MAX_RUN_EVIDENCE_BYTES + MAX_RUN_TERMINAL_BYTES + MAX_RUN_RECOVERY_SUFFIX_BYTES)
2058
+ return yield* storeError("Run evidence", "Run byte bounds exceeded");
2059
+ records.push(entry);
2060
+ }
2058
2061
 
2059
- return records.sort((a, b) => a.sequence - b.sequence);
2060
- });
2062
+ return records.sort((a, b) => a.sequence - b.sequence);
2063
+ });
2061
2064
 
2062
2065
  const exactRecordReader = (
2063
2066
  threadId: ThreadId,
@@ -2853,33 +2856,41 @@ const makeThreadStore = Effect.gen(function* () {
2853
2856
  },
2854
2857
  registerWorkOwner: (kind, owner) =>
2855
2858
  withMutation(
2856
- Effect.sync(() => {
2859
+ Effect.gen(function* () {
2857
2860
  if (workOwners.has(kind))
2858
- throw new Error(`MemoryThreadStore already has a ${kind} work owner`);
2861
+ return yield* Effect.die(
2862
+ storeError("initialize", `MemoryThreadStore already has a ${kind} work owner`),
2863
+ );
2859
2864
  workOwners.set(kind, owner);
2860
2865
  }),
2861
2866
  ),
2862
2867
  registerDeliveryLookup: (lookup) =>
2863
2868
  withMutation(
2864
- Effect.sync(() => {
2869
+ Effect.gen(function* () {
2865
2870
  if (deliveryLookup !== undefined)
2866
- throw new Error("MemoryThreadStore already has a delivery lookup");
2871
+ return yield* Effect.die(
2872
+ storeError("initialize", "MemoryThreadStore already has a delivery lookup"),
2873
+ );
2867
2874
  deliveryLookup = lookup;
2868
2875
  }),
2869
2876
  ),
2870
2877
  registerLedgerTransfer: (transfer) =>
2871
2878
  withMutation(
2872
- Effect.sync(() => {
2879
+ Effect.gen(function* () {
2873
2880
  if (ledgerTransfer !== undefined)
2874
- throw new Error("MemoryThreadStore already has a paired SubmissionLedger");
2881
+ return yield* Effect.die(
2882
+ storeError("initialize", "MemoryThreadStore already has a paired SubmissionLedger"),
2883
+ );
2875
2884
  ledgerTransfer = transfer;
2876
2885
  }),
2877
2886
  ),
2878
2887
  registerDeliveryTransfer: (transfer) =>
2879
2888
  withMutation(
2880
- Effect.sync(() => {
2889
+ Effect.gen(function* () {
2881
2890
  if (deliveryTransfer !== undefined)
2882
- throw new Error("MemoryThreadStore already has a paired delivery store");
2891
+ return yield* Effect.die(
2892
+ storeError("initialize", "MemoryThreadStore already has a paired delivery store"),
2893
+ );
2883
2894
  deliveryTransfer = transfer;
2884
2895
  }),
2885
2896
  ),