@effect-agent/platform-cloudflare 0.0.1-beta.0 → 0.0.1-beta.4

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,8 +1,8 @@
1
1
  {
2
2
  "name": "@effect-agent/platform-cloudflare",
3
- "version": "0.0.1-beta.0",
3
+ "version": "0.0.1-beta.4",
4
4
  "description": "Class DC layer assembly for Effect Agent: SQLite-backed Conversation Durable Objects with alarm-driven recovery.",
5
- "license": "UNLICENSED",
5
+ "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/danieljvdm/effect-agent.git",
@@ -28,29 +28,24 @@
28
28
  "test": "vitest run"
29
29
  },
30
30
  "dependencies": {
31
- "@effect-agent/core": "0.0.1-beta.2",
32
- "@effect-agent/session": "0.0.1-beta.2",
33
- "@effect-agent/storage-cloudflare": "0.0.1-beta.0"
31
+ "@effect-agent/core": "0.0.1-beta.4",
32
+ "@effect-agent/session": "0.0.1-beta.4",
33
+ "@effect-agent/storage-cloudflare": "0.0.1-beta.4",
34
+ "@effect/platform-browser": "4.0.0-beta.102",
35
+ "@effect/sql-sqlite-do": "4.0.0-beta.102",
36
+ "effect": "4.0.0-beta.102"
34
37
  },
35
38
  "devDependencies": {
36
39
  "@cloudflare/vitest-pool-workers": "0.21.3",
37
40
  "@cloudflare/workers-types": "5.20260813.1",
38
- "@effect-agent/capabilities": "0.0.1-beta.1",
39
- "@effect-agent/engine": "0.0.1-beta.1",
40
- "@effect-agent/testing": "0.0.1-beta.1",
41
- "@effect/platform-browser": "4.0.0-beta.105",
42
- "@effect/sql-sqlite-do": "4.0.0-beta.105",
43
- "@effect/vitest": "4.0.0-beta.105",
44
- "effect": "4.0.0-beta.105",
41
+ "@effect-agent/capabilities": "0.0.1-beta.3",
42
+ "@effect-agent/engine": "0.0.1-beta.3",
43
+ "@effect-agent/testing": "0.0.1-beta.3",
44
+ "@effect/vitest": "4.0.0-beta.102",
45
45
  "esbuild": "0.28.1",
46
46
  "miniflare": "4.20260730.0",
47
47
  "typescript": "7.0.2",
48
48
  "vite-plus": "0.2.6",
49
49
  "vitest": "4.1.10"
50
- },
51
- "peerDependencies": {
52
- "@effect/platform-browser": "4.0.0-beta.105",
53
- "@effect/sql-sqlite-do": "4.0.0-beta.105",
54
- "effect": "4.0.0-beta.105"
55
50
  }
56
51
  }
package/src/alarm.ts CHANGED
@@ -25,7 +25,7 @@ import { CloudflareDurableRuntimeConfig } from "./config.ts";
25
25
  */
26
26
 
27
27
  /** The Durable Object alarm API failed; surfaces on host entry points as a typed refusal. */
28
- export class DurableAlarmError extends Schema.TaggedError<DurableAlarmError>()(
28
+ export class DurableAlarmError extends Schema.TaggedErrorClass<DurableAlarmError>()(
29
29
  "DurableAlarmError",
30
30
  {
31
31
  operation: Schema.String,
package/src/bindings.ts CHANGED
@@ -10,7 +10,7 @@ import { Context, Effect, Layer, Schema } from "effect";
10
10
  */
11
11
 
12
12
  /** A Cloudflare platform binding was missing or carried the wrong shape (DEPLOY-003/010). */
13
- export class CloudflareBindingError extends Schema.TaggedError<CloudflareBindingError>()(
13
+ export class CloudflareBindingError extends Schema.TaggedErrorClass<CloudflareBindingError>()(
14
14
  "CloudflareBindingError",
15
15
  {
16
16
  binding: Schema.String,
package/src/client.ts CHANGED
@@ -59,7 +59,7 @@ export const boundHostDiagnostic = (value: string): string =>
59
59
  * The envelope itself could not be honored: the Object could not decode the request, or a
60
60
  * response could not be encoded/decoded. Never carries operation semantics.
61
61
  */
62
- export class HostProtocolError extends Schema.TaggedError<HostProtocolError>()(
62
+ export class HostProtocolError extends Schema.TaggedErrorClass<HostProtocolError>()(
63
63
  "HostProtocolError",
64
64
  {
65
65
  message: BoundedDiagnostic,
@@ -67,7 +67,7 @@ export class HostProtocolError extends Schema.TaggedError<HostProtocolError>()(
67
67
  ) {}
68
68
 
69
69
  /** The Worker-side stub call itself failed (RPC rejection, overload, eviction mid-call). */
70
- export class ConversationClientError extends Schema.TaggedError<ConversationClientError>()(
70
+ export class ConversationClientError extends Schema.TaggedErrorClass<ConversationClientError>()(
71
71
  "ConversationClientError",
72
72
  {
73
73
  conversationId: Schema.String,
package/src/config.ts CHANGED
@@ -12,7 +12,7 @@ const PositiveMillis = Schema.Int.check(Schema.isGreaterThan(0));
12
12
  const NonNegativeMillis = Schema.Int.check(Schema.isGreaterThanOrEqualTo(0));
13
13
 
14
14
  /** The supplied Cloudflare durable runtime configuration failed validation (DEPLOY-003). */
15
- export class CloudflarePlatformConfigError extends Schema.TaggedError<CloudflarePlatformConfigError>()(
15
+ export class CloudflarePlatformConfigError extends Schema.TaggedErrorClass<CloudflarePlatformConfigError>()(
16
16
  "CloudflarePlatformConfigError",
17
17
  {
18
18
  message: Schema.String,
@@ -28,7 +28,7 @@ export class CloudflarePlatformConfigError extends Schema.TaggedError<Cloudflare
28
28
  * Conversation Object's submit entry point before `DurableAgentRuntime.submit` runs, and
29
29
  * nothing was admitted or written.
30
30
  */
31
- export class AdmissionLimitExceeded extends Schema.TaggedError<AdmissionLimitExceeded>()(
31
+ export class AdmissionLimitExceeded extends Schema.TaggedErrorClass<AdmissionLimitExceeded>()(
32
32
  "AdmissionLimitExceeded",
33
33
  {
34
34
  limit: Schema.Literals(["queue-depth", "input-bytes", "database-bytes"]),
@@ -38,7 +38,6 @@ import {
38
38
  DurableObjectContext,
39
39
  conversationNamespaceLayer,
40
40
  type CloudflareBindingError,
41
- type ConversationObjectRpc,
42
41
  } from "./bindings.ts";
43
42
  import {
44
43
  AbortRecorded,
@@ -96,25 +95,6 @@ export interface ConversationObjectOptions extends CloudflareDurableRuntimeOptio
96
95
  readonly namespaceBinding: string;
97
96
  }
98
97
 
99
- /**
100
- * Public instance surface of the class returned by `makeConversationObjectClass`. It includes
101
- * the Worker/sibling RPC contract, the administrative RPC entry points, the platform alarm
102
- * handler, and the inherited Object context used by application subclasses.
103
- */
104
- export interface ConversationObjectInstance
105
- extends DurableObject<Cloudflare.Env>, ConversationObjectRpc {
106
- explainEncoded(encoded: unknown): Promise<unknown>;
107
- verifyEncoded(encoded: unknown): Promise<unknown>;
108
- retryEncoded(encoded: unknown): Promise<unknown>;
109
- obligationsEncoded(encoded: unknown): Promise<unknown>;
110
- alarm(): Promise<void>;
111
- }
112
-
113
- /** Public constructor returned by `makeConversationObjectClass`. */
114
- export interface ConversationObjectConstructor {
115
- new (ctx: DurableObjectState, env: Cloudflare.Env): ConversationObjectInstance;
116
- }
117
-
118
98
  type ConversationObjectError = CloudflareDurableRuntimeInitializationError | CloudflareBindingError;
119
99
 
120
100
  type EndpointServices = CloudflareDurableRuntimeServices | DurableObjectContext;
@@ -628,10 +608,37 @@ const gateEndpoint: Effect.Effect<void, unknown, EndpointServices> = Effect.gen(
628
608
  yield* maintenance.ensureAlarm;
629
609
  });
630
610
 
631
- /** Build the application's Conversation Object class (export it from the Worker entry). */
611
+ /** The public endpoint surface of one Conversation Object instance. */
612
+ export interface ConversationObjectInstance extends DurableObject {
613
+ submitEncoded(encoded: unknown): Promise<unknown>;
614
+ awaitSettlementEncoded(encoded: unknown): Promise<unknown>;
615
+ observePage(encoded: unknown): Promise<unknown>;
616
+ abortEncoded(encoded: unknown): Promise<unknown>;
617
+ resolveApprovalEncoded(encoded: unknown): Promise<unknown>;
618
+ resolveUnknownEncoded(encoded: unknown): Promise<unknown>;
619
+ explainEncoded(encoded: unknown): Promise<unknown>;
620
+ verifyEncoded(encoded: unknown): Promise<unknown>;
621
+ retryEncoded(encoded: unknown): Promise<unknown>;
622
+ obligationsEncoded(encoded: unknown): Promise<unknown>;
623
+ portCall(encoded: unknown): Promise<unknown>;
624
+ wake(): Promise<void>;
625
+ alarm(): Promise<void>;
626
+ }
627
+
628
+ /** The constructor shape workerd instantiates for each Conversation Object. */
629
+ export interface ConversationObjectClass {
630
+ new (ctx: DurableObjectState, env: Cloudflare.Env): ConversationObjectInstance;
631
+ }
632
+
633
+ /**
634
+ * Build the application's Conversation Object class (export it from the
635
+ * Worker entry). The explicit return type is what makes declaration emit
636
+ * possible: the class body carries a private runtime field, and TS4094
637
+ * rejects inferring an exported anonymous class type around it.
638
+ */
632
639
  export const makeConversationObjectClass = (
633
640
  options: ConversationObjectOptions,
634
- ): ConversationObjectConstructor => {
641
+ ): ConversationObjectClass => {
635
642
  class ConversationObject extends DurableObject {
636
643
  readonly #runtime: ManagedRuntime.ManagedRuntime<EndpointServices, ConversationObjectError>;
637
644
 
@@ -649,7 +656,7 @@ export const makeConversationObjectClass = (
649
656
  );
650
657
  // The constructor gate: local-only checks; never the recovery pass (deadlock argument,
651
658
  // plan §1.4). A failure here fails every delivery with the typed construction error.
652
- void ctx.blockConcurrencyWhile(() => this.#runtime.runPromise(gateEndpoint));
659
+ ctx.blockConcurrencyWhile(() => this.#runtime.runPromise(gateEndpoint));
653
660
  }
654
661
 
655
662
  async submitEncoded(encoded: unknown): Promise<unknown> {
package/src/layers.ts CHANGED
@@ -97,35 +97,16 @@ export interface CloudflareDurableRuntimeOptions {
97
97
  readonly toolReconciler?: Layer.Layer<ToolReconciler> | undefined;
98
98
  /**
99
99
  * Registered worker Bindings resolved at durable claim time (S2, spec/subagents.md §11):
100
- * build each with `DurableWorkerBinding.make(binding, digests)`. An Effect or callback form is
101
- * accepted because capture can be effectful. The callback receives the live Object context and
102
- * derived identities and is evaluated once per incarnation during Layer construction. Defaults
103
- * to the empty registration (every resolved claim fails closed).
100
+ * build each with `DurableWorkerBinding.make(binding, digests)`. An Effect form is accepted
101
+ * because the capture is effectful; it runs once per incarnation during Layer construction.
102
+ * Defaults to the empty registration (every resolved claim fails closed).
104
103
  */
105
- readonly bindings?: CloudflareBindingSource | undefined;
106
- }
107
-
108
- /** Per-incarnation host values available while registered worker Bindings are captured. */
109
- export interface CloudflareBindingSourceContext {
110
- readonly ctx: DurableObjectState;
111
- readonly env: unknown;
112
- readonly conversationId: ConversationId;
113
- readonly producerId: ProducerId;
104
+ readonly bindings?:
105
+ | ReadonlyArray<ResolvedBinding>
106
+ | Effect.Effect<ReadonlyArray<ResolvedBinding>>
107
+ | undefined;
114
108
  }
115
109
 
116
- /**
117
- * Registered worker Bindings, or a closed Effect/callback that captures them once for each
118
- * Durable Object incarnation. Callback Effects cannot require services or fail typed.
119
- */
120
- export type CloudflareBindingSource =
121
- | ReadonlyArray<ResolvedBinding>
122
- | Effect.Effect<ReadonlyArray<ResolvedBinding>, never, never>
123
- | ((
124
- context: CloudflareBindingSourceContext,
125
- ) =>
126
- | ReadonlyArray<ResolvedBinding>
127
- | Effect.Effect<ReadonlyArray<ResolvedBinding>, never, never>);
128
-
129
110
  /** Every construction failure of the assembled Cloudflare durable runtime stack. */
130
111
  export type CloudflareDurableRuntimeInitializationError =
131
112
  | CloudflarePlatformConfigError
@@ -227,19 +208,13 @@ const conversationIdFromState = (
227
208
  );
228
209
 
229
210
  const resolveBindings = (
230
- source: CloudflareDurableRuntimeOptions["bindings"],
231
- context: CloudflareBindingSourceContext,
211
+ bindings: CloudflareDurableRuntimeOptions["bindings"],
232
212
  ): Effect.Effect<ReadonlyArray<ResolvedBinding>> =>
233
- source === undefined
213
+ bindings === undefined
234
214
  ? Effect.succeed([])
235
- : Effect.isEffect(source)
236
- ? source
237
- : typeof source === "function"
238
- ? Effect.suspend(() => {
239
- const bindings = source(context);
240
- return Effect.isEffect(bindings) ? bindings : Effect.succeed(bindings);
241
- })
242
- : Effect.succeed(source);
215
+ : Effect.isEffect(bindings)
216
+ ? bindings
217
+ : Effect.succeed(bindings);
243
218
 
244
219
  /**
245
220
  * The DC Layer assembly (deployment §12: a Layer-assembly library, not an app entrypoint;
@@ -268,7 +243,7 @@ export class CloudflareDurableRuntime {
268
243
  > {
269
244
  return Layer.unwrap(
270
245
  Effect.gen(function* () {
271
- const { ctx, env } = yield* DurableObjectContext;
246
+ const { ctx } = yield* DurableObjectContext;
272
247
  const config = yield* configFromOptions(options);
273
248
  const conversationId = yield* conversationIdFromState(ctx);
274
249
  const producerId = yield* decodeProducerId(
@@ -342,10 +317,7 @@ export class CloudflareDurableRuntime {
342
317
  : Layer.succeed(DurableRuntimeFailpoint)({ hit: options.runtimeFailpoint(ctx) });
343
318
  const reconcilerLayer = options.toolReconciler ?? ToolReconciler.uncertain;
344
319
  const bindingResolverLayer = Layer.effect(AgentBindingResolver)(
345
- Effect.map(
346
- resolveBindings(options.bindings, { ctx, env, conversationId, producerId }),
347
- (bindings) => AgentBindingResolver.fromBindings(bindings),
348
- ),
320
+ Effect.map(resolveBindings(options.bindings), AgentBindingResolver.fromBindings),
349
321
  );
350
322
 
351
323
  const base = Layer.mergeAll(
@@ -14,7 +14,7 @@ import { ConversationObjectIdentity, ConversationObjectNamespace } from "./bindi
14
14
  const WAKE_BUFFER_CAPACITY = 1_024;
15
15
 
16
16
  /** A remote wake stub call failed; always swallowed and logged (hints are droppable). */
17
- class RemoteWakeDropped extends Schema.TaggedError<RemoteWakeDropped>()("RemoteWakeDropped", {
17
+ class RemoteWakeDropped extends Schema.TaggedErrorClass<RemoteWakeDropped>()("RemoteWakeDropped", {
18
18
  conversationId: Schema.String,
19
19
  message: Schema.String,
20
20
  cause: Schema.optionalKey(Schema.Defect()),