@effect-agent/storage-cloudflare 0.1.0-beta.11 → 0.1.0-beta.110

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 (74) hide show
  1. package/dist/DoMemoryStore.d.mts +29 -0
  2. package/dist/DoMemoryStore.mjs +55 -0
  3. package/dist/DoMemoryStore.mjs.map +1 -0
  4. package/dist/DoMessageDeliveryStore.d.mts +17 -0
  5. package/dist/DoMessageDeliveryStore.mjs +32 -0
  6. package/dist/DoMessageDeliveryStore.mjs.map +1 -0
  7. package/dist/DoScheduleStore.d.mts +36 -0
  8. package/dist/DoScheduleStore.mjs +388 -0
  9. package/dist/DoScheduleStore.mjs.map +1 -0
  10. package/dist/DoStorageConfig.d.mts +45 -0
  11. package/dist/DoStorageConfig.mjs +52 -0
  12. package/dist/DoStorageConfig.mjs.map +1 -0
  13. package/dist/DoStorageError-Cmhvl4TQ.d.mts +98 -0
  14. package/dist/DoStorageError.d.mts +2 -0
  15. package/dist/DoStorageError.mjs +164 -0
  16. package/dist/DoStorageError.mjs.map +1 -0
  17. package/dist/DoStorageFailpoint.d.mts +17 -0
  18. package/dist/DoStorageFailpoint.mjs +14 -0
  19. package/dist/DoStorageFailpoint.mjs.map +1 -0
  20. package/dist/DoStorageFailpointTesting.d.mts +33 -0
  21. package/dist/DoStorageFailpointTesting.mjs +35 -0
  22. package/dist/DoStorageFailpointTesting.mjs.map +1 -0
  23. package/dist/DoStorageVersion-Db6fjP-I.d.mts +12 -0
  24. package/dist/DoStorageVersion.d.mts +2 -0
  25. package/dist/DoStorageVersion.mjs +8 -0
  26. package/dist/DoStorageVersion.mjs.map +1 -0
  27. package/dist/DoSubmissionLedger.d.mts +23 -0
  28. package/dist/DoSubmissionLedger.mjs +1864 -0
  29. package/dist/DoSubmissionLedger.mjs.map +1 -0
  30. package/dist/DoSubscriptionStore.d.mts +25 -0
  31. package/dist/DoSubscriptionStore.mjs +183 -0
  32. package/dist/DoSubscriptionStore.mjs.map +1 -0
  33. package/dist/DoThreadStore.d.mts +59 -0
  34. package/dist/DoThreadStore.mjs +481 -0
  35. package/dist/DoThreadStore.mjs.map +1 -0
  36. package/dist/MemoryProtocol.d.mts +38160 -0
  37. package/dist/MemoryProtocol.mjs +219 -0
  38. package/dist/MemoryProtocol.mjs.map +1 -0
  39. package/dist/PortProtocol.d.mts +4933 -0
  40. package/dist/PortProtocol.mjs +193 -0
  41. package/dist/PortProtocol.mjs.map +1 -0
  42. package/dist/PortRouting.d.mts +86 -0
  43. package/dist/PortRouting.mjs +439 -0
  44. package/dist/PortRouting.mjs.map +1 -0
  45. package/dist/do-journal-THW8-ZeP.mjs +1041 -0
  46. package/dist/do-journal-THW8-ZeP.mjs.map +1 -0
  47. package/dist/index.d.mts +14 -1525
  48. package/dist/index.mjs +14 -3695
  49. package/dist/migrations-DZKTNU88.mjs +291 -0
  50. package/dist/migrations-DZKTNU88.mjs.map +1 -0
  51. package/dist/rolldown-runtime-D7D4PA-g.mjs +13 -0
  52. package/package.json +1 -45
  53. package/src/DoMemoryStore.ts +56 -0
  54. package/src/DoMessageDeliveryStore.ts +53 -0
  55. package/src/DoScheduleStore.ts +622 -0
  56. package/src/{errors.ts → DoStorageError.ts} +10 -3
  57. package/src/DoStorageFailpoint.ts +20 -0
  58. package/src/{do-storage-failpoint.ts → DoStorageFailpointTesting.ts} +5 -18
  59. package/src/DoStorageVersion.ts +2 -0
  60. package/src/{do-ledger.ts → DoSubmissionLedger.ts} +960 -237
  61. package/src/DoSubscriptionStore.ts +329 -0
  62. package/src/DoThreadStore.ts +1039 -0
  63. package/src/MemoryProtocol.ts +351 -0
  64. package/src/{port-protocol.ts → PortProtocol.ts} +76 -38
  65. package/src/{routing.ts → PortRouting.ts} +374 -264
  66. package/src/index.ts +13 -32
  67. package/src/internal/do-journal.ts +1656 -0
  68. package/src/internal/message-delivery-schema.ts +24 -0
  69. package/src/{migrations.ts → internal/migrations.ts} +55 -35
  70. package/src/internal/recovery-checkpoint-schema.ts +17 -0
  71. package/dist/index.mjs.map +0 -1
  72. package/src/do-conversation-store.ts +0 -850
  73. package/src/do-journal.ts +0 -1078
  74. /package/src/{do-storage-config.ts → DoStorageConfig.ts} +0 -0
@@ -0,0 +1,351 @@
1
+ import { Clock, Context, Effect, Schema } from "effect";
2
+ import * as MemoryNamespace from "effect-agent/memory-namespace";
3
+ import { MemoryLookup, MemoryRecallError, MemoryRecallLimits } from "effect-agent/memory-reference";
4
+ import { MemoryAccess, revalidateMemoryLookup } from "effect-agent/memory-revalidation";
5
+ import {
6
+ MemoryKey,
7
+ MemoryReader,
8
+ MemoryConflict,
9
+ MemoryDocument,
10
+ MemoryMutationFailure,
11
+ MemoryOperationConflict,
12
+ MemoryStorageError,
13
+ MemoryWithdrawn,
14
+ MemoryWrite,
15
+ MemoryWriter,
16
+ } from "effect-agent/memory-store";
17
+ import {
18
+ MemoryIndexSearch,
19
+ MemoryIndexError,
20
+ SemanticMemoryProfile,
21
+ } from "effect-agent/semantic-memory-index";
22
+ import {
23
+ SemanticMemoryError,
24
+ SemanticCandidateLimits,
25
+ SemanticCandidateResult,
26
+ revalidateSemanticMemoryCandidates,
27
+ } from "effect-agent/semantic-memory-revalidation";
28
+ import { Principal } from "effect-agent/submission-ledger";
29
+
30
+ export class MemoryRpcError extends Schema.TaggedError<MemoryRpcError>()("MemoryRpcError", {
31
+ reason: Schema.Literals(["denied", "protocol", "budget", "timeout", "unavailable"]),
32
+ }) {}
33
+
34
+ export class MemoryRpcLimits extends Schema.Class<MemoryRpcLimits>(
35
+ "@effect-agent/storage-cloudflare/MemoryRpcLimits",
36
+ )({
37
+ maxRequestBytes: Schema.Int.check(Schema.isBetween({ minimum: 256, maximum: 4_194_304 })),
38
+ maxResponseBytes: Schema.Int.check(Schema.isBetween({ minimum: 256, maximum: 16_777_216 })),
39
+ maxSourceBytes: Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: 67_108_864 })),
40
+ maxSources: MemoryRecallLimits.fields.maxSources,
41
+ timeoutMillis: MemoryRecallLimits.fields.timeoutMillis,
42
+ }) {}
43
+
44
+ export const defaultMemoryRpcLimits = MemoryRpcLimits.make({
45
+ maxRequestBytes: 1_048_576,
46
+ maxResponseBytes: 4_194_304,
47
+ maxSourceBytes: 16_777_216,
48
+ maxSources: 16,
49
+ timeoutMillis: 10_000,
50
+ });
51
+
52
+ const RequestFields = {
53
+ version: Schema.Literal(1),
54
+ access: MemoryAccess.Wire,
55
+ /** Host-authenticated identity, never copied from model input. The owner still authorizes it. */
56
+ principal: Principal,
57
+ deadlineMillis: Schema.Finite.check(Schema.isGreaterThanOrEqualTo(0)),
58
+ };
59
+
60
+ const RevalidateRequest = Schema.TaggedStruct("Revalidate", {
61
+ ...RequestFields,
62
+ lookup: MemoryLookup,
63
+ limits: MemoryRecallLimits,
64
+ });
65
+
66
+ const ChangeRequest = Schema.TaggedStruct("Change", { ...RequestFields, write: MemoryWrite.Wire });
67
+
68
+ const GetRequest = Schema.TaggedStruct("Get", { ...RequestFields, key: MemoryKey.Wire });
69
+
70
+ const SemanticRequest: Schema.TaggedStruct<
71
+ "RevalidateSemantic",
72
+ typeof RequestFields & {
73
+ readonly found: typeof MemoryIndexSearch.Wire;
74
+ readonly profile: typeof SemanticMemoryProfile;
75
+ readonly limits: typeof SemanticCandidateLimits;
76
+ }
77
+ > = Schema.TaggedStruct("RevalidateSemantic", {
78
+ ...RequestFields,
79
+ found: MemoryIndexSearch.Wire,
80
+ profile: SemanticMemoryProfile,
81
+ limits: SemanticCandidateLimits,
82
+ });
83
+
84
+ export const MemoryOwnerRequest: Schema.Union<
85
+ [typeof RevalidateRequest, typeof ChangeRequest, typeof SemanticRequest, typeof GetRequest]
86
+ > = Schema.Union([RevalidateRequest, ChangeRequest, SemanticRequest, GetRequest]);
87
+
88
+ export type MemoryOwnerRequest = typeof MemoryOwnerRequest.Type;
89
+
90
+ export const MemoryOwnerFailure = Schema.Union([
91
+ MemoryRpcError,
92
+ MemoryStorageError,
93
+ MemoryRecallError,
94
+ MemoryConflict,
95
+ MemoryWithdrawn,
96
+ MemoryOperationConflict,
97
+ MemoryMutationFailure,
98
+ MemoryIndexError,
99
+ SemanticMemoryError,
100
+ ]);
101
+
102
+ export type MemoryOwnerFailure = typeof MemoryOwnerFailure.Type;
103
+
104
+ const LookupResponse = Schema.TaggedStruct("Lookup", {
105
+ access: MemoryAccess.Wire,
106
+ lookup: MemoryLookup,
107
+ });
108
+
109
+ const ChangedResponse = Schema.TaggedStruct("Changed", {
110
+ access: MemoryAccess.Wire,
111
+ document: MemoryDocument.Wire,
112
+ });
113
+
114
+ const SemanticResponse = Schema.TaggedStruct("Semantic", {
115
+ access: MemoryAccess.Wire,
116
+ result: SemanticCandidateResult,
117
+ });
118
+
119
+ const DocumentResponse = Schema.TaggedStruct("Document", {
120
+ access: MemoryAccess.Wire,
121
+ key: MemoryKey.Wire,
122
+ document: Schema.NullOr(MemoryDocument.Wire),
123
+ });
124
+
125
+ const FailedResponse = Schema.TaggedStruct("Failed", { failure: MemoryOwnerFailure });
126
+
127
+ export const MemoryOwnerResponse: Schema.Union<
128
+ [
129
+ typeof LookupResponse,
130
+ typeof ChangedResponse,
131
+ typeof SemanticResponse,
132
+ typeof DocumentResponse,
133
+ typeof FailedResponse,
134
+ ]
135
+ > = Schema.Union([
136
+ LookupResponse,
137
+ ChangedResponse,
138
+ SemanticResponse,
139
+ DocumentResponse,
140
+ FailedResponse,
141
+ ]);
142
+
143
+ export type MemoryOwnerResponse = typeof MemoryOwnerResponse.Type;
144
+
145
+ /**
146
+ * Fail-closed application policy. Authorize the namespace, principal, scope, and full command.
147
+ * Get requires exact-key authority, including application source/provenance checks where needed.
148
+ * Possession of a key or scope is not authorization, including for absent or withdrawn documents.
149
+ */
150
+ export class MemoryOwnerAuthorizer extends Context.Service<
151
+ MemoryOwnerAuthorizer,
152
+ {
153
+ readonly authorize: (request: MemoryOwnerRequest) => Effect.Effect<void, MemoryRpcError>;
154
+ }
155
+ >()("@effect-agent/storage-cloudflare/MemoryOwnerAuthorizer") {}
156
+
157
+ /** Canonical namespace derived from this object's idFromName identity, never its request. */
158
+ export class MemoryOwnerIdentity extends Context.Service<
159
+ MemoryOwnerIdentity,
160
+ {
161
+ readonly namespace: MemoryNamespace.Any;
162
+ }
163
+ >()("@effect-agent/storage-cloudflare/MemoryOwnerIdentity") {}
164
+
165
+ export const memoryWireBytes = (text: string): number => new TextEncoder().encode(text).byteLength;
166
+
167
+ export const decodeMemoryWire = Effect.fn("decodeMemoryWire")(function* <A, I>(
168
+ schema: Schema.Codec<A, I, never>,
169
+ raw: unknown,
170
+ maxBytes: number,
171
+ ) {
172
+ const text = yield* Schema.decodeUnknownEffect(Schema.String)(raw).pipe(
173
+ Effect.mapError(() => MemoryRpcError.make({ reason: "protocol" })),
174
+ );
175
+
176
+ if (text.length > maxBytes || memoryWireBytes(text) > maxBytes)
177
+ return yield* MemoryRpcError.make({ reason: "budget" });
178
+
179
+ return yield* Schema.decodeEffect(Schema.fromJsonString(schema))(text).pipe(
180
+ Effect.mapError(() => MemoryRpcError.make({ reason: "protocol" })),
181
+ );
182
+ });
183
+
184
+ export const encodeMemoryWire = Effect.fn("encodeMemoryWire")(function* <A, I>(
185
+ schema: Schema.Codec<A, I, never, never>,
186
+ value: A,
187
+ maxBytes: number,
188
+ ) {
189
+ const encoded = yield* Schema.encodeEffect(Schema.fromJsonString(schema))(value).pipe(
190
+ Effect.mapError(() => MemoryRpcError.make({ reason: "protocol" })),
191
+ );
192
+
193
+ if (encoded.length > maxBytes || memoryWireBytes(encoded) > maxBytes)
194
+ return yield* MemoryRpcError.make({ reason: "budget" });
195
+
196
+ return encoded;
197
+ });
198
+
199
+ /** One local read for Get, or per distinct candidate source. No discovery or background work. */
200
+ export const handleMemoryOwnerRequest = Effect.fn("MemoryOwner.handleRequest")(function* (
201
+ raw: unknown,
202
+ limits: MemoryRpcLimits = defaultMemoryRpcLimits,
203
+ ): Effect.fn.Return<
204
+ string,
205
+ never,
206
+ MemoryOwnerIdentity | MemoryOwnerAuthorizer | MemoryReader | MemoryWriter
207
+ > {
208
+ const result = yield* Effect.gen(function* (): Effect.fn.Return<
209
+ MemoryOwnerResponse,
210
+ MemoryOwnerFailure,
211
+ MemoryOwnerIdentity | MemoryOwnerAuthorizer | MemoryReader | MemoryWriter
212
+ > {
213
+ limits = yield* Schema.decodeEffect(MemoryRpcLimits)(limits).pipe(
214
+ Effect.mapError(() => MemoryRpcError.make({ reason: "protocol" })),
215
+ );
216
+ const request = yield* decodeMemoryWire(MemoryOwnerRequest, raw, limits.maxRequestBytes);
217
+ const { namespace } = yield* MemoryOwnerIdentity;
218
+
219
+ if (
220
+ !MemoryNamespace.equals(namespace, request.access.namespace) ||
221
+ (request._tag === "Get" && !MemoryNamespace.equals(namespace, request.key.namespace)) ||
222
+ (request._tag === "Change" &&
223
+ !MemoryNamespace.equals(namespace, request.write.key.namespace)) ||
224
+ (request._tag === "RevalidateSemantic" &&
225
+ request.found.candidates.some(
226
+ (candidate) => !MemoryNamespace.equals(namespace, candidate.key.namespace),
227
+ ))
228
+ )
229
+ return yield* MemoryRpcError.make({ reason: "denied" });
230
+
231
+ const remaining = Math.min(
232
+ limits.timeoutMillis,
233
+ request.deadlineMillis - (yield* Clock.currentTimeMillis),
234
+ );
235
+
236
+ if (remaining <= 0) return yield* MemoryRpcError.make({ reason: "timeout" });
237
+
238
+ return yield* Effect.gen(function* (): Effect.fn.Return<
239
+ MemoryOwnerResponse,
240
+ MemoryOwnerFailure,
241
+ MemoryOwnerAuthorizer | MemoryReader | MemoryWriter
242
+ > {
243
+ const authorizer = yield* MemoryOwnerAuthorizer;
244
+
245
+ yield* authorizer.authorize(request);
246
+ if (request._tag === "Get") {
247
+ const reader = yield* MemoryReader;
248
+ const current = yield* reader.get(request.key);
249
+
250
+ const document =
251
+ current === null ? null : yield* MemoryDocument.restore(namespace, current);
252
+
253
+ if (document !== null) {
254
+ if (document.key.id !== request.key.id || document.source.id !== request.key.id)
255
+ return yield* MemoryStorageError.make({
256
+ operation: "validate memory read identity",
257
+ reason: "corrupt",
258
+ });
259
+ if (
260
+ document._tag === "ActiveMemoryDocument" &&
261
+ !document.scopes.includes(request.access.scope)
262
+ )
263
+ return yield* MemoryRpcError.make({ reason: "denied" });
264
+
265
+ yield* encodeMemoryWire(MemoryDocument.Wire, document, limits.maxSourceBytes);
266
+ }
267
+
268
+ return { _tag: "Document", access: request.access, key: request.key, document };
269
+ }
270
+ if (request._tag === "Change") {
271
+ const writer = yield* MemoryWriter;
272
+
273
+ return {
274
+ _tag: "Changed",
275
+ access: request.access,
276
+ document: yield* writer.change(request.write),
277
+ };
278
+ }
279
+ if (request._tag === "RevalidateSemantic") {
280
+ if (
281
+ new Set(request.found.candidates.map((candidate) => candidate.key.id)).size >
282
+ limits.maxSources
283
+ )
284
+ return yield* MemoryRpcError.make({ reason: "budget" });
285
+
286
+ const result = yield* revalidateSemanticMemoryCandidates(
287
+ request.found,
288
+ request.access,
289
+ request.profile,
290
+ {
291
+ ...request.limits,
292
+ maxSourceBytes: Math.min(
293
+ limits.maxSourceBytes,
294
+ request.limits.maxSourceBytes ?? 16_777_216,
295
+ ),
296
+ maxOutputBytes: Math.min(
297
+ limits.maxResponseBytes,
298
+ request.limits.maxOutputBytes ?? 16_777_216,
299
+ ),
300
+ },
301
+ );
302
+
303
+ return { _tag: "Semantic", access: request.access, result };
304
+ }
305
+
306
+ const count =
307
+ request.lookup._tag === "Found"
308
+ ? new Set(request.lookup.passages.map((passage) => passage.source.id)).size
309
+ : 0;
310
+
311
+ if (count > Math.min(limits.maxSources, request.limits.maxSources))
312
+ return yield* MemoryRpcError.make({ reason: "budget" });
313
+
314
+ const lookup = yield* revalidateMemoryLookup(request.lookup, request.access, {
315
+ maxSourceBytes: limits.maxSourceBytes,
316
+ maxInputBytes: Math.min(limits.maxSourceBytes, request.limits.maxInputBytes ?? 16_777_216),
317
+ });
318
+
319
+ return { _tag: "Lookup", access: request.access, lookup };
320
+ }).pipe(
321
+ Effect.scoped,
322
+ Effect.timeoutOrElse({
323
+ duration: remaining,
324
+ orElse: () => Effect.fail(MemoryRpcError.make({ reason: "timeout" })),
325
+ }),
326
+ );
327
+ }).pipe(
328
+ Effect.flatMap((response) =>
329
+ encodeMemoryWire(MemoryOwnerResponse, response, limits.maxResponseBytes),
330
+ ),
331
+ Effect.result,
332
+ );
333
+
334
+ if (result._tag === "Success") return result.success;
335
+
336
+ return yield* encodeMemoryWire(
337
+ MemoryOwnerResponse,
338
+ {
339
+ _tag: "Failed",
340
+ failure: result.failure,
341
+ },
342
+ limits.maxResponseBytes,
343
+ ).pipe(
344
+ Effect.catch(() =>
345
+ Schema.encodeEffect(Schema.fromJsonString(MemoryOwnerResponse))({
346
+ _tag: "Failed",
347
+ failure: MemoryRpcError.make({ reason: "budget" }),
348
+ }).pipe(Effect.orDie),
349
+ ),
350
+ );
351
+ });
@@ -1,25 +1,20 @@
1
+ import { Schema } from "effect";
2
+ import {
3
+ MessageDeliveryError,
4
+ MessageDeliveryPageRequest,
5
+ MessageDeliveryPage,
6
+ } from "effect-agent/message-delivery";
7
+ import { CanonicalRecordEnvelope } from "effect-agent/records";
1
8
  import {
2
9
  AbortCommand,
3
10
  AbortIntent,
4
11
  AdmissionConflict,
12
+ AdmissionPolicyError,
5
13
  AdmissionRequest,
6
14
  AdmissionResolution,
7
15
  AdmissionResult,
8
- AppendConflict,
9
- AppendResult,
10
- CanonicalRecordEnvelope,
11
16
  ChildSettledNotification,
12
17
  ChildSettledOutcome,
13
- ConversationExport,
14
- ConversationExportRequest,
15
- ConversationMaterialization,
16
- ConversationNotMaterialized,
17
- ConversationRead,
18
- ConversationStoreError,
19
- ConversationTail,
20
- ConversationTailRequest,
21
- FenceRejected,
22
- FencedAppendRequest,
23
18
  JoinedToHost,
24
19
  LedgerError,
25
20
  MarkReadyRequest,
@@ -27,33 +22,47 @@ import {
27
22
  SubmissionLookup,
28
23
  SubmissionLookupByKey,
29
24
  SubmissionSnapshot,
30
- } from "@effect-agent/session";
31
- import { Schema } from "effect";
25
+ } from "effect-agent/submission-ledger";
26
+ import {
27
+ AppendConflict,
28
+ AppendResult,
29
+ ThreadExport,
30
+ ThreadPeerCountRequest,
31
+ ThreadExportRequest,
32
+ ThreadMaterialization,
33
+ ThreadNotMaterialized,
34
+ ThreadReadRequest,
35
+ ThreadStoreError,
36
+ ThreadTail,
37
+ ThreadTailRequest,
38
+ FenceRejected,
39
+ FencedAppendRequest,
40
+ } from "effect-agent/thread-store";
32
41
 
33
42
  /**
34
43
  * The cross-Durable-Object port protocol (plan §1.3, D-P6-3): Schema request/response/error
35
- * envelopes for the CLOSED route-capable subset of the session ports. One Conversation's
36
- * Durable Object executes another Conversation's request against its OWN local facets; the
44
+ * envelopes for the CLOSED route-capable subset of the thread ports. One Thread's
45
+ * Durable Object executes another Thread's request against its OWN local facets; the
37
46
  * envelopes here are the only values that cross the Object boundary, and they are
38
47
  * transport-agnostic — native Durable Object JS RPC is the shipped carrier, fetch-with-JSON
39
48
  * the documented fallback, and both move the same Schema-encoded JSON.
40
49
  *
41
50
  * The closed subset is exactly the set of operations the durable coordinator performs against
42
- * a FOREIGN Conversation (parent/child establishment, status checks, abort propagation,
43
- * child-settlement notification, and the child-conversation store operations used by
51
+ * a FOREIGN Thread (parent/child establishment, status checks, abort propagation,
52
+ * child-settlement notification, and the child-thread store operations used by
44
53
  * establishment, `verifySettledChild`, and result projection):
45
54
  *
46
55
  * - ledger: `admit`, `markReady`, `lookup`, `resolveAdmission`, `requestAbort`,
47
56
  * `recordChildSettled`;
48
57
  * - store: `materialize`, `append`, `read` (one page), `inspectTail`, `export`.
49
58
  *
50
- * Every other port operation is lane-local by construction and is NOT given an envelope:
51
- * honesty over accidental distribution the routing layer fails such calls fast and typed
52
- * instead of quietly widening the distributed surface.
59
+ * Every other port operation is lane-local and has no envelope. A foreign disposable
60
+ * recovery-cache load returns a miss so the caller can replay canonical history. Other
61
+ * foreign operations fail fast and typed instead of widening the distributed surface.
53
62
  *
54
63
  * Failures cross the boundary as the `PortFailure` union and re-decode on the caller side to
55
64
  * the SAME tagged error types the local facet would have produced, so routed calls keep
56
- * error-tag fidelity. `cause` chains inside `LedgerError`/`ConversationStoreError` travel as
65
+ * error-tag fidelity. `cause` chains inside `LedgerError`/`ThreadStoreError` travel as
57
66
  * Schema defects and do not claim instance fidelity across Objects (plan §2.8).
58
67
  */
59
68
 
@@ -71,7 +80,7 @@ export const boundPortDiagnostic = (value: string): string =>
71
80
  /**
72
81
  * The envelope itself could not be honored: the receiving Object could not decode the
73
82
  * request, or a response could not be encoded/decoded. It never carries port semantics —
74
- * callers fold it into the operation's base error (`LedgerError`/`ConversationStoreError`),
83
+ * callers fold it into the operation's base error (`LedgerError`/`ThreadStoreError`),
75
84
  * except `resolveAdmission`, which folds it into `AdmissionIndeterminate` because a
76
85
  * non-answer is never proof of absence (SUB-031).
77
86
  */
@@ -128,43 +137,54 @@ export class LedgerRecordChildSettledCall extends Schema.TaggedClass<LedgerRecor
128
137
  request: ChildSettledNotification,
129
138
  }) {}
130
139
 
131
- /** Routed `ConversationStore.materialize` against the owning Object. */
140
+ /** Routed `ThreadStore.materialize` against the owning Object. */
132
141
  export class StoreMaterializeCall extends Schema.TaggedClass<StoreMaterializeCall>(
133
142
  "@effect-agent/storage-cloudflare/StoreMaterializeCall",
134
143
  )("StoreMaterialize", {
135
- request: ConversationMaterialization,
144
+ request: ThreadMaterialization,
136
145
  }) {}
137
146
 
138
- /** Routed `ConversationStore.append` against the owning Object. */
147
+ /** Routed `ThreadStore.append` against the owning Object. */
139
148
  export class StoreAppendCall extends Schema.TaggedClass<StoreAppendCall>(
140
149
  "@effect-agent/storage-cloudflare/StoreAppendCall",
141
150
  )("StoreAppend", {
142
151
  request: FencedAppendRequest,
143
152
  }) {}
144
153
 
145
- /** Routed one-page `ConversationStore.read`; the page bound is the request's own `limit`. */
154
+ /** Routed one-page `ThreadStore.read`; the page bound is the request's own `limit`. */
146
155
  export class StoreReadPageCall extends Schema.TaggedClass<StoreReadPageCall>(
147
156
  "@effect-agent/storage-cloudflare/StoreReadPageCall",
148
157
  )("StoreReadPage", {
149
- request: ConversationRead,
158
+ request: ThreadReadRequest,
150
159
  }) {}
151
160
 
152
- /** Routed `ConversationStore.inspectTail` against the owning Object. */
161
+ /** Routed `ThreadStore.inspectTail` against the owning Object. */
153
162
  export class StoreInspectTailCall extends Schema.TaggedClass<StoreInspectTailCall>(
154
163
  "@effect-agent/storage-cloudflare/StoreInspectTailCall",
155
164
  )("StoreInspectTail", {
156
- request: ConversationTailRequest,
165
+ request: ThreadTailRequest,
157
166
  }) {}
158
167
 
159
- /** Routed `ConversationStore.export` against the owning Object. */
168
+ /** Routed `ThreadStore.export` against the owning Object. */
160
169
  export class StoreExportCall extends Schema.TaggedClass<StoreExportCall>(
161
170
  "@effect-agent/storage-cloudflare/StoreExportCall",
162
171
  )("StoreExport", {
163
- request: ConversationExportRequest,
172
+ request: ThreadExportRequest,
164
173
  }) {}
165
174
 
175
+ export class StoreCountPeerMessagesCall extends Schema.TaggedClass<StoreCountPeerMessagesCall>()(
176
+ "StoreCountPeerMessages",
177
+ { request: ThreadPeerCountRequest },
178
+ ) {}
179
+
180
+ export class MessageDeliveryListCall extends Schema.TaggedClass<MessageDeliveryListCall>()(
181
+ "MessageDeliveryList",
182
+ { request: MessageDeliveryPageRequest },
183
+ ) {}
184
+
166
185
  /** Every request that may cross a Durable Object boundary — the CLOSED route-capable subset. */
167
186
  export const PortRequest = Schema.Union([
187
+ MessageDeliveryListCall,
168
188
  LedgerAdmitCall,
169
189
  LedgerMarkReadyCall,
170
190
  LedgerLookupCall,
@@ -176,7 +196,9 @@ export const PortRequest = Schema.Union([
176
196
  StoreReadPageCall,
177
197
  StoreInspectTailCall,
178
198
  StoreExportCall,
199
+ StoreCountPeerMessagesCall,
179
200
  ]);
201
+
180
202
  export type PortRequest = typeof PortRequest.Type;
181
203
 
182
204
  /** The wire form of one port request (what a transport actually carries). */
@@ -241,17 +263,28 @@ export class StoreReadPageResult extends Schema.TaggedClass<StoreReadPageResult>
241
263
  export class StoreInspectTailResult extends Schema.TaggedClass<StoreInspectTailResult>(
242
264
  "@effect-agent/storage-cloudflare/StoreInspectTailResult",
243
265
  )("StoreInspectTailResult", {
244
- tail: ConversationTail,
266
+ tail: ThreadTail,
245
267
  }) {}
246
268
 
247
269
  export class StoreExportResult extends Schema.TaggedClass<StoreExportResult>(
248
270
  "@effect-agent/storage-cloudflare/StoreExportResult",
249
271
  )("StoreExportResult", {
250
- export: ConversationExport,
272
+ export: ThreadExport,
251
273
  }) {}
252
274
 
275
+ export class StoreCountPeerMessagesResult extends Schema.TaggedClass<StoreCountPeerMessagesResult>()(
276
+ "StoreCountPeerMessagesResult",
277
+ { count: Schema.Int.check(Schema.isBetween({ minimum: 0, maximum: 1000 })) },
278
+ ) {}
279
+
280
+ export class MessageDeliveryListResult extends Schema.TaggedClass<MessageDeliveryListResult>()(
281
+ "MessageDeliveryListResult",
282
+ { page: MessageDeliveryPage },
283
+ ) {}
284
+
253
285
  /** Every successful routed result. Callers narrow by the tag their request implies. */
254
286
  export const PortResult = Schema.Union([
287
+ MessageDeliveryListResult,
255
288
  LedgerAdmitResult,
256
289
  LedgerMarkReadyResult,
257
290
  LedgerLookupResult,
@@ -263,7 +296,9 @@ export const PortResult = Schema.Union([
263
296
  StoreReadPageResult,
264
297
  StoreInspectTailResult,
265
298
  StoreExportResult,
299
+ StoreCountPeerMessagesResult,
266
300
  ]);
301
+
267
302
  export type PortResult = typeof PortResult.Type;
268
303
 
269
304
  // ---------------------------------------------------------------------------
@@ -273,19 +308,22 @@ export type PortResult = typeof PortResult.Type;
273
308
  /**
274
309
  * Every typed failure a route-capable operation can produce on its owning Object, plus the
275
310
  * protocol's own `PortProtocolError`. Members re-decode to the SAME tagged classes the
276
- * session ports declare, so a routed caller observes identical error tags and fields.
311
+ * thread ports declare, so a routed caller observes identical error tags and fields.
277
312
  */
278
313
  export const PortFailure = Schema.Union([
314
+ MessageDeliveryError,
279
315
  AdmissionConflict,
316
+ AdmissionPolicyError,
280
317
  SettlementConflict,
281
318
  JoinedToHost,
282
319
  LedgerError,
283
- ConversationStoreError,
284
- ConversationNotMaterialized,
320
+ ThreadStoreError,
321
+ ThreadNotMaterialized,
285
322
  AppendConflict,
286
323
  FenceRejected,
287
324
  PortProtocolError,
288
325
  ]);
326
+
289
327
  export type PortFailure = typeof PortFailure.Type;
290
328
 
291
329
  /** The routed operation succeeded on its owning Object. */