@yielded/agent-platform-cloudflare 0.1.0-beta.167 → 0.1.0-beta.169

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.
Files changed (97) hide show
  1. package/dist/{Alarm-B0ODr1NE.mjs → Alarm-BMEAZo3p.mjs} +261 -159
  2. package/dist/Alarm-BMEAZo3p.mjs.map +1 -0
  3. package/dist/Alarm.d.mts +29 -36
  4. package/dist/Alarm.mjs +2 -2
  5. package/dist/BrowserCredentials-C5IWfi7f.d.mts +91 -0
  6. package/dist/BrowserCredentials.d.mts +2 -91
  7. package/dist/BrowserRestCapture.mjs +3 -3
  8. package/dist/BrowserRestCapture.mjs.map +1 -1
  9. package/dist/BrowserRestCrawl.mjs +6 -6
  10. package/dist/BrowserRestCrawl.mjs.map +1 -1
  11. package/dist/{BrowserSession-RfIzxGCH.mjs → BrowserSession-BfNmyayH.mjs} +5 -5
  12. package/dist/BrowserSession-BfNmyayH.mjs.map +1 -0
  13. package/dist/{BrowserSession-B969Xg-2.d.mts → BrowserSession-Bx0V1-6_.d.mts} +6 -3
  14. package/dist/BrowserSession.d.mts +1 -1
  15. package/dist/BrowserSession.mjs +2 -2
  16. package/dist/BrowserUse-Bc2JdLW2.mjs +1528 -0
  17. package/dist/BrowserUse-Bc2JdLW2.mjs.map +1 -0
  18. package/dist/BrowserUse.d.mts +83 -0
  19. package/dist/BrowserUse.mjs +2 -0
  20. package/dist/CloudflareBindings.d.mts +8 -1
  21. package/dist/CloudflareBindings.mjs +2 -2
  22. package/dist/CloudflareBindings.mjs.map +1 -1
  23. package/dist/{CloudflareBrowser-5an6m-Qb.mjs → CloudflareBrowser-Vt8qTdYW.mjs} +11 -13
  24. package/dist/CloudflareBrowser-Vt8qTdYW.mjs.map +1 -0
  25. package/dist/CloudflareBrowser.mjs +1 -1
  26. package/dist/CloudflareCodeMode.mjs +1 -1
  27. package/dist/CloudflareCodeMode.mjs.map +1 -1
  28. package/dist/{CloudflareConfig-qDrRLofL.d.mts → CloudflareConfig-C9MvPbX8.d.mts} +9 -11
  29. package/dist/CloudflareConfig.d.mts +1 -1
  30. package/dist/CloudflareConfig.mjs +9 -12
  31. package/dist/CloudflareConfig.mjs.map +1 -1
  32. package/dist/CloudflareMemory.d.mts +3 -25
  33. package/dist/CloudflareMemory.mjs +33 -31
  34. package/dist/CloudflareMemory.mjs.map +1 -1
  35. package/dist/CloudflareScheduling.mjs +8 -15
  36. package/dist/CloudflareScheduling.mjs.map +1 -1
  37. package/dist/CloudflareSubscriptions.mjs +9 -16
  38. package/dist/CloudflareSubscriptions.mjs.map +1 -1
  39. package/dist/CloudflareThreadClient-CLZpN9zU.mjs +588 -0
  40. package/dist/CloudflareThreadClient-CLZpN9zU.mjs.map +1 -0
  41. package/dist/CloudflareThreadClient-QsVzLGGZ.d.mts +2033 -0
  42. package/dist/CloudflareThreadClient.d.mts +2 -1796
  43. package/dist/CloudflareThreadClient.mjs +2 -382
  44. package/dist/{InteractiveBrowser-BbG3kGA9.mjs → InteractiveBrowser-LdKzQeLR.mjs} +18 -19
  45. package/dist/InteractiveBrowser-LdKzQeLR.mjs.map +1 -0
  46. package/dist/InteractiveBrowser.mjs +1 -1
  47. package/dist/{ThreadObject-BcfXbzSO.d.mts → ThreadObject-7s5XnlH-.d.mts} +103 -79
  48. package/dist/{ThreadObject-DHjrnlX4.mjs → ThreadObject-CgXZMlr4.mjs} +265 -66
  49. package/dist/ThreadObject-CgXZMlr4.mjs.map +1 -0
  50. package/dist/ThreadObject.d.mts +2 -2
  51. package/dist/ThreadObject.mjs +2 -3
  52. package/dist/WakeScheduler.d.mts +6 -5
  53. package/dist/WakeScheduler.mjs +15 -11
  54. package/dist/WakeScheduler.mjs.map +1 -1
  55. package/dist/index.d.mts +7 -6
  56. package/dist/index.mjs +7 -6
  57. package/dist/page-function-CmUCcyNP.mjs +11 -0
  58. package/dist/page-function-CmUCcyNP.mjs.map +1 -0
  59. package/dist/{prepared-admission-DMX5p9dC.mjs → prepared-admission-B61A7y6O.mjs} +3 -3
  60. package/dist/{prepared-admission-DMX5p9dC.mjs.map → prepared-admission-B61A7y6O.mjs.map} +1 -1
  61. package/package.json +1 -1
  62. package/src/Alarm.ts +512 -279
  63. package/src/BrowserRestCapture.ts +2 -2
  64. package/src/BrowserRestCrawl.ts +10 -14
  65. package/src/BrowserSession.ts +10 -2
  66. package/src/BrowserUse.ts +1591 -0
  67. package/src/CloudflareBindings.ts +13 -4
  68. package/src/CloudflareCodeMode.ts +1 -1
  69. package/src/CloudflareConfig.ts +9 -12
  70. package/src/CloudflareMemory.ts +21 -28
  71. package/src/CloudflareScheduling.ts +7 -15
  72. package/src/CloudflareSubscriptions.ts +11 -20
  73. package/src/CloudflareThreadClient.ts +289 -9
  74. package/src/InteractiveBrowser.ts +325 -323
  75. package/src/ThreadObject.ts +172 -52
  76. package/src/WakeScheduler.ts +29 -18
  77. package/src/index.ts +1 -0
  78. package/src/internal/browser-dom.ts +886 -0
  79. package/src/internal/browser-file-selection.ts +8 -1
  80. package/src/internal/browser-jev-dom.ts +362 -0
  81. package/src/internal/browser-quick-action.ts +7 -8
  82. package/src/internal/browser-session-lifecycle.ts +2 -5
  83. package/src/internal/crypto.ts +41 -0
  84. package/src/internal/due-queue.ts +5 -69
  85. package/src/internal/layers.ts +100 -17
  86. package/src/internal/live-text-protocol.ts +51 -0
  87. package/src/internal/live-text.ts +256 -0
  88. package/src/internal/page-function.ts +12 -0
  89. package/src/internal/prepared-admission.ts +1 -1
  90. package/src/internal/progress-wait.ts +19 -24
  91. package/src/internal/transport.ts +1 -1
  92. package/dist/Alarm-B0ODr1NE.mjs.map +0 -1
  93. package/dist/BrowserSession-RfIzxGCH.mjs.map +0 -1
  94. package/dist/CloudflareBrowser-5an6m-Qb.mjs.map +0 -1
  95. package/dist/CloudflareThreadClient.mjs.map +0 -1
  96. package/dist/InteractiveBrowser-BbG3kGA9.mjs.map +0 -1
  97. package/dist/ThreadObject-DHjrnlX4.mjs.map +0 -1
@@ -0,0 +1,588 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
+ import { ThreadObjectNamespace, callThreadObject } from "./CloudflareBindings.mjs";
3
+ import { AdmissionLimitExceeded } from "./CloudflareConfig.mjs";
4
+ import { r as safeCauseMessage, t as cloudflareFailureSignals } from "./boundary-BguazVkh.mjs";
5
+ import { n as DurableAlarmError } from "./Alarm-BMEAZo3p.mjs";
6
+ import { Receipt } from "@yielded/agent/durable-agent-runtime";
7
+ import { AgentId, ThreadId } from "@yielded/agent/identifiers";
8
+ import { AbortCommand, AbortIntent, AdmissionConflict, AdmissionFence, AdmissionGroup, AdmissionPolicyError, ApprovalConflict, ApprovalDecisionCommand, ApprovalDecisionIntent, IdempotencyKey, JoinedToHost, LedgerError, OwnershipLost, Principal, Settlement, SettlementConflict, UnknownResolutionCommand, UnknownResolutionConflict, UnknownResolutionIntent } from "@yielded/agent/submission-ledger";
9
+ import { Context, Crypto, Duration, Effect, Layer, PlatformError, Predicate, Schema, Stream } from "effect";
10
+ import { RpcTargets, RpcTracing } from "effect-cf";
11
+ import { CanonicalRecordEnvelope, CanonicalSequence, DefinitionDigests, PersistedJson, SubmissionSettledRecord, WorkerAdmission } from "@yielded/agent/records";
12
+ import { AgentInputError } from "@yielded/agent/agent-error";
13
+ import { DigestError } from "@yielded/agent/digest";
14
+ import { DurableRuntimeFailpointError } from "@yielded/agent/durable-failpoint";
15
+ import { InputMessage } from "@yielded/agent/messaging";
16
+ import { OperationDenied } from "@yielded/agent/operation-authorizer";
17
+ import { SubmissionStatus } from "@yielded/agent/submission-status";
18
+ import { AppendConflict, ThreadNotMaterialized, ThreadStoreError } from "@yielded/agent/thread-store";
19
+ import { createHash } from "node:crypto";
20
+ import { BrowserCrypto } from "@effect/platform-browser";
21
+ import { Event } from "@yielded/agent/provisional-text";
22
+ //#region src/internal/crypto.ts
23
+ /** Workers use native SHA-256 while retaining BrowserCrypto's services and overrides. */
24
+ const cloudflareCryptoLayer = Layer.effect(Crypto.Crypto, Effect.gen(function* () {
25
+ const base = yield* Crypto.Crypto;
26
+ const webCrypto = yield* BrowserCrypto.WebCrypto;
27
+ const hostGlobals = globalThis;
28
+ return Crypto.Crypto.of({
29
+ ...base,
30
+ digest: (algorithm, data) => {
31
+ if (algorithm !== "SHA-256" || !("crypto" in hostGlobals) || webCrypto !== hostGlobals.crypto || typeof webCrypto.subtle?.digest !== "function") return base.digest(algorithm, data);
32
+ return Effect.try({
33
+ try: () => Uint8Array.from(createHash("sha256").update(new Uint8Array(data)).digest()),
34
+ catch: (cause) => PlatformError.systemError({
35
+ module: "Crypto",
36
+ method: "digest",
37
+ _tag: "Unknown",
38
+ description: "Could not compute digest",
39
+ cause
40
+ })
41
+ });
42
+ }
43
+ });
44
+ })).pipe(Layer.provide(BrowserCrypto.layer));
45
+ //#endregion
46
+ //#region src/internal/live-text-protocol.ts
47
+ const MAX_FRAME_BYTES = 32768;
48
+ const MAX_DELTA_LENGTH = 4096;
49
+ const MAX_DRAFT_LENGTH = 2097152;
50
+ const streamId = Schema.NonEmptyString.check(Schema.isMaxLength(256));
51
+ const Request = Schema.Struct({ schemaVersion: Schema.Literal(1) });
52
+ /**
53
+ * Reset replaces all drafts with a snapshot, streamed as native Text parts before live deltas.
54
+ * Each snapshot starts a fresh streamId. Its sequences are unrelated to canonical sequences.
55
+ */
56
+ const Frame = Schema.Union([Schema.TaggedStruct("Reset", {
57
+ schemaVersion: Schema.Literal(1),
58
+ streamId,
59
+ threadId: ThreadId,
60
+ sequence: Schema.Literal(0)
61
+ }), Schema.TaggedStruct("Event", {
62
+ schemaVersion: Schema.Literal(1),
63
+ streamId,
64
+ sequence: Schema.Int.check(Schema.isGreaterThan(0)),
65
+ event: Event
66
+ })]);
67
+ /** Bounds are checked before queueing; provider metadata is deliberately absent. */
68
+ const isBoundedEvent = (event) => {
69
+ const ids = [
70
+ event.threadId,
71
+ event.submissionId,
72
+ event.attemptId
73
+ ];
74
+ if (event._tag !== "AttemptEnded") ids.push(event.runId, event.turnId);
75
+ if (ids.some((id) => id.length > 256)) return false;
76
+ return event._tag !== "Text" || event.part.id.length <= 256 && Object.keys(event.part.metadata).length === 0 && (event.part.type !== "text-delta" || event.part.delta.length <= 4096);
77
+ };
78
+ //#endregion
79
+ //#region src/CloudflareThreadClient.ts
80
+ var CloudflareThreadClient_exports = /* @__PURE__ */ __exportAll({
81
+ AbortRecorded: () => AbortRecorded,
82
+ ApprovalRecorded: () => ApprovalRecorded,
83
+ AwaitProgressRequest: () => AwaitProgressRequest,
84
+ CancelProgressRequest: () => CancelProgressRequest,
85
+ CloudflareThreadClient: () => CloudflareThreadClient,
86
+ HostFailed: () => HostFailed,
87
+ HostFailure: () => HostFailure,
88
+ HostProtocolError: () => HostProtocolError,
89
+ HostResponse: () => HostResponse,
90
+ LiveTextFrame: () => Frame,
91
+ ObservePageRequest: () => ObservePageRequest,
92
+ ObservedPage: () => ObservedPage,
93
+ ProgressCancelled: () => ProgressCancelled,
94
+ ProgressObserved: () => ProgressObserved,
95
+ SettlementReached: () => SettlementReached,
96
+ SettlementRecordReached: () => SettlementRecordReached,
97
+ SubmissionStatusResponse: () => SubmissionStatusResponse,
98
+ SubmitRequest: () => SubmitRequest,
99
+ SubmitSucceeded: () => SubmitSucceeded,
100
+ ThreadClientError: () => ThreadClientError,
101
+ UnknownResolutionRecorded: () => UnknownResolutionRecorded,
102
+ boundHostDiagnostic: () => boundHostDiagnostic,
103
+ decodeAbortCommand: () => decodeAbortCommand,
104
+ decodeApprovalDecisionCommand: () => decodeApprovalDecisionCommand,
105
+ decodeAwaitProgressRequest: () => decodeAwaitProgressRequest,
106
+ decodeCancelProgressRequest: () => decodeCancelProgressRequest,
107
+ decodeHostResponse: () => decodeHostResponse,
108
+ decodeObservePageRequest: () => decodeObservePageRequest,
109
+ decodeReceipt: () => decodeReceipt,
110
+ decodeSubmitRequest: () => decodeSubmitRequest,
111
+ decodeUnknownResolutionCommand: () => decodeUnknownResolutionCommand,
112
+ encodeAbortCommand: () => encodeAbortCommand,
113
+ encodeApprovalDecisionCommand: () => encodeApprovalDecisionCommand,
114
+ encodeAwaitProgressRequest: () => encodeAwaitProgressRequest,
115
+ encodeCancelProgressRequest: () => encodeCancelProgressRequest,
116
+ encodeHostResponse: () => encodeHostResponse,
117
+ encodeObservePageRequest: () => encodeObservePageRequest,
118
+ encodeReceipt: () => encodeReceipt,
119
+ encodeSubmitRequest: () => encodeSubmitRequest,
120
+ encodeUnknownResolutionCommand: () => encodeUnknownResolutionCommand
121
+ });
122
+ /**
123
+ * The Worker↔Thread-Object host protocol (plan §1.4): Schema envelopes for the host
124
+ * entry points (`submitEncoded`, `awaitSettlementEncoded`, `observePage`, `abortEncoded`,
125
+ * `resolveApprovalEncoded`, `resolveUnknownEncoded`) plus the Worker-side client that speaks
126
+ * it. Mirrors the WP2 port protocol: requests and responses are closed Schema unions, typed
127
+ * failures travel as their own tagged classes and RE-DECODE to identical tags on the caller
128
+ * (error-tag fidelity), and protocol anomalies are answered typed instead of thrown.
129
+ */
130
+ /** Ceiling for host protocol diagnostic strings. */
131
+ const MAX_HOST_DIAGNOSTIC_LENGTH = 4096;
132
+ const PROGRESS_CANCELLATION_TIMEOUT = "1 second";
133
+ const BoundedDiagnostic = Schema.String.check(Schema.isMaxLength(MAX_HOST_DIAGNOSTIC_LENGTH));
134
+ /** Truncate a diagnostic string to the host protocol's bounded length. */
135
+ const boundHostDiagnostic = (value) => value.length > MAX_HOST_DIAGNOSTIC_LENGTH ? `${value.slice(0, 4093)}...` : value;
136
+ /**
137
+ * The envelope itself could not be honored: the Object could not decode the request, or a
138
+ * response could not be encoded/decoded. Never carries operation semantics.
139
+ */
140
+ var HostProtocolError = class extends Schema.TaggedError()("HostProtocolError", { message: BoundedDiagnostic }) {};
141
+ /** The Worker-side stub call itself failed (RPC rejection, overload, eviction mid-call). */
142
+ var ThreadClientError = class extends Schema.TaggedError()("ThreadClientError", {
143
+ threadId: Schema.String,
144
+ message: Schema.String,
145
+ cause: Schema.optionalKey(Schema.Defect()),
146
+ /** Cloudflare's own classification for a failure safe to retry with a fresh stub. */
147
+ retryable: Schema.optionalKey(Schema.Boolean),
148
+ /** Cloudflare overloads are surfaced immediately instead of adding retry pressure. */
149
+ overloaded: Schema.optionalKey(Schema.Boolean)
150
+ }) {};
151
+ /**
152
+ * One durable submission, input ALREADY encoded by the caller through the Agent Binding's
153
+ * input schema (the Worker bundles the same Agent definitions as the Object, so schema
154
+ * validation happens client-side; the resolved Binding re-validates at claim time). The
155
+ * Thread identity is deliberately absent — the addressed Object IS the lane.
156
+ */
157
+ var SubmitRequest = class extends Schema.Class("@effect-agent/platform-cloudflare/SubmitRequest")({
158
+ agentId: AgentId,
159
+ principal: Principal,
160
+ idempotencyKey: IdempotencyKey,
161
+ admissionGroup: Schema.optionalKey(AdmissionGroup),
162
+ admissionFence: Schema.optionalKey(AdmissionFence),
163
+ workerAdmission: Schema.optionalKey(WorkerAdmission),
164
+ messageAdmission: Schema.optionalKey(InputMessage),
165
+ definitions: DefinitionDigests,
166
+ inputPayload: PersistedJson
167
+ }) {};
168
+ /** One bounded page of canonical records after an optional sequence. */
169
+ var ObservePageRequest = class extends Schema.Class("@effect-agent/platform-cloudflare/ObservePageRequest")({
170
+ afterSequence: Schema.optionalKey(CanonicalSequence),
171
+ limit: Schema.Int.check(Schema.isGreaterThan(0), Schema.isLessThanOrEqualTo(1024))
172
+ }) {};
173
+ /** One event-driven wait for canonical progress strictly after this sequence. */
174
+ var AwaitProgressRequest = class extends Schema.Class("@effect-agent/platform-cloudflare/AwaitProgressRequest")({
175
+ afterSequence: CanonicalSequence,
176
+ waiterId: Schema.String.check(Schema.isMinLength(1), Schema.isMaxLength(256))
177
+ }) {};
178
+ /** Best-effort cancellation of one in-flight progress RPC. */
179
+ var CancelProgressRequest = class extends Schema.Class("@effect-agent/platform-cloudflare/CancelProgressRequest")({ waiterId: Schema.String.check(Schema.isMinLength(1), Schema.isMaxLength(256)) }) {};
180
+ /**
181
+ * Every typed failure a host entry point can produce, plus the protocol's own errors. Same
182
+ * closed-union discipline as the WP2 `PortFailure`: members re-decode to the SAME tagged
183
+ * classes on the Worker side; `cause` chains travel as Schema defects without instance
184
+ * fidelity (plan §2.8).
185
+ */
186
+ const HostFailure = Schema.Union([
187
+ AgentInputError,
188
+ DigestError,
189
+ AdmissionConflict,
190
+ AdmissionPolicyError,
191
+ SettlementConflict,
192
+ ApprovalConflict,
193
+ UnknownResolutionConflict,
194
+ JoinedToHost,
195
+ LedgerError,
196
+ OwnershipLost,
197
+ ThreadStoreError,
198
+ ThreadNotMaterialized,
199
+ AppendConflict,
200
+ DurableRuntimeFailpointError,
201
+ AdmissionLimitExceeded,
202
+ DurableAlarmError,
203
+ OperationDenied,
204
+ HostProtocolError
205
+ ]);
206
+ var SubmitSucceeded = class extends Schema.TaggedClass("@effect-agent/platform-cloudflare/SubmitSucceeded")("SubmitSucceeded", { receipt: Receipt }) {};
207
+ var SubmissionStatusResponse = class extends Schema.TaggedClass("@effect-agent/platform-cloudflare/SubmissionStatusResponse")("SubmissionStatusResponse", { status: SubmissionStatus }) {};
208
+ var SettlementReached = class extends Schema.TaggedClass("@effect-agent/platform-cloudflare/SettlementReached")("SettlementReached", { settlement: Settlement }) {};
209
+ /** The exact canonical record of an operationally finalized Submission. */
210
+ var SettlementRecordReached = class extends Schema.TaggedClass("@effect-agent/platform-cloudflare/SettlementRecordReached")("SettlementRecordReached", { record: SubmissionSettledRecord }) {};
211
+ var ObservedPage = class extends Schema.TaggedClass("@effect-agent/platform-cloudflare/ObservedPage")("ObservedPage", { records: Schema.Array(CanonicalRecordEnvelope).check(Schema.isMaxLength(1024)) }) {};
212
+ /** A record was already committed or an incarnation-local hint says the caller should re-read. */
213
+ var ProgressObserved = class extends Schema.TaggedClass("@effect-agent/platform-cloudflare/ProgressObserved")("ProgressObserved", {}) {};
214
+ var ProgressCancelled = class extends Schema.TaggedClass("@effect-agent/platform-cloudflare/ProgressCancelled")("ProgressCancelled", {}) {};
215
+ var AbortRecorded = class extends Schema.TaggedClass("@effect-agent/platform-cloudflare/AbortRecorded")("AbortRecorded", { intent: AbortIntent }) {};
216
+ var ApprovalRecorded = class extends Schema.TaggedClass("@effect-agent/platform-cloudflare/ApprovalRecorded")("ApprovalRecorded", { intent: ApprovalDecisionIntent }) {};
217
+ var UnknownResolutionRecorded = class extends Schema.TaggedClass("@effect-agent/platform-cloudflare/UnknownResolutionRecorded")("UnknownResolutionRecorded", { intent: UnknownResolutionIntent }) {};
218
+ /** The entry point failed TYPED on the Object; the failure re-decodes verbatim. */
219
+ var HostFailed = class extends Schema.TaggedClass("@effect-agent/platform-cloudflare/HostFailed")("HostFailed", { failure: HostFailure }) {};
220
+ /** The uniform answer of one host entry point. Callers narrow by the tag their call implies. */
221
+ const HostResponse = Schema.Union([
222
+ SubmitSucceeded,
223
+ SettlementReached,
224
+ SettlementRecordReached,
225
+ SubmissionStatusResponse,
226
+ ObservedPage,
227
+ ProgressObserved,
228
+ ProgressCancelled,
229
+ AbortRecorded,
230
+ ApprovalRecorded,
231
+ UnknownResolutionRecorded,
232
+ HostFailed
233
+ ]);
234
+ const decodeSubmitRequest = Schema.decodeUnknownEffect(SubmitRequest);
235
+ const encodeSubmitRequest = Schema.encodeEffect(SubmitRequest);
236
+ const decodeReceipt = Schema.decodeUnknownEffect(Receipt);
237
+ const encodeReceipt = Schema.encodeEffect(Receipt);
238
+ const decodeObservePageRequest = Schema.decodeUnknownEffect(ObservePageRequest);
239
+ const encodeObservePageRequest = Schema.encodeEffect(ObservePageRequest);
240
+ const decodeAwaitProgressRequest = Schema.decodeUnknownEffect(AwaitProgressRequest);
241
+ const encodeAwaitProgressRequest = Schema.encodeEffect(AwaitProgressRequest);
242
+ const decodeCancelProgressRequest = Schema.decodeUnknownEffect(CancelProgressRequest);
243
+ const encodeCancelProgressRequest = Schema.encodeEffect(CancelProgressRequest);
244
+ const decodeAbortCommand = Schema.decodeUnknownEffect(AbortCommand);
245
+ const encodeAbortCommand = Schema.encodeEffect(AbortCommand);
246
+ const decodeApprovalDecisionCommand = Schema.decodeUnknownEffect(ApprovalDecisionCommand);
247
+ const encodeApprovalDecisionCommand = Schema.encodeEffect(ApprovalDecisionCommand);
248
+ const decodeUnknownResolutionCommand = Schema.decodeUnknownEffect(UnknownResolutionCommand);
249
+ const encodeUnknownResolutionCommand = Schema.encodeEffect(UnknownResolutionCommand);
250
+ const encodeHostResponse = Schema.encodeEffect(HostResponse);
251
+ const decodeHostResponse = Schema.decodeUnknownEffect(HostResponse);
252
+ /** Failure surface of `CloudflareThreadClient.submit`. */
253
+ const ClientSubmitHostFailure = Schema.Union([
254
+ AgentInputError,
255
+ DigestError,
256
+ AdmissionConflict,
257
+ AdmissionPolicyError,
258
+ LedgerError,
259
+ OwnershipLost,
260
+ ThreadStoreError,
261
+ ThreadNotMaterialized,
262
+ AppendConflict,
263
+ DurableRuntimeFailpointError,
264
+ AdmissionLimitExceeded,
265
+ DurableAlarmError,
266
+ HostProtocolError
267
+ ]);
268
+ const ClientAwaitHostFailure = Schema.Union([
269
+ LedgerError,
270
+ OwnershipLost,
271
+ SettlementConflict,
272
+ OperationDenied,
273
+ HostProtocolError
274
+ ]);
275
+ const ClientObserveHostFailure = Schema.Union([
276
+ ThreadStoreError,
277
+ ThreadNotMaterialized,
278
+ OperationDenied,
279
+ HostProtocolError
280
+ ]);
281
+ const ClientAbortHostFailure = Schema.Union([
282
+ OperationDenied,
283
+ LedgerError,
284
+ OwnershipLost,
285
+ SettlementConflict,
286
+ JoinedToHost,
287
+ DurableRuntimeFailpointError,
288
+ DurableAlarmError,
289
+ HostProtocolError
290
+ ]);
291
+ const ClientApprovalHostFailure = Schema.Union([
292
+ LedgerError,
293
+ OwnershipLost,
294
+ SettlementConflict,
295
+ ApprovalConflict,
296
+ OperationDenied,
297
+ DurableAlarmError,
298
+ HostProtocolError
299
+ ]);
300
+ const ClientUnknownHostFailure = Schema.Union([
301
+ LedgerError,
302
+ OwnershipLost,
303
+ SettlementConflict,
304
+ UnknownResolutionConflict,
305
+ JoinedToHost,
306
+ DurableRuntimeFailpointError,
307
+ OperationDenied,
308
+ DurableAlarmError,
309
+ HostProtocolError
310
+ ]);
311
+ const liveTextProtocolFailure = () => HostProtocolError.make({ message: "Provisional text is incomplete or invalid; discard drafts and read canonical records" });
312
+ const decodeLiveText = (threadId, source) => Stream.suspend(() => {
313
+ const decoder = new TextDecoder("utf-8", {
314
+ fatal: true,
315
+ ignoreBOM: false
316
+ });
317
+ const decode = Schema.decodeUnknownSync(Schema.fromJsonString(Frame));
318
+ let pending = "";
319
+ let pendingBytes = 0;
320
+ let expected = 0;
321
+ let streamId;
322
+ const models = /* @__PURE__ */ new Map();
323
+ const accept = (frame) => {
324
+ if (frame._tag === "Reset") {
325
+ if (frame.streamId === streamId || frame.threadId !== threadId) throw liveTextProtocolFailure();
326
+ streamId = frame.streamId;
327
+ expected = 1;
328
+ models.clear();
329
+ return true;
330
+ }
331
+ if (streamId === void 0 || frame.streamId !== streamId || frame.sequence !== expected++ || frame.event.threadId !== threadId || !isBoundedEvent(frame.event)) throw liveTextProtocolFailure();
332
+ const event = frame.event;
333
+ if (event._tag === "AttemptEnded") {
334
+ for (const [key, model] of models) if (model.attemptId === event.attemptId) models.delete(key);
335
+ return true;
336
+ }
337
+ const key = JSON.stringify([
338
+ event.attemptId,
339
+ event.runId,
340
+ event.turnId,
341
+ event.generation
342
+ ]);
343
+ if (event._tag === "Discard") {
344
+ models.delete(key);
345
+ return true;
346
+ }
347
+ let model = models.get(key);
348
+ if (event.part.type === "text-start") {
349
+ if (model?.parts.has(event.part.id)) throw liveTextProtocolFailure();
350
+ if ([...models.values()].reduce((size, value) => size + value.parts.size, 0) >= 32) throw liveTextProtocolFailure();
351
+ if (model === void 0) {
352
+ model = {
353
+ attemptId: event.attemptId,
354
+ parts: /* @__PURE__ */ new Set()
355
+ };
356
+ models.set(key, model);
357
+ }
358
+ model.parts.add(event.part.id);
359
+ return true;
360
+ }
361
+ if (!model?.parts.has(event.part.id)) throw liveTextProtocolFailure();
362
+ if (event.part.type === "text-end") {
363
+ model.parts.delete(event.part.id);
364
+ if (model.parts.size === 0) models.delete(key);
365
+ }
366
+ return true;
367
+ };
368
+ return Stream.fromReadableStream({
369
+ evaluate: () => source,
370
+ releaseLockOnEnd: true,
371
+ onError: (cause) => ThreadClientError.make({
372
+ threadId,
373
+ message: "Provisional text disconnected; discard drafts and read canonical records",
374
+ cause
375
+ })
376
+ }).pipe(Stream.mapEffect((chunk) => Effect.try({
377
+ try: () => {
378
+ if (!(chunk instanceof Uint8Array)) throw liveTextProtocolFailure();
379
+ const frames = [];
380
+ for (let offset = 0; offset < chunk.byteLength;) {
381
+ const newline = chunk.indexOf(10, offset);
382
+ const end = newline < 0 ? chunk.byteLength : newline;
383
+ pendingBytes += end - offset;
384
+ if (pendingBytes > 32768) throw liveTextProtocolFailure();
385
+ pending += decoder.decode(chunk.subarray(offset, end), { stream: newline < 0 });
386
+ offset = end + 1;
387
+ if (newline < 0) break;
388
+ const frame = decode(pending);
389
+ pending = "";
390
+ pendingBytes = 0;
391
+ if (accept(frame)) frames.push(frame);
392
+ }
393
+ return frames;
394
+ },
395
+ catch: liveTextProtocolFailure
396
+ })), Stream.flatMap(Stream.fromArray), Stream.concat(Stream.fail(liveTextProtocolFailure())));
397
+ });
398
+ const outOfContract = (threadId, operation, observed) => ThreadClientError.make({
399
+ threadId,
400
+ message: boundHostDiagnostic(`The Thread Object answered ${operation} with the out-of-contract ${observed}.`)
401
+ });
402
+ const hostRpcMethods = {
403
+ submit: "submitEncoded",
404
+ awaitSettlement: "awaitSettlementEncoded",
405
+ awaitSettlementRecord: "awaitSettlementRecordEncoded",
406
+ submissionStatus: "submissionStatusEncoded",
407
+ awaitProgress: "awaitProgressEncoded",
408
+ cancelProgress: "cancelProgressEncoded",
409
+ observePage: "observePage",
410
+ abort: "abortEncoded",
411
+ resolveApproval: "resolveApprovalEncoded",
412
+ resolveUnknown: "resolveUnknownEncoded"
413
+ };
414
+ /** Worker-side client over the Thread Object namespace (DEPLOY-010). */
415
+ var CloudflareThreadClient = class CloudflareThreadClient extends Context.Service()("@effect-agent/platform-cloudflare/CloudflareThreadClient") {
416
+ /**
417
+ * Assemble the client from a resolved namespace and the platform Crypto implementation.
418
+ * rpcTracing is the binding name and remains opt-in. Caller authentication, principals,
419
+ * idempotency keys, and definition digests are still explicit submission inputs.
420
+ */
421
+ static layerFromBinding(options) {
422
+ return CloudflareThreadClient.layer.pipe(Layer.provide([ThreadObjectNamespace.layer(options.namespace, options), cloudflareCryptoLayer]));
423
+ }
424
+ static layer = Layer.effect(CloudflareThreadClient)(Effect.gen(function* () {
425
+ const namespace = yield* ThreadObjectNamespace;
426
+ const { rpcTracing } = namespace;
427
+ const crypto = yield* Crypto.Crypto;
428
+ const call = Effect.fnUntraced(function* (threadId, operation, encoded) {
429
+ const traceArgs = rpcTracing === void 0 ? [] : yield* RpcTracing.withRpcTraceContext([]);
430
+ const raw = yield* callThreadObject(threadId, (stub) => stub[hostRpcMethods[operation]](encoded, ...traceArgs), (cause) => ThreadClientError.make({
431
+ threadId,
432
+ message: boundHostDiagnostic(`${operation} did not reach the Thread Object: ${safeCauseMessage(cause, "the RPC failed without a diagnostic")}`),
433
+ cause,
434
+ ...cloudflareFailureSignals(cause)
435
+ })).pipe(Effect.provideService(ThreadObjectNamespace, namespace));
436
+ return yield* decodeHostResponse(raw).pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`The ${operation} answer could not be decoded: ${error.message}`) })));
437
+ }, (effect, threadId, operation) => rpcTracing === void 0 ? Effect.withSpan(effect, "CloudflareThreadClient.call", { attributes: {
438
+ threadId,
439
+ operation
440
+ } }) : RpcTracing.withRpcClientSpan(effect, rpcTracing, hostRpcMethods[operation]));
441
+ const expect = (threadId, operation, resultSchema, failureSchema) => {
442
+ const isExpectedResult = Schema.is(resultSchema);
443
+ const isExpectedFailure = Schema.is(failureSchema);
444
+ return (response) => {
445
+ if (response._tag === "HostFailed") {
446
+ const failure = response.failure;
447
+ return isExpectedFailure(failure) ? Effect.fail(failure) : Effect.fail(outOfContract(threadId, operation, `failure ${failure._tag}`));
448
+ }
449
+ if (!isExpectedResult(response)) return Effect.fail(outOfContract(threadId, operation, `result ${response._tag}`));
450
+ return Effect.succeed(response);
451
+ };
452
+ };
453
+ const readPage = (threadId, options) => Effect.gen(function* () {
454
+ const request = ObservePageRequest.make({
455
+ ...options?.afterSequence === void 0 ? {} : { afterSequence: options.afterSequence },
456
+ limit: options?.limit ?? 256
457
+ });
458
+ const encoded = yield* encodeObservePageRequest(request).pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`observePage request encode failed: ${error.message}`) })));
459
+ const response = yield* call(threadId, "observePage", encoded);
460
+ return (yield* expect(threadId, "observePage", ObservedPage, ClientObserveHostFailure)(response)).records;
461
+ });
462
+ const cancelProgress = (threadId, waiterId) => encodeCancelProgressRequest(CancelProgressRequest.make({ waiterId })).pipe(Effect.mapError(() => void 0), Effect.flatMap((encoded) => call(threadId, "cancelProgress", encoded)), Effect.interruptible, Effect.timeout(PROGRESS_CANCELLATION_TIMEOUT), Effect.asVoid, Effect.ignore);
463
+ return CloudflareThreadClient.of({
464
+ submit: (agent, input, options) => Effect.gen(function* () {
465
+ const encodedInput = yield* Schema.encodeEffect(agent.definition.input)(input).pipe(Effect.mapError((cause) => AgentInputError.make({ message: `Unable to encode Agent input: ${cause.message}` })));
466
+ const inputPayload = yield* Schema.decodeUnknownEffect(PersistedJson)(encodedInput).pipe(Effect.mapError(() => AgentInputError.make({ message: "Agent input does not satisfy the canonical persistence bounds" })));
467
+ const request = SubmitRequest.make({
468
+ agentId: agent.definition.id,
469
+ principal: options.principal,
470
+ idempotencyKey: options.idempotencyKey,
471
+ ...options.admissionGroup === void 0 ? {} : { admissionGroup: options.admissionGroup },
472
+ ...options.admissionFence === void 0 ? {} : { admissionFence: options.admissionFence },
473
+ ...options.workerAdmission === void 0 ? {} : { workerAdmission: options.workerAdmission },
474
+ ...options.messageAdmission === void 0 ? {} : { messageAdmission: options.messageAdmission },
475
+ definitions: options.definitions,
476
+ inputPayload
477
+ });
478
+ const encoded = yield* encodeSubmitRequest(request).pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`submit request encode failed: ${error.message}`) })));
479
+ const response = yield* call(options.threadId, "submit", encoded);
480
+ return (yield* expect(options.threadId, "submit", SubmitSucceeded, ClientSubmitHostFailure)(response)).receipt;
481
+ }),
482
+ submissionStatus: (receipt) => Effect.gen(function* () {
483
+ const encoded = yield* encodeReceipt(receipt).pipe(Effect.mapError(() => HostProtocolError.make({ message: "Invalid receipt" })));
484
+ const response = yield* call(receipt.threadId, "submissionStatus", encoded);
485
+ return (yield* expect(receipt.threadId, "submissionStatus", SubmissionStatusResponse, ClientAwaitHostFailure)(response)).status;
486
+ }),
487
+ awaitSettlement: (receipt) => Effect.gen(function* () {
488
+ const encoded = yield* encodeReceipt(receipt).pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`receipt encode failed: ${error.message}`) })));
489
+ const response = yield* call(receipt.threadId, "awaitSettlement", encoded);
490
+ return (yield* expect(receipt.threadId, "awaitSettlement", SettlementReached, ClientAwaitHostFailure)(response)).settlement;
491
+ }),
492
+ awaitSettlementRecord: (receipt) => Effect.gen(function* () {
493
+ const encoded = yield* encodeReceipt(receipt).pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`receipt encode failed: ${error.message}`) })));
494
+ const response = yield* call(receipt.threadId, "awaitSettlementRecord", encoded);
495
+ return (yield* expect(receipt.threadId, "awaitSettlementRecord", SettlementRecordReached, ClientAwaitHostFailure)(response)).record;
496
+ }),
497
+ awaitProgress: (threadId, afterSequence) => Effect.gen(function* () {
498
+ const waiterId = yield* crypto.randomUUIDv4().pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`awaitProgress cancellation identity generation failed: ${error.message}`) })));
499
+ const request = AwaitProgressRequest.make({
500
+ afterSequence,
501
+ waiterId
502
+ });
503
+ const encoded = yield* encodeAwaitProgressRequest(request).pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`awaitProgress request encode failed: ${error.message}`) })));
504
+ const attempt = (retry) => call(threadId, "awaitProgress", encoded).pipe(Effect.flatMap(expect(threadId, "awaitProgress", ProgressObserved, ClientObserveHostFailure)), Effect.asVoid, Effect.catchTag("ThreadClientError", (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)));
505
+ yield* attempt(0).pipe(Effect.onInterrupt(() => cancelProgress(threadId, waiterId)));
506
+ }),
507
+ watchText: (threadId) => Stream.unwrap(Effect.gen(function* () {
508
+ const traceArgs = rpcTracing === void 0 ? [] : yield* RpcTracing.withRpcTraceContext([]);
509
+ const openingFailure = (cause) => ThreadClientError.make({
510
+ threadId,
511
+ message: "Provisional text observation could not reach the Thread Object",
512
+ cause,
513
+ ...cloudflareFailureSignals(cause)
514
+ });
515
+ const target = yield* RpcTargets.get(namespace, threadId, () => namespace.get(threadId)).pipe(Effect.mapError(openingFailure));
516
+ let request;
517
+ let received;
518
+ let closed = false;
519
+ const cancel = () => {
520
+ const value = received;
521
+ received = void 0;
522
+ return value instanceof ReadableStream && !value.locked ? value.cancel().catch(() => void 0) : Promise.resolve();
523
+ };
524
+ yield* Effect.addFinalizer(() => Effect.try({
525
+ try: () => {
526
+ closed = true;
527
+ if (Predicate.hasProperty(request, Symbol.dispose)) {
528
+ const dispose = request[Symbol.dispose];
529
+ if (typeof dispose === "function") dispose.call(request);
530
+ }
531
+ },
532
+ catch: () => void 0
533
+ }).pipe(Effect.ignore, Effect.andThen(Effect.tryPromise({
534
+ try: cancel,
535
+ catch: () => void 0
536
+ }).pipe(Effect.interruptible, Effect.timeout(PROGRESS_CANCELLATION_TIMEOUT), Effect.ignore))));
537
+ const raw = yield* Effect.tryPromise({
538
+ try: () => {
539
+ request = target.watchTextEncoded(Schema.encodeSync(Request)({ schemaVersion: 1 }), ...traceArgs);
540
+ return request.then((value) => {
541
+ received = value;
542
+ return closed ? cancel().then(() => value) : value;
543
+ });
544
+ },
545
+ catch: openingFailure
546
+ }).pipe(Effect.interruptible, Effect.tapCause(() => RpcTargets.invalidate(target)));
547
+ if (raw instanceof ReadableStream) return decodeLiveText(threadId, raw);
548
+ const response = yield* decodeHostResponse(raw).pipe(Effect.mapError(liveTextProtocolFailure));
549
+ if (response._tag === "HostFailed" && Schema.is(ClientObserveHostFailure)(response.failure)) return yield* response.failure;
550
+ return yield* liveTextProtocolFailure();
551
+ })),
552
+ readPage,
553
+ readAll: (threadId) => Effect.gen(function* () {
554
+ const all = [];
555
+ let after;
556
+ for (;;) {
557
+ const page = yield* readPage(threadId, {
558
+ afterSequence: after,
559
+ limit: 1024
560
+ });
561
+ all.push(...page);
562
+ const last = page.at(-1);
563
+ if (page.length < 1024 || last === void 0) return all;
564
+ after = last.sequence;
565
+ }
566
+ }),
567
+ abort: (threadId, command) => Effect.gen(function* () {
568
+ const encoded = yield* encodeAbortCommand(command).pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`abort command encode failed: ${error.message}`) })));
569
+ const response = yield* call(threadId, "abort", encoded);
570
+ return (yield* expect(threadId, "abort", AbortRecorded, ClientAbortHostFailure)(response)).intent;
571
+ }),
572
+ resolveApproval: (threadId, command) => Effect.gen(function* () {
573
+ const encoded = yield* encodeApprovalDecisionCommand(command).pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`approval command encode failed: ${error.message}`) })));
574
+ const response = yield* call(threadId, "resolveApproval", encoded);
575
+ return (yield* expect(threadId, "resolveApproval", ApprovalRecorded, ClientApprovalHostFailure)(response)).intent;
576
+ }),
577
+ resolveUnknown: (threadId, command) => Effect.gen(function* () {
578
+ const encoded = yield* encodeUnknownResolutionCommand(command).pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`resolution command encode failed: ${error.message}`) })));
579
+ const response = yield* call(threadId, "resolveUnknown", encoded);
580
+ return (yield* expect(threadId, "resolveUnknown", UnknownResolutionRecorded, ClientUnknownHostFailure)(response)).intent;
581
+ })
582
+ });
583
+ }));
584
+ };
585
+ //#endregion
586
+ export { decodeSubmitRequest as A, encodeUnknownResolutionCommand as B, decodeAbortCommand as C, decodeHostResponse as D, decodeCancelProgressRequest as E, encodeCancelProgressRequest as F, Request as G, MAX_DELTA_LENGTH as H, encodeHostResponse as I, isBoundedEvent as K, encodeObservePageRequest as L, encodeAbortCommand as M, encodeApprovalDecisionCommand as N, decodeObservePageRequest as O, encodeAwaitProgressRequest as P, encodeReceipt as R, boundHostDiagnostic as S, decodeAwaitProgressRequest as T, MAX_DRAFT_LENGTH as U, Frame as V, MAX_FRAME_BYTES as W, SubmissionStatusResponse as _, CloudflareThreadClient as a, ThreadClientError as b, HostFailure as c, ObservePageRequest as d, ObservedPage as f, SettlementRecordReached as g, SettlementReached as h, CancelProgressRequest as i, decodeUnknownResolutionCommand as j, decodeReceipt as k, HostProtocolError as l, ProgressObserved as m, ApprovalRecorded as n, CloudflareThreadClient_exports as o, ProgressCancelled as p, cloudflareCryptoLayer as q, AwaitProgressRequest as r, HostFailed as s, AbortRecorded as t, HostResponse as u, SubmitRequest as v, decodeApprovalDecisionCommand as w, UnknownResolutionRecorded as x, SubmitSucceeded as y, encodeSubmitRequest as z };
587
+
588
+ //# sourceMappingURL=CloudflareThreadClient-CLZpN9zU.mjs.map