@effect-agent/platform-cloudflare 0.0.1-beta.0
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/dist/index.d.mts +1486 -0
- package/dist/index.mjs +1073 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +56 -0
- package/src/alarm.ts +334 -0
- package/src/bindings.ts +145 -0
- package/src/client.ts +646 -0
- package/src/config.ts +137 -0
- package/src/conversation-object.ts +709 -0
- package/src/index.ts +22 -0
- package/src/layers.ts +376 -0
- package/src/transport.ts +38 -0
- package/src/wake-scheduler.ts +85 -0
package/src/config.ts
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { DEFAULT_OWNERSHIP_LEASE_DURATION, DeploymentId } from "@effect-agent/session";
|
|
2
|
+
import { DEFAULT_MAX_STORED_VALUE_BYTES } from "@effect-agent/storage-cloudflare";
|
|
3
|
+
import { Context, Duration, Schema } from "effect";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Schema-validated configuration for the Cloudflare durable runtime (deployment spec §4:
|
|
7
|
+
* decoded once during Layer construction, exposed as a typed service; DEPLOY-003). Every
|
|
8
|
+
* cadence is in milliseconds; every bound is finite and checked before any resource opens.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const PositiveMillis = Schema.Int.check(Schema.isGreaterThan(0));
|
|
12
|
+
const NonNegativeMillis = Schema.Int.check(Schema.isGreaterThanOrEqualTo(0));
|
|
13
|
+
|
|
14
|
+
/** The supplied Cloudflare durable runtime configuration failed validation (DEPLOY-003). */
|
|
15
|
+
export class CloudflarePlatformConfigError extends Schema.TaggedError<CloudflarePlatformConfigError>()(
|
|
16
|
+
"CloudflarePlatformConfigError",
|
|
17
|
+
{
|
|
18
|
+
message: Schema.String,
|
|
19
|
+
cause: Schema.optionalKey(Schema.Defect()),
|
|
20
|
+
},
|
|
21
|
+
) {}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* An admission was refused by a host resource limit BEFORE any ledger row existed
|
|
25
|
+
* (deployment spec §8, DEPLOY-007: "Admission has explicit bounded quota and overload
|
|
26
|
+
* behavior... a typed rejection"). This is the DC analogue of `NodeDurableHost`'s
|
|
27
|
+
* `AdmissionClosed` host gate: the port surface stays untouched, the refusal happens in the
|
|
28
|
+
* Conversation Object's submit entry point before `DurableAgentRuntime.submit` runs, and
|
|
29
|
+
* nothing was admitted or written.
|
|
30
|
+
*/
|
|
31
|
+
export class AdmissionLimitExceeded extends Schema.TaggedError<AdmissionLimitExceeded>()(
|
|
32
|
+
"AdmissionLimitExceeded",
|
|
33
|
+
{
|
|
34
|
+
limit: Schema.Literals(["queue-depth", "input-bytes", "database-bytes"]),
|
|
35
|
+
actual: Schema.Int,
|
|
36
|
+
maximum: Schema.Int,
|
|
37
|
+
},
|
|
38
|
+
) {
|
|
39
|
+
override get message() {
|
|
40
|
+
return (
|
|
41
|
+
`Admission refused before any ledger row existed: ${this.limit} ${this.actual} exceeds ` +
|
|
42
|
+
`the configured maximum ${this.maximum}. Accepted work is unaffected; retry after the ` +
|
|
43
|
+
"lane drains or raise the limit (DEPLOY-007)."
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** The platform's hard per-Object database cap (10 GB, developers.cloudflare.com limits). */
|
|
49
|
+
export const CLOUDFLARE_DATABASE_CAP_BYTES = 10_000_000_000;
|
|
50
|
+
|
|
51
|
+
/** Default database-size admission ceiling: a 1 GB safety margin under the platform cap. */
|
|
52
|
+
export const DEFAULT_MAX_DATABASE_BYTES = 9_000_000_000;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Explicit bounded admission quotas checked by the Conversation Object BEFORE admission
|
|
56
|
+
* (exit gate "resource limits are checked before admission").
|
|
57
|
+
*/
|
|
58
|
+
export class CloudflareAdmissionLimitsValue extends Schema.Class<CloudflareAdmissionLimitsValue>(
|
|
59
|
+
"@effect-agent/platform-cloudflare/CloudflareAdmissionLimitsValue",
|
|
60
|
+
)({
|
|
61
|
+
/** Maximum nonterminal Submissions per Conversation lane before new admissions refuse. */
|
|
62
|
+
maxQueueDepthPerLane: Schema.Int.check(
|
|
63
|
+
Schema.isGreaterThan(0),
|
|
64
|
+
Schema.isLessThanOrEqualTo(100_000),
|
|
65
|
+
),
|
|
66
|
+
/** Maximum encoded input bytes; never above the storage per-value bound. */
|
|
67
|
+
maxInputBytes: Schema.Int.check(Schema.isGreaterThan(0), Schema.isLessThanOrEqualTo(2_000_000)),
|
|
68
|
+
/** Maximum `ctx.storage.sql.databaseSize` at admission; stays under the 10 GB platform cap. */
|
|
69
|
+
maxDatabaseBytes: Schema.Int.check(
|
|
70
|
+
Schema.isGreaterThan(0),
|
|
71
|
+
Schema.isLessThanOrEqualTo(CLOUDFLARE_DATABASE_CAP_BYTES),
|
|
72
|
+
),
|
|
73
|
+
}) {}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Validated Cloudflare durable runtime configuration. The producer identity of one
|
|
77
|
+
* Conversation Object is `{producerPrefix}:{conversationId}` — stable across incarnations of
|
|
78
|
+
* the same deployment, distinct across deployments — and producer-epoch fencing (not the
|
|
79
|
+
* producer name) remains the correctness authority (DUR-006).
|
|
80
|
+
*/
|
|
81
|
+
export class CloudflareDurableRuntimeConfigValue extends Schema.Class<CloudflareDurableRuntimeConfigValue>(
|
|
82
|
+
"@effect-agent/platform-cloudflare/CloudflareDurableRuntimeConfigValue",
|
|
83
|
+
)({
|
|
84
|
+
deploymentId: DeploymentId,
|
|
85
|
+
/** Head of the minted producer identity `{producerPrefix}:{conversationId}`. */
|
|
86
|
+
producerPrefix: Schema.NonEmptyString.check(Schema.isMaxLength(256)),
|
|
87
|
+
/** Submission ownership lease duration (D5); fences work across Object incarnations. */
|
|
88
|
+
ownershipLeaseDuration: PositiveMillis,
|
|
89
|
+
/** Base delay of the alarm re-arm backoff when a pass makes no progress. */
|
|
90
|
+
alarmBackoffBase: PositiveMillis,
|
|
91
|
+
/** Ceiling of the alarm re-arm backoff. */
|
|
92
|
+
alarmBackoffCap: PositiveMillis,
|
|
93
|
+
/**
|
|
94
|
+
* The maintenance-pass scan cadence and the ceiling of every re-arm delay: nonterminal
|
|
95
|
+
* work is revisited at least this often (wake/scan pairing, persistence §14).
|
|
96
|
+
*/
|
|
97
|
+
wakeScanInterval: PositiveMillis,
|
|
98
|
+
/** `awaitSettlement` ledger re-check cadence when no wake arrives. */
|
|
99
|
+
settlementPollInterval: PositiveMillis,
|
|
100
|
+
/** Worker ownership-lease renewal cadence during an active Attempt. */
|
|
101
|
+
leaseRenewalInterval: PositiveMillis,
|
|
102
|
+
/** Active-Run abort-intent poll cadence. */
|
|
103
|
+
abortPollInterval: PositiveMillis,
|
|
104
|
+
/** Canonical observation poll cadence of the Durable Object store. */
|
|
105
|
+
observationPollInterval: NonNegativeMillis,
|
|
106
|
+
/** Per-value byte bound; must stay under the platform's 2 MB SQLite value limit. */
|
|
107
|
+
maxStoredValueBytes: Schema.Int.check(
|
|
108
|
+
Schema.isGreaterThan(0),
|
|
109
|
+
Schema.isLessThanOrEqualTo(2_000_000),
|
|
110
|
+
),
|
|
111
|
+
/** Opt-in full payload/digest-chain audit while opening the store. */
|
|
112
|
+
verifyOnOpen: Schema.Boolean,
|
|
113
|
+
limits: CloudflareAdmissionLimitsValue,
|
|
114
|
+
}) {}
|
|
115
|
+
|
|
116
|
+
/** Explicit configuration authority for the assembled Cloudflare durable runtime. */
|
|
117
|
+
export class CloudflareDurableRuntimeConfig extends Context.Service<
|
|
118
|
+
CloudflareDurableRuntimeConfig,
|
|
119
|
+
CloudflareDurableRuntimeConfigValue
|
|
120
|
+
>()("@effect-agent/platform-cloudflare/CloudflareDurableRuntimeConfig") {}
|
|
121
|
+
|
|
122
|
+
/** Documented production defaults applied by `CloudflareDurableRuntime.layer`. */
|
|
123
|
+
export const CLOUDFLARE_RUNTIME_DEFAULTS = {
|
|
124
|
+
ownershipLeaseDuration: Duration.toMillis(DEFAULT_OWNERSHIP_LEASE_DURATION),
|
|
125
|
+
alarmBackoffBase: 100,
|
|
126
|
+
alarmBackoffCap: 5_000,
|
|
127
|
+
wakeScanInterval: 1_000,
|
|
128
|
+
settlementPollInterval: 500,
|
|
129
|
+
leaseRenewalInterval: 10_000,
|
|
130
|
+
abortPollInterval: 500,
|
|
131
|
+
observationPollInterval: 25,
|
|
132
|
+
maxStoredValueBytes: DEFAULT_MAX_STORED_VALUE_BYTES,
|
|
133
|
+
verifyOnOpen: false,
|
|
134
|
+
maxQueueDepthPerLane: 256,
|
|
135
|
+
maxInputBytes: DEFAULT_MAX_STORED_VALUE_BYTES,
|
|
136
|
+
maxDatabaseBytes: DEFAULT_MAX_DATABASE_BYTES,
|
|
137
|
+
} as const;
|