@effect-agent/platform-cloudflare 0.1.0-beta.38 → 0.1.0-beta.39

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.
@@ -0,0 +1,90 @@
1
+ import type { AgentId } from "@effect-agent/core";
2
+ import {
3
+ type DurableSubmitAgent,
4
+ PersistedJson,
5
+ type PreparedInput,
6
+ PreparedInputAdmission,
7
+ type ScheduledEnvelope,
8
+ ScheduledInputAdmission,
9
+ ScheduledInputRetryable,
10
+ ScheduleStorageError,
11
+ } from "@effect-agent/thread";
12
+ import { Effect, Layer } from "effect";
13
+
14
+ import { CloudflareThreadClient, type ThreadClientError } from "./client.ts";
15
+
16
+ const passthroughAgent = (agentId: AgentId): DurableSubmitAgent<typeof PersistedJson> => ({
17
+ definition: { id: agentId, input: PersistedJson },
18
+ });
19
+
20
+ /** Ordinary prepared admission through one freshly addressed Thread Object call. */
21
+ export const cloudflarePreparedInputAdmissionLayer: Layer.Layer<
22
+ PreparedInputAdmission,
23
+ never,
24
+ CloudflareThreadClient
25
+ > = Layer.effect(
26
+ PreparedInputAdmission,
27
+ Effect.gen(function* () {
28
+ const client = yield* CloudflareThreadClient;
29
+ return PreparedInputAdmission.of({
30
+ submit: (envelope) =>
31
+ client
32
+ .submit(passthroughAgent(envelope.agentId), envelope.input, {
33
+ threadId: envelope.threadId,
34
+ principal: envelope.deliveryPrincipal,
35
+ idempotencyKey: envelope.admissionKey,
36
+ definitions: envelope.definitions,
37
+ })
38
+ .pipe(
39
+ Effect.catchTags({
40
+ AdmissionConflict: () =>
41
+ ScheduleStorageError.make({ operation: "prepared admission", reason: "corrupt" }),
42
+ AdmissionLimitExceeded: () => ScheduledInputRetryable.make({ reason: "capacity" }),
43
+ ThreadClientError: (error: ThreadClientError) =>
44
+ ScheduledInputRetryable.make({
45
+ reason: error.overloaded === true ? "capacity" : "transport",
46
+ }),
47
+ HostProtocolError: () => ScheduledInputRetryable.make({ reason: "ambiguous" }),
48
+ LedgerError: () => ScheduledInputRetryable.make({ reason: "storage" }),
49
+ ThreadStoreError: () => ScheduledInputRetryable.make({ reason: "storage" }),
50
+ DurableAlarmError: () => ScheduledInputRetryable.make({ reason: "storage" }),
51
+ AgentInputError: () =>
52
+ ScheduleStorageError.make({ operation: "prepared admission", reason: "corrupt" }),
53
+ DigestError: () =>
54
+ ScheduleStorageError.make({ operation: "prepared admission", reason: "corrupt" }),
55
+ ThreadNotMaterialized: () => ScheduledInputRetryable.make({ reason: "storage" }),
56
+ AppendConflict: () => ScheduledInputRetryable.make({ reason: "ambiguous" }),
57
+ FenceRejected: () => ScheduledInputRetryable.make({ reason: "ambiguous" }),
58
+ DurableRuntimeFailpointError: () =>
59
+ ScheduledInputRetryable.make({ reason: "ambiguous" }),
60
+ }),
61
+ ),
62
+ });
63
+ }),
64
+ );
65
+
66
+ const preparedFromSchedule = (envelope: ScheduledEnvelope): PreparedInput => ({
67
+ schemaVersion: 1,
68
+ threadId: envelope.threadId,
69
+ deliveryPrincipal: envelope.deliveryPrincipal,
70
+ agentId: envelope.agentId,
71
+ definitions: envelope.definitions,
72
+ input: envelope.input,
73
+ inputDigest: envelope.inputDigest,
74
+ admissionKey: envelope.admissionKey,
75
+ authorization: envelope.authorization,
76
+ });
77
+
78
+ /** Compatibility adapter retaining Scheduling's public admission port. */
79
+ export const cloudflareScheduledInputAdmissionLayer: Layer.Layer<
80
+ ScheduledInputAdmission,
81
+ never,
82
+ PreparedInputAdmission
83
+ > = Layer.effect(
84
+ ScheduledInputAdmission,
85
+ Effect.map(PreparedInputAdmission, (admission) =>
86
+ ScheduledInputAdmission.of({
87
+ submit: (envelope) => admission.submit(preparedFromSchedule(envelope)),
88
+ }),
89
+ ),
90
+ );
package/src/scheduling.ts CHANGED
@@ -1,4 +1,9 @@
1
1
  import { AgentId } from "@effect-agent/core";
2
+ import {
3
+ DoScheduleAlarmControl,
4
+ DoScheduleTransaction,
5
+ scheduleStoreLayer,
6
+ } from "@effect-agent/storage-cloudflare";
2
7
  import {
3
8
  DefinitionDigests,
4
9
  PersistedJson,
@@ -20,21 +25,13 @@ import {
20
25
  ScheduleStorageError,
21
26
  ScheduleTimingRequest,
22
27
  ScheduleValidationError,
23
- ScheduledInputAdmission,
24
- ScheduledInputRetryable,
25
- type ScheduledEnvelope,
26
28
  Scheduling,
27
29
  ScheduleDriver,
28
30
  type ScheduleManagementFailure,
29
31
  defaultSchedulingLimits,
30
32
  scheduleOwnerKey,
31
33
  ScheduleWakeNoop,
32
- } from "@effect-agent/session";
33
- import {
34
- DoScheduleAlarmControl,
35
- DoScheduleTransaction,
36
- scheduleStoreLayer,
37
- } from "@effect-agent/storage-cloudflare";
34
+ } from "@effect-agent/thread";
38
35
  import { BrowserCrypto } from "@effect/platform-browser";
39
36
  import { SqliteClient } from "@effect/sql-sqlite-do";
40
37
  import { Clock, Context, DateTime, Effect, Layer, Schema } from "effect";
@@ -45,8 +42,12 @@ import {
45
42
  type WorkerEnvironment,
46
43
  } from "effect-cf";
47
44
 
48
- import type { ConversationObjectNamespace } from "./bindings.ts";
49
- import { CloudflareConversationClient, type ConversationClientError } from "./client.ts";
45
+ import type { ThreadObjectNamespace } from "./bindings.ts";
46
+ import { CloudflareThreadClient } from "./client.ts";
47
+ import {
48
+ cloudflarePreparedInputAdmissionLayer,
49
+ cloudflareScheduledInputAdmissionLayer,
50
+ } from "./prepared-admission.ts";
50
51
 
51
52
  const SCHEDULE_ALARM_TAG = "effect-agent/ScheduleOwnerWake";
52
53
  const SCHEDULE_ALARM_ID = "driver";
@@ -421,48 +422,6 @@ const transactionLayer: Layer.Layer<
421
422
  }),
422
423
  );
423
424
 
424
- const admissionLayer: Layer.Layer<ScheduledInputAdmission, never, CloudflareConversationClient> =
425
- Layer.effect(
426
- ScheduledInputAdmission,
427
- Effect.gen(function* () {
428
- const client = yield* CloudflareConversationClient;
429
- const submit = (envelope: ScheduledEnvelope) =>
430
- client
431
- .submit(passthroughAgent(envelope.agentId), envelope.input, {
432
- conversationId: envelope.conversationId,
433
- principal: envelope.deliveryPrincipal,
434
- idempotencyKey: envelope.admissionKey,
435
- definitions: envelope.definitions,
436
- })
437
- .pipe(
438
- Effect.catchTags({
439
- AdmissionConflict: () =>
440
- ScheduleStorageError.make({ operation: "scheduled admission", reason: "corrupt" }),
441
- AdmissionLimitExceeded: () => ScheduledInputRetryable.make({ reason: "capacity" }),
442
- ConversationClientError: (error: ConversationClientError) =>
443
- ScheduledInputRetryable.make({
444
- reason: error.overloaded === true ? "capacity" : "transport",
445
- }),
446
- HostProtocolError: () => ScheduledInputRetryable.make({ reason: "ambiguous" }),
447
- LedgerError: () => ScheduledInputRetryable.make({ reason: "storage" }),
448
- ConversationStoreError: () => ScheduledInputRetryable.make({ reason: "storage" }),
449
- DurableAlarmError: () => ScheduledInputRetryable.make({ reason: "storage" }),
450
- AgentInputError: () =>
451
- ScheduleStorageError.make({ operation: "scheduled admission", reason: "corrupt" }),
452
- DigestError: () =>
453
- ScheduleStorageError.make({ operation: "scheduled admission", reason: "corrupt" }),
454
- ConversationNotMaterialized: () =>
455
- ScheduledInputRetryable.make({ reason: "storage" }),
456
- AppendConflict: () => ScheduledInputRetryable.make({ reason: "ambiguous" }),
457
- FenceRejected: () => ScheduledInputRetryable.make({ reason: "ambiguous" }),
458
- DurableRuntimeFailpointError: () =>
459
- ScheduledInputRetryable.make({ reason: "ambiguous" }),
460
- }),
461
- );
462
- return ScheduledInputAdmission.of({ submit });
463
- }),
464
- );
465
-
466
425
  type ScheduleRuntimeServices =
467
426
  | Scheduling
468
427
  | ScheduleDriver
@@ -616,7 +575,7 @@ export interface ScheduleOwnerObjectClass {
616
575
  */
617
576
  export const makeScheduleOwnerObjectClass = <E>(
618
577
  host: Layer.Layer<
619
- ScheduleAuthorizer | ConversationObjectNamespace,
578
+ ScheduleAuthorizer | ThreadObjectNamespace,
620
579
  E,
621
580
  EffectCfDurableObjectState.DurableObjectState | WorkerEnvironment | ScheduleOwnerIdentity
622
581
  >,
@@ -638,7 +597,12 @@ export const makeScheduleOwnerObjectClass = <E>(
638
597
  Layer.provideMerge(
639
598
  scheduleStoreLayer.pipe(Layer.provide(transactionLayer), Layer.provide(sqlLayer)),
640
599
  ),
641
- Layer.provide(admissionLayer.pipe(Layer.provide(CloudflareConversationClient.layer))),
600
+ Layer.provide(
601
+ cloudflareScheduledInputAdmissionLayer.pipe(
602
+ Layer.provide(cloudflarePreparedInputAdmissionLayer),
603
+ Layer.provide(CloudflareThreadClient.layer),
604
+ ),
605
+ ),
642
606
  Layer.provide(ScheduleWakeNoop),
643
607
  Layer.provide(BrowserCrypto.layer),
644
608
  Layer.provideMerge(DurableObjectAlarm.DurableObjectAlarm.layer),