@effect-agent/storage-cloudflare 0.1.0-beta.49 → 0.1.0-beta.51

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":"@effect-agent/storage-cloudflare","version":"0.1.0-beta.49","dependencies":{"@effect-agent/core":"0.1.0-beta.49","@effect-agent/thread":"0.1.0-beta.49","@effect/platform-browser":"4.0.0-rc.112","@effect/sql-sqlite-do":"4.0.0-rc.112"},"devDependencies":{"@cloudflare/vitest-pool-workers":"0.21.3","@cloudflare/workers-types":"5.20260825.1","@effect-agent/testing":"0.1.0-beta.49","@effect/vitest":"4.0.0-rc.112","effect":"4.0.0-rc.112","typescript":"7.0.2","vite-plus":"0.3.0","vitest":"4.1.11"},"peerDependencies":{"effect":"^4.0.0-rc.112"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./DoMemoryStore":{"types":"./dist/DoMemoryStore.d.mts","default":"./dist/DoMemoryStore.mjs"},"./DoScheduleStore":{"types":"./dist/DoScheduleStore.d.mts","default":"./dist/DoScheduleStore.mjs"},"./DoStorageConfig":{"types":"./dist/DoStorageConfig.d.mts","default":"./dist/DoStorageConfig.mjs"},"./DoStorageError":{"types":"./dist/DoStorageError.d.mts","default":"./dist/DoStorageError.mjs"},"./DoStorageFailpoint":{"types":"./dist/DoStorageFailpoint.d.mts","default":"./dist/DoStorageFailpoint.mjs"},"./DoStorageVersion":{"types":"./dist/DoStorageVersion.d.mts","default":"./dist/DoStorageVersion.mjs"},"./DoSubmissionLedger":{"types":"./dist/DoSubmissionLedger.d.mts","default":"./dist/DoSubmissionLedger.mjs"},"./DoSubscriptionStore":{"types":"./dist/DoSubscriptionStore.d.mts","default":"./dist/DoSubscriptionStore.mjs"},"./DoThreadStore":{"types":"./dist/DoThreadStore.d.mts","default":"./dist/DoThreadStore.mjs"},"./MemoryProtocol":{"types":"./dist/MemoryProtocol.d.mts","default":"./dist/MemoryProtocol.mjs"},"./PortProtocol":{"types":"./dist/PortProtocol.d.mts","default":"./dist/PortProtocol.mjs"},"./PortRouting":{"types":"./dist/PortRouting.d.mts","default":"./dist/PortRouting.mjs"},"./testing/DoStorageFailpointTesting":{"types":"./dist/DoStorageFailpointTesting.d.mts","default":"./dist/DoStorageFailpointTesting.mjs"}},"description":"Durable Object SQLite storage adapters and the routed port protocol for Effect Agent on Cloudflare.","license":"MIT","repository":{"type":"git","url":"git+https://github.com/danieljvdm/effect-agent.git","directory":"packages/storage-cloudflare"},"files":["dist","src"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json"}}
1
+ {"name":"@effect-agent/storage-cloudflare","version":"0.1.0-beta.51","dependencies":{"@effect-agent/core":"0.1.0-beta.51","@effect-agent/thread":"0.1.0-beta.51","@effect/platform-browser":"4.0.0-rc.112","@effect/sql-sqlite-do":"4.0.0-rc.112"},"devDependencies":{"@cloudflare/vitest-pool-workers":"0.21.3","@cloudflare/workers-types":"5.20260825.1","@effect-agent/testing":"0.1.0-beta.51","@effect/vitest":"4.0.0-rc.112","effect":"4.0.0-rc.112","typescript":"7.0.2","vite-plus":"0.3.0","vitest":"4.1.11"},"peerDependencies":{"effect":"^4.0.0-rc.112"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./DoMemoryStore":{"types":"./dist/DoMemoryStore.d.mts","default":"./dist/DoMemoryStore.mjs"},"./DoScheduleStore":{"types":"./dist/DoScheduleStore.d.mts","default":"./dist/DoScheduleStore.mjs"},"./DoStorageConfig":{"types":"./dist/DoStorageConfig.d.mts","default":"./dist/DoStorageConfig.mjs"},"./DoStorageError":{"types":"./dist/DoStorageError.d.mts","default":"./dist/DoStorageError.mjs"},"./DoStorageFailpoint":{"types":"./dist/DoStorageFailpoint.d.mts","default":"./dist/DoStorageFailpoint.mjs"},"./DoStorageVersion":{"types":"./dist/DoStorageVersion.d.mts","default":"./dist/DoStorageVersion.mjs"},"./DoSubmissionLedger":{"types":"./dist/DoSubmissionLedger.d.mts","default":"./dist/DoSubmissionLedger.mjs"},"./DoSubscriptionStore":{"types":"./dist/DoSubscriptionStore.d.mts","default":"./dist/DoSubscriptionStore.mjs"},"./DoThreadStore":{"types":"./dist/DoThreadStore.d.mts","default":"./dist/DoThreadStore.mjs"},"./MemoryProtocol":{"types":"./dist/MemoryProtocol.d.mts","default":"./dist/MemoryProtocol.mjs"},"./PortProtocol":{"types":"./dist/PortProtocol.d.mts","default":"./dist/PortProtocol.mjs"},"./PortRouting":{"types":"./dist/PortRouting.d.mts","default":"./dist/PortRouting.mjs"},"./testing/DoStorageFailpointTesting":{"types":"./dist/DoStorageFailpointTesting.d.mts","default":"./dist/DoStorageFailpointTesting.mjs"}},"description":"Durable Object SQLite storage adapters and the routed port protocol for Effect Agent on Cloudflare.","license":"MIT","repository":{"type":"git","url":"git+https://github.com/danieljvdm/effect-agent.git","directory":"packages/storage-cloudflare"},"files":["dist","src"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json"}}
@@ -25,7 +25,7 @@ import {
25
25
  import { Context, Effect, Layer, Result, Schema } from "effect";
26
26
  import * as SqlClientService from "effect/unstable/sql/SqlClient";
27
27
 
28
- const CURRENT_SCHEDULE_STORE_VERSION = 2;
28
+ const CURRENT_SCHEDULE_STORE_VERSION = 3;
29
29
  const MAX_STORED_SCHEDULE_BYTES = 1_900_000;
30
30
 
31
31
  const StoredScheduleJson = Schema.String.check(Schema.isMaxLength(MAX_STORED_SCHEDULE_BYTES));
@@ -15,8 +15,12 @@ import {
15
15
  AbortIntentRequest,
16
16
  AdmissionAdmitted,
17
17
  AdmissionConflict,
18
+ AdmissionFence,
19
+ AdmissionGroup,
20
+ AdmissionPolicyError,
18
21
  AdmissionNotAdmitted,
19
22
  AdmissionRequest,
23
+ SubmissionAdmissionFence,
20
24
  AdmissionResult,
21
25
  ApprovalConflict,
22
26
  ApprovalDecisionCommand,
@@ -143,6 +147,8 @@ class SubmissionRow extends Schema.Class<SubmissionRow>("SubmissionRow")({
143
147
  unknown_tool_call_ids_json: Schema.NullOr(BoundedStoredText),
144
148
  parent_submission_id: Schema.NullOr(BoundedIdentifier),
145
149
  parent_tool_call_id: Schema.NullOr(BoundedIdentifier),
150
+ admission_group: Schema.NullOr(AdmissionGroup),
151
+ admission_fence_json: Schema.NullOr(BoundedStoredText),
146
152
  }) {}
147
153
 
148
154
  class ChildReservationRow extends Schema.Class<ChildReservationRow>("ChildReservationRow")({
@@ -255,7 +261,9 @@ const SUBMISSION_COLUMNS = `
255
261
  unknown_reason,
256
262
  unknown_tool_call_ids_json,
257
263
  parent_submission_id,
258
- parent_tool_call_id
264
+ parent_tool_call_id,
265
+ admission_group,
266
+ admission_fence_json
259
267
  `;
260
268
 
261
269
  const CHILD_RESERVATION_COLUMNS = `
@@ -342,6 +350,7 @@ const makeServices = Effect.fn("DoSubmissionLedger.makeServices")(function* () {
342
350
  const failpoint = yield* DoStorageFailpoint;
343
351
  const sql = yield* SqlClientService.SqlClient;
344
352
  const crypto = yield* Crypto.Crypto;
353
+ const admissionFence = yield* SubmissionAdmissionFence;
345
354
  const journal = yield* initializeDoJournal(sql, failpoint.hit, config.maxStoredValueBytes);
346
355
 
347
356
  const hitFailpoint = (
@@ -359,6 +368,7 @@ const makeServices = Effect.fn("DoSubmissionLedger.makeServices")(function* () {
359
368
  A,
360
369
  E extends
361
370
  | AdmissionConflict
371
+ | AdmissionPolicyError
362
372
  | ApprovalConflict
363
373
  | ChildReservationConflict
364
374
  | JoinedToHost
@@ -560,6 +570,14 @@ const makeServices = Effect.fn("DoSubmissionLedger.makeServices")(function* () {
560
570
  receiptId: row.receipt_id,
561
571
  state: row.state,
562
572
  createdAt: row.created_at,
573
+ ...(row.admission_group === null ? {} : { admissionGroup: row.admission_group }),
574
+ ...(row.admission_fence_json === null
575
+ ? {}
576
+ : {
577
+ admissionFence: yield* parseStoredJsonText(row.admission_fence_json).pipe(
578
+ Effect.mapError(internalFailure(operation)),
579
+ ),
580
+ }),
563
581
  ...(row.settled_outcome === null ? {} : { settledOutcome: row.settled_outcome }),
564
582
  ...(row.ready_at === null ? {} : { readyAt: row.ready_at }),
565
583
  ...(row.parent_submission_id === null || row.parent_tool_call_id === null
@@ -1082,6 +1100,28 @@ const makeServices = Effect.fn("DoSubmissionLedger.makeServices")(function* () {
1082
1100
  });
1083
1101
  }
1084
1102
 
1103
+ const retainedFence =
1104
+ existing[0].admission_fence_json === null
1105
+ ? undefined
1106
+ : yield* Schema.decodeEffect(Schema.fromJsonString(AdmissionFence))(
1107
+ existing[0].admission_fence_json,
1108
+ ).pipe(Effect.mapError(internalFailure(operation)));
1109
+
1110
+ if (
1111
+ (existing[0].admission_group ?? undefined) !== validated.admissionGroup ||
1112
+ !Schema.toEquivalence(Schema.optional(AdmissionFence))(
1113
+ retainedFence,
1114
+ validated.admissionFence,
1115
+ )
1116
+ )
1117
+ return yield* AdmissionConflict.make({
1118
+ threadId: validated.threadId,
1119
+ principal: validated.principal,
1120
+ idempotencyKey: validated.idempotencyKey,
1121
+ existingInputDigest: existing[0].input_digest,
1122
+ attemptedInputDigest: validated.inputDigest,
1123
+ });
1124
+
1085
1125
  return yield* decodeAdmissionResult({
1086
1126
  submissionId: existing[0].submission_id,
1087
1127
  receiptId: existing[0].receipt_id,
@@ -1091,6 +1131,20 @@ const makeServices = Effect.fn("DoSubmissionLedger.makeServices")(function* () {
1091
1131
  }).pipe(Effect.mapError(internalFailure(operation)));
1092
1132
  }
1093
1133
 
1134
+ yield* admissionFence.check(validated);
1135
+ if (validated.admissionGroup !== undefined) {
1136
+ const occupied = yield* sql<Record<string, unknown>>`
1137
+ SELECT submission_id FROM effect_agent_submissions
1138
+ WHERE thread_id=${validated.threadId} AND admission_group=${validated.admissionGroup} AND state<>'settled' LIMIT 1
1139
+ `.pipe(Effect.mapError(sqlFailure(operation)));
1140
+
1141
+ if (occupied.length > 0)
1142
+ return yield* AdmissionPolicyError.make({
1143
+ reason: "occupied",
1144
+ code: "admission-group",
1145
+ });
1146
+ }
1147
+
1094
1148
  const maxRows = yield* sql<Record<string, unknown>>`
1095
1149
  SELECT COALESCE(MAX(queue_sequence), 0) AS max_queue_sequence
1096
1150
  FROM effect_agent_submissions
@@ -1126,7 +1180,9 @@ const makeServices = Effect.fn("DoSubmissionLedger.makeServices")(function* () {
1126
1180
  state,
1127
1181
  created_at,
1128
1182
  parent_submission_id,
1129
- parent_tool_call_id
1183
+ parent_tool_call_id,
1184
+ admission_group,
1185
+ admission_fence_json
1130
1186
  ) VALUES (
1131
1187
  ${mintedSubmissionId},
1132
1188
  ${validated.threadId},
@@ -1142,7 +1198,9 @@ const makeServices = Effect.fn("DoSubmissionLedger.makeServices")(function* () {
1142
1198
  'admitted',
1143
1199
  ${now.iso},
1144
1200
  ${validated.parentLinkage?.parentSubmissionId ?? null},
1145
- ${validated.parentLinkage?.parentToolCallId ?? null}
1201
+ ${validated.parentLinkage?.parentToolCallId ?? null},
1202
+ ${validated.admissionGroup ?? null},
1203
+ ${validated.admissionFence === undefined ? null : JSON.stringify(validated.admissionFence)}
1146
1204
  )
1147
1205
  `.pipe(Effect.mapError(sqlFailure(operation)));
1148
1206