@effect-agent/storage-cloudflare 0.1.0-beta.97 → 0.1.0-beta.99

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.
@@ -576,6 +576,13 @@ declare const encodePortRequest: (input: LedgerAdmitCall | LedgerLookupCall | Le
576
576
  readonly messages?: Schema.Json | undefined;
577
577
  } | {
578
578
  readonly _tag: "ModelResponseRecorded";
579
+ readonly toolOperations?: readonly {
580
+ readonly toolCallId: string;
581
+ readonly toolName: string;
582
+ readonly executionClass: "idempotent" | "readonly" | "uncertain";
583
+ readonly executionKind: "delegation" | "orchestration" | "ordinary";
584
+ readonly replay: string;
585
+ }[] | undefined;
579
586
  readonly toolParameterRejections?: readonly {
580
587
  readonly toolCallId: string;
581
588
  readonly parameters: Schema.Json;
@@ -641,6 +648,8 @@ declare const encodePortRequest: (input: LedgerAdmitCall | LedgerLookupCall | Le
641
648
  readonly parameters: Schema.Json;
642
649
  readonly parametersDigest: string;
643
650
  readonly executionKind?: "delegation" | "orchestration" | "ordinary" | undefined;
651
+ readonly executionClass?: "idempotent" | "readonly" | "uncertain" | undefined;
652
+ readonly replay?: string | undefined;
644
653
  } | {
645
654
  readonly _tag: "ToolCallSettled";
646
655
  readonly toolSelection?: {
@@ -711,6 +720,7 @@ declare const encodePortRequest: (input: LedgerAdmitCall | LedgerLookupCall | Le
711
720
  readonly _tag: "RunCompleted";
712
721
  readonly runId: string;
713
722
  readonly output: Schema.Json;
723
+ readonly resultDigest?: string | undefined;
714
724
  readonly runDisposition?: Schema.Json | undefined;
715
725
  readonly finishReason?: "budget-exhausted" | undefined;
716
726
  readonly exhausted?: "tokens" | "tool-calls" | "turns" | undefined;
@@ -1358,6 +1368,13 @@ declare const encodePortRequest: (input: LedgerAdmitCall | LedgerLookupCall | Le
1358
1368
  readonly messages?: Schema.Json | undefined;
1359
1369
  } | {
1360
1370
  readonly _tag: "ModelResponseRecorded";
1371
+ readonly toolOperations?: readonly {
1372
+ readonly toolCallId: string;
1373
+ readonly toolName: string;
1374
+ readonly executionClass: "idempotent" | "readonly" | "uncertain";
1375
+ readonly executionKind: "delegation" | "orchestration" | "ordinary";
1376
+ readonly replay: string;
1377
+ }[] | undefined;
1361
1378
  readonly toolParameterRejections?: readonly {
1362
1379
  readonly toolCallId: string;
1363
1380
  readonly parameters: Schema.Json;
@@ -1423,6 +1440,8 @@ declare const encodePortRequest: (input: LedgerAdmitCall | LedgerLookupCall | Le
1423
1440
  readonly parameters: Schema.Json;
1424
1441
  readonly parametersDigest: string;
1425
1442
  readonly executionKind?: "delegation" | "orchestration" | "ordinary" | undefined;
1443
+ readonly executionClass?: "idempotent" | "readonly" | "uncertain" | undefined;
1444
+ readonly replay?: string | undefined;
1426
1445
  } | {
1427
1446
  readonly _tag: "ToolCallSettled";
1428
1447
  readonly toolSelection?: {
@@ -1493,6 +1512,7 @@ declare const encodePortRequest: (input: LedgerAdmitCall | LedgerLookupCall | Le
1493
1512
  readonly _tag: "RunCompleted";
1494
1513
  readonly runId: string;
1495
1514
  readonly output: Schema.Json;
1515
+ readonly resultDigest?: string | undefined;
1496
1516
  readonly runDisposition?: Schema.Json | undefined;
1497
1517
  readonly finishReason?: "budget-exhausted" | undefined;
1498
1518
  readonly exhausted?: "tokens" | "tool-calls" | "turns" | undefined;
@@ -2653,6 +2673,13 @@ declare const encodePortResponse: (input: PortFailed | PortSucceeded, options?:
2653
2673
  readonly messages?: Schema.Json | undefined;
2654
2674
  } | {
2655
2675
  readonly _tag: "ModelResponseRecorded";
2676
+ readonly toolOperations?: readonly {
2677
+ readonly toolCallId: string;
2678
+ readonly toolName: string;
2679
+ readonly executionClass: "idempotent" | "readonly" | "uncertain";
2680
+ readonly executionKind: "delegation" | "orchestration" | "ordinary";
2681
+ readonly replay: string;
2682
+ }[] | undefined;
2656
2683
  readonly toolParameterRejections?: readonly {
2657
2684
  readonly toolCallId: string;
2658
2685
  readonly parameters: Schema.Json;
@@ -2718,6 +2745,8 @@ declare const encodePortResponse: (input: PortFailed | PortSucceeded, options?:
2718
2745
  readonly parameters: Schema.Json;
2719
2746
  readonly parametersDigest: string;
2720
2747
  readonly executionKind?: "delegation" | "orchestration" | "ordinary" | undefined;
2748
+ readonly executionClass?: "idempotent" | "readonly" | "uncertain" | undefined;
2749
+ readonly replay?: string | undefined;
2721
2750
  } | {
2722
2751
  readonly _tag: "ToolCallSettled";
2723
2752
  readonly toolSelection?: {
@@ -2788,6 +2817,7 @@ declare const encodePortResponse: (input: PortFailed | PortSucceeded, options?:
2788
2817
  readonly _tag: "RunCompleted";
2789
2818
  readonly runId: string;
2790
2819
  readonly output: Schema.Json;
2820
+ readonly resultDigest?: string | undefined;
2791
2821
  readonly runDisposition?: Schema.Json | undefined;
2792
2822
  readonly finishReason?: "budget-exhausted" | undefined;
2793
2823
  readonly exhausted?: "tokens" | "tool-calls" | "turns" | undefined;
@@ -3457,6 +3487,13 @@ declare const encodePortResponse: (input: PortFailed | PortSucceeded, options?:
3457
3487
  readonly messages?: Schema.Json | undefined;
3458
3488
  } | {
3459
3489
  readonly _tag: "ModelResponseRecorded";
3490
+ readonly toolOperations?: readonly {
3491
+ readonly toolCallId: string;
3492
+ readonly toolName: string;
3493
+ readonly executionClass: "idempotent" | "readonly" | "uncertain";
3494
+ readonly executionKind: "delegation" | "orchestration" | "ordinary";
3495
+ readonly replay: string;
3496
+ }[] | undefined;
3460
3497
  readonly toolParameterRejections?: readonly {
3461
3498
  readonly toolCallId: string;
3462
3499
  readonly parameters: Schema.Json;
@@ -3522,6 +3559,8 @@ declare const encodePortResponse: (input: PortFailed | PortSucceeded, options?:
3522
3559
  readonly parameters: Schema.Json;
3523
3560
  readonly parametersDigest: string;
3524
3561
  readonly executionKind?: "delegation" | "orchestration" | "ordinary" | undefined;
3562
+ readonly executionClass?: "idempotent" | "readonly" | "uncertain" | undefined;
3563
+ readonly replay?: string | undefined;
3525
3564
  } | {
3526
3565
  readonly _tag: "ToolCallSettled";
3527
3566
  readonly toolSelection?: {
@@ -3592,6 +3631,7 @@ declare const encodePortResponse: (input: PortFailed | PortSucceeded, options?:
3592
3631
  readonly _tag: "RunCompleted";
3593
3632
  readonly runId: string;
3594
3633
  readonly output: Schema.Json;
3634
+ readonly resultDigest?: string | undefined;
3595
3635
  readonly runDisposition?: Schema.Json | undefined;
3596
3636
  readonly finishReason?: "budget-exhausted" | undefined;
3597
3637
  readonly exhausted?: "tokens" | "tool-calls" | "turns" | undefined;
@@ -4105,6 +4145,9 @@ declare const encodePortResponse: (input: PortFailed | PortSucceeded, options?:
4105
4145
  } | {
4106
4146
  readonly _tag: "PortFailed";
4107
4147
  readonly failure: {
4148
+ readonly _tag: "PortProtocolError";
4149
+ readonly message: string;
4150
+ } | {
4108
4151
  readonly _tag: "ThreadNotMaterialized";
4109
4152
  readonly threadId: string;
4110
4153
  } | {
@@ -4112,9 +4155,6 @@ declare const encodePortResponse: (input: PortFailed | PortSucceeded, options?:
4112
4155
  readonly threadId: string;
4113
4156
  readonly actualEpoch: number;
4114
4157
  readonly attemptedEpoch: number;
4115
- } | {
4116
- readonly _tag: "PortProtocolError";
4117
- readonly message: string;
4118
4158
  } | {
4119
4159
  readonly _tag: "AdmissionConflict";
4120
4160
  readonly threadId: string;
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@effect-agent/storage-cloudflare","version":"0.1.0-beta.97","dependencies":{"@effect/platform-browser":"4.0.0-rc.115","@effect/sql-sqlite-do":"4.0.0-rc.115","effect-agent":"0.1.0-beta.97"},"devDependencies":{"@cloudflare/vitest-pool-workers":"0.21.3","@cloudflare/workers-types":"5.20260825.1","@effect-agent/testing":"0.1.0-beta.97","@effect/vitest":"4.0.0-rc.115","effect":"4.0.0-rc.115","typescript":"7.0.2","vite-plus":"0.3.0","vitest":"4.1.11"},"peerDependencies":{"effect":"^4.0.0-rc.115"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./do-memory-store":{"types":"./dist/DoMemoryStore.d.mts","default":"./dist/DoMemoryStore.mjs"},"./do-schedule-store":{"types":"./dist/DoScheduleStore.d.mts","default":"./dist/DoScheduleStore.mjs"},"./do-storage-config":{"types":"./dist/DoStorageConfig.d.mts","default":"./dist/DoStorageConfig.mjs"},"./do-storage-error":{"types":"./dist/DoStorageError.d.mts","default":"./dist/DoStorageError.mjs"},"./do-storage-failpoint":{"types":"./dist/DoStorageFailpoint.d.mts","default":"./dist/DoStorageFailpoint.mjs"},"./do-storage-version":{"types":"./dist/DoStorageVersion.d.mts","default":"./dist/DoStorageVersion.mjs"},"./do-submission-ledger":{"types":"./dist/DoSubmissionLedger.d.mts","default":"./dist/DoSubmissionLedger.mjs"},"./do-subscription-store":{"types":"./dist/DoSubscriptionStore.d.mts","default":"./dist/DoSubscriptionStore.mjs"},"./do-thread-store":{"types":"./dist/DoThreadStore.d.mts","default":"./dist/DoThreadStore.mjs"},"./memory-protocol":{"types":"./dist/MemoryProtocol.d.mts","default":"./dist/MemoryProtocol.mjs"},"./port-protocol":{"types":"./dist/PortProtocol.d.mts","default":"./dist/PortProtocol.mjs"},"./port-routing":{"types":"./dist/PortRouting.d.mts","default":"./dist/PortRouting.mjs"},"./testing/do-storage-failpoint-testing":{"types":"./dist/DoStorageFailpointTesting.d.mts","default":"./dist/DoStorageFailpointTesting.mjs"},"./do-message-delivery-store":{"types":"./dist/DoMessageDeliveryStore.d.mts","default":"./dist/DoMessageDeliveryStore.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.99","dependencies":{"@effect/platform-browser":"4.0.0-rc.115","@effect/sql-sqlite-do":"4.0.0-rc.115","effect-agent":"0.1.0-beta.99"},"devDependencies":{"@cloudflare/vitest-pool-workers":"0.21.3","@cloudflare/workers-types":"5.20260825.1","@effect-agent/testing":"0.1.0-beta.99","@effect/vitest":"4.0.0-rc.115","effect":"4.0.0-rc.115","typescript":"7.0.2","vite-plus":"0.3.0","vitest":"4.1.11"},"peerDependencies":{"effect":"^4.0.0-rc.115"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./do-memory-store":{"types":"./dist/DoMemoryStore.d.mts","default":"./dist/DoMemoryStore.mjs"},"./do-schedule-store":{"types":"./dist/DoScheduleStore.d.mts","default":"./dist/DoScheduleStore.mjs"},"./do-storage-config":{"types":"./dist/DoStorageConfig.d.mts","default":"./dist/DoStorageConfig.mjs"},"./do-storage-error":{"types":"./dist/DoStorageError.d.mts","default":"./dist/DoStorageError.mjs"},"./do-storage-failpoint":{"types":"./dist/DoStorageFailpoint.d.mts","default":"./dist/DoStorageFailpoint.mjs"},"./do-storage-version":{"types":"./dist/DoStorageVersion.d.mts","default":"./dist/DoStorageVersion.mjs"},"./do-submission-ledger":{"types":"./dist/DoSubmissionLedger.d.mts","default":"./dist/DoSubmissionLedger.mjs"},"./do-subscription-store":{"types":"./dist/DoSubscriptionStore.d.mts","default":"./dist/DoSubscriptionStore.mjs"},"./do-thread-store":{"types":"./dist/DoThreadStore.d.mts","default":"./dist/DoThreadStore.mjs"},"./memory-protocol":{"types":"./dist/MemoryProtocol.d.mts","default":"./dist/MemoryProtocol.mjs"},"./port-protocol":{"types":"./dist/PortProtocol.d.mts","default":"./dist/PortProtocol.mjs"},"./port-routing":{"types":"./dist/PortRouting.d.mts","default":"./dist/PortRouting.mjs"},"./testing/do-storage-failpoint-testing":{"types":"./dist/DoStorageFailpointTesting.d.mts","default":"./dist/DoStorageFailpointTesting.mjs"},"./do-message-delivery-store":{"types":"./dist/DoMessageDeliveryStore.d.mts","default":"./dist/DoMessageDeliveryStore.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"}}
@@ -512,10 +512,13 @@ const makeServices = Effect.fn("DoSubmissionLedger.makeServices")(function* () {
512
512
  ownershipToken: string,
513
513
  ): Effect.fn.Return<OwnershipRow, OwnershipLost | LedgerError> {
514
514
  const ownership = yield* readOwnership(operation, submission.submission_id);
515
+ const actualEpoch = yield* threadEpoch(operation, submission.thread_id);
515
516
 
516
- if (Option.isNone(ownership) || ownership.value.ownership_token !== ownershipToken) {
517
- const actualEpoch = yield* threadEpoch(operation, submission.thread_id);
518
-
517
+ if (
518
+ Option.isNone(ownership) ||
519
+ ownership.value.ownership_token !== ownershipToken ||
520
+ ownership.value.producer_epoch !== actualEpoch
521
+ ) {
519
522
  const submissionId = yield* Schema.decodeEffect(SubmissionSnapshot.fields.submissionId)(
520
523
  submission.submission_id,
521
524
  ).pipe(Effect.mapError(internalFailure(operation)));
@@ -1465,11 +1468,48 @@ const makeServices = Effect.fn("DoSubmissionLedger.makeServices")(function* () {
1465
1468
  const claimed = yield* inWriteTransaction(
1466
1469
  operation,
1467
1470
  Effect.gen(function* () {
1471
+ const now = yield* currentInstant;
1472
+
1473
+ // Ownership belongs to the whole Thread, including unknown work skipped below.
1474
+ // Stored lease instants are normalized UTC strings, so the latest expiry covers
1475
+ // every live lease. This check and the epoch grant share one write transaction.
1476
+ const ownershipRows = yield* sql<Record<string, unknown>>`
1477
+ SELECT ownership.*
1478
+ FROM effect_agent_submission_ownership AS ownership
1479
+ JOIN effect_agent_submissions AS submission
1480
+ ON submission.submission_id = ownership.submission_id
1481
+ WHERE submission.thread_id = ${validated.threadId}
1482
+ ORDER BY ownership.lease_expires_at DESC
1483
+ LIMIT 1
1484
+ `.pipe(Effect.mapError(sqlFailure(operation)));
1485
+
1486
+ const ownership = yield* decodeRows(
1487
+ Schema.Array(OwnershipRow),
1488
+ "effect_agent_submission_ownership",
1489
+ validated.threadId,
1490
+ ownershipRows,
1491
+ ).pipe(Effect.mapError(internalFailure(operation)));
1492
+
1493
+ if (ownership.length > 0) {
1494
+ const expiresAt = yield* timestampMillis(
1495
+ operation,
1496
+ ownership[0].submission_id,
1497
+ )(ownership[0].lease_expires_at);
1498
+
1499
+ if (expiresAt > now.millis) return Option.none<Claim>();
1500
+ }
1501
+
1468
1502
  const headRows = yield* sql<Record<string, unknown>>`
1469
1503
  SELECT ${sql.literal(SUBMISSION_COLUMNS)}
1470
1504
  FROM effect_agent_submissions
1471
1505
  WHERE thread_id = ${validated.threadId}
1472
1506
  AND state <> 'settled'
1507
+ AND (
1508
+ state <> 'unknown' OR EXISTS (
1509
+ SELECT 1 FROM effect_agent_abort_intents
1510
+ WHERE submission_id = effect_agent_submissions.submission_id
1511
+ )
1512
+ )
1473
1513
  ORDER BY queue_sequence ASC
1474
1514
  LIMIT 1
1475
1515
  `.pipe(Effect.mapError(sqlFailure(operation)));
@@ -1479,9 +1519,8 @@ const makeServices = Effect.fn("DoSubmissionLedger.makeServices")(function* () {
1479
1519
  if (heads.length === 0) return Option.none<Claim>();
1480
1520
  const head = heads[0];
1481
1521
 
1482
- // Unknown work is claimable only for a durably requested abort: the coordinator
1483
- // cleans up children and settles without replaying ordinary Tools. Read the intent
1484
- // in this claim transaction; retain uncertainty evidence and all ownership fencing.
1522
+ // Approval/delegation suspension and joined work retain their queue barrier.
1523
+ // Unknown work with an abort intent is selected for cleanup without Tool replay.
1485
1524
  if (
1486
1525
  head.state === "joining" ||
1487
1526
  head.state === "joined" ||
@@ -1492,21 +1531,6 @@ const makeServices = Effect.fn("DoSubmissionLedger.makeServices")(function* () {
1492
1531
  return Option.none<Claim>();
1493
1532
  }
1494
1533
 
1495
- const now = yield* currentInstant;
1496
- const ownership = yield* readOwnership(operation, head.submission_id);
1497
-
1498
- if (Option.isSome(ownership)) {
1499
- const expiresAt = yield* timestampMillis(
1500
- operation,
1501
- head.submission_id,
1502
- )(ownership.value.lease_expires_at);
1503
-
1504
- // A live lease blocks every new claim; expiry alone only revokes the liveness
1505
- // assumption — correctness stays with producer-epoch fencing (D5). In DC a live
1506
- // lease under another token can only come from an evicted incarnation.
1507
- if (expiresAt > now.millis) return Option.none<Claim>();
1508
- }
1509
-
1510
1534
  // Bump the Thread's producer epoch atomically with the claim so every stale
1511
1535
  // Attempt is fenced out of canonical appends (DUR-006). A Thread that was
1512
1536
  // never materialized (eviction between admission and materialization) is created