@effect-agent/platform-cloudflare 0.1.0-beta.35 → 0.1.0-beta.37
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 +4 -98
- package/dist/index.mjs +8 -817
- package/dist/index.mjs.map +1 -1
- package/dist/interactive-browser.d.mts +27 -5
- package/dist/interactive-browser.mjs +530 -69
- package/dist/interactive-browser.mjs.map +1 -1
- package/dist/scheduling-B-OFqoS9.mjs +1189 -0
- package/dist/scheduling-B-OFqoS9.mjs.map +1 -0
- package/dist/scheduling-BJs_kHTx.d.mts +142 -0
- package/dist/scheduling.d.mts +2 -0
- package/dist/scheduling.mjs +2 -0
- package/package.json +11 -10
- package/src/alarm.ts +19 -2
- package/src/index.ts +1 -0
- package/src/interactive-browser.ts +843 -75
- package/src/layers.ts +1 -1
- package/src/scheduling.ts +676 -0
package/dist/index.mjs
CHANGED
|
@@ -1,532 +1,18 @@
|
|
|
1
|
+
import { $ as CLOUDFLARE_RUNTIME_DEFAULTS, A as decodeHostResponse, B as encodeObservePageRequest, C as SubmitSucceeded, D as decodeApprovalDecisionCommand, E as decodeAbortCommand, F as encodeAbortCommand, G as ConversationMaintenanceFailpoint, H as encodeSubmitRequest, I as encodeApprovalDecisionCommand, J as MaintenancePassReport, K as DurableAlarmError, L as encodeAwaitProgressRequest, M as decodeReceipt, N as decodeSubmitRequest, O as decodeAwaitProgressRequest, P as decodeUnknownResolutionCommand, Q as CLOUDFLARE_DATABASE_CAP_BYTES, R as encodeCancelProgressRequest, S as SubmitRequest, T as boundHostDiagnostic, U as encodeUnknownResolutionCommand, V as encodeReceipt, W as ConversationMaintenance, X as safeCauseMessage, Y as safeCauseDiagnostic, Z as AdmissionLimitExceeded, _ as ObservePageRequest, a as ScheduleOwnerProtocolError, at as CloudflareBindingError, b as ProgressObserved, c as ApprovalRecorded, ct as DurableObjectContext, d as CloudflareConversationClient, et as CloudflareAdmissionLimitsValue, f as ConversationClientError, g as HostResponse, h as HostProtocolError, i as ScheduleOwnerNamespace, it as DEFAULT_MAX_DATABASE_BYTES, j as decodeObservePageRequest, k as decodeCancelProgressRequest, l as AwaitProgressRequest, lt as conversationNamespaceFromEnv, m as HostFailure, n as ScheduleAlarmProtocolError, nt as CloudflareDurableRuntimeConfigValue, o as makeScheduleOwnerObjectClass, ot as ConversationObjectIdentity, p as HostFailed, q as DurableAlarmService, r as ScheduleOwnerIdentity, rt as CloudflarePlatformConfigError, s as AbortRecorded, st as ConversationObjectNamespace, t as CloudflareSchedulingClient, tt as CloudflareDurableRuntimeConfig, u as CancelProgressRequest, ut as conversationNamespaceLayer, v as ObservedPage, w as UnknownResolutionRecorded, x as SettlementReached, y as ProgressCancelled, z as encodeHostResponse } from "./scheduling-B-OFqoS9.mjs";
|
|
1
2
|
import { BrowserQuickActionBrowserBinding, BrowserQuickActionRpcError, BrowserQuickActionWorkersAi, BrowserQuickActionWorkersAiPolicyError, browserQuickActionCaptureLayer, browserQuickActionImplementation, browserQuickActionScreenshotLayer, browserQuickActionWorkersAiCaptureLayer } from "./browser-quick-action.mjs";
|
|
2
3
|
import { browserRestCaptureImplementation, browserRestCaptureLayer, browserRestWorkersAiCaptureLayer } from "./browser-rest-capture.mjs";
|
|
3
|
-
import { BrowserRunHandoffRequest, BrowserRunHandoffResult, BrowserRunHandoffState, BrowserRunInteractiveBinding, BrowserRunInteractiveHost, BrowserRunLiveViewRequest, BrowserRunLiveViewResult, browserRunInteractiveHostLayer, browserRunInteractiveImplementation, browserRunInteractiveLayer } from "./interactive-browser.mjs";
|
|
4
|
+
import { BrowserRunHandoffRequest, BrowserRunHandoffResult, BrowserRunHandoffState, BrowserRunInteractiveBinding, BrowserRunInteractiveHost, BrowserRunLiveViewRequest, BrowserRunLiveViewResult, BrowserRunViewport, browserRunInteractiveHostLayer, browserRunInteractiveImplementation, browserRunInteractiveLayer, isBrowserRunUndispatchedActionError } from "./interactive-browser.mjs";
|
|
4
5
|
import { browserRestCrawlImplementation, browserRestCrawlLayer } from "./browser-rest-crawl.mjs";
|
|
5
|
-
import { Clock, Context,
|
|
6
|
-
import {
|
|
7
|
-
import { ConversationPortTransport,
|
|
8
|
-
import {
|
|
6
|
+
import { Clock, Context, Deferred, Duration, Effect, Exit, Fiber, Layer, Option, PubSub, Queue, Ref, Schema, Stream } from "effect";
|
|
7
|
+
import { AgentBindingResolver, AppendConflict, ConversationNotMaterialized, ConversationRead, ConversationStore, ConversationStoreError, DigestError, DurableAgentRuntime, DurableRuntimeConfig, DurableRuntimeFailpoint, DurableRuntimeFailpointError, FenceRejected, IntegrityReport, LedgerError, ObligationReport, ObligationThresholds, OperationAuthorizationRequest, OperationAuthorizer, OperationDenied, OwnershipLost, PersistedJson, ProducerId, RecoveryExplanation, RecoveryReport, RetryCommand, RetryRefused, RunJournalError, SettlementConflict, SubmissionLedger, SubmissionLookupByKey, ToolReconciler, WakeScheduler, makeWakeSubscriptionHub, operationAuthorizerLayer } from "@effect-agent/session";
|
|
8
|
+
import { ConversationPortTransport, conversationStoreLayer, decodePortRequest, encodePortResponse, executePortRequest, portTransportFailure, routedConversationStoreLayer, routedSubmissionLedgerLayer, storageConfigLayer, storageFailpointLayer, submissionLedgerLayer } from "@effect-agent/storage-cloudflare";
|
|
9
|
+
import { ConversationId, SubmissionId } from "@effect-agent/core";
|
|
9
10
|
import { CurrentToolFailureObserver, RunContextPreparationPassthrough, toolFailureObserverLayer } from "@effect-agent/engine";
|
|
10
11
|
import { BrowserCrypto } from "@effect/platform-browser";
|
|
11
12
|
import { SqliteClient } from "@effect/sql-sqlite-do";
|
|
12
|
-
import { DurableObject, DurableObjectState,
|
|
13
|
+
import { DurableObject, DurableObjectState, WorkerEnvironment } from "effect-cf";
|
|
13
14
|
import { CodeExecutionHost, CodeExecutionProtocolError, CodeExecutionResourceUse, CodeExecutionResult, CodeExecutionTimeoutError, CodeExecutor, CodeExecutorStartError, CodeExecutorTerminatedError, CodeExecutorUnsupportedError, CodeHostCall, CodeHostCallLimitError, CodeHostCallResult, CodeOutputLimitError, CodeProgramFailedError, CodeSourceError, SandboxImplementation } from "@effect-agent/sandbox";
|
|
14
15
|
import { RpcTarget } from "cloudflare:workers";
|
|
15
|
-
//#region src/bindings.ts
|
|
16
|
-
/**
|
|
17
|
-
* Cloudflare platform bindings as Effect services (DEPLOY-010: "Cloudflare platform bindings
|
|
18
|
-
* are supplied as Effect services/Layers"). Application code never reads `env` or touches a
|
|
19
|
-
* `DurableObjectState` directly — the Conversation Object class constructs these Layers once
|
|
20
|
-
* per incarnation and everything downstream consumes the services.
|
|
21
|
-
*/
|
|
22
|
-
/** A Cloudflare platform binding was missing or carried the wrong shape (DEPLOY-003/010). */
|
|
23
|
-
var CloudflareBindingError = class extends Schema.TaggedError()("CloudflareBindingError", {
|
|
24
|
-
binding: Schema.String,
|
|
25
|
-
message: Schema.String
|
|
26
|
-
}) {};
|
|
27
|
-
/**
|
|
28
|
-
* The `DurableObjectNamespace` binding that addresses Conversation Objects. The Object
|
|
29
|
-
* identity rule is `namespace.idFromName(conversationId)` (plan §1.2): Conversation IDs are
|
|
30
|
-
* globally unique, so the mapping is total and deterministic and no directory service exists.
|
|
31
|
-
*/
|
|
32
|
-
var ConversationObjectNamespace = class ConversationObjectNamespace extends Context.Service()("@effect-agent/platform-cloudflare/ConversationObjectNamespace") {
|
|
33
|
-
static layer(namespace) {
|
|
34
|
-
return Layer.succeed(ConversationObjectNamespace)({ namespace });
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
/**
|
|
38
|
-
* Narrow one `env` member to a `DurableObjectNamespace`. `env` is an untyped platform value,
|
|
39
|
-
* and a namespace binding is a host object no Schema can decode, so this is the documented
|
|
40
|
-
* narrowest-boundary check (structural probe for the namespace surface the transport uses);
|
|
41
|
-
* a missing or misshaped binding fails typed before any Layer is built.
|
|
42
|
-
*/
|
|
43
|
-
const conversationNamespaceFromEnv = Effect.fn("conversationNamespaceFromEnv")(function* (env, binding) {
|
|
44
|
-
if (!Predicate.isObjectKeyword(env)) return yield* CloudflareBindingError.make({
|
|
45
|
-
binding,
|
|
46
|
-
message: "The Worker environment is not an object; no bindings are available."
|
|
47
|
-
});
|
|
48
|
-
const candidate = yield* Effect.try({
|
|
49
|
-
try: () => {
|
|
50
|
-
const value = Reflect.get(env, binding);
|
|
51
|
-
if (!Predicate.isObjectKeyword(value)) return void 0;
|
|
52
|
-
const idFromName = Reflect.get(value, "idFromName");
|
|
53
|
-
const get = Reflect.get(value, "get");
|
|
54
|
-
return typeof idFromName === "function" && typeof get === "function" ? value : void 0;
|
|
55
|
-
},
|
|
56
|
-
catch: () => CloudflareBindingError.make({
|
|
57
|
-
binding,
|
|
58
|
-
message: `env.${binding} could not be inspected as a DurableObjectNamespace binding.`
|
|
59
|
-
})
|
|
60
|
-
});
|
|
61
|
-
if (candidate !== void 0) return candidate;
|
|
62
|
-
return yield* CloudflareBindingError.make({
|
|
63
|
-
binding,
|
|
64
|
-
message: `env.${binding} is not a DurableObjectNamespace binding; declare the Conversation Object class under this binding in the Worker configuration.`
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
/**
|
|
68
|
-
* Build the namespace from Worker `env` (fails typed). Enable `rpcTracing` only when the
|
|
69
|
-
* receiver also opts into the effect-cf native RPC trace-context contract.
|
|
70
|
-
*/
|
|
71
|
-
const conversationNamespaceLayer = (env, binding, options = {}) => Layer.effect(ConversationObjectNamespace)(Effect.map(conversationNamespaceFromEnv(env, binding), (namespace) => ({
|
|
72
|
-
namespace,
|
|
73
|
-
...options.rpcTracing === true ? { rpcTracing: binding } : {}
|
|
74
|
-
})));
|
|
75
|
-
/**
|
|
76
|
-
* The live Durable Object execution context of THIS incarnation. Only Layer construction and
|
|
77
|
-
* the alarm service consume it; important state never lives on it (`ctx.storage` is truth,
|
|
78
|
-
* everything in memory is a cache — deployment spec §11).
|
|
79
|
-
*/
|
|
80
|
-
var DurableObjectContext = class DurableObjectContext extends Context.Service()("@effect-agent/platform-cloudflare/DurableObjectContext") {
|
|
81
|
-
static layer(ctx, env) {
|
|
82
|
-
return Layer.succeed(DurableObjectContext)({
|
|
83
|
-
ctx,
|
|
84
|
-
env
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
/**
|
|
89
|
-
* The Conversation identity this Object serializes and the producer identity its Attempts
|
|
90
|
-
* write with (`{producerPrefix}:{conversationId}`, plan §1.4). Derived once per incarnation
|
|
91
|
-
* from `ctx.id.name` — the Object identity rule guarantees the name IS the Conversation ID.
|
|
92
|
-
*/
|
|
93
|
-
var ConversationObjectIdentity = class extends Context.Service()("@effect-agent/platform-cloudflare/ConversationObjectIdentity") {};
|
|
94
|
-
//#endregion
|
|
95
|
-
//#region src/config.ts
|
|
96
|
-
/**
|
|
97
|
-
* Schema-validated configuration for the Cloudflare durable runtime (deployment spec §4:
|
|
98
|
-
* decoded once during Layer construction, exposed as a typed service; DEPLOY-003). Every
|
|
99
|
-
* cadence is in milliseconds; every bound is finite and checked before any resource opens.
|
|
100
|
-
*/
|
|
101
|
-
const PositiveMillis = Schema.Int.check(Schema.isGreaterThan(0));
|
|
102
|
-
const NonNegativeMillis = Schema.Int.check(Schema.isGreaterThanOrEqualTo(0));
|
|
103
|
-
/** The supplied Cloudflare durable runtime configuration failed validation (DEPLOY-003). */
|
|
104
|
-
var CloudflarePlatformConfigError = class extends Schema.TaggedError()("CloudflarePlatformConfigError", {
|
|
105
|
-
message: Schema.String,
|
|
106
|
-
cause: Schema.optionalKey(Schema.Defect())
|
|
107
|
-
}) {};
|
|
108
|
-
/**
|
|
109
|
-
* An admission was refused by a host resource limit BEFORE any ledger row existed
|
|
110
|
-
* (deployment spec §8, DEPLOY-007: "Admission has explicit bounded quota and overload
|
|
111
|
-
* behavior... a typed rejection"). This is the DC analogue of `NodeDurableHost`'s
|
|
112
|
-
* `AdmissionClosed` host gate: the port surface stays untouched, the refusal happens in the
|
|
113
|
-
* Conversation Object's submit entry point before `DurableAgentRuntime.submit` runs, and
|
|
114
|
-
* nothing was admitted or written.
|
|
115
|
-
*/
|
|
116
|
-
var AdmissionLimitExceeded = class extends Schema.TaggedError()("AdmissionLimitExceeded", {
|
|
117
|
-
limit: Schema.Literals([
|
|
118
|
-
"queue-depth",
|
|
119
|
-
"input-bytes",
|
|
120
|
-
"database-bytes"
|
|
121
|
-
]),
|
|
122
|
-
actual: Schema.Int,
|
|
123
|
-
maximum: Schema.Int
|
|
124
|
-
}) {
|
|
125
|
-
get message() {
|
|
126
|
-
return `Admission refused before any ledger row existed: ${this.limit} ${this.actual} exceeds the configured maximum ${this.maximum}. Accepted work is unaffected; retry after the lane drains or raise the limit (DEPLOY-007).`;
|
|
127
|
-
}
|
|
128
|
-
};
|
|
129
|
-
/** The platform's hard per-Object database cap (10 GB, developers.cloudflare.com limits). */
|
|
130
|
-
const CLOUDFLARE_DATABASE_CAP_BYTES = 1e10;
|
|
131
|
-
/** Default database-size admission ceiling: a 1 GB safety margin under the platform cap. */
|
|
132
|
-
const DEFAULT_MAX_DATABASE_BYTES = 9e9;
|
|
133
|
-
/**
|
|
134
|
-
* Explicit bounded admission quotas checked by the Conversation Object BEFORE admission
|
|
135
|
-
* (exit gate "resource limits are checked before admission").
|
|
136
|
-
*/
|
|
137
|
-
var CloudflareAdmissionLimitsValue = class extends Schema.Class("@effect-agent/platform-cloudflare/CloudflareAdmissionLimitsValue")({
|
|
138
|
-
/** Maximum nonterminal Submissions per Conversation lane before new admissions refuse. */
|
|
139
|
-
maxQueueDepthPerLane: Schema.Int.check(Schema.isGreaterThan(0), Schema.isLessThanOrEqualTo(1e5)),
|
|
140
|
-
/** Maximum encoded input bytes; never above the storage per-value bound. */
|
|
141
|
-
maxInputBytes: Schema.Int.check(Schema.isGreaterThan(0), Schema.isLessThanOrEqualTo(2e6)),
|
|
142
|
-
/** Maximum `ctx.storage.sql.databaseSize` at admission; stays under the 10 GB platform cap. */
|
|
143
|
-
maxDatabaseBytes: Schema.Int.check(Schema.isGreaterThan(0), Schema.isLessThanOrEqualTo(CLOUDFLARE_DATABASE_CAP_BYTES))
|
|
144
|
-
}) {};
|
|
145
|
-
/**
|
|
146
|
-
* Validated Cloudflare durable runtime configuration. The producer identity of one
|
|
147
|
-
* Conversation Object is `{producerPrefix}:{conversationId}` — stable across incarnations of
|
|
148
|
-
* the same deployment, distinct across deployments — and producer-epoch fencing (not the
|
|
149
|
-
* producer name) remains the correctness authority (DUR-006).
|
|
150
|
-
*/
|
|
151
|
-
var CloudflareDurableRuntimeConfigValue = class extends Schema.Class("@effect-agent/platform-cloudflare/CloudflareDurableRuntimeConfigValue")({
|
|
152
|
-
deploymentId: DeploymentId,
|
|
153
|
-
/** Head of the minted producer identity `{producerPrefix}:{conversationId}`. */
|
|
154
|
-
producerPrefix: Schema.NonEmptyString.check(Schema.isMaxLength(256)),
|
|
155
|
-
/** Submission ownership lease duration (D5); fences work across Object incarnations. */
|
|
156
|
-
ownershipLeaseDuration: PositiveMillis,
|
|
157
|
-
/** Base delay of the alarm re-arm backoff when a pass makes no progress. */
|
|
158
|
-
alarmBackoffBase: PositiveMillis,
|
|
159
|
-
/** Ceiling of the alarm re-arm backoff. */
|
|
160
|
-
alarmBackoffCap: PositiveMillis,
|
|
161
|
-
/**
|
|
162
|
-
* The maintenance-pass scan cadence and the ceiling of every re-arm delay: nonterminal
|
|
163
|
-
* work is revisited at least this often (wake/scan pairing, persistence §14).
|
|
164
|
-
*/
|
|
165
|
-
wakeScanInterval: PositiveMillis,
|
|
166
|
-
/** `awaitSettlement` ledger re-check cadence when no wake arrives. */
|
|
167
|
-
settlementPollInterval: PositiveMillis,
|
|
168
|
-
/** Worker ownership-lease renewal cadence during an active Attempt. */
|
|
169
|
-
leaseRenewalInterval: PositiveMillis,
|
|
170
|
-
/** Active-Run abort-intent poll cadence. */
|
|
171
|
-
abortPollInterval: PositiveMillis,
|
|
172
|
-
/** Canonical observation poll cadence of the Durable Object store. */
|
|
173
|
-
observationPollInterval: NonNegativeMillis,
|
|
174
|
-
/** Per-value byte bound; must stay under the platform's 2 MB SQLite value limit. */
|
|
175
|
-
maxStoredValueBytes: Schema.Int.check(Schema.isGreaterThan(0), Schema.isLessThanOrEqualTo(2e6)),
|
|
176
|
-
/** Opt-in full payload/digest-chain audit while opening the store. */
|
|
177
|
-
verifyOnOpen: Schema.Boolean,
|
|
178
|
-
limits: CloudflareAdmissionLimitsValue
|
|
179
|
-
}) {};
|
|
180
|
-
/** Explicit configuration authority for the assembled Cloudflare durable runtime. */
|
|
181
|
-
var CloudflareDurableRuntimeConfig = class extends Context.Service()("@effect-agent/platform-cloudflare/CloudflareDurableRuntimeConfig") {};
|
|
182
|
-
/** Documented production defaults applied by `CloudflareDurableRuntime.layer`. */
|
|
183
|
-
const CLOUDFLARE_RUNTIME_DEFAULTS = {
|
|
184
|
-
ownershipLeaseDuration: Duration.toMillis(DEFAULT_OWNERSHIP_LEASE_DURATION),
|
|
185
|
-
alarmBackoffBase: 100,
|
|
186
|
-
alarmBackoffCap: 5e3,
|
|
187
|
-
wakeScanInterval: 1e3,
|
|
188
|
-
settlementPollInterval: 500,
|
|
189
|
-
leaseRenewalInterval: 1e4,
|
|
190
|
-
abortPollInterval: 500,
|
|
191
|
-
observationPollInterval: 25,
|
|
192
|
-
maxStoredValueBytes: DEFAULT_MAX_STORED_VALUE_BYTES,
|
|
193
|
-
verifyOnOpen: false,
|
|
194
|
-
maxQueueDepthPerLane: 256,
|
|
195
|
-
maxInputBytes: DEFAULT_MAX_STORED_VALUE_BYTES,
|
|
196
|
-
maxDatabaseBytes: DEFAULT_MAX_DATABASE_BYTES
|
|
197
|
-
};
|
|
198
|
-
//#endregion
|
|
199
|
-
//#region src/boundary.ts
|
|
200
|
-
const MAX_FOREIGN_DIAGNOSTIC_LENGTH = 8192;
|
|
201
|
-
const boundForeignDiagnostic = (message) => message.slice(0, MAX_FOREIGN_DIAGNOSTIC_LENGTH);
|
|
202
|
-
/** Render a foreign failure without trusting accessors or coercion hooks on the value. */
|
|
203
|
-
const safeCauseMessage = (cause, fallback) => {
|
|
204
|
-
try {
|
|
205
|
-
const message = cause instanceof Error ? cause.message : cause;
|
|
206
|
-
return boundForeignDiagnostic(typeof message === "string" ? message : String(message));
|
|
207
|
-
} catch {
|
|
208
|
-
return boundForeignDiagnostic(fallback);
|
|
209
|
-
}
|
|
210
|
-
};
|
|
211
|
-
/** Include an Error name when worker-failure classification needs it. */
|
|
212
|
-
const safeCauseDiagnostic = (cause, fallback) => {
|
|
213
|
-
try {
|
|
214
|
-
return cause instanceof Error ? boundForeignDiagnostic(`${cause.name}: ${cause.message}`) : safeCauseMessage(cause, fallback);
|
|
215
|
-
} catch {
|
|
216
|
-
return boundForeignDiagnostic(fallback);
|
|
217
|
-
}
|
|
218
|
-
};
|
|
219
|
-
/** Read Cloudflare RPC classifications without letting a hostile proxy defect the client. */
|
|
220
|
-
const cloudflareFailureSignals = (cause) => {
|
|
221
|
-
if (!Predicate.isObjectKeyword(cause)) return {};
|
|
222
|
-
try {
|
|
223
|
-
const retryableValue = Reflect.get(cause, "retryable");
|
|
224
|
-
const overloadedValue = Reflect.get(cause, "overloaded");
|
|
225
|
-
const resetValue = Reflect.get(cause, "durableObjectReset");
|
|
226
|
-
const retryable = typeof retryableValue === "boolean" ? retryableValue : resetValue === true ? true : void 0;
|
|
227
|
-
const overloaded = typeof overloadedValue === "boolean" ? overloadedValue : void 0;
|
|
228
|
-
return {
|
|
229
|
-
...retryable === void 0 ? {} : { retryable },
|
|
230
|
-
...overloaded === void 0 ? {} : { overloaded }
|
|
231
|
-
};
|
|
232
|
-
} catch {
|
|
233
|
-
return {};
|
|
234
|
-
}
|
|
235
|
-
};
|
|
236
|
-
//#endregion
|
|
237
|
-
//#region src/alarm.ts
|
|
238
|
-
/**
|
|
239
|
-
* The single multiplexed Durable Object alarm (decision D-P6-2). A Durable Object has ONE
|
|
240
|
-
* alarm slot; every cadence the Node host ran on fibers (wake scan, lease expiry, settlement
|
|
241
|
-
* and abort re-checks, retry backoff) multiplexes into one idempotent maintenance pass, and
|
|
242
|
-
* the slot always holds the EARLIEST deadline any caller asked for.
|
|
243
|
-
*
|
|
244
|
-
* The alarm invariant (plan §1.4): every committed actionable mutation carries a newer durable
|
|
245
|
-
* maintenance generation and a committed alarm. Stable externally-driven waits may be
|
|
246
|
-
* nonterminal without retaining an alarm; their resolving mutation advances the generation and
|
|
247
|
-
* restores the alarm atomically.
|
|
248
|
-
*/
|
|
249
|
-
/** The Durable Object alarm API failed; surfaces on host entry points as a typed refusal. */
|
|
250
|
-
var DurableAlarmError = class extends Schema.TaggedError()("DurableAlarmError", {
|
|
251
|
-
operation: Schema.String,
|
|
252
|
-
message: Schema.String,
|
|
253
|
-
cause: Schema.optionalKey(Schema.Defect())
|
|
254
|
-
}) {};
|
|
255
|
-
const alarmFailure = (operation) => (cause) => DurableAlarmError.make({
|
|
256
|
-
operation,
|
|
257
|
-
message: safeCauseMessage(cause, "The Cloudflare alarm API failed without a diagnostic"),
|
|
258
|
-
cause
|
|
259
|
-
});
|
|
260
|
-
/** `ctx.storage` alarm slot as an Effect service; storage is truth, never a memory field. */
|
|
261
|
-
var DurableAlarmService = class DurableAlarmService extends Context.Service()("@effect-agent/platform-cloudflare/DurableAlarmService") {
|
|
262
|
-
static layer = Layer.effect(DurableAlarmService)(Effect.gen(function* () {
|
|
263
|
-
const { ctx } = yield* DurableObjectContext;
|
|
264
|
-
/**
|
|
265
|
-
* In-memory pass bookkeeping — a pure CACHE, never state: a fresh incarnation has no
|
|
266
|
-
* running pass, and a deferred wake lost to eviction was only ever a promptness hint
|
|
267
|
-
* on top of the already-committed pre-armed alarm.
|
|
268
|
-
*/
|
|
269
|
-
const runningPasses = yield* Ref.make(0);
|
|
270
|
-
const scheduled = Effect.tryPromise({
|
|
271
|
-
try: () => ctx.storage.getAlarm(),
|
|
272
|
-
catch: alarmFailure("get alarm")
|
|
273
|
-
}).pipe(Effect.map((deadline) => deadline === null ? Option.none() : Option.some(deadline)));
|
|
274
|
-
const scheduleAt = (epochMillis) => Effect.tryPromise({
|
|
275
|
-
try: () => ctx.storage.setAlarm(epochMillis),
|
|
276
|
-
catch: alarmFailure("set alarm")
|
|
277
|
-
});
|
|
278
|
-
const ensureScheduledBy = (epochMillis) => scheduled.pipe(Effect.flatMap((existing) => Option.isSome(existing) && existing.value <= epochMillis ? Effect.void : scheduleAt(epochMillis)));
|
|
279
|
-
const armNow = Clock.currentTimeMillis.pipe(Effect.flatMap((now) => ensureScheduledBy(now)));
|
|
280
|
-
const scheduleNow = Ref.get(runningPasses).pipe(Effect.flatMap((passes) => passes > 0 ? Effect.void : armNow));
|
|
281
|
-
const withWakesDeferred = (body) => Ref.update(runningPasses, (passes) => passes + 1).pipe(Effect.andThen(body), Effect.ensuring(Ref.update(runningPasses, (passes) => passes - 1)));
|
|
282
|
-
const cancel = Effect.tryPromise({
|
|
283
|
-
try: () => ctx.storage.deleteAlarm(),
|
|
284
|
-
catch: alarmFailure("delete alarm")
|
|
285
|
-
});
|
|
286
|
-
return DurableAlarmService.of({
|
|
287
|
-
scheduled,
|
|
288
|
-
scheduleAt,
|
|
289
|
-
ensureScheduledBy,
|
|
290
|
-
scheduleNow,
|
|
291
|
-
withWakesDeferred,
|
|
292
|
-
cancel
|
|
293
|
-
});
|
|
294
|
-
}));
|
|
295
|
-
};
|
|
296
|
-
/** What one maintenance pass did — auditable evidence mirroring `NodeDurableHost`'s report. */
|
|
297
|
-
var MaintenancePassReport = class extends Schema.Class("@effect-agent/platform-cloudflare/MaintenancePassReport")({
|
|
298
|
-
/** `caught-up` is generation-only; `actionable` ran recovery and one bounded drain. */
|
|
299
|
-
phase: Schema.Literals(["caught-up", "actionable"]),
|
|
300
|
-
/** Recovery decisions executed (or deferred) BEFORE any new claim in this pass. */
|
|
301
|
-
recovered: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
|
|
302
|
-
/** Settlements the drain pass finalized. */
|
|
303
|
-
settled: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
|
|
304
|
-
/** Submissions still nonterminal after the pass (suspended/unknown lanes stay honest). */
|
|
305
|
-
nonterminal: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
|
|
306
|
-
/** `rearmed` for dirty/autonomous work, `cleared` for stable waits or settlement. */
|
|
307
|
-
alarm: Schema.Literals(["rearmed", "cleared"])
|
|
308
|
-
}) {};
|
|
309
|
-
/** Test-only fault authority; production uses the inert layer. */
|
|
310
|
-
var ConversationMaintenanceFailpoint = class extends Context.Service()("@effect-agent/platform-cloudflare/ConversationMaintenanceFailpoint") {
|
|
311
|
-
static layer = Layer.succeed(this)({ hit: () => Effect.void });
|
|
312
|
-
};
|
|
313
|
-
const MaintenanceGeneration = Schema.BigIntFromString.check(Schema.isGreaterThanOrEqualToBigInt(0n));
|
|
314
|
-
/** Versioned, platform-private maintenance state stored through Durable Object KV. */
|
|
315
|
-
var ConversationMaintenanceState = class extends Schema.Class("@effect-agent/platform-cloudflare/ConversationMaintenanceState")({
|
|
316
|
-
schemaVersion: Schema.Literal(1),
|
|
317
|
-
dirty: MaintenanceGeneration,
|
|
318
|
-
processed: MaintenanceGeneration,
|
|
319
|
-
nonterminal: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0))
|
|
320
|
-
}) {};
|
|
321
|
-
const MAINTENANCE_STATE_KEY = "effect-agent:conversation-maintenance:v1";
|
|
322
|
-
const decodeMaintenanceState = Schema.decodeUnknownSync(ConversationMaintenanceState);
|
|
323
|
-
const encodeMaintenanceState = Schema.encodeSync(ConversationMaintenanceState);
|
|
324
|
-
const initialMaintenanceState = () => ConversationMaintenanceState.make({
|
|
325
|
-
schemaVersion: 1,
|
|
326
|
-
dirty: 1n,
|
|
327
|
-
processed: 0n,
|
|
328
|
-
nonterminal: 0
|
|
329
|
-
});
|
|
330
|
-
const readMaintenanceState = async (transaction) => {
|
|
331
|
-
const encoded = await transaction.get(MAINTENANCE_STATE_KEY);
|
|
332
|
-
return encoded === void 0 ? {
|
|
333
|
-
state: initialMaintenanceState(),
|
|
334
|
-
initialized: false
|
|
335
|
-
} : {
|
|
336
|
-
state: decodeMaintenanceState(encoded),
|
|
337
|
-
initialized: true
|
|
338
|
-
};
|
|
339
|
-
};
|
|
340
|
-
const ensureTransactionAlarmBy = async (transaction, deadline) => {
|
|
341
|
-
const scheduled = await transaction.getAlarm();
|
|
342
|
-
if (scheduled === null || scheduled > deadline) await transaction.setAlarm(deadline);
|
|
343
|
-
};
|
|
344
|
-
const stableExternalWait = (snapshot, reports) => {
|
|
345
|
-
switch (snapshot.state) {
|
|
346
|
-
case "suspended":
|
|
347
|
-
case "unknown":
|
|
348
|
-
case "joined": return true;
|
|
349
|
-
case "admitted": return reports.get(snapshot.submissionId)?.decision._tag === "AwaitParentEstablishment";
|
|
350
|
-
case "input-applied":
|
|
351
|
-
case "joining":
|
|
352
|
-
case "ready":
|
|
353
|
-
case "running":
|
|
354
|
-
case "settled":
|
|
355
|
-
case "terminalizing": return false;
|
|
356
|
-
}
|
|
357
|
-
};
|
|
358
|
-
/**
|
|
359
|
-
* Incremental, quiescent maintenance over a durable dirty/processed generation (issue #93).
|
|
360
|
-
*
|
|
361
|
-
* `pass` = generation snapshot/pre-arm → recovery → bounded drain → generation acknowledgement:
|
|
362
|
-
*
|
|
363
|
-
* 1. One storage transaction reads dirty/processed and re-arms before work. A caught-up forced
|
|
364
|
-
* alarm takes an O(1) path without recovery, ledger scans, or canonical-history reads.
|
|
365
|
-
* 2. Recovery still strictly precedes a new claim, and one bounded drain advances the lane.
|
|
366
|
-
* 3. The final transaction acknowledges only the generation observed at pass start. A racing
|
|
367
|
-
* mutation therefore remains `dirty > processed` and retains its atomically-established alarm.
|
|
368
|
-
* 4. Stable external waits acknowledge and clear. Autonomous retry, indeterminate, and lease
|
|
369
|
-
* recovery states leave their generation dirty and retain bounded backoff rearming.
|
|
370
|
-
*/
|
|
371
|
-
var ConversationMaintenance = class ConversationMaintenance extends Context.Service()("@effect-agent/platform-cloudflare/ConversationMaintenance") {
|
|
372
|
-
static layer = Layer.effect(ConversationMaintenance)(Effect.gen(function* () {
|
|
373
|
-
const runtime = yield* DurableAgentRuntime;
|
|
374
|
-
const resolver = yield* AgentBindingResolver;
|
|
375
|
-
const ledger = yield* SubmissionLedger;
|
|
376
|
-
const alarm = yield* DurableAlarmService;
|
|
377
|
-
const config = yield* CloudflareDurableRuntimeConfig;
|
|
378
|
-
const identity = yield* ConversationObjectIdentity;
|
|
379
|
-
const { ctx } = yield* DurableObjectContext;
|
|
380
|
-
const failpoint = yield* ConversationMaintenanceFailpoint;
|
|
381
|
-
/**
|
|
382
|
-
* Consecutive no-progress passes — an in-memory CACHE, not state: a fresh incarnation
|
|
383
|
-
* restarts at zero and merely re-arms sooner than a long-lived one would have.
|
|
384
|
-
*/
|
|
385
|
-
const stalls = yield* Ref.make(0);
|
|
386
|
-
/**
|
|
387
|
-
* Incarnation-local mutation count guarded with the generation transactions below. It is
|
|
388
|
-
* deliberately not durable: after eviction every begun mutation has stopped, while its
|
|
389
|
-
* pre-armed dirty generation remains durable for recovery. The short gate never spans the
|
|
390
|
-
* caller's mutation or cross-Object I/O.
|
|
391
|
-
*/
|
|
392
|
-
const activeMutations = yield* Ref.make(0);
|
|
393
|
-
const generationGate = yield* Semaphore.make(1);
|
|
394
|
-
const maintenancePassGate = yield* Semaphore.make(1);
|
|
395
|
-
const minimumAlarmDelay = Math.max(1, Math.ceil(config.alarmBackoffBase / 2));
|
|
396
|
-
const runTransaction = (operation, transaction) => Effect.tryPromise({
|
|
397
|
-
try: transaction,
|
|
398
|
-
catch: alarmFailure(operation)
|
|
399
|
-
});
|
|
400
|
-
const beginMutation = Effect.fn("ConversationMaintenance.beginMutation")(function* () {
|
|
401
|
-
yield* failpoint.hit("maintenance:dirty:before");
|
|
402
|
-
const now = yield* Clock.currentTimeMillis;
|
|
403
|
-
yield* runTransaction("advance maintenance generation", () => ctx.storage.transaction(async (transaction) => {
|
|
404
|
-
const { state } = await readMaintenanceState(transaction);
|
|
405
|
-
const next = ConversationMaintenanceState.make({
|
|
406
|
-
...state,
|
|
407
|
-
dirty: state.dirty + 1n
|
|
408
|
-
});
|
|
409
|
-
await transaction.put(MAINTENANCE_STATE_KEY, encodeMaintenanceState(next));
|
|
410
|
-
await ensureTransactionAlarmBy(transaction, now + minimumAlarmDelay);
|
|
411
|
-
}));
|
|
412
|
-
yield* failpoint.hit("maintenance:dirty:after");
|
|
413
|
-
yield* Ref.update(activeMutations, (active) => active + 1);
|
|
414
|
-
});
|
|
415
|
-
const endMutation = generationGate.withPermit(Ref.update(activeMutations, (active) => Math.max(0, active - 1)));
|
|
416
|
-
const withMutation = (body) => Effect.acquireUseRelease(generationGate.withPermit(beginMutation()), () => failpoint.hit("maintenance:mutation:armed").pipe(Effect.andThen(body), Effect.tap(() => failpoint.hit("maintenance:mutation:finished"))), () => endMutation);
|
|
417
|
-
const ensureAlarm = Effect.fn("ConversationMaintenance.ensureAlarm")(function* () {
|
|
418
|
-
yield* failpoint.hit("maintenance:ensure:before");
|
|
419
|
-
const now = yield* Clock.currentTimeMillis;
|
|
420
|
-
yield* runTransaction("ensure maintenance alarm", () => ctx.storage.transaction(async (transaction) => {
|
|
421
|
-
const { state, initialized } = await readMaintenanceState(transaction);
|
|
422
|
-
if (!initialized) await transaction.put(MAINTENANCE_STATE_KEY, encodeMaintenanceState(state));
|
|
423
|
-
if (state.dirty > state.processed) await ensureTransactionAlarmBy(transaction, now + config.wakeScanInterval);
|
|
424
|
-
}));
|
|
425
|
-
yield* failpoint.hit("maintenance:ensure:after");
|
|
426
|
-
});
|
|
427
|
-
const beginPass = Effect.fn("ConversationMaintenance.beginPass")(function* () {
|
|
428
|
-
yield* failpoint.hit("maintenance:begin:before");
|
|
429
|
-
const now = yield* Clock.currentTimeMillis;
|
|
430
|
-
const result = yield* runTransaction("begin maintenance pass", () => ctx.storage.transaction(async (transaction) => {
|
|
431
|
-
const { state, initialized } = await readMaintenanceState(transaction);
|
|
432
|
-
if (!initialized) await transaction.put(MAINTENANCE_STATE_KEY, encodeMaintenanceState(state));
|
|
433
|
-
if (state.processed >= state.dirty) {
|
|
434
|
-
await transaction.deleteAlarm();
|
|
435
|
-
return {
|
|
436
|
-
_tag: "CaughtUp",
|
|
437
|
-
nonterminal: state.nonterminal
|
|
438
|
-
};
|
|
439
|
-
}
|
|
440
|
-
await ensureTransactionAlarmBy(transaction, now + minimumAlarmDelay);
|
|
441
|
-
return {
|
|
442
|
-
_tag: "Actionable",
|
|
443
|
-
generation: state.dirty
|
|
444
|
-
};
|
|
445
|
-
}));
|
|
446
|
-
yield* failpoint.hit("maintenance:begin:after");
|
|
447
|
-
return result;
|
|
448
|
-
});
|
|
449
|
-
const rearmDelay = Effect.fn("ConversationMaintenance.rearmDelay")(function* (progressed) {
|
|
450
|
-
const priorStalls = yield* Ref.getAndUpdate(stalls, (count) => progressed ? 0 : count + 1);
|
|
451
|
-
if (progressed) return config.alarmBackoffBase;
|
|
452
|
-
const exponent = Math.min(priorStalls, 30);
|
|
453
|
-
const backoff = Math.min(config.alarmBackoffCap, config.alarmBackoffBase * 2 ** exponent);
|
|
454
|
-
const jitter = yield* Random.next;
|
|
455
|
-
const jittered = Math.ceil(backoff / 2 + backoff / 2 * jitter);
|
|
456
|
-
return Math.min(jittered, config.wakeScanInterval);
|
|
457
|
-
});
|
|
458
|
-
const pass = Effect.fn("ConversationMaintenance.pass")(function* () {
|
|
459
|
-
const annotate = (report) => Effect.annotateCurrentSpan({
|
|
460
|
-
phase: report.phase,
|
|
461
|
-
recovered: report.recovered,
|
|
462
|
-
settled: report.settled,
|
|
463
|
-
nonterminal: report.nonterminal,
|
|
464
|
-
alarm: report.alarm
|
|
465
|
-
}).pipe(Effect.as(report));
|
|
466
|
-
const started = yield* generationGate.withPermit(Effect.gen(function* () {
|
|
467
|
-
const activeAtStart = yield* Ref.get(activeMutations);
|
|
468
|
-
return {
|
|
469
|
-
...yield* beginPass(),
|
|
470
|
-
activeAtStart
|
|
471
|
-
};
|
|
472
|
-
}));
|
|
473
|
-
if (started._tag === "CaughtUp") return yield* annotate(MaintenancePassReport.make({
|
|
474
|
-
phase: "caught-up",
|
|
475
|
-
recovered: 0,
|
|
476
|
-
settled: 0,
|
|
477
|
-
nonterminal: started.nonterminal,
|
|
478
|
-
alarm: "cleared"
|
|
479
|
-
}));
|
|
480
|
-
const recovered = yield* runtime.runRecovery;
|
|
481
|
-
const settlements = yield* runtime.processConversationResolved(identity.conversationId).pipe(Effect.provideService(AgentBindingResolver, resolver));
|
|
482
|
-
const remaining = yield* Stream.runCollect(ledger.scanNonterminal);
|
|
483
|
-
const reports = new Map(recovered.map((report) => [report.submissionId, report]));
|
|
484
|
-
const autonomous = remaining.some((snapshot) => !stableExternalWait(snapshot, reports));
|
|
485
|
-
const progressed = settlements.length > 0 || recovered.some((report) => report.disposition === "repaired");
|
|
486
|
-
const delay = autonomous ? yield* rearmDelay(progressed) : 0;
|
|
487
|
-
const now = yield* Clock.currentTimeMillis;
|
|
488
|
-
yield* failpoint.hit("maintenance:finish:before");
|
|
489
|
-
const alarmDisposition = yield* generationGate.withPermit(Effect.gen(function* () {
|
|
490
|
-
const active = yield* Ref.get(activeMutations);
|
|
491
|
-
return yield* runTransaction("finish maintenance pass", () => ctx.storage.transaction(async (transaction) => {
|
|
492
|
-
const { state } = await readMaintenanceState(transaction);
|
|
493
|
-
const processed = autonomous || started.activeAtStart > 0 || active > 0 ? state.processed : state.processed > started.generation ? state.processed : started.generation;
|
|
494
|
-
const next = ConversationMaintenanceState.make({
|
|
495
|
-
...state,
|
|
496
|
-
processed,
|
|
497
|
-
nonterminal: remaining.length
|
|
498
|
-
});
|
|
499
|
-
await transaction.put(MAINTENANCE_STATE_KEY, encodeMaintenanceState(next));
|
|
500
|
-
if (autonomous) {
|
|
501
|
-
await transaction.setAlarm(now + delay);
|
|
502
|
-
return "rearmed";
|
|
503
|
-
}
|
|
504
|
-
if (started.activeAtStart > 0 || active > 0 || next.dirty > next.processed) {
|
|
505
|
-
await ensureTransactionAlarmBy(transaction, now + config.wakeScanInterval);
|
|
506
|
-
return "rearmed";
|
|
507
|
-
}
|
|
508
|
-
await transaction.deleteAlarm();
|
|
509
|
-
return "cleared";
|
|
510
|
-
}));
|
|
511
|
-
}));
|
|
512
|
-
yield* failpoint.hit("maintenance:finish:after");
|
|
513
|
-
if (alarmDisposition === "cleared") yield* Ref.set(stalls, 0);
|
|
514
|
-
return yield* annotate(MaintenancePassReport.make({
|
|
515
|
-
phase: "actionable",
|
|
516
|
-
recovered: recovered.length,
|
|
517
|
-
settled: settlements.length,
|
|
518
|
-
nonterminal: remaining.length,
|
|
519
|
-
alarm: alarmDisposition
|
|
520
|
-
}));
|
|
521
|
-
});
|
|
522
|
-
return ConversationMaintenance.of({
|
|
523
|
-
pass: alarm.withWakesDeferred(maintenancePassGate.withPermit(pass())),
|
|
524
|
-
ensureAlarm: ensureAlarm(),
|
|
525
|
-
withMutation
|
|
526
|
-
});
|
|
527
|
-
}));
|
|
528
|
-
};
|
|
529
|
-
//#endregion
|
|
530
16
|
//#region src/wake-scheduler.ts
|
|
531
17
|
/**
|
|
532
18
|
* Bounded in-memory wake buffer for same-incarnation `awaitSettlement` subscribers. Wake
|
|
@@ -791,301 +277,6 @@ var CloudflareDurableRuntime = class {
|
|
|
791
277
|
}
|
|
792
278
|
};
|
|
793
279
|
//#endregion
|
|
794
|
-
//#region src/client.ts
|
|
795
|
-
/**
|
|
796
|
-
* The Worker↔Conversation-Object host protocol (plan §1.4): Schema envelopes for the host
|
|
797
|
-
* entry points (`submitEncoded`, `awaitSettlementEncoded`, `observePage`, `abortEncoded`,
|
|
798
|
-
* `resolveApprovalEncoded`, `resolveUnknownEncoded`) plus the Worker-side client that speaks
|
|
799
|
-
* it. Mirrors the WP2 port protocol: requests and responses are closed Schema unions, typed
|
|
800
|
-
* failures travel as their own tagged classes and RE-DECODE to identical tags on the caller
|
|
801
|
-
* (error-tag fidelity), and protocol anomalies are answered typed instead of thrown.
|
|
802
|
-
*/
|
|
803
|
-
/** Ceiling for host protocol diagnostic strings. */
|
|
804
|
-
const MAX_HOST_DIAGNOSTIC_LENGTH = 4096;
|
|
805
|
-
const BoundedDiagnostic = Schema.String.check(Schema.isMaxLength(MAX_HOST_DIAGNOSTIC_LENGTH));
|
|
806
|
-
/** Truncate a diagnostic string to the host protocol's bounded length. */
|
|
807
|
-
const boundHostDiagnostic = (value) => value.length > MAX_HOST_DIAGNOSTIC_LENGTH ? `${value.slice(0, MAX_HOST_DIAGNOSTIC_LENGTH - 3)}...` : value;
|
|
808
|
-
/**
|
|
809
|
-
* The envelope itself could not be honored: the Object could not decode the request, or a
|
|
810
|
-
* response could not be encoded/decoded. Never carries operation semantics.
|
|
811
|
-
*/
|
|
812
|
-
var HostProtocolError = class extends Schema.TaggedError()("HostProtocolError", { message: BoundedDiagnostic }) {};
|
|
813
|
-
/** The Worker-side stub call itself failed (RPC rejection, overload, eviction mid-call). */
|
|
814
|
-
var ConversationClientError = class extends Schema.TaggedError()("ConversationClientError", {
|
|
815
|
-
conversationId: Schema.String,
|
|
816
|
-
message: Schema.String,
|
|
817
|
-
cause: Schema.optionalKey(Schema.Defect()),
|
|
818
|
-
/** Cloudflare's own classification for a failure safe to retry with a fresh stub. */
|
|
819
|
-
retryable: Schema.optionalKey(Schema.Boolean),
|
|
820
|
-
/** Cloudflare overloads are surfaced immediately instead of adding retry pressure. */
|
|
821
|
-
overloaded: Schema.optionalKey(Schema.Boolean)
|
|
822
|
-
}) {};
|
|
823
|
-
/**
|
|
824
|
-
* One durable submission, input ALREADY encoded by the caller through the Agent Binding's
|
|
825
|
-
* input schema (the Worker bundles the same Agent definitions as the Object, so schema
|
|
826
|
-
* validation happens client-side; the resolved Binding re-validates at claim time). The
|
|
827
|
-
* Conversation identity is deliberately absent — the addressed Object IS the lane.
|
|
828
|
-
*/
|
|
829
|
-
var SubmitRequest = class extends Schema.Class("@effect-agent/platform-cloudflare/SubmitRequest")({
|
|
830
|
-
agentId: AgentId,
|
|
831
|
-
principal: Principal,
|
|
832
|
-
idempotencyKey: IdempotencyKey,
|
|
833
|
-
definitions: DefinitionDigests,
|
|
834
|
-
inputPayload: PersistedJson
|
|
835
|
-
}) {};
|
|
836
|
-
/** One bounded page of canonical records after an optional sequence. */
|
|
837
|
-
var ObservePageRequest = class extends Schema.Class("@effect-agent/platform-cloudflare/ObservePageRequest")({
|
|
838
|
-
afterSequence: Schema.optionalKey(CanonicalSequence),
|
|
839
|
-
limit: Schema.Int.check(Schema.isGreaterThan(0), Schema.isLessThanOrEqualTo(1024))
|
|
840
|
-
}) {};
|
|
841
|
-
/** One event-driven wait for canonical progress strictly after this sequence. */
|
|
842
|
-
var AwaitProgressRequest = class extends Schema.Class("@effect-agent/platform-cloudflare/AwaitProgressRequest")({
|
|
843
|
-
afterSequence: CanonicalSequence,
|
|
844
|
-
waiterId: Schema.String.check(Schema.isMinLength(1), Schema.isMaxLength(256))
|
|
845
|
-
}) {};
|
|
846
|
-
/** Best-effort cancellation of one in-flight progress RPC. */
|
|
847
|
-
var CancelProgressRequest = class extends Schema.Class("@effect-agent/platform-cloudflare/CancelProgressRequest")({ waiterId: Schema.String.check(Schema.isMinLength(1), Schema.isMaxLength(256)) }) {};
|
|
848
|
-
/**
|
|
849
|
-
* Every typed failure a host entry point can produce, plus the protocol's own errors. Same
|
|
850
|
-
* closed-union discipline as the WP2 `PortFailure`: members re-decode to the SAME tagged
|
|
851
|
-
* classes on the Worker side; `cause` chains travel as Schema defects without instance
|
|
852
|
-
* fidelity (plan §2.8).
|
|
853
|
-
*/
|
|
854
|
-
const HostFailure = Schema.Union([
|
|
855
|
-
AgentInputError,
|
|
856
|
-
DigestError,
|
|
857
|
-
AdmissionConflict,
|
|
858
|
-
SettlementConflict,
|
|
859
|
-
ApprovalConflict,
|
|
860
|
-
UnknownResolutionConflict,
|
|
861
|
-
JoinedToHost,
|
|
862
|
-
LedgerError,
|
|
863
|
-
ConversationStoreError,
|
|
864
|
-
ConversationNotMaterialized,
|
|
865
|
-
AppendConflict,
|
|
866
|
-
FenceRejected,
|
|
867
|
-
DurableRuntimeFailpointError,
|
|
868
|
-
AdmissionLimitExceeded,
|
|
869
|
-
DurableAlarmError,
|
|
870
|
-
OperationDenied,
|
|
871
|
-
HostProtocolError
|
|
872
|
-
]);
|
|
873
|
-
var SubmitSucceeded = class extends Schema.TaggedClass("@effect-agent/platform-cloudflare/SubmitSucceeded")("SubmitSucceeded", { receipt: Receipt }) {};
|
|
874
|
-
var SettlementReached = class extends Schema.TaggedClass("@effect-agent/platform-cloudflare/SettlementReached")("SettlementReached", { settlement: Settlement }) {};
|
|
875
|
-
var ObservedPage = class extends Schema.TaggedClass("@effect-agent/platform-cloudflare/ObservedPage")("ObservedPage", { records: Schema.Array(CanonicalRecordEnvelope).check(Schema.isMaxLength(1024)) }) {};
|
|
876
|
-
/** A record was already committed or an incarnation-local hint says the caller should re-read. */
|
|
877
|
-
var ProgressObserved = class extends Schema.TaggedClass("@effect-agent/platform-cloudflare/ProgressObserved")("ProgressObserved", {}) {};
|
|
878
|
-
var ProgressCancelled = class extends Schema.TaggedClass("@effect-agent/platform-cloudflare/ProgressCancelled")("ProgressCancelled", {}) {};
|
|
879
|
-
var AbortRecorded = class extends Schema.TaggedClass("@effect-agent/platform-cloudflare/AbortRecorded")("AbortRecorded", { intent: AbortIntent }) {};
|
|
880
|
-
var ApprovalRecorded = class extends Schema.TaggedClass("@effect-agent/platform-cloudflare/ApprovalRecorded")("ApprovalRecorded", { intent: ApprovalDecisionIntent }) {};
|
|
881
|
-
var UnknownResolutionRecorded = class extends Schema.TaggedClass("@effect-agent/platform-cloudflare/UnknownResolutionRecorded")("UnknownResolutionRecorded", { intent: UnknownResolutionIntent }) {};
|
|
882
|
-
/** The entry point failed TYPED on the Object; the failure re-decodes verbatim. */
|
|
883
|
-
var HostFailed = class extends Schema.TaggedClass("@effect-agent/platform-cloudflare/HostFailed")("HostFailed", { failure: HostFailure }) {};
|
|
884
|
-
/** The uniform answer of one host entry point. Callers narrow by the tag their call implies. */
|
|
885
|
-
const HostResponse = Schema.Union([
|
|
886
|
-
SubmitSucceeded,
|
|
887
|
-
SettlementReached,
|
|
888
|
-
ObservedPage,
|
|
889
|
-
ProgressObserved,
|
|
890
|
-
ProgressCancelled,
|
|
891
|
-
AbortRecorded,
|
|
892
|
-
ApprovalRecorded,
|
|
893
|
-
UnknownResolutionRecorded,
|
|
894
|
-
HostFailed
|
|
895
|
-
]);
|
|
896
|
-
const decodeSubmitRequest = Schema.decodeUnknownEffect(SubmitRequest);
|
|
897
|
-
const encodeSubmitRequest = Schema.encodeEffect(SubmitRequest);
|
|
898
|
-
const decodeReceipt = Schema.decodeUnknownEffect(Receipt);
|
|
899
|
-
const encodeReceipt = Schema.encodeEffect(Receipt);
|
|
900
|
-
const decodeObservePageRequest = Schema.decodeUnknownEffect(ObservePageRequest);
|
|
901
|
-
const encodeObservePageRequest = Schema.encodeEffect(ObservePageRequest);
|
|
902
|
-
const decodeAwaitProgressRequest = Schema.decodeUnknownEffect(AwaitProgressRequest);
|
|
903
|
-
const encodeAwaitProgressRequest = Schema.encodeEffect(AwaitProgressRequest);
|
|
904
|
-
const decodeCancelProgressRequest = Schema.decodeUnknownEffect(CancelProgressRequest);
|
|
905
|
-
const encodeCancelProgressRequest = Schema.encodeEffect(CancelProgressRequest);
|
|
906
|
-
const decodeAbortCommand = Schema.decodeUnknownEffect(AbortCommand);
|
|
907
|
-
const encodeAbortCommand = Schema.encodeEffect(AbortCommand);
|
|
908
|
-
const decodeApprovalDecisionCommand = Schema.decodeUnknownEffect(ApprovalDecisionCommand);
|
|
909
|
-
const encodeApprovalDecisionCommand = Schema.encodeEffect(ApprovalDecisionCommand);
|
|
910
|
-
const decodeUnknownResolutionCommand = Schema.decodeUnknownEffect(UnknownResolutionCommand);
|
|
911
|
-
const encodeUnknownResolutionCommand = Schema.encodeEffect(UnknownResolutionCommand);
|
|
912
|
-
const encodeHostResponse = Schema.encodeEffect(HostResponse);
|
|
913
|
-
const decodeHostResponse = Schema.decodeUnknownEffect(HostResponse);
|
|
914
|
-
/** Failure surface of `CloudflareConversationClient.submit`. */
|
|
915
|
-
const ClientSubmitHostFailure = Schema.Union([
|
|
916
|
-
AgentInputError,
|
|
917
|
-
DigestError,
|
|
918
|
-
AdmissionConflict,
|
|
919
|
-
LedgerError,
|
|
920
|
-
ConversationStoreError,
|
|
921
|
-
ConversationNotMaterialized,
|
|
922
|
-
AppendConflict,
|
|
923
|
-
FenceRejected,
|
|
924
|
-
DurableRuntimeFailpointError,
|
|
925
|
-
AdmissionLimitExceeded,
|
|
926
|
-
DurableAlarmError,
|
|
927
|
-
HostProtocolError
|
|
928
|
-
]);
|
|
929
|
-
const ClientAwaitHostFailure = Schema.Union([
|
|
930
|
-
LedgerError,
|
|
931
|
-
SettlementConflict,
|
|
932
|
-
HostProtocolError
|
|
933
|
-
]);
|
|
934
|
-
const ClientObserveHostFailure = Schema.Union([
|
|
935
|
-
ConversationStoreError,
|
|
936
|
-
ConversationNotMaterialized,
|
|
937
|
-
OperationDenied,
|
|
938
|
-
HostProtocolError
|
|
939
|
-
]);
|
|
940
|
-
const ClientAbortHostFailure = Schema.Union([
|
|
941
|
-
LedgerError,
|
|
942
|
-
SettlementConflict,
|
|
943
|
-
JoinedToHost,
|
|
944
|
-
DurableRuntimeFailpointError,
|
|
945
|
-
DurableAlarmError,
|
|
946
|
-
HostProtocolError
|
|
947
|
-
]);
|
|
948
|
-
const ClientApprovalHostFailure = Schema.Union([
|
|
949
|
-
LedgerError,
|
|
950
|
-
SettlementConflict,
|
|
951
|
-
ApprovalConflict,
|
|
952
|
-
OperationDenied,
|
|
953
|
-
DurableAlarmError,
|
|
954
|
-
HostProtocolError
|
|
955
|
-
]);
|
|
956
|
-
const ClientUnknownHostFailure = Schema.Union([
|
|
957
|
-
LedgerError,
|
|
958
|
-
SettlementConflict,
|
|
959
|
-
UnknownResolutionConflict,
|
|
960
|
-
JoinedToHost,
|
|
961
|
-
DurableRuntimeFailpointError,
|
|
962
|
-
OperationDenied,
|
|
963
|
-
DurableAlarmError,
|
|
964
|
-
HostProtocolError
|
|
965
|
-
]);
|
|
966
|
-
const outOfContract = (conversationId, operation, observed) => ConversationClientError.make({
|
|
967
|
-
conversationId,
|
|
968
|
-
message: boundHostDiagnostic(`The Conversation Object answered ${operation} with the out-of-contract ${observed}.`)
|
|
969
|
-
});
|
|
970
|
-
const hostRpcMethods = {
|
|
971
|
-
submit: "submitEncoded",
|
|
972
|
-
awaitSettlement: "awaitSettlementEncoded",
|
|
973
|
-
awaitProgress: "awaitProgressEncoded",
|
|
974
|
-
cancelProgress: "cancelProgressEncoded",
|
|
975
|
-
observePage: "observePage",
|
|
976
|
-
abort: "abortEncoded",
|
|
977
|
-
resolveApproval: "resolveApprovalEncoded",
|
|
978
|
-
resolveUnknown: "resolveUnknownEncoded"
|
|
979
|
-
};
|
|
980
|
-
/** Worker-side client over the Conversation Object namespace (DEPLOY-010). */
|
|
981
|
-
var CloudflareConversationClient = class CloudflareConversationClient extends Context.Service()("@effect-agent/platform-cloudflare/CloudflareConversationClient") {
|
|
982
|
-
static layer = Layer.effect(CloudflareConversationClient)(Effect.gen(function* () {
|
|
983
|
-
const { namespace, rpcTracing } = yield* ConversationObjectNamespace;
|
|
984
|
-
const crypto = yield* Crypto.Crypto;
|
|
985
|
-
const call = Effect.fn(function* (conversationId, operation, encoded) {
|
|
986
|
-
const traceArgs = rpcTracing === void 0 ? [] : yield* RpcTracing.withRpcTraceContext([]);
|
|
987
|
-
const raw = yield* Effect.tryPromise({
|
|
988
|
-
try: () => {
|
|
989
|
-
return namespace.get(namespace.idFromName(conversationId))[hostRpcMethods[operation]](encoded, ...traceArgs);
|
|
990
|
-
},
|
|
991
|
-
catch: (cause) => ConversationClientError.make({
|
|
992
|
-
conversationId,
|
|
993
|
-
message: boundHostDiagnostic(`${operation} did not reach the Conversation Object: ${safeCauseMessage(cause, "the RPC failed without a diagnostic")}`),
|
|
994
|
-
cause,
|
|
995
|
-
...cloudflareFailureSignals(cause)
|
|
996
|
-
})
|
|
997
|
-
});
|
|
998
|
-
return yield* decodeHostResponse(raw).pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`The ${operation} answer could not be decoded: ${error.message}`) })));
|
|
999
|
-
}, (effect, conversationId, operation) => rpcTracing === void 0 ? Effect.withSpan(effect, "CloudflareConversationClient.call", { attributes: {
|
|
1000
|
-
conversationId,
|
|
1001
|
-
operation
|
|
1002
|
-
} }) : RpcTracing.withRpcClientSpan(effect, rpcTracing, hostRpcMethods[operation]));
|
|
1003
|
-
const expect = (conversationId, operation, resultSchema, failureSchema) => {
|
|
1004
|
-
const isExpectedResult = Schema.is(resultSchema);
|
|
1005
|
-
const isExpectedFailure = Schema.is(failureSchema);
|
|
1006
|
-
return (response) => {
|
|
1007
|
-
if (response._tag === "HostFailed") {
|
|
1008
|
-
const failure = response.failure;
|
|
1009
|
-
return isExpectedFailure(failure) ? Effect.fail(failure) : Effect.fail(outOfContract(conversationId, operation, `failure ${failure._tag}`));
|
|
1010
|
-
}
|
|
1011
|
-
if (!isExpectedResult(response)) return Effect.fail(outOfContract(conversationId, operation, `result ${response._tag}`));
|
|
1012
|
-
return Effect.succeed(response);
|
|
1013
|
-
};
|
|
1014
|
-
};
|
|
1015
|
-
const readPage = (conversationId, options) => Effect.gen(function* () {
|
|
1016
|
-
const request = ObservePageRequest.make({
|
|
1017
|
-
...options?.afterSequence === void 0 ? {} : { afterSequence: options.afterSequence },
|
|
1018
|
-
limit: options?.limit ?? 256
|
|
1019
|
-
});
|
|
1020
|
-
const encoded = yield* encodeObservePageRequest(request).pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`observePage request encode failed: ${error.message}`) })));
|
|
1021
|
-
const response = yield* call(conversationId, "observePage", encoded);
|
|
1022
|
-
return (yield* expect(conversationId, "observePage", ObservedPage, ClientObserveHostFailure)(response)).records;
|
|
1023
|
-
});
|
|
1024
|
-
const cancelProgress = (conversationId, waiterId) => encodeCancelProgressRequest(CancelProgressRequest.make({ waiterId })).pipe(Effect.mapError(() => void 0), Effect.flatMap((encoded) => call(conversationId, "cancelProgress", encoded)), Effect.asVoid, Effect.ignore);
|
|
1025
|
-
return CloudflareConversationClient.of({
|
|
1026
|
-
submit: (agent, input, options) => Effect.gen(function* () {
|
|
1027
|
-
const encodedInput = yield* Schema.encodeEffect(agent.definition.input)(input).pipe(Effect.mapError((cause) => AgentInputError.make({ message: `Unable to encode Agent input: ${cause.message}` })));
|
|
1028
|
-
const inputPayload = yield* Schema.decodeUnknownEffect(PersistedJson)(encodedInput).pipe(Effect.mapError(() => AgentInputError.make({ message: "Agent input does not satisfy the canonical persistence bounds" })));
|
|
1029
|
-
const request = SubmitRequest.make({
|
|
1030
|
-
agentId: agent.definition.id,
|
|
1031
|
-
principal: options.principal,
|
|
1032
|
-
idempotencyKey: options.idempotencyKey,
|
|
1033
|
-
definitions: options.definitions,
|
|
1034
|
-
inputPayload
|
|
1035
|
-
});
|
|
1036
|
-
const encoded = yield* encodeSubmitRequest(request).pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`submit request encode failed: ${error.message}`) })));
|
|
1037
|
-
const response = yield* call(options.conversationId, "submit", encoded);
|
|
1038
|
-
return (yield* expect(options.conversationId, "submit", SubmitSucceeded, ClientSubmitHostFailure)(response)).receipt;
|
|
1039
|
-
}),
|
|
1040
|
-
awaitSettlement: (receipt) => Effect.gen(function* () {
|
|
1041
|
-
const encoded = yield* encodeReceipt(receipt).pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`receipt encode failed: ${error.message}`) })));
|
|
1042
|
-
const response = yield* call(receipt.conversationId, "awaitSettlement", encoded);
|
|
1043
|
-
return (yield* expect(receipt.conversationId, "awaitSettlement", SettlementReached, ClientAwaitHostFailure)(response)).settlement;
|
|
1044
|
-
}),
|
|
1045
|
-
awaitProgress: (conversationId, afterSequence) => Effect.gen(function* () {
|
|
1046
|
-
const waiterId = yield* crypto.randomUUIDv4.pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`awaitProgress cancellation identity generation failed: ${error.message}`) })));
|
|
1047
|
-
const request = AwaitProgressRequest.make({
|
|
1048
|
-
afterSequence,
|
|
1049
|
-
waiterId
|
|
1050
|
-
});
|
|
1051
|
-
const encoded = yield* encodeAwaitProgressRequest(request).pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`awaitProgress request encode failed: ${error.message}`) })));
|
|
1052
|
-
const attempt = (retry) => call(conversationId, "awaitProgress", encoded).pipe(Effect.flatMap(expect(conversationId, "awaitProgress", ProgressObserved, ClientObserveHostFailure)), Effect.asVoid, Effect.catchTag("ConversationClientError", (error) => error.retryable === true && error.overloaded !== true && retry < 5 ? Effect.sleep(Duration.millis(10 * 2 ** retry)).pipe(Effect.andThen(attempt(retry + 1))) : Effect.fail(error)));
|
|
1053
|
-
yield* attempt(0).pipe(Effect.onInterrupt(() => cancelProgress(conversationId, waiterId)));
|
|
1054
|
-
}),
|
|
1055
|
-
readPage,
|
|
1056
|
-
readAll: (conversationId) => Effect.gen(function* () {
|
|
1057
|
-
const all = [];
|
|
1058
|
-
let after;
|
|
1059
|
-
for (;;) {
|
|
1060
|
-
const page = yield* readPage(conversationId, {
|
|
1061
|
-
afterSequence: after,
|
|
1062
|
-
limit: 1024
|
|
1063
|
-
});
|
|
1064
|
-
all.push(...page);
|
|
1065
|
-
const last = page.at(-1);
|
|
1066
|
-
if (page.length < 1024 || last === void 0) return all;
|
|
1067
|
-
after = last.sequence;
|
|
1068
|
-
}
|
|
1069
|
-
}),
|
|
1070
|
-
abort: (conversationId, command) => Effect.gen(function* () {
|
|
1071
|
-
const encoded = yield* encodeAbortCommand(command).pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`abort command encode failed: ${error.message}`) })));
|
|
1072
|
-
const response = yield* call(conversationId, "abort", encoded);
|
|
1073
|
-
return (yield* expect(conversationId, "abort", AbortRecorded, ClientAbortHostFailure)(response)).intent;
|
|
1074
|
-
}),
|
|
1075
|
-
resolveApproval: (conversationId, command) => Effect.gen(function* () {
|
|
1076
|
-
const encoded = yield* encodeApprovalDecisionCommand(command).pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`approval command encode failed: ${error.message}`) })));
|
|
1077
|
-
const response = yield* call(conversationId, "resolveApproval", encoded);
|
|
1078
|
-
return (yield* expect(conversationId, "resolveApproval", ApprovalRecorded, ClientApprovalHostFailure)(response)).intent;
|
|
1079
|
-
}),
|
|
1080
|
-
resolveUnknown: (conversationId, command) => Effect.gen(function* () {
|
|
1081
|
-
const encoded = yield* encodeUnknownResolutionCommand(command).pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`resolution command encode failed: ${error.message}`) })));
|
|
1082
|
-
const response = yield* call(conversationId, "resolveUnknown", encoded);
|
|
1083
|
-
return (yield* expect(conversationId, "resolveUnknown", UnknownResolutionRecorded, ClientUnknownHostFailure)(response)).intent;
|
|
1084
|
-
})
|
|
1085
|
-
});
|
|
1086
|
-
}));
|
|
1087
|
-
};
|
|
1088
|
-
//#endregion
|
|
1089
280
|
//#region src/conversation-object.ts
|
|
1090
281
|
/** Classify only a decoded port request so new protocol members cannot bypass pre-arming. */
|
|
1091
282
|
const isMutatingPortRequest = (request) => {
|
|
@@ -2008,6 +1199,6 @@ const dynamicWorkerCodeExecutorLayer = (options) => Layer.effect(CodeExecutor, E
|
|
|
2008
1199
|
return CodeExecutor.of({ execute: makeExecute(options, clock) });
|
|
2009
1200
|
}));
|
|
2010
1201
|
//#endregion
|
|
2011
|
-
export { AbortRecorded, AdminExplainRequest, AdminFailed, AdminFailure, AdminResponse, AdminVerifyRequest, AdmissionLimitExceeded, ApprovalRecorded, AwaitProgressRequest, BrowserQuickActionBrowserBinding, BrowserQuickActionRpcError, BrowserQuickActionWorkersAi, BrowserQuickActionWorkersAiPolicyError, BrowserRunHandoffRequest, BrowserRunHandoffResult, BrowserRunHandoffState, BrowserRunInteractiveBinding, BrowserRunInteractiveHost, BrowserRunLiveViewRequest, BrowserRunLiveViewResult, CLOUDFLARE_DATABASE_CAP_BYTES, CLOUDFLARE_RUNTIME_DEFAULTS, CancelProgressRequest, CloudflareAdmissionLimitsValue, CloudflareBindingError, CloudflareConversationClient, CloudflareDurableRuntime, CloudflareDurableRuntimeConfig, CloudflareDurableRuntimeConfigValue, CloudflarePlatformConfigError, ConversationClientError, ConversationMaintenance, ConversationMaintenanceFailpoint, ConversationObjectIdentity, ConversationObjectNamespace, ConversationObjectPorts, DEFAULT_MAX_DATABASE_BYTES, DurableAlarmError, DurableAlarmService, DurableObjectContext, ExplainedRecovery, HostFailed, HostFailure, HostProtocolError, HostResponse, MaintenancePassReport, ObligationsScanned, ObservePageRequest, ObservedPage, ProgressCancelled, ProgressObserved, ProgressWaitRegistry, RetryExecuted, SettlementReached, SubmitRequest, SubmitSucceeded, UnknownResolutionRecorded, VerifiedIntegrity, boundHostDiagnostic, browserQuickActionCaptureLayer, browserQuickActionImplementation, browserQuickActionScreenshotLayer, browserQuickActionWorkersAiCaptureLayer, browserRestCaptureImplementation, browserRestCaptureLayer, browserRestCrawlImplementation, browserRestCrawlLayer, browserRestWorkersAiCaptureLayer, browserRunInteractiveHostLayer, browserRunInteractiveImplementation, browserRunInteractiveLayer, cloudflareWakeSchedulerLayer, conversationNamespaceFromEnv, conversationNamespaceLayer, conversationPortTransportLayer, decodeAbortCommand, decodeAdminExplainRequest, decodeAdminResponse, decodeAdminVerifyRequest, decodeApprovalDecisionCommand, decodeAwaitProgressRequest, decodeCancelProgressRequest, decodeHostResponse, decodeObligationThresholds, decodeObservePageRequest, decodeReceipt, decodeRetryCommand, decodeSubmitRequest, decodeUnknownResolutionCommand, disposeRpcHandle, dynamicWorkerCodeExecutorLayer, dynamicWorkerImplementation, encodeAbortCommand, encodeAdminResponse, encodeApprovalDecisionCommand, encodeAwaitProgressRequest, encodeCancelProgressRequest, encodeHostResponse, encodeObservePageRequest, encodeReceipt, encodeSubmitRequest, encodeUnknownResolutionCommand, makeConversationObjectClass };
|
|
1202
|
+
export { AbortRecorded, AdminExplainRequest, AdminFailed, AdminFailure, AdminResponse, AdminVerifyRequest, AdmissionLimitExceeded, ApprovalRecorded, AwaitProgressRequest, BrowserQuickActionBrowserBinding, BrowserQuickActionRpcError, BrowserQuickActionWorkersAi, BrowserQuickActionWorkersAiPolicyError, BrowserRunHandoffRequest, BrowserRunHandoffResult, BrowserRunHandoffState, BrowserRunInteractiveBinding, BrowserRunInteractiveHost, BrowserRunLiveViewRequest, BrowserRunLiveViewResult, BrowserRunViewport, CLOUDFLARE_DATABASE_CAP_BYTES, CLOUDFLARE_RUNTIME_DEFAULTS, CancelProgressRequest, CloudflareAdmissionLimitsValue, CloudflareBindingError, CloudflareConversationClient, CloudflareDurableRuntime, CloudflareDurableRuntimeConfig, CloudflareDurableRuntimeConfigValue, CloudflarePlatformConfigError, CloudflareSchedulingClient, ConversationClientError, ConversationMaintenance, ConversationMaintenanceFailpoint, ConversationObjectIdentity, ConversationObjectNamespace, ConversationObjectPorts, DEFAULT_MAX_DATABASE_BYTES, DurableAlarmError, DurableAlarmService, DurableObjectContext, ExplainedRecovery, HostFailed, HostFailure, HostProtocolError, HostResponse, MaintenancePassReport, ObligationsScanned, ObservePageRequest, ObservedPage, ProgressCancelled, ProgressObserved, ProgressWaitRegistry, RetryExecuted, ScheduleAlarmProtocolError, ScheduleOwnerIdentity, ScheduleOwnerNamespace, ScheduleOwnerProtocolError, SettlementReached, SubmitRequest, SubmitSucceeded, UnknownResolutionRecorded, VerifiedIntegrity, boundHostDiagnostic, browserQuickActionCaptureLayer, browserQuickActionImplementation, browserQuickActionScreenshotLayer, browserQuickActionWorkersAiCaptureLayer, browserRestCaptureImplementation, browserRestCaptureLayer, browserRestCrawlImplementation, browserRestCrawlLayer, browserRestWorkersAiCaptureLayer, browserRunInteractiveHostLayer, browserRunInteractiveImplementation, browserRunInteractiveLayer, cloudflareWakeSchedulerLayer, conversationNamespaceFromEnv, conversationNamespaceLayer, conversationPortTransportLayer, decodeAbortCommand, decodeAdminExplainRequest, decodeAdminResponse, decodeAdminVerifyRequest, decodeApprovalDecisionCommand, decodeAwaitProgressRequest, decodeCancelProgressRequest, decodeHostResponse, decodeObligationThresholds, decodeObservePageRequest, decodeReceipt, decodeRetryCommand, decodeSubmitRequest, decodeUnknownResolutionCommand, disposeRpcHandle, dynamicWorkerCodeExecutorLayer, dynamicWorkerImplementation, encodeAbortCommand, encodeAdminResponse, encodeApprovalDecisionCommand, encodeAwaitProgressRequest, encodeCancelProgressRequest, encodeHostResponse, encodeObservePageRequest, encodeReceipt, encodeSubmitRequest, encodeUnknownResolutionCommand, isBrowserRunUndispatchedActionError, makeConversationObjectClass, makeScheduleOwnerObjectClass };
|
|
2012
1203
|
|
|
2013
1204
|
//# sourceMappingURL=index.mjs.map
|