@yielded/agent-storage-cloudflare 0.1.0-beta.166 → 0.1.0-beta.168

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.
Files changed (71) hide show
  1. package/dist/DoMemoryStore.mjs +1 -1
  2. package/dist/DoMessageDeliveryStore.d.mts +1 -1
  3. package/dist/DoMessageDeliveryStore.mjs +3 -2
  4. package/dist/DoMessageDeliveryStore.mjs.map +1 -1
  5. package/dist/DoScheduleStore.mjs +16 -37
  6. package/dist/DoScheduleStore.mjs.map +1 -1
  7. package/dist/DoStorageConfig.d.mts +2 -10
  8. package/dist/DoStorageConfig.mjs +2 -11
  9. package/dist/DoStorageConfig.mjs.map +1 -1
  10. package/dist/{DoStorageError-CGuAfSwF.d.mts → DoStorageError-CxjMnzUA.d.mts} +7 -18
  11. package/dist/DoStorageError.d.mts +2 -2
  12. package/dist/DoStorageError.mjs +14 -30
  13. package/dist/DoStorageError.mjs.map +1 -1
  14. package/dist/DoStorageFailpoint.d.mts +1 -1
  15. package/dist/DoStorageFailpointTesting.d.mts +1 -1
  16. package/dist/{DoStorageVersion-iNSyi3cJ.d.mts → DoStorageVersion-DTFoLglB.d.mts} +3 -4
  17. package/dist/DoStorageVersion.d.mts +1 -1
  18. package/dist/DoStorageVersion.mjs +2 -2
  19. package/dist/DoStorageVersion.mjs.map +1 -1
  20. package/dist/DoSubmissionLedger.d.mts +7 -5
  21. package/dist/DoSubmissionLedger.mjs +378 -528
  22. package/dist/DoSubmissionLedger.mjs.map +1 -1
  23. package/dist/DoSubscriptionStore.mjs +5 -24
  24. package/dist/DoSubscriptionStore.mjs.map +1 -1
  25. package/dist/{DoThreadStore-D_83OjCH.d.mts → DoThreadStore-Bd4fTns3.d.mts} +17 -18
  26. package/dist/DoThreadStore-CwBvTLoq.mjs +468 -0
  27. package/dist/DoThreadStore-CwBvTLoq.mjs.map +1 -0
  28. package/dist/DoThreadStore.d.mts +2 -2
  29. package/dist/DoThreadStore.mjs +4 -529
  30. package/dist/MemoryProtocol.mjs +3 -3
  31. package/dist/MemoryProtocol.mjs.map +1 -1
  32. package/dist/PortProtocol.d.mts +11727 -3410
  33. package/dist/PortProtocol.mjs +103 -15
  34. package/dist/PortProtocol.mjs.map +1 -1
  35. package/dist/PortRouting.d.mts +14 -9
  36. package/dist/PortRouting.mjs +155 -29
  37. package/dist/PortRouting.mjs.map +1 -1
  38. package/dist/do-journal-Cawnsetj.mjs +761 -0
  39. package/dist/do-journal-Cawnsetj.mjs.map +1 -0
  40. package/dist/index.d.mts +3 -3
  41. package/dist/index.mjs +1 -1
  42. package/dist/migrations-D_EP3KYf.mjs +148 -0
  43. package/dist/migrations-D_EP3KYf.mjs.map +1 -0
  44. package/dist/{owned-state-DHm2aRXx.mjs → owned-state-BHzUi0eb.mjs} +50 -19
  45. package/dist/owned-state-BHzUi0eb.mjs.map +1 -0
  46. package/package.json +1 -1
  47. package/src/DoMessageDeliveryStore.ts +2 -1
  48. package/src/DoScheduleStore.ts +19 -59
  49. package/src/DoStorageConfig.ts +2 -11
  50. package/src/DoStorageError.ts +3 -26
  51. package/src/DoStorageVersion.ts +1 -1
  52. package/src/DoSubmissionLedger.ts +1806 -2030
  53. package/src/DoSubscriptionStore.ts +5 -47
  54. package/src/DoThreadStore.ts +276 -622
  55. package/src/MemoryProtocol.ts +3 -3
  56. package/src/PortProtocol.ts +198 -12
  57. package/src/PortRouting.ts +527 -108
  58. package/src/internal/canonical-append.ts +15 -0
  59. package/src/internal/do-journal.ts +548 -1440
  60. package/src/internal/migrations.ts +184 -287
  61. package/src/internal/owned-state.ts +81 -30
  62. package/src/internal/prompt-checkpoint.ts +158 -0
  63. package/src/internal/storage-span.ts +2 -5
  64. package/dist/DoThreadStore.mjs.map +0 -1
  65. package/dist/do-journal-DUhjZkOf.mjs +0 -1352
  66. package/dist/do-journal-DUhjZkOf.mjs.map +0 -1
  67. package/dist/migrations-DtKz_Gxr.mjs +0 -306
  68. package/dist/migrations-DtKz_Gxr.mjs.map +0 -1
  69. package/dist/owned-state-DHm2aRXx.mjs.map +0 -1
  70. package/src/internal/message-delivery-schema.ts +0 -24
  71. package/src/internal/recovery-checkpoint-schema.ts +0 -17
@@ -1,529 +1,4 @@
1
- import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
- import { DoStorageConfig, DoStorageConfigValue } from "./DoStorageConfig.mjs";
3
- import { DoStorageFailpoint } from "./DoStorageFailpoint.mjs";
4
- import { DoAppendConflict, DoCheckpointConflict, DoFenceRejected, DoStorageCorruptionError, DoStorageError } from "./DoStorageError.mjs";
5
- import { r as ownedState, t as invalidateOwnedState } from "./owned-state-DHm2aRXx.mjs";
6
- import { a as initializeDoJournal, n as RawCheckpoint, o as isAppendContention, r as RawReadRequest, s as withStorageSpan, t as RawAppendRequest } from "./do-journal-DUhjZkOf.mjs";
7
- import { SqlStorageOwner } from "@yielded/agent/sql-memory-store";
8
- import { Clock, Context, Crypto, Duration, Effect, Layer, Option, Ref, Schema, Stream } from "effect";
9
- import * as SqlClientService from "effect/sql/SqlClient";
10
- import { SqliteClient } from "@effect/sql-sqlite-do";
11
- import { SelectedReadOwner, makeSelectedReads } from "@yielded/agent-storage-sql/sql-thread-native-reads";
12
- import { EMPTY_TAIL_DIGEST, digestCanonicalBatch } from "@yielded/agent/digest";
13
- import { CanonicalBatch, CanonicalRecord, CanonicalRecordEnvelope, CanonicalSequence, Digest, ObservationOffset } from "@yielded/agent/records";
14
- import { AppendConflict, AppendResult, CheckpointRejected, FenceRejected, FencedAppendRequest, LoadCheckpointRequest, MAX_THREAD_EXPORT_RECORDS, SaveCheckpointRequest, SaveRecoveryCheckpointRequest, ThreadCheckpoint, ThreadExport, ThreadExportRequest, ThreadMaterialization, ThreadNotMaterialized, ThreadObservation, ThreadReadRequest, ThreadStore, ThreadStoreDiagnostic, ThreadStoreError, ThreadTail, ThreadTailRequest } from "@yielded/agent/thread-store";
15
- import { BrowserCrypto } from "@effect/platform-browser";
16
- import { DEFAULT_OWNERSHIP_LEASE_DURATION } from "@yielded/agent/submission-ledger";
17
- //#region src/DoThreadStore.ts
18
- var DoThreadStore_exports = /* @__PURE__ */ __exportAll({
19
- invalidate: () => invalidate,
20
- layer: () => layer,
21
- sqlOwnerLayer: () => sqlOwnerLayer,
22
- storageConfigLayer: () => storageConfigLayer,
23
- storageFailpointLayer: () => storageFailpointLayer,
24
- threadStoreLayer: () => threadStoreLayer
25
- });
26
- const OffsetText = Schema.String.check(Schema.isMaxLength(4096));
27
- const DO_OFFSET_PREFIX = "effect-agent-do@1:";
28
- const ZERO_CANONICAL_SEQUENCE = Schema.decodeSync(CanonicalSequence)(0);
29
- const isDigest = Schema.is(Digest);
30
- const isDoFenceRejected = Schema.is(DoFenceRejected);
31
- const isDoAppendConflict = Schema.is(DoAppendConflict);
32
- const isDoCheckpointConflict = Schema.is(DoCheckpointConflict);
33
- const CanonicalRecordJson = Schema.fromJsonString(CanonicalRecord);
34
- const CanonicalBatchJson = Schema.fromJsonString(CanonicalBatch);
35
- const ThreadCheckpointJson = Schema.fromJsonString(ThreadCheckpoint);
36
- const decodeCanonicalRecord = Schema.decodeEffect(CanonicalRecordJson);
37
- const storeError = (operation, error) => ThreadStoreError.make({
38
- cause: error,
39
- operation,
40
- message: error.message,
41
- ...error.diagnostic === void 0 ? {} : { diagnostic: error.diagnostic }
42
- });
43
- const schemaStoreError = (operation, error) => ThreadStoreError.make({
44
- operation,
45
- message: "A Thread storage value does not satisfy its schema",
46
- diagnostic: ThreadStoreDiagnostic.make({
47
- causeTag: error._tag,
48
- operation,
49
- issueTag: error.issue._tag
50
- })
51
- });
52
- const makeOffset = Effect.fn(function* (threadId, sequence) {
53
- return yield* Schema.decodeEffect(CanonicalSequence)(sequence).pipe(Effect.flatMap((validatedSequence) => Schema.decodeEffect(ObservationOffset)(`${DO_OFFSET_PREFIX}${encodeURIComponent(threadId)}:${validatedSequence}`)), Effect.mapError((error) => schemaStoreError("encode observation offset", error)));
54
- });
55
- const parseOffset = Effect.fn(function* (threadId, offset) {
56
- if (offset === void 0) return ZERO_CANONICAL_SEQUENCE;
57
- const text = yield* Schema.decodeEffect(OffsetText)(offset).pipe(Effect.mapError((error) => schemaStoreError("decode observation offset", error)));
58
- const threadPrefix = `${DO_OFFSET_PREFIX}${encodeURIComponent(threadId)}:`;
59
- if (!text.startsWith(threadPrefix)) return yield* ThreadStoreError.make({
60
- operation: "decode observation offset",
61
- message: "The observation offset belongs to a different adapter, storage version, or Thread."
62
- });
63
- const sequenceText = text.slice(threadPrefix.length);
64
- if (!/^(0|[1-9][0-9]*)$/.test(sequenceText)) return yield* ThreadStoreError.make({
65
- operation: "decode observation offset",
66
- message: "The observation offset is malformed."
67
- });
68
- return yield* Schema.decodeEffect(CanonicalSequence)(Number(sequenceText)).pipe(Effect.mapError((error) => schemaStoreError("decode observation offset", error)));
69
- });
70
- const mapFence = (threadId, error) => FenceRejected.make({
71
- threadId,
72
- actualEpoch: error.actualEpoch,
73
- attemptedEpoch: error.producerEpoch
74
- });
75
- const encodeCanonicalRecord = Effect.fn(function* (record) {
76
- return yield* Schema.encodeEffect(CanonicalRecordJson)(record).pipe(Effect.mapError((error) => schemaStoreError("encode canonical record", error)));
77
- });
78
- const encodeCanonicalBatch = Effect.fn(function* (batch) {
79
- return yield* Schema.encodeEffect(CanonicalBatchJson)(batch).pipe(Effect.mapError((error) => schemaStoreError("encode canonical batch", error)));
80
- });
81
- const encodeCheckpoint = Effect.fn(function* (checkpoint) {
82
- return yield* Schema.encodeEffect(ThreadCheckpointJson)(checkpoint).pipe(Effect.mapError((error) => schemaStoreError("encode checkpoint", error)));
83
- });
84
- const envelopes = /* @__PURE__ */ new WeakMap();
85
- const decodeEnvelope = Effect.fnUntraced(function* (row) {
86
- const cached = envelopes.get(row);
87
- if (cached !== void 0) return cached;
88
- const record = yield* decodeCanonicalRecord(row.record_json).pipe(Effect.mapError((error) => ThreadStoreError.make({
89
- operation: "decode canonical record",
90
- message: "The canonical record does not satisfy its schema",
91
- diagnostic: ThreadStoreDiagnostic.make({
92
- causeTag: error._tag,
93
- operation: "decode canonical record",
94
- decoder: "CanonicalRecord",
95
- sequence: row.sequence,
96
- issueTag: error.issue._tag
97
- })
98
- })), Effect.tapError((error) => Effect.annotateCurrentSpan({
99
- "storage.failure.operation": error.diagnostic?.operation,
100
- "storage.failure.cause": error.diagnostic?.causeTag,
101
- "storage.failure.decoder": error.diagnostic?.decoder,
102
- "storage.failure.sequence": row.sequence,
103
- "storage.failure.issue": error.diagnostic?.issueTag
104
- })));
105
- const threadId = yield* Schema.decodeEffect(CanonicalRecordEnvelope.fields.threadId)(row.thread_id).pipe(Effect.mapError((error) => schemaStoreError("decode thread identity", error)));
106
- const offset = yield* makeOffset(threadId, row.sequence);
107
- const batchId = yield* Schema.decodeEffect(CanonicalRecordEnvelope.fields.batchId)(row.batch_id).pipe(Effect.mapError((error) => schemaStoreError("decode batch identity", error)));
108
- const envelope = CanonicalRecordEnvelope.make({
109
- threadId,
110
- batchId,
111
- sequence: row.sequence,
112
- offset,
113
- record
114
- });
115
- envelopes.set(row, envelope);
116
- return envelope;
117
- });
118
- const decodeCheckpoint = Effect.fn(function* (checkpointJson) {
119
- return yield* Schema.decodeEffect(Schema.fromJsonString(ThreadCheckpoint))(checkpointJson).pipe(Effect.mapError((error) => schemaStoreError("decode checkpoint", error)));
120
- });
121
- const requireThread = Effect.fn("DoThreadStore.requireThread")(function* (journal, threadId) {
122
- const rows = yield* journal.getThread(threadId).pipe(Effect.mapError((error) => storeError("read thread", error)));
123
- if (rows.length === 0) return yield* ThreadNotMaterialized.make({ threadId });
124
- return rows[0];
125
- });
126
- const tailDigestAt = Effect.fn("DoThreadStore.tailDigestAt")(function* (journal, threadId, sequence) {
127
- if (sequence === 0) return EMPTY_TAIL_DIGEST;
128
- const digests = yield* journal.getTailDigestAt(threadId, sequence).pipe(Effect.mapError((error) => storeError("read checkpoint digest", error)));
129
- if (digests.length !== 1) return yield* CheckpointRejected.make({
130
- threadId,
131
- reason: "digest-mismatch"
132
- });
133
- return yield* Schema.decodeEffect(Digest)(digests[0]).pipe(Effect.mapError((error) => schemaStoreError("decode checkpoint digest", error)));
134
- });
135
- const groupByKey = (rows, key) => {
136
- const grouped = /* @__PURE__ */ new Map();
137
- for (const row of rows) {
138
- const existing = grouped.get(key(row));
139
- if (existing === void 0) grouped.set(key(row), [row]);
140
- else existing.push(row);
141
- }
142
- return grouped;
143
- };
144
- /**
145
- * Opt-in integrity audit (`verifyOnOpen`) of canonical payloads, their digest chains and generic
146
- * projection checkpoints. Disposable recovery checkpoints are validated when loaded. Routine opens
147
- * skip this scan: per-operation Schema decoding fails clearly on corrupt canonical rows.
148
- */
149
- const decodeStartupPayloads = Effect.fn("DoThreadStore.decodeStartupPayloads")(function* (journal, crypto) {
150
- const stored = yield* journal.scanStoredPayloads();
151
- const batches = yield* Effect.forEach(stored.batches, (batch) => Schema.decodeEffect(Schema.fromJsonString(CanonicalBatch))(batch.batch_json).pipe(Effect.map((decoded) => ({
152
- decoded,
153
- row: batch
154
- })), Effect.mapError((error) => DoStorageCorruptionError.make({
155
- table: "effect_agent_canonical_batches",
156
- rowKey: `${batch.thread_id}/${batch.batch_id}`,
157
- message: error.message
158
- }))));
159
- const records = yield* Effect.forEach(stored.records, (record) => Schema.decodeEffect(Schema.fromJsonString(CanonicalRecord))(record.record_json).pipe(Effect.map((decoded) => ({
160
- decoded,
161
- row: record
162
- })), Effect.mapError((error) => DoStorageCorruptionError.make({
163
- table: "effect_agent_canonical_records",
164
- rowKey: `${record.thread_id}/${record.sequence}`,
165
- message: error.message
166
- }))));
167
- const checkpoints = yield* Effect.forEach(stored.checkpoints, (checkpoint) => Schema.decodeEffect(Schema.fromJsonString(ThreadCheckpoint))(checkpoint.checkpoint_json).pipe(Effect.map((decoded) => ({
168
- decoded,
169
- row: checkpoint
170
- })), Effect.mapError((error) => DoStorageCorruptionError.make({
171
- table: "effect_agent_checkpoints",
172
- rowKey: `${checkpoint.thread_id}/${checkpoint.through_sequence}`,
173
- message: error.message
174
- }))));
175
- const batchesByThread = groupByKey(batches, ({ row }) => row.thread_id);
176
- const recordsByThread = groupByKey(records, ({ row }) => row.thread_id);
177
- const checkpointsByThread = groupByKey(checkpoints, ({ row }) => row.thread_id);
178
- const materializedIds = new Set(stored.threads.map((thread) => thread.thread_id));
179
- for (const thread of stored.threads) {
180
- const threadBatches = batchesByThread.get(thread.thread_id) ?? [];
181
- const threadRecords = recordsByThread.get(thread.thread_id) ?? [];
182
- const threadCheckpoints = checkpointsByThread.get(thread.thread_id) ?? [];
183
- const recordsByBatch = groupByKey(threadRecords, ({ row }) => row.batch_id);
184
- let previousDigest = EMPTY_TAIL_DIGEST;
185
- let expectedSequence = 1;
186
- const tailDigests = /* @__PURE__ */ new Map([[0, EMPTY_TAIL_DIGEST]]);
187
- for (const { decoded: canonicalBatch, row: batchRow } of threadBatches) {
188
- const key = `${batchRow.thread_id}/${batchRow.batch_id}`;
189
- if (canonicalBatch.batchId !== batchRow.batch_id || batchRow.first_sequence !== expectedSequence || batchRow.last_sequence !== batchRow.first_sequence + canonicalBatch.records.length - 1) return yield* DoStorageCorruptionError.make({
190
- table: "effect_agent_canonical_batches",
191
- rowKey: key,
192
- message: "Canonical batch identity, sequence, or record count is inconsistent."
193
- });
194
- const digest = yield* digestCanonicalBatch(previousDigest, canonicalBatch).pipe(Effect.provideService(Crypto.Crypto, crypto), Effect.mapError((error) => DoStorageCorruptionError.make({
195
- table: "effect_agent_canonical_batches",
196
- rowKey: key,
197
- message: error.message
198
- })));
199
- if (batchRow.batch_digest !== digest || batchRow.tail_digest !== digest) return yield* DoStorageCorruptionError.make({
200
- table: "effect_agent_canonical_batches",
201
- rowKey: key,
202
- message: "Canonical batch digest does not match its decoded content and prior tail."
203
- });
204
- const batchRecords = recordsByBatch.get(batchRow.batch_id) ?? [];
205
- if (batchRecords.length !== canonicalBatch.records.length) return yield* DoStorageCorruptionError.make({
206
- table: "effect_agent_canonical_records",
207
- rowKey: key,
208
- message: "Canonical batch and record-table counts differ."
209
- });
210
- for (let index = 0; index < canonicalBatch.records.length; index++) {
211
- const expectedRecord = canonicalBatch.records[index];
212
- const storedRecord = batchRecords[index];
213
- const expectedJson = yield* Schema.encodeEffect(Schema.fromJsonString(CanonicalRecord))(expectedRecord).pipe(Effect.mapError((error) => DoStorageCorruptionError.make({
214
- table: "effect_agent_canonical_batches",
215
- rowKey: key,
216
- message: error.message
217
- })));
218
- const storedJson = yield* Schema.encodeEffect(Schema.fromJsonString(CanonicalRecord))(storedRecord.decoded).pipe(Effect.mapError((error) => DoStorageCorruptionError.make({
219
- table: "effect_agent_canonical_records",
220
- rowKey: `${key}/${storedRecord.row.sequence}`,
221
- message: error.message
222
- })));
223
- if (storedRecord.row.sequence !== batchRow.first_sequence + index || storedRecord.row.record_id !== expectedRecord.recordId || expectedJson !== storedJson) return yield* DoStorageCorruptionError.make({
224
- table: "effect_agent_canonical_records",
225
- rowKey: `${key}/${storedRecord.row.sequence}`,
226
- message: "Canonical record identity, sequence, or payload differs from its batch."
227
- });
228
- }
229
- previousDigest = digest;
230
- expectedSequence = batchRow.last_sequence + 1;
231
- tailDigests.set(batchRow.last_sequence, digest);
232
- }
233
- if (threadRecords.length !== thread.tail_sequence || thread.tail_sequence !== expectedSequence - 1 || thread.tail_digest !== previousDigest) return yield* DoStorageCorruptionError.make({
234
- table: "effect_agent_threads",
235
- rowKey: thread.thread_id,
236
- message: "Thread tail does not match its canonical batch chain."
237
- });
238
- for (const checkpoint of threadCheckpoints) if (checkpoint.decoded.threadId !== thread.thread_id || checkpoint.decoded.throughSequence !== checkpoint.row.through_sequence || checkpoint.decoded.tailDigest !== checkpoint.row.tail_digest || tailDigests.get(checkpoint.row.through_sequence) !== checkpoint.row.tail_digest) return yield* DoStorageCorruptionError.make({
239
- table: "effect_agent_checkpoints",
240
- rowKey: `${thread.thread_id}/${checkpoint.row.through_sequence}`,
241
- message: "Checkpoint identity or digest is not bound to a canonical batch tail."
242
- });
243
- }
244
- if (batches.some(({ row }) => !materializedIds.has(row.thread_id)) || records.some(({ row }) => !materializedIds.has(row.thread_id)) || checkpoints.some(({ row }) => !materializedIds.has(row.thread_id))) return yield* DoStorageCorruptionError.make({
245
- table: "effect_agent_threads",
246
- rowKey: "startup_scan",
247
- message: "Canonical rows exist without a materialized Thread."
248
- });
249
- });
250
- const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
251
- const config = yield* DoStorageConfig;
252
- const failpoint = yield* DoStorageFailpoint;
253
- const sql = yield* SqlClientService.SqlClient;
254
- const crypto = yield* Crypto.Crypto;
255
- const journal = yield* initializeDoJournal(sql, failpoint.hit, config.maxStoredValueBytes);
256
- if (config.verifyOnOpen) yield* decodeStartupPayloads(journal, crypto);
257
- const provideCrypto = (effect) => Effect.provideService(effect, Crypto.Crypto, crypto);
258
- const hitFailpoint = Effect.fn((location) => failpoint.hit(location).pipe(Effect.mapError((error) => storeError(`storage failpoint ${location}`, error))));
259
- const materialize = Effect.fnUntraced(function* (request) {
260
- const validated = yield* Schema.decodeEffect(Schema.toType(ThreadMaterialization))(request).pipe(Effect.mapError((error) => schemaStoreError("validate materialization", error)));
261
- const now = yield* Clock.currentTimeMillis;
262
- yield* hitFailpoint("materialize:before");
263
- yield* journal.materialize(validated.threadId, new Date(now).toISOString(), EMPTY_TAIL_DIGEST, validated.producerEpoch).pipe(Effect.mapError((error) => error._tag === "DoFenceRejected" ? mapFence(validated.threadId, error) : storeError("materialize thread", error)));
264
- yield* hitFailpoint("materialize:after");
265
- }, withStorageSpan("DoThreadStore.materialize", (error) => error._tag === "FenceRejected"));
266
- const append = Effect.fnUntraced(function* (request) {
267
- const validated = yield* Schema.decodeEffect(Schema.toType(FencedAppendRequest))(request).pipe(Effect.mapError((error) => schemaStoreError("validate canonical append", error)));
268
- const observed = yield* requireThread(journal, validated.threadId);
269
- const tailDigest = yield* provideCrypto(digestCanonicalBatch(validated.expectedTailDigest, validated.batch)).pipe(Effect.mapError((error) => storeError("digest canonical append", error)));
270
- const batchJson = yield* encodeCanonicalBatch(validated.batch);
271
- const rawRecords = yield* Effect.forEach(validated.batch.records, (record) => encodeCanonicalRecord(record).pipe(Effect.map((recordJson) => ({
272
- recordId: record.recordId,
273
- recordJson
274
- }))));
275
- const rawRequest = yield* Schema.decodeEffect(RawAppendRequest)({
276
- threadId: validated.threadId,
277
- batchId: validated.batch.batchId,
278
- batchDigest: tailDigest,
279
- batchJson,
280
- expectedTailSequence: validated.expectedTailSequence,
281
- expectedTailDigest: validated.expectedTailDigest,
282
- producerEpoch: validated.producerEpoch,
283
- records: rawRecords,
284
- tailDigest
285
- }).pipe(Effect.mapError((error) => schemaStoreError("encode canonical append", error)));
286
- yield* hitFailpoint("append:before");
287
- const result = yield* journal.append(rawRequest, observed).pipe(Effect.mapError((error) => {
288
- if (isDoFenceRejected(error)) return mapFence(validated.threadId, error);
289
- if (isDoAppendConflict(error)) return error.actualTailSequence !== void 0 && isDigest(error.actualTailDigest) ? AppendConflict.make({
290
- threadId: validated.threadId,
291
- batchId: validated.batch.batchId,
292
- reason: error.reason,
293
- actualTailSequence: error.actualTailSequence,
294
- actualTailDigest: error.actualTailDigest
295
- }) : AppendConflict.make({
296
- threadId: validated.threadId,
297
- batchId: validated.batch.batchId,
298
- reason: error.reason
299
- });
300
- return storeError("append canonical batch", error);
301
- }), Effect.flatMap((result) => Schema.decodeEffect(AppendResult)(result).pipe(Effect.mapError((error) => schemaStoreError("decode append result", error)))));
302
- yield* hitFailpoint("append:after");
303
- return result;
304
- }, withStorageSpan("DoThreadStore.append", isAppendContention));
305
- const loadRecords = Effect.fnUntraced(function* (request) {
306
- const result = yield* journal.read(request).pipe(Effect.mapError((error) => storeError("read canonical records", error)));
307
- return {
308
- count: result.count,
309
- records: result.records.pipe(Stream.mapError((error) => storeError("read canonical records", error)), Stream.mapEffect(decodeEnvelope))
310
- };
311
- });
312
- const readEffect = Effect.fn("DoThreadStore.read")(function* (request) {
313
- const validated = yield* Schema.decodeEffect(Schema.toType(ThreadReadRequest))(request).pipe(Effect.mapError((error) => schemaStoreError("validate thread read", error)));
314
- if ("selection" in validated) return Stream.fromIterable(yield* selectedReads.read(validated));
315
- yield* requireThread(journal, validated.threadId);
316
- return (yield* loadRecords(RawReadRequest.make({
317
- threadId: validated.threadId,
318
- fromSequenceExclusive: validated.afterSequence ?? ZERO_CANONICAL_SEQUENCE,
319
- limit: validated.limit
320
- }))).records;
321
- });
322
- const read = (request) => Stream.unwrap(readEffect(request));
323
- const observeEffect = Effect.fnUntraced(function* (request) {
324
- const validated = yield* Schema.decodeEffect(Schema.toType(ThreadObservation))(request).pipe(Effect.mapError((error) => schemaStoreError("validate thread observation", error)));
325
- yield* requireThread(journal, validated.threadId);
326
- const initialSequence = yield* parseOffset(validated.threadId, validated.afterOffset);
327
- const cursor = yield* Ref.make(initialSequence);
328
- let polls = 0;
329
- let emptyPolls = 0;
330
- let deliveredRecords = 0;
331
- const poll = Effect.fnUntraced(function* () {
332
- polls++;
333
- const fromSequenceExclusive = yield* Ref.get(cursor);
334
- const result = yield* loadRecords(RawReadRequest.make({
335
- threadId: validated.threadId,
336
- fromSequenceExclusive,
337
- limit: 1024
338
- }));
339
- if (result.count === 0) {
340
- emptyPolls++;
341
- yield* Effect.sleep(config.observationPollInterval);
342
- return Stream.empty;
343
- }
344
- return result.records.pipe(Stream.tap((record) => {
345
- deliveredRecords++;
346
- return Ref.set(cursor, record.sequence);
347
- }));
348
- });
349
- return Stream.fromEffectRepeat(poll()).pipe(Stream.flatten, Stream.ensuring(Effect.suspend(() => Effect.annotateCurrentSpan({
350
- "effect_agent.observation.polls": polls,
351
- "effect_agent.observation.empty_polls": emptyPolls,
352
- "effect_agent.observation.records": deliveredRecords
353
- }))));
354
- });
355
- const observe = (request) => Stream.unwrap(observeEffect(request)).pipe(Stream.withSpan("DoThreadStore.observe"));
356
- const exportThread = Effect.fn("DoThreadStore.export")(function* (request) {
357
- const validated = yield* Schema.decodeEffect(Schema.toType(ThreadExportRequest))(request).pipe(Effect.mapError((error) => schemaStoreError("validate thread export", error)));
358
- yield* requireThread(journal, validated.threadId);
359
- const exported = yield* journal.exportThread(validated.threadId).pipe(Effect.mapError((error) => storeError("export thread", error)));
360
- const records = yield* Effect.forEach(exported.records, decodeEnvelope);
361
- if (records.length > MAX_THREAD_EXPORT_RECORDS) return yield* ThreadStoreError.make({
362
- operation: "decode thread export",
363
- message: "The thread exceeds the current export record limit."
364
- });
365
- const tailDigest = yield* Schema.decodeEffect(Digest)(exported.thread.tail_digest).pipe(Effect.mapError((error) => schemaStoreError("decode export tail digest", error)));
366
- return ThreadExport.make({
367
- format: "effect-agent/thread@1",
368
- threadId: validated.threadId,
369
- tailSequence: exported.thread.tail_sequence,
370
- tailDigest,
371
- records
372
- });
373
- });
374
- const inspectTail = Effect.fn("DoThreadStore.inspectTail")(function* (request) {
375
- const validated = yield* Schema.decodeEffect(Schema.toType(ThreadTailRequest))(request).pipe(Effect.mapError((error) => schemaStoreError("validate tail inspection", error)));
376
- const thread = yield* requireThread(journal, validated.threadId);
377
- const tailDigest = yield* Schema.decodeEffect(Digest)(thread.tail_digest).pipe(Effect.mapError((error) => schemaStoreError("decode tail digest", error)));
378
- return ThreadTail.make({
379
- threadId: validated.threadId,
380
- tailSequence: thread.tail_sequence,
381
- tailDigest,
382
- producerEpoch: thread.producer_epoch
383
- });
384
- });
385
- const saveCheckpoint = Effect.fn("DoThreadStore.saveCheckpoint")(function* (request) {
386
- const validated = yield* Schema.decodeEffect(Schema.toType(SaveCheckpointRequest))(request).pipe(Effect.mapError((error) => schemaStoreError("validate checkpoint", error)));
387
- const thread = yield* requireThread(journal, validated.checkpoint.threadId);
388
- if (validated.checkpoint.throughSequence > thread.tail_sequence) return yield* CheckpointRejected.make({
389
- threadId: validated.checkpoint.threadId,
390
- reason: "ahead-of-tail"
391
- });
392
- if ((yield* tailDigestAt(journal, validated.checkpoint.threadId, validated.checkpoint.throughSequence)) !== validated.checkpoint.tailDigest) return yield* CheckpointRejected.make({
393
- threadId: validated.checkpoint.threadId,
394
- reason: "digest-mismatch"
395
- });
396
- const checkpointJson = yield* encodeCheckpoint(validated.checkpoint);
397
- const raw = RawCheckpoint.make({
398
- threadId: validated.checkpoint.threadId,
399
- throughSequence: validated.checkpoint.throughSequence,
400
- tailDigest: validated.checkpoint.tailDigest,
401
- checkpointJson
402
- });
403
- yield* hitFailpoint("save-checkpoint:before");
404
- yield* journal.saveCheckpoint(raw).pipe(Effect.mapError((error) => isDoCheckpointConflict(error) ? CheckpointRejected.make({
405
- threadId: validated.checkpoint.threadId,
406
- reason: "digest-mismatch"
407
- }) : storeError("save checkpoint", error)));
408
- yield* hitFailpoint("save-checkpoint:after");
409
- });
410
- const loadCheckpoint = Effect.fn("DoThreadStore.loadCheckpoint")(function* (request) {
411
- const validated = yield* Schema.decodeEffect(Schema.toType(LoadCheckpointRequest))(request).pipe(Effect.mapError((error) => schemaStoreError("validate checkpoint lookup", error)));
412
- const thread = yield* requireThread(journal, validated.threadId);
413
- const rows = yield* journal.loadCheckpoint(validated.threadId, validated.atOrBeforeSequence ?? thread.tail_sequence).pipe(Effect.mapError((error) => storeError("load checkpoint", error)));
414
- if (rows.length === 0) return Option.none();
415
- if (rows.length !== 1) return yield* ThreadStoreError.make({
416
- operation: "load checkpoint",
417
- message: `Expected at most one checkpoint row but found ${rows.length}.`
418
- });
419
- const row = rows[0];
420
- const checkpoint = yield* decodeCheckpoint(row.checkpoint_json);
421
- if (row.thread_id !== validated.threadId || checkpoint.threadId !== row.thread_id || checkpoint.throughSequence !== row.through_sequence || checkpoint.tailDigest !== row.tail_digest) return yield* ThreadStoreError.make({
422
- operation: "load checkpoint",
423
- message: "Stored checkpoint metadata does not match its canonical row."
424
- });
425
- if ((yield* tailDigestAt(journal, checkpoint.threadId, checkpoint.throughSequence)) !== checkpoint.tailDigest) return yield* CheckpointRejected.make({
426
- threadId: checkpoint.threadId,
427
- reason: "digest-mismatch"
428
- });
429
- return Option.some(checkpoint);
430
- });
431
- const saveRecoveryCheckpoint = Effect.fn("DoThreadStore.saveRecoveryCheckpoint")(function* (request) {
432
- const validated = yield* Schema.decodeEffect(Schema.toType(SaveRecoveryCheckpointRequest))(request).pipe(Effect.mapError((error) => schemaStoreError("validate recovery checkpoint", error)));
433
- const checkpointJson = yield* encodeCheckpoint(validated.checkpoint);
434
- yield* journal.saveRecoveryCheckpoint(validated, checkpointJson).pipe(Effect.mapError((error) => error._tag === "CheckpointRejected" || error._tag === "FenceRejected" || error._tag === "ThreadNotMaterialized" ? error : storeError("save recovery checkpoint", error)));
435
- });
436
- const loadRecoveryCheckpoint = Effect.fn("DoThreadStore.loadRecoveryCheckpoint")(function* (request) {
437
- const validated = yield* Schema.decodeEffect(Schema.toType(LoadCheckpointRequest))(request).pipe(Effect.mapError((error) => schemaStoreError("validate recovery checkpoint lookup", error)));
438
- const thread = yield* requireThread(journal, validated.threadId);
439
- const corrupt = () => CheckpointRejected.make({
440
- threadId: validated.threadId,
441
- reason: "corrupt"
442
- });
443
- const rows = yield* journal.loadRecoveryCheckpoint(validated.threadId).pipe(Effect.mapError((error) => error._tag === "DoStorageCorruptionError" ? corrupt() : storeError("load recovery checkpoint", error)));
444
- if (rows.length === 0) return Option.none();
445
- if (rows.length !== 1) return yield* corrupt();
446
- const row = rows[0];
447
- const checkpoint = yield* Schema.decodeEffect(Schema.fromJsonString(ThreadCheckpoint))(row.checkpoint_json).pipe(Effect.mapError(corrupt));
448
- if (row.thread_id !== validated.threadId || checkpoint.threadId !== row.thread_id || checkpoint.throughSequence !== row.through_sequence || checkpoint.tailDigest !== row.tail_digest) return yield* corrupt();
449
- if (checkpoint.throughSequence > thread.tail_sequence) return yield* CheckpointRejected.make({
450
- threadId: validated.threadId,
451
- reason: "ahead-of-tail"
452
- });
453
- if (checkpoint.throughSequence > (validated.atOrBeforeSequence ?? thread.tail_sequence)) return Option.none();
454
- if ((yield* tailDigestAt(journal, checkpoint.threadId, checkpoint.throughSequence)) !== checkpoint.tailDigest) return yield* CheckpointRejected.make({
455
- threadId: validated.threadId,
456
- reason: "digest-mismatch"
457
- });
458
- return Option.some(checkpoint);
459
- });
460
- const selectedReads = yield* makeSelectedReads(decodeEnvelope).pipe(Effect.provideService(SelectedReadOwner, {
461
- snapshot: journal.state.read,
462
- tail: (threadId) => journal.getThread(threadId).pipe(Effect.flatMap((rows) => Schema.decodeEffect(Schema.UndefinedOr(Schema.Struct({
463
- tail_sequence: CanonicalSequence,
464
- tail_digest: Digest,
465
- producer_epoch: ThreadMaterialization.fields.producerEpoch
466
- })))(rows[0])), Effect.mapError((error) => storeError("native thread tail", error)))
467
- }));
468
- const threadStore = ThreadStore.of({
469
- ...journal.lifecycle === void 0 ? {} : { lifecyclePublications: journal.lifecycle.storage },
470
- readIdentity: selectedReads.readIdentity,
471
- countPeerMessages: selectedReads.countPeerMessages,
472
- append,
473
- export: exportThread,
474
- inspectTail,
475
- materialize,
476
- observe,
477
- read,
478
- checkpoints: {
479
- save: saveCheckpoint,
480
- load: loadCheckpoint
481
- },
482
- recoveryCheckpoints: {
483
- save: saveRecoveryCheckpoint,
484
- load: loadRecoveryCheckpoint
485
- }
486
- });
487
- return Context.make(ThreadStore, threadStore);
488
- });
489
- /**
490
- * Durable Object Thread Store implementation with configuration, failpoint, SQL, and
491
- * Crypto authority kept visible in its input channel.
492
- */
493
- const threadStoreLayer = Layer.effectContext(makeServices());
494
- /**
495
- * Validated Durable Object storage configuration Layer with the documented defaults applied.
496
- * Shared by the ThreadStore and SubmissionLedger convenience layers so their defaults
497
- * cannot drift.
498
- */
499
- const storageConfigLayer = (options) => Layer.effect(DoStorageConfig)(Schema.decodeEffect(DoStorageConfigValue)({
500
- observationPollInterval: options.observationPollInterval ?? 25,
501
- ownershipLeaseDuration: options.ownershipLeaseDuration ?? Duration.toMillis(DEFAULT_OWNERSHIP_LEASE_DURATION),
502
- maxStoredValueBytes: options.maxStoredValueBytes ?? 19e5,
503
- verifyOnOpen: options.verifyOnOpen ?? false
504
- }).pipe(Effect.mapError((error) => DoStorageError.make({
505
- cause: error,
506
- operation: "configure Durable Object storage",
507
- message: error.message
508
- }))));
509
- /** The failpoint Layer selected by convenience options: explicit handler or the no-op default. */
510
- const storageFailpointLayer = (options) => options.failpoint === void 0 ? DoStorageFailpoint.layer : Layer.succeed(DoStorageFailpoint)({ hit: options.failpoint });
511
- /**
512
- * A composition-root convenience Layer for canonical Threads inside one Durable Object,
513
- * built over `ctx.storage`. Durable accepted work is served by the separate SubmissionLedger
514
- * port; point both at the SAME `ctx.storage` so claims fence the same producer epochs
515
- * (ADR-0011 D7's "same file" rule, transposed to one object's private database).
516
- */
517
- const layer = (options) => Layer.unwrap(Effect.map(DoStorageConfig, (config) => threadStoreLayer.pipe(Layer.provide(Layer.mergeAll(Layer.succeed(DoStorageConfig)(config), storageFailpointLayer(options), SqliteClient.layer({ storage: options.storage }), BrowserCrypto.layer))))).pipe(Layer.provide(storageConfigLayer(options)));
518
- /**
519
- * Discard the Object's derived thread and ledger state after direct SQL maintenance.
520
- * Quiesce port operations during the raw write and invalidation, and enroll the write with
521
- * the host mutation gate. Ordinary ThreadStore/SubmissionLedger writes maintain this view.
522
- */
523
- const invalidate = invalidateOwnedState;
524
- /** Share the Object's transaction gate with owner-local SQL Memory compositions. */
525
- const sqlOwnerLayer = Layer.effect(SqlStorageOwner)(Effect.flatMap(SqlClientService.SqlClient, ownedState));
526
- //#endregion
527
- export { invalidate, layer, sqlOwnerLayer, storageConfigLayer, storageFailpointLayer, DoThreadStore_exports as t, threadStoreLayer };
528
-
529
- //# sourceMappingURL=DoThreadStore.mjs.map
1
+ import "./DoStorageConfig.mjs";
2
+ import "./DoStorageFailpoint.mjs";
3
+ import { a as sqlOwnerLayer, c as threadStoreLayer, i as layer, n as exportThread, o as storageConfigLayer, r as invalidate, s as storageFailpointLayer } from "./DoThreadStore-CwBvTLoq.mjs";
4
+ export { exportThread, invalidate, layer, sqlOwnerLayer, storageConfigLayer, storageFailpointLayer, threadStoreLayer };
@@ -129,18 +129,18 @@ var MemoryOwnerAuthorizer = class extends Context.Service()("@effect-agent/stora
129
129
  /** Canonical namespace derived from this object's idFromName identity, never its request. */
130
130
  var MemoryOwnerIdentity = class extends Context.Service()("@effect-agent/storage-cloudflare/MemoryOwnerIdentity") {};
131
131
  const memoryWireBytes = (text) => new TextEncoder().encode(text).byteLength;
132
- const decodeMemoryWire = Effect.fn("decodeMemoryWire")(function* (schema, raw, maxBytes) {
132
+ const decodeMemoryWire = Effect.fnUntraced(function* (schema, raw, maxBytes) {
133
133
  const text = yield* Schema.decodeUnknownEffect(Schema.String)(raw).pipe(Effect.mapError(() => MemoryRpcError.make({ reason: "protocol" })));
134
134
  if (text.length > maxBytes || memoryWireBytes(text) > maxBytes) return yield* MemoryRpcError.make({ reason: "budget" });
135
135
  return yield* Schema.decodeEffect(Schema.fromJsonString(schema))(text).pipe(Effect.mapError(() => MemoryRpcError.make({ reason: "protocol" })));
136
136
  });
137
- const encodeMemoryWire = Effect.fn("encodeMemoryWire")(function* (schema, value, maxBytes) {
137
+ const encodeMemoryWire = Effect.fnUntraced(function* (schema, value, maxBytes) {
138
138
  const encoded = yield* Schema.encodeEffect(Schema.fromJsonString(schema))(value).pipe(Effect.mapError(() => MemoryRpcError.make({ reason: "protocol" })));
139
139
  if (encoded.length > maxBytes || memoryWireBytes(encoded) > maxBytes) return yield* MemoryRpcError.make({ reason: "budget" });
140
140
  return encoded;
141
141
  });
142
142
  /** One local read for Get, or per distinct candidate source. No discovery or background work. */
143
- const handleMemoryOwnerRequest = Effect.fn("MemoryOwner.handleRequest")(function* (raw, limits = defaultMemoryRpcLimits) {
143
+ const handleMemoryOwnerRequest = Effect.fnUntraced(function* (raw, limits = defaultMemoryRpcLimits) {
144
144
  const result = yield* Effect.gen(function* () {
145
145
  limits = yield* Schema.decodeEffect(MemoryRpcLimits)(limits).pipe(Effect.mapError(() => MemoryRpcError.make({ reason: "protocol" })));
146
146
  const request = yield* decodeMemoryWire(MemoryOwnerRequest, raw, limits.maxRequestBytes);
@@ -1 +1 @@
1
- {"version":3,"file":"MemoryProtocol.mjs","names":[],"sources":["../src/MemoryProtocol.ts"],"sourcesContent":["import * as MemoryNamespace from \"@yielded/agent/memory-namespace\";\nimport {\n MemoryLookup,\n MemoryRecallError,\n MemoryRecallLimits,\n} from \"@yielded/agent/memory-reference\";\nimport { MemoryAccess, revalidateMemoryLookup } from \"@yielded/agent/memory-revalidation\";\nimport {\n MemoryKey,\n MemoryReader,\n MemoryConflict,\n MemoryDocument,\n MemoryMutationFailure,\n MemoryOperationConflict,\n MemoryStorageError,\n MemoryWithdrawn,\n MemoryWrite,\n MemoryWriter,\n} from \"@yielded/agent/memory-store\";\nimport {\n MemoryIndexSearch,\n MemoryIndexError,\n SemanticMemoryProfile,\n} from \"@yielded/agent/semantic-memory-index\";\nimport {\n SemanticMemoryError,\n SemanticCandidateLimits,\n SemanticCandidateResult,\n revalidateSemanticMemoryCandidates,\n} from \"@yielded/agent/semantic-memory-revalidation\";\nimport { Principal } from \"@yielded/agent/submission-ledger\";\nimport { Clock, Context, Effect, Schema } from \"effect\";\n\nexport class MemoryRpcError extends Schema.TaggedError<MemoryRpcError>()(\"MemoryRpcError\", {\n reason: Schema.Literals([\"denied\", \"protocol\", \"budget\", \"timeout\", \"unavailable\"]),\n}) {}\n\nexport class MemoryRpcLimits extends Schema.Class<MemoryRpcLimits>(\n \"@effect-agent/storage-cloudflare/MemoryRpcLimits\",\n)({\n maxRequestBytes: Schema.Int.check(Schema.isBetween({ minimum: 256, maximum: 4_194_304 })),\n maxResponseBytes: Schema.Int.check(Schema.isBetween({ minimum: 256, maximum: 16_777_216 })),\n maxSourceBytes: Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: 67_108_864 })),\n maxSources: MemoryRecallLimits.fields.maxSources,\n timeoutMillis: MemoryRecallLimits.fields.timeoutMillis,\n}) {}\n\nexport const defaultMemoryRpcLimits = MemoryRpcLimits.make({\n maxRequestBytes: 1_048_576,\n maxResponseBytes: 4_194_304,\n maxSourceBytes: 16_777_216,\n maxSources: 16,\n timeoutMillis: 10_000,\n});\n\nconst RequestFields = {\n version: Schema.Literal(1),\n access: MemoryAccess.Wire,\n /** Host-authenticated identity, never copied from model input. The owner still authorizes it. */\n principal: Principal,\n deadlineMillis: Schema.Finite.check(Schema.isGreaterThanOrEqualTo(0)),\n};\n\nconst RevalidateRequest = Schema.TaggedStruct(\"Revalidate\", {\n ...RequestFields,\n lookup: MemoryLookup,\n limits: MemoryRecallLimits,\n});\n\nconst ChangeRequest = Schema.TaggedStruct(\"Change\", { ...RequestFields, write: MemoryWrite.Wire });\n\nconst GetRequest = Schema.TaggedStruct(\"Get\", { ...RequestFields, key: MemoryKey.Wire });\n\nconst SemanticRequest: Schema.TaggedStruct<\n \"RevalidateSemantic\",\n typeof RequestFields & {\n readonly found: typeof MemoryIndexSearch.Wire;\n readonly profile: typeof SemanticMemoryProfile;\n readonly limits: typeof SemanticCandidateLimits;\n }\n> = Schema.TaggedStruct(\"RevalidateSemantic\", {\n ...RequestFields,\n found: MemoryIndexSearch.Wire,\n profile: SemanticMemoryProfile,\n limits: SemanticCandidateLimits,\n});\n\nexport const MemoryOwnerRequest: Schema.Union<\n [typeof RevalidateRequest, typeof ChangeRequest, typeof SemanticRequest, typeof GetRequest]\n> = Schema.Union([RevalidateRequest, ChangeRequest, SemanticRequest, GetRequest]);\n\nexport type MemoryOwnerRequest = typeof MemoryOwnerRequest.Type;\n\nexport const MemoryOwnerFailure = Schema.Union([\n MemoryRpcError,\n MemoryStorageError,\n MemoryRecallError,\n MemoryConflict,\n MemoryWithdrawn,\n MemoryOperationConflict,\n MemoryMutationFailure,\n MemoryIndexError,\n SemanticMemoryError,\n]);\n\nexport type MemoryOwnerFailure = typeof MemoryOwnerFailure.Type;\n\nconst LookupResponse = Schema.TaggedStruct(\"Lookup\", {\n access: MemoryAccess.Wire,\n lookup: MemoryLookup,\n});\n\nconst ChangedResponse = Schema.TaggedStruct(\"Changed\", {\n access: MemoryAccess.Wire,\n document: MemoryDocument.Wire,\n});\n\nconst SemanticResponse = Schema.TaggedStruct(\"Semantic\", {\n access: MemoryAccess.Wire,\n result: SemanticCandidateResult,\n});\n\nconst DocumentResponse = Schema.TaggedStruct(\"Document\", {\n access: MemoryAccess.Wire,\n key: MemoryKey.Wire,\n document: Schema.NullOr(MemoryDocument.Wire),\n});\n\nconst FailedResponse = Schema.TaggedStruct(\"Failed\", { failure: MemoryOwnerFailure });\n\nexport const MemoryOwnerResponse: Schema.Union<\n [\n typeof LookupResponse,\n typeof ChangedResponse,\n typeof SemanticResponse,\n typeof DocumentResponse,\n typeof FailedResponse,\n ]\n> = Schema.Union([\n LookupResponse,\n ChangedResponse,\n SemanticResponse,\n DocumentResponse,\n FailedResponse,\n]);\n\nexport type MemoryOwnerResponse = typeof MemoryOwnerResponse.Type;\n\n/**\n * Fail-closed application policy. Authorize the namespace, principal, scope, and full command.\n * Get requires exact-key authority, including application source/provenance checks where needed.\n * Possession of a key or scope is not authorization, including for absent or withdrawn documents.\n */\nexport class MemoryOwnerAuthorizer extends Context.Service<\n MemoryOwnerAuthorizer,\n {\n readonly authorize: (request: MemoryOwnerRequest) => Effect.Effect<void, MemoryRpcError>;\n }\n>()(\"@effect-agent/storage-cloudflare/MemoryOwnerAuthorizer\") {}\n\n/** Canonical namespace derived from this object's idFromName identity, never its request. */\nexport class MemoryOwnerIdentity extends Context.Service<\n MemoryOwnerIdentity,\n {\n readonly namespace: MemoryNamespace.Any;\n }\n>()(\"@effect-agent/storage-cloudflare/MemoryOwnerIdentity\") {}\n\nexport const memoryWireBytes = (text: string): number => new TextEncoder().encode(text).byteLength;\n\nexport const decodeMemoryWire = Effect.fn(\"decodeMemoryWire\")(function* <A, I>(\n schema: Schema.Codec<A, I, never>,\n raw: unknown,\n maxBytes: number,\n) {\n const text = yield* Schema.decodeUnknownEffect(Schema.String)(raw).pipe(\n Effect.mapError(() => MemoryRpcError.make({ reason: \"protocol\" })),\n );\n\n if (text.length > maxBytes || memoryWireBytes(text) > maxBytes)\n return yield* MemoryRpcError.make({ reason: \"budget\" });\n\n return yield* Schema.decodeEffect(Schema.fromJsonString(schema))(text).pipe(\n Effect.mapError(() => MemoryRpcError.make({ reason: \"protocol\" })),\n );\n});\n\nexport const encodeMemoryWire = Effect.fn(\"encodeMemoryWire\")(function* <A, I>(\n schema: Schema.Codec<A, I, never, never>,\n value: A,\n maxBytes: number,\n) {\n const encoded = yield* Schema.encodeEffect(Schema.fromJsonString(schema))(value).pipe(\n Effect.mapError(() => MemoryRpcError.make({ reason: \"protocol\" })),\n );\n\n if (encoded.length > maxBytes || memoryWireBytes(encoded) > maxBytes)\n return yield* MemoryRpcError.make({ reason: \"budget\" });\n\n return encoded;\n});\n\n/** One local read for Get, or per distinct candidate source. No discovery or background work. */\nexport const handleMemoryOwnerRequest = Effect.fn(\"MemoryOwner.handleRequest\")(function* (\n raw: unknown,\n limits: MemoryRpcLimits = defaultMemoryRpcLimits,\n): Effect.fn.Return<\n string,\n never,\n MemoryOwnerIdentity | MemoryOwnerAuthorizer | MemoryReader | MemoryWriter\n> {\n const result = yield* Effect.gen(function* (): Effect.fn.Return<\n MemoryOwnerResponse,\n MemoryOwnerFailure,\n MemoryOwnerIdentity | MemoryOwnerAuthorizer | MemoryReader | MemoryWriter\n > {\n limits = yield* Schema.decodeEffect(MemoryRpcLimits)(limits).pipe(\n Effect.mapError(() => MemoryRpcError.make({ reason: \"protocol\" })),\n );\n const request = yield* decodeMemoryWire(MemoryOwnerRequest, raw, limits.maxRequestBytes);\n const { namespace } = yield* MemoryOwnerIdentity;\n\n if (\n !MemoryNamespace.equals(namespace, request.access.namespace) ||\n (request._tag === \"Get\" && !MemoryNamespace.equals(namespace, request.key.namespace)) ||\n (request._tag === \"Change\" &&\n !MemoryNamespace.equals(namespace, request.write.key.namespace)) ||\n (request._tag === \"RevalidateSemantic\" &&\n request.found.candidates.some(\n (candidate) => !MemoryNamespace.equals(namespace, candidate.key.namespace),\n ))\n )\n return yield* MemoryRpcError.make({ reason: \"denied\" });\n\n const remaining = Math.min(\n limits.timeoutMillis,\n request.deadlineMillis - (yield* Clock.currentTimeMillis),\n );\n\n if (remaining <= 0) return yield* MemoryRpcError.make({ reason: \"timeout\" });\n\n return yield* Effect.gen(function* (): Effect.fn.Return<\n MemoryOwnerResponse,\n MemoryOwnerFailure,\n MemoryOwnerAuthorizer | MemoryReader | MemoryWriter\n > {\n const authorizer = yield* MemoryOwnerAuthorizer;\n\n yield* authorizer.authorize(request);\n if (request._tag === \"Get\") {\n const reader = yield* MemoryReader;\n const current = yield* reader.get(request.key);\n\n const document =\n current === null ? null : yield* MemoryDocument.restore(namespace, current);\n\n if (document !== null) {\n if (document.key.id !== request.key.id || document.source.id !== request.key.id)\n return yield* MemoryStorageError.make({\n operation: \"validate memory read identity\",\n reason: \"corrupt\",\n });\n if (\n document._tag === \"ActiveMemoryDocument\" &&\n !document.scopes.includes(request.access.scope)\n )\n return yield* MemoryRpcError.make({ reason: \"denied\" });\n\n yield* encodeMemoryWire(MemoryDocument.Wire, document, limits.maxSourceBytes);\n }\n\n return { _tag: \"Document\", access: request.access, key: request.key, document };\n }\n if (request._tag === \"Change\") {\n const writer = yield* MemoryWriter;\n\n return {\n _tag: \"Changed\",\n access: request.access,\n document: yield* writer.change(request.write),\n };\n }\n if (request._tag === \"RevalidateSemantic\") {\n if (\n new Set(request.found.candidates.map((candidate) => candidate.key.id)).size >\n limits.maxSources\n )\n return yield* MemoryRpcError.make({ reason: \"budget\" });\n\n const result = yield* revalidateSemanticMemoryCandidates(\n request.found,\n request.access,\n request.profile,\n {\n ...request.limits,\n maxSourceBytes: Math.min(\n limits.maxSourceBytes,\n request.limits.maxSourceBytes ?? 16_777_216,\n ),\n maxOutputBytes: Math.min(\n limits.maxResponseBytes,\n request.limits.maxOutputBytes ?? 16_777_216,\n ),\n },\n );\n\n return { _tag: \"Semantic\", access: request.access, result };\n }\n\n const count =\n request.lookup._tag === \"Found\"\n ? new Set(request.lookup.passages.map((passage) => passage.source.id)).size\n : 0;\n\n if (count > Math.min(limits.maxSources, request.limits.maxSources))\n return yield* MemoryRpcError.make({ reason: \"budget\" });\n\n const lookup = yield* revalidateMemoryLookup(request.lookup, request.access, {\n maxSourceBytes: limits.maxSourceBytes,\n maxInputBytes: Math.min(limits.maxSourceBytes, request.limits.maxInputBytes ?? 16_777_216),\n });\n\n return { _tag: \"Lookup\", access: request.access, lookup };\n }).pipe(\n Effect.scoped,\n Effect.timeoutOrElse({\n duration: remaining,\n orElse: () => Effect.fail(MemoryRpcError.make({ reason: \"timeout\" })),\n }),\n );\n }).pipe(\n Effect.flatMap((response) =>\n encodeMemoryWire(MemoryOwnerResponse, response, limits.maxResponseBytes),\n ),\n Effect.result,\n );\n\n if (result._tag === \"Success\") return result.success;\n\n return yield* encodeMemoryWire(\n MemoryOwnerResponse,\n {\n _tag: \"Failed\",\n failure: result.failure,\n },\n limits.maxResponseBytes,\n ).pipe(\n Effect.catch(() =>\n Schema.encodeEffect(Schema.fromJsonString(MemoryOwnerResponse))({\n _tag: \"Failed\",\n failure: MemoryRpcError.make({ reason: \"budget\" }),\n }).pipe(Effect.orDie),\n ),\n );\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"MemoryProtocol.mjs","names":[],"sources":["../src/MemoryProtocol.ts"],"sourcesContent":["import * as MemoryNamespace from \"@yielded/agent/memory-namespace\";\nimport {\n MemoryLookup,\n MemoryRecallError,\n MemoryRecallLimits,\n} from \"@yielded/agent/memory-reference\";\nimport { MemoryAccess, revalidateMemoryLookup } from \"@yielded/agent/memory-revalidation\";\nimport {\n MemoryKey,\n MemoryReader,\n MemoryConflict,\n MemoryDocument,\n MemoryMutationFailure,\n MemoryOperationConflict,\n MemoryStorageError,\n MemoryWithdrawn,\n MemoryWrite,\n MemoryWriter,\n} from \"@yielded/agent/memory-store\";\nimport {\n MemoryIndexSearch,\n MemoryIndexError,\n SemanticMemoryProfile,\n} from \"@yielded/agent/semantic-memory-index\";\nimport {\n SemanticMemoryError,\n SemanticCandidateLimits,\n SemanticCandidateResult,\n revalidateSemanticMemoryCandidates,\n} from \"@yielded/agent/semantic-memory-revalidation\";\nimport { Principal } from \"@yielded/agent/submission-ledger\";\nimport { Clock, Context, Effect, Schema } from \"effect\";\n\nexport class MemoryRpcError extends Schema.TaggedError<MemoryRpcError>()(\"MemoryRpcError\", {\n reason: Schema.Literals([\"denied\", \"protocol\", \"budget\", \"timeout\", \"unavailable\"]),\n}) {}\n\nexport class MemoryRpcLimits extends Schema.Class<MemoryRpcLimits>(\n \"@effect-agent/storage-cloudflare/MemoryRpcLimits\",\n)({\n maxRequestBytes: Schema.Int.check(Schema.isBetween({ minimum: 256, maximum: 4_194_304 })),\n maxResponseBytes: Schema.Int.check(Schema.isBetween({ minimum: 256, maximum: 16_777_216 })),\n maxSourceBytes: Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: 67_108_864 })),\n maxSources: MemoryRecallLimits.fields.maxSources,\n timeoutMillis: MemoryRecallLimits.fields.timeoutMillis,\n}) {}\n\nexport const defaultMemoryRpcLimits = MemoryRpcLimits.make({\n maxRequestBytes: 1_048_576,\n maxResponseBytes: 4_194_304,\n maxSourceBytes: 16_777_216,\n maxSources: 16,\n timeoutMillis: 10_000,\n});\n\nconst RequestFields = {\n version: Schema.Literal(1),\n access: MemoryAccess.Wire,\n /** Host-authenticated identity, never copied from model input. The owner still authorizes it. */\n principal: Principal,\n deadlineMillis: Schema.Finite.check(Schema.isGreaterThanOrEqualTo(0)),\n};\n\nconst RevalidateRequest = Schema.TaggedStruct(\"Revalidate\", {\n ...RequestFields,\n lookup: MemoryLookup,\n limits: MemoryRecallLimits,\n});\n\nconst ChangeRequest = Schema.TaggedStruct(\"Change\", { ...RequestFields, write: MemoryWrite.Wire });\n\nconst GetRequest = Schema.TaggedStruct(\"Get\", { ...RequestFields, key: MemoryKey.Wire });\n\nconst SemanticRequest: Schema.TaggedStruct<\n \"RevalidateSemantic\",\n typeof RequestFields & {\n readonly found: typeof MemoryIndexSearch.Wire;\n readonly profile: typeof SemanticMemoryProfile;\n readonly limits: typeof SemanticCandidateLimits;\n }\n> = Schema.TaggedStruct(\"RevalidateSemantic\", {\n ...RequestFields,\n found: MemoryIndexSearch.Wire,\n profile: SemanticMemoryProfile,\n limits: SemanticCandidateLimits,\n});\n\nexport const MemoryOwnerRequest: Schema.Union<\n [typeof RevalidateRequest, typeof ChangeRequest, typeof SemanticRequest, typeof GetRequest]\n> = Schema.Union([RevalidateRequest, ChangeRequest, SemanticRequest, GetRequest]);\n\nexport type MemoryOwnerRequest = typeof MemoryOwnerRequest.Type;\n\nexport const MemoryOwnerFailure = Schema.Union([\n MemoryRpcError,\n MemoryStorageError,\n MemoryRecallError,\n MemoryConflict,\n MemoryWithdrawn,\n MemoryOperationConflict,\n MemoryMutationFailure,\n MemoryIndexError,\n SemanticMemoryError,\n]);\n\nexport type MemoryOwnerFailure = typeof MemoryOwnerFailure.Type;\n\nconst LookupResponse = Schema.TaggedStruct(\"Lookup\", {\n access: MemoryAccess.Wire,\n lookup: MemoryLookup,\n});\n\nconst ChangedResponse = Schema.TaggedStruct(\"Changed\", {\n access: MemoryAccess.Wire,\n document: MemoryDocument.Wire,\n});\n\nconst SemanticResponse = Schema.TaggedStruct(\"Semantic\", {\n access: MemoryAccess.Wire,\n result: SemanticCandidateResult,\n});\n\nconst DocumentResponse = Schema.TaggedStruct(\"Document\", {\n access: MemoryAccess.Wire,\n key: MemoryKey.Wire,\n document: Schema.NullOr(MemoryDocument.Wire),\n});\n\nconst FailedResponse = Schema.TaggedStruct(\"Failed\", { failure: MemoryOwnerFailure });\n\nexport const MemoryOwnerResponse: Schema.Union<\n [\n typeof LookupResponse,\n typeof ChangedResponse,\n typeof SemanticResponse,\n typeof DocumentResponse,\n typeof FailedResponse,\n ]\n> = Schema.Union([\n LookupResponse,\n ChangedResponse,\n SemanticResponse,\n DocumentResponse,\n FailedResponse,\n]);\n\nexport type MemoryOwnerResponse = typeof MemoryOwnerResponse.Type;\n\n/**\n * Fail-closed application policy. Authorize the namespace, principal, scope, and full command.\n * Get requires exact-key authority, including application source/provenance checks where needed.\n * Possession of a key or scope is not authorization, including for absent or withdrawn documents.\n */\nexport class MemoryOwnerAuthorizer extends Context.Service<\n MemoryOwnerAuthorizer,\n {\n readonly authorize: (request: MemoryOwnerRequest) => Effect.Effect<void, MemoryRpcError>;\n }\n>()(\"@effect-agent/storage-cloudflare/MemoryOwnerAuthorizer\") {}\n\n/** Canonical namespace derived from this object's idFromName identity, never its request. */\nexport class MemoryOwnerIdentity extends Context.Service<\n MemoryOwnerIdentity,\n {\n readonly namespace: MemoryNamespace.Any;\n }\n>()(\"@effect-agent/storage-cloudflare/MemoryOwnerIdentity\") {}\n\nexport const memoryWireBytes = (text: string): number => new TextEncoder().encode(text).byteLength;\n\nexport const decodeMemoryWire = Effect.fnUntraced(function* <A, I>(\n schema: Schema.Codec<A, I, never>,\n raw: unknown,\n maxBytes: number,\n) {\n const text = yield* Schema.decodeUnknownEffect(Schema.String)(raw).pipe(\n Effect.mapError(() => MemoryRpcError.make({ reason: \"protocol\" })),\n );\n\n if (text.length > maxBytes || memoryWireBytes(text) > maxBytes)\n return yield* MemoryRpcError.make({ reason: \"budget\" });\n\n return yield* Schema.decodeEffect(Schema.fromJsonString(schema))(text).pipe(\n Effect.mapError(() => MemoryRpcError.make({ reason: \"protocol\" })),\n );\n});\n\nexport const encodeMemoryWire = Effect.fnUntraced(function* <A, I>(\n schema: Schema.Codec<A, I, never, never>,\n value: A,\n maxBytes: number,\n) {\n const encoded = yield* Schema.encodeEffect(Schema.fromJsonString(schema))(value).pipe(\n Effect.mapError(() => MemoryRpcError.make({ reason: \"protocol\" })),\n );\n\n if (encoded.length > maxBytes || memoryWireBytes(encoded) > maxBytes)\n return yield* MemoryRpcError.make({ reason: \"budget\" });\n\n return encoded;\n});\n\n/** One local read for Get, or per distinct candidate source. No discovery or background work. */\nexport const handleMemoryOwnerRequest = Effect.fnUntraced(function* (\n raw: unknown,\n limits: MemoryRpcLimits = defaultMemoryRpcLimits,\n): Effect.fn.Return<\n string,\n never,\n MemoryOwnerIdentity | MemoryOwnerAuthorizer | MemoryReader | MemoryWriter\n> {\n const result = yield* Effect.gen(function* (): Effect.fn.Return<\n MemoryOwnerResponse,\n MemoryOwnerFailure,\n MemoryOwnerIdentity | MemoryOwnerAuthorizer | MemoryReader | MemoryWriter\n > {\n limits = yield* Schema.decodeEffect(MemoryRpcLimits)(limits).pipe(\n Effect.mapError(() => MemoryRpcError.make({ reason: \"protocol\" })),\n );\n const request = yield* decodeMemoryWire(MemoryOwnerRequest, raw, limits.maxRequestBytes);\n const { namespace } = yield* MemoryOwnerIdentity;\n\n if (\n !MemoryNamespace.equals(namespace, request.access.namespace) ||\n (request._tag === \"Get\" && !MemoryNamespace.equals(namespace, request.key.namespace)) ||\n (request._tag === \"Change\" &&\n !MemoryNamespace.equals(namespace, request.write.key.namespace)) ||\n (request._tag === \"RevalidateSemantic\" &&\n request.found.candidates.some(\n (candidate) => !MemoryNamespace.equals(namespace, candidate.key.namespace),\n ))\n )\n return yield* MemoryRpcError.make({ reason: \"denied\" });\n\n const remaining = Math.min(\n limits.timeoutMillis,\n request.deadlineMillis - (yield* Clock.currentTimeMillis),\n );\n\n if (remaining <= 0) return yield* MemoryRpcError.make({ reason: \"timeout\" });\n\n return yield* Effect.gen(function* (): Effect.fn.Return<\n MemoryOwnerResponse,\n MemoryOwnerFailure,\n MemoryOwnerAuthorizer | MemoryReader | MemoryWriter\n > {\n const authorizer = yield* MemoryOwnerAuthorizer;\n\n yield* authorizer.authorize(request);\n if (request._tag === \"Get\") {\n const reader = yield* MemoryReader;\n const current = yield* reader.get(request.key);\n\n const document =\n current === null ? null : yield* MemoryDocument.restore(namespace, current);\n\n if (document !== null) {\n if (document.key.id !== request.key.id || document.source.id !== request.key.id)\n return yield* MemoryStorageError.make({\n operation: \"validate memory read identity\",\n reason: \"corrupt\",\n });\n if (\n document._tag === \"ActiveMemoryDocument\" &&\n !document.scopes.includes(request.access.scope)\n )\n return yield* MemoryRpcError.make({ reason: \"denied\" });\n\n yield* encodeMemoryWire(MemoryDocument.Wire, document, limits.maxSourceBytes);\n }\n\n return { _tag: \"Document\", access: request.access, key: request.key, document };\n }\n if (request._tag === \"Change\") {\n const writer = yield* MemoryWriter;\n\n return {\n _tag: \"Changed\",\n access: request.access,\n document: yield* writer.change(request.write),\n };\n }\n if (request._tag === \"RevalidateSemantic\") {\n if (\n new Set(request.found.candidates.map((candidate) => candidate.key.id)).size >\n limits.maxSources\n )\n return yield* MemoryRpcError.make({ reason: \"budget\" });\n\n const result = yield* revalidateSemanticMemoryCandidates(\n request.found,\n request.access,\n request.profile,\n {\n ...request.limits,\n maxSourceBytes: Math.min(\n limits.maxSourceBytes,\n request.limits.maxSourceBytes ?? 16_777_216,\n ),\n maxOutputBytes: Math.min(\n limits.maxResponseBytes,\n request.limits.maxOutputBytes ?? 16_777_216,\n ),\n },\n );\n\n return { _tag: \"Semantic\", access: request.access, result };\n }\n\n const count =\n request.lookup._tag === \"Found\"\n ? new Set(request.lookup.passages.map((passage) => passage.source.id)).size\n : 0;\n\n if (count > Math.min(limits.maxSources, request.limits.maxSources))\n return yield* MemoryRpcError.make({ reason: \"budget\" });\n\n const lookup = yield* revalidateMemoryLookup(request.lookup, request.access, {\n maxSourceBytes: limits.maxSourceBytes,\n maxInputBytes: Math.min(limits.maxSourceBytes, request.limits.maxInputBytes ?? 16_777_216),\n });\n\n return { _tag: \"Lookup\", access: request.access, lookup };\n }).pipe(\n Effect.scoped,\n Effect.timeoutOrElse({\n duration: remaining,\n orElse: () => Effect.fail(MemoryRpcError.make({ reason: \"timeout\" })),\n }),\n );\n }).pipe(\n Effect.flatMap((response) =>\n encodeMemoryWire(MemoryOwnerResponse, response, limits.maxResponseBytes),\n ),\n Effect.result,\n );\n\n if (result._tag === \"Success\") return result.success;\n\n return yield* encodeMemoryWire(\n MemoryOwnerResponse,\n {\n _tag: \"Failed\",\n failure: result.failure,\n },\n limits.maxResponseBytes,\n ).pipe(\n Effect.catch(() =>\n Schema.encodeEffect(Schema.fromJsonString(MemoryOwnerResponse))({\n _tag: \"Failed\",\n failure: MemoryRpcError.make({ reason: \"budget\" }),\n }).pipe(Effect.orDie),\n ),\n );\n});\n"],"mappings":"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"}