@effect-agent/platform-cloudflare 0.1.0-beta.91 → 0.1.0-beta.93

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.
@@ -1348,41 +1348,15 @@ declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorded | Hos
1348
1348
  } | {
1349
1349
  readonly _tag: "HostFailed";
1350
1350
  readonly failure: {
1351
- readonly _tag: "DurableAlarmError";
1352
- readonly operation: string;
1351
+ readonly _tag: "HostProtocolError";
1353
1352
  readonly message: string;
1354
- readonly cause?: Schema.Json | undefined;
1355
1353
  } | {
1356
- readonly _tag: "LedgerError";
1357
- readonly operation: string;
1354
+ readonly _tag: "AgentInputError";
1358
1355
  readonly message: string;
1359
- readonly cause?: Schema.Json | undefined;
1360
- } | {
1361
- readonly _tag: "AppendConflict";
1362
- readonly threadId: string;
1363
- readonly batchId: string;
1364
- readonly reason: "batch-digest" | "record-identity" | "tail";
1365
- readonly actualTailSequence?: number | undefined;
1366
- readonly actualTailDigest?: string | undefined;
1367
- } | {
1368
- readonly _tag: "FenceRejected";
1369
- readonly threadId: string;
1370
- readonly actualEpoch: number;
1371
- readonly attemptedEpoch: number;
1372
- } | {
1373
- readonly _tag: "ThreadNotMaterialized";
1374
- readonly threadId: string;
1375
1356
  } | {
1376
- readonly _tag: "ThreadStoreError";
1377
- readonly operation: string;
1357
+ readonly _tag: "DigestError";
1378
1358
  readonly message: string;
1379
1359
  readonly cause?: Schema.Json | undefined;
1380
- } | {
1381
- readonly _tag: "OperationDenied";
1382
- readonly operation: "abort" | "awaitSettlement" | "explain" | "observe" | "resolveApproval" | "resolveUnknown" | "retry" | "scanObligations" | "verify" | "wake";
1383
- readonly reason: string;
1384
- readonly threadId?: string | undefined;
1385
- readonly submissionId?: string | undefined;
1386
1360
  } | {
1387
1361
  readonly _tag: "AdmissionConflict";
1388
1362
  readonly threadId: string;
@@ -1394,27 +1368,10 @@ declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorded | Hos
1394
1368
  readonly _tag: "AdmissionPolicyError";
1395
1369
  readonly reason: "occupied" | "refused" | "unavailable";
1396
1370
  readonly code: string;
1397
- } | {
1398
- readonly _tag: "AgentInputError";
1399
- readonly message: string;
1400
- } | {
1401
- readonly _tag: "DigestError";
1402
- readonly message: string;
1403
- readonly cause?: Schema.Json | undefined;
1404
- } | {
1405
- readonly _tag: "DurableRuntimeFailpointError";
1406
- readonly location: "abort:after-intent" | "approval:after-request-append" | "approval:after-suspend" | "checkpoint:after-save" | "checkpoint:before-save" | "claim:after-claim" | "compaction:after-canonical-append" | "compaction:before-canonical-append" | "input:after-canonical-append" | "join:after-canonical-append" | "join:after-claim" | "policy:after-reservation-append" | "policy:before-reservation-append" | "resolve:after-intent" | "run:after-start-append" | "run:before-start-append" | "step:after-step-append" | "subagent:after-admit" | "subagent:after-child-abort-intent" | "subagent:after-child-ready" | "subagent:after-join-append" | "subagent:after-release" | "subagent:after-release-pending" | "subagent:after-request-append" | "subagent:after-reserve" | "subagent:after-sibling-settle" | "subagent:after-start-append" | "subagent:after-suspend" | "subagent:before-join-append" | "submit:after-admit" | "submit:after-materialize" | "terminalize:after-canonical-append" | "terminalize:after-reserve" | "tools:after-prepared-append" | "tools:before-prepared-append" | "turn:after-canonical-append" | "turn:after-response-append" | "turn:after-results-append" | "update:after-canonical-append" | "update:after-delivery-insert" | "update:before-canonical-append" | "update:before-delivery-insert" | "worker:after-completion-append" | "worker:after-origin-append" | "worker:after-report-append" | "worker:after-report-delivery" | "worker:after-source-append" | "worker:after-subtree-append" | "worker:before-completion-append" | "worker:before-origin-append" | "worker:before-report-append" | "worker:before-report-delivery" | "worker:before-source-append" | "worker:before-subtree-append";
1407
1371
  } | {
1408
1372
  readonly _tag: "SettlementConflict";
1409
1373
  readonly submissionId: string;
1410
1374
  readonly existingOutcome: "aborted" | "completed" | "failed";
1411
- } | {
1412
- readonly _tag: "JoinedToHost";
1413
- readonly submissionId: string;
1414
- readonly hostSubmissionId: string;
1415
- } | {
1416
- readonly _tag: "HostProtocolError";
1417
- readonly message: string;
1418
1375
  } | {
1419
1376
  readonly _tag: "ApprovalConflict";
1420
1377
  readonly submissionId: string;
@@ -1424,11 +1381,54 @@ declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorded | Hos
1424
1381
  readonly _tag: "UnknownResolutionConflict";
1425
1382
  readonly submissionId: string;
1426
1383
  readonly toolCallId: string;
1384
+ } | {
1385
+ readonly _tag: "JoinedToHost";
1386
+ readonly submissionId: string;
1387
+ readonly hostSubmissionId: string;
1388
+ } | {
1389
+ readonly _tag: "LedgerError";
1390
+ readonly operation: string;
1391
+ readonly message: string;
1392
+ readonly cause?: Schema.Json | undefined;
1393
+ } | {
1394
+ readonly _tag: "ThreadStoreError";
1395
+ readonly operation: string;
1396
+ readonly message: string;
1397
+ readonly cause?: Schema.Json | undefined;
1398
+ } | {
1399
+ readonly _tag: "ThreadNotMaterialized";
1400
+ readonly threadId: string;
1401
+ } | {
1402
+ readonly _tag: "AppendConflict";
1403
+ readonly threadId: string;
1404
+ readonly batchId: string;
1405
+ readonly reason: "batch-digest" | "record-identity" | "tail";
1406
+ readonly actualTailSequence?: number | undefined;
1407
+ readonly actualTailDigest?: string | undefined;
1408
+ } | {
1409
+ readonly _tag: "FenceRejected";
1410
+ readonly threadId: string;
1411
+ readonly actualEpoch: number;
1412
+ readonly attemptedEpoch: number;
1413
+ } | {
1414
+ readonly _tag: "DurableRuntimeFailpointError";
1415
+ readonly location: "abort:after-intent" | "approval:after-request-append" | "approval:after-suspend" | "checkpoint:after-save" | "checkpoint:before-save" | "claim:after-claim" | "compaction:after-canonical-append" | "compaction:before-canonical-append" | "input:after-canonical-append" | "join:after-canonical-append" | "join:after-claim" | "policy:after-reservation-append" | "policy:before-reservation-append" | "resolve:after-intent" | "run:after-start-append" | "run:before-start-append" | "step:after-step-append" | "subagent:after-admit" | "subagent:after-child-abort-intent" | "subagent:after-child-ready" | "subagent:after-join-append" | "subagent:after-release" | "subagent:after-release-pending" | "subagent:after-request-append" | "subagent:after-reserve" | "subagent:after-sibling-settle" | "subagent:after-start-append" | "subagent:after-suspend" | "subagent:before-join-append" | "submit:after-admit" | "submit:after-materialize" | "terminalize:after-canonical-append" | "terminalize:after-reserve" | "tools:after-prepared-append" | "tools:before-prepared-append" | "turn:after-canonical-append" | "turn:after-response-append" | "turn:after-results-append" | "update:after-canonical-append" | "update:after-delivery-insert" | "update:before-canonical-append" | "update:before-delivery-insert" | "worker:after-completion-append" | "worker:after-origin-append" | "worker:after-report-append" | "worker:after-report-delivery" | "worker:after-source-append" | "worker:after-subtree-append" | "worker:before-completion-append" | "worker:before-origin-append" | "worker:before-report-append" | "worker:before-report-delivery" | "worker:before-source-append" | "worker:before-subtree-append";
1427
1416
  } | {
1428
1417
  readonly _tag: "AdmissionLimitExceeded";
1429
1418
  readonly limit: "database-bytes" | "input-bytes" | "queue-depth";
1430
1419
  readonly actual: number;
1431
1420
  readonly maximum: number;
1421
+ } | {
1422
+ readonly _tag: "DurableAlarmError";
1423
+ readonly operation: string;
1424
+ readonly message: string;
1425
+ readonly cause?: Schema.Json | undefined;
1426
+ } | {
1427
+ readonly _tag: "OperationDenied";
1428
+ readonly operation: "abort" | "awaitSettlement" | "explain" | "observe" | "resolveApproval" | "resolveUnknown" | "retry" | "scanObligations" | "verify" | "wake";
1429
+ readonly reason: string;
1430
+ readonly threadId?: string | undefined;
1431
+ readonly submissionId?: string | undefined;
1432
1432
  };
1433
1433
  }, Schema.SchemaError, never>;
1434
1434
  declare const decodeHostResponse: (input: unknown, options?: import("effect/SchemaAST").ParseOptions) => Effect.Effect<AbortRecorded | ApprovalRecorded | HostFailed | ObservedPage | ProgressCancelled | ProgressObserved | SettlementReached | SubmissionStatusResponse | SubmitSucceeded | UnknownResolutionRecorded, Schema.SchemaError, never>;
@@ -1,4 +1,4 @@
1
- import { Clock, Context, Duration, Effect, Layer, Option, Redacted, Ref, Schema, Semaphore, Stream } from "effect";
1
+ import { Clock, Context, Duration, Effect, Layer, Option, Redacted, Ref, Schema, Scope, Semaphore, Stream } from "effect";
2
2
  import { PageScreenshotResult } from "effect-agent/page-screenshot";
3
3
  import { SandboxImplementation } from "effect-agent/sandbox";
4
4
  import { FetchHttpClient, HttpClient, HttpClientRequest } from "effect/unstable/http";
@@ -226,17 +226,15 @@ var BrowserRunHandoffState = class extends Schema.Class("BrowserRunHandoffState"
226
226
  handoffId: Schema.optionalKey(Schema.Redacted(BoundedHostText)),
227
227
  durationMs: Schema.optionalKey(HandoffDuration)
228
228
  }) {};
229
- /** Host-supplied Browser Run binding projected into one fakeable launch operation. */
229
+ /** Host-supplied Browser Run allocation and connection transport. */
230
230
  var BrowserRunInteractiveBinding = class BrowserRunInteractiveBinding extends Context.Service()("@effect-agent/platform-cloudflare/BrowserRunInteractiveBinding") {
231
231
  static layer(options) {
232
232
  return Layer.effect(BrowserRunInteractiveBinding)(Effect.gen(function* () {
233
233
  const lifecycle = yield* BrowserRunSessionLifecycle;
234
234
  const viewport = options.viewport === void 0 ? void 0 : yield* decodeViewport(options.viewport);
235
235
  return {
236
- launch: async (keepAliveMillis) => makeProductionBrowser(await puppeteer.launch(options.browser, {
237
- keep_alive: keepAliveMillis,
238
- ...viewport === void 0 ? {} : { defaultViewport: { ...viewport } }
239
- })),
236
+ acquire: async (keepAliveMillis) => (await puppeteer.acquire(options.browser, { keep_alive: keepAliveMillis })).sessionId,
237
+ connect: async (sessionId) => makeProductionBrowser(await puppeteer.connect(options.browser, sessionId), viewport),
240
238
  closeSession: (sessionId) => lifecycle.close(sessionId).pipe(Effect.mapError((cause) => actionError("close", cause)))
241
239
  };
242
240
  }));
@@ -631,12 +629,16 @@ const makeProductionPage = (page) => {
631
629
  setViewport: (viewport) => page.setViewport(viewport)
632
630
  };
633
631
  };
634
- const makeProductionContext = (context) => ({
635
- newPage: async () => makeProductionPage(await context.newPage()),
632
+ const makeProductionContext = (context, viewport) => ({
633
+ newPage: async () => {
634
+ const page = await context.newPage();
635
+ if (viewport !== void 0) await page.setViewport(viewport);
636
+ return makeProductionPage(page);
637
+ },
636
638
  close: () => context.close()
637
639
  });
638
- const makeProductionBrowser = (browser) => ({
639
- createContext: async () => makeProductionContext(await browser.createBrowserContext()),
640
+ const makeProductionBrowser = (browser, viewport) => ({
641
+ createContext: async () => makeProductionContext(await browser.createBrowserContext(), viewport),
640
642
  close: () => browser.close(),
641
643
  sessionId: () => browser.sessionId(),
642
644
  isConnected: () => browser.isConnected(),
@@ -680,7 +682,7 @@ const causeText = (cause) => {
680
682
  const isCapacityRefusal = (cause) => /(^|\D)429(\D|$)|browser time limit|capacity|too many concurrent/i.test(causeText(cause));
681
683
  const isRemoteClosure = (cause) => /target closed|browser.*closed|session.*closed|connection.*closed|not connected|websocket.*closed/i.test(causeText(cause));
682
684
  const snapshotPolicy = Effect.fn("BrowserRunInteractive.snapshotPolicy")(function* (input) {
683
- const decoded = yield* Schema.decodeEffect(InteractiveBrowserPolicy)(input).pipe(Effect.mapError(() => policyError("The interactive browser policy is malformed")));
685
+ const decoded = yield* Schema.decodeEffect(InteractiveBrowserPolicy, { onExcessProperty: "error" })(input).pipe(Effect.mapError(() => policyError("The interactive browser policy is malformed")));
684
686
  if (decoded.network._tag === "PublicWeb") return yield* InteractiveBrowserUnsupportedError.make({
685
687
  implementation: browserRunInteractiveImplementation,
686
688
  feature: "policy",
@@ -1019,7 +1021,8 @@ const makeHostService = (binding) => {
1019
1021
  }).pipe(Effect.flatMap(Schema.decodeUnknownEffect(BrowserRunSessionId)), Effect.mapError(() => actionError("close")), Effect.onError(() => closeWithWarning(browser.close, "Closing an unidentified browser failed")));
1020
1022
  yield* terminate(Redacted.make(sessionId), [closeEntry(browser.close, "Closing the local browser connection failed")]);
1021
1023
  });
1022
- const open = Effect.fn("BrowserRunInteractiveHost.open")(function* (policy) {
1024
+ const acquire = Effect.fn("BrowserRunInteractiveHost.acquire")(function* (policy) {
1025
+ const scope = yield* Scope.Scope;
1023
1026
  const fixedPolicy = yield* snapshotPolicy(policy);
1024
1027
  const startedAt = yield* Effect.clockWith((clock) => clock.currentTimeMillis);
1025
1028
  const runCleanup = Effect.runPromiseWith(Context.make(Clock.Clock, yield* Clock.Clock));
@@ -1033,110 +1036,118 @@ const makeHostService = (binding) => {
1033
1036
  const lifecycle = { managedTeardownInstalled: false };
1034
1037
  const closers = [];
1035
1038
  const releaseBeforeManaged = (entry) => Effect.suspend(() => lifecycle.managedTeardownInstalled ? Effect.void : entry.close.pipe(Effect.catchCause(() => Effect.logWarning(entry.warning))));
1036
- const browser = yield* Effect.acquireRelease(withinDeadline(Effect.tryPromise({
1037
- try: (signal) => closeLateAcquisition(signal, () => binding.launch(keepAliveMillis(fixedPolicy)), (acquired) => runCleanup(closeAcquired(acquired))),
1039
+ const sessionIdValue = yield* Effect.acquireRelease(withinDeadline(Effect.tryPromise({
1040
+ try: (signal) => closeLateAcquisition(signal, () => binding.acquire(keepAliveMillis(fixedPolicy)), (id) => runCleanup(Schema.decodeUnknownEffect(BrowserRunSessionId)(id).pipe(Effect.flatMap((value) => terminate(Redacted.make(value), []))))),
1038
1041
  catch: (cause) => isCapacityRefusal(cause) ? InteractiveBrowserCapacityError.make({
1039
1042
  implementation: browserRunInteractiveImplementation,
1040
1043
  message: "Browser Run has no capacity for a new browser session"
1041
- }) : protocolError("Launching the Browser Run session failed", cause)
1042
- }), fixedPolicy, startedAt), (acquired) => {
1043
- state.disconnected.value = true;
1044
- return lifecycle.managedTeardownInstalled ? Effect.void : closeAcquired(acquired).pipe(Effect.catch(() => Effect.logWarning("Whole-browser cleanup remains unconfirmed")));
1045
- }, { interruptible: true });
1046
- closers.push(closeEntry(browser.close, "Closing the interactive browser failed"));
1047
- const disconnected = () => {
1048
- state.disconnected.value = true;
1049
- };
1050
- yield* Effect.acquireRelease(Effect.try({
1051
- try: () => browser.onDisconnected(disconnected),
1052
- catch: (cause) => protocolError("Installing the browser disconnect listener failed", cause)
1053
- }), () => releaseBeforeManaged(syncCloseEntry(() => browser.offDisconnected(disconnected), "Removing the browser disconnect listener failed")));
1054
- closers.push(syncCloseEntry(() => browser.offDisconnected(disconnected), "Removing the browser disconnect listener failed"));
1055
- if (!(yield* Effect.try({
1056
- try: browser.isConnected,
1057
- catch: (cause) => protocolError("Reading the Browser Run connection state failed", cause)
1058
- }))) {
1044
+ }) : protocolError("Acquiring the Browser Run session failed", cause)
1045
+ }).pipe(Effect.flatMap(Schema.decodeUnknownEffect(BrowserRunSessionId)), Effect.catchTag("SchemaError", () => protocolError("The Browser Run session identity was malformed"))), fixedPolicy, startedAt), (id) => Effect.suspend(() => {
1046
+ state.closed.value = true;
1059
1047
  state.disconnected.value = true;
1060
- return yield* expiredError();
1061
- }
1062
- const sessionIdValue = yield* Effect.try({
1063
- try: browser.sessionId,
1064
- catch: (cause) => protocolError("Reading the Browser Run session identity failed", cause)
1065
- }).pipe(Effect.flatMap((value) => Schema.decodeUnknownEffect(BrowserRunSessionId)(value).pipe(Effect.mapError(() => protocolError("The Browser Run session identity was malformed")))));
1066
- const context = yield* Effect.acquireRelease(withinDeadline(Effect.tryPromise({
1067
- try: (signal) => closeLateAcquisition(signal, browser.createContext, (acquired) => acquired.close()),
1068
- catch: (cause) => state.disconnected.value || isRemoteClosure(cause) ? expiredError() : protocolError("Creating the browser context failed", cause)
1069
- }), fixedPolicy, startedAt), (acquired) => releaseBeforeManaged(closeEntry(acquired.close, "Closing the interactive browser context failed")), { interruptible: true });
1070
- closers.push(closeEntry(context.close, "Closing the interactive browser context failed"));
1071
- const page = yield* Effect.acquireRelease(withinDeadline(Effect.tryPromise({
1072
- try: (signal) => closeLateAcquisition(signal, context.newPage, (acquired) => acquired.close()),
1073
- catch: (cause) => state.disconnected.value || isRemoteClosure(cause) ? expiredError() : protocolError("Creating the browser page failed", cause)
1074
- }), fixedPolicy, startedAt), (acquired) => releaseBeforeManaged(closeEntry(acquired.close, "Closing the interactive browser page failed")), { interruptible: true });
1075
- closers.push(closeEntry(page.close, "Closing the interactive browser page failed"));
1076
- yield* withinDeadline(Effect.tryPromise({
1077
- try: () => page.setBypassServiceWorker(true),
1078
- catch: (cause) => protocolError("Bypassing browser service workers failed", cause)
1079
- }), fixedPolicy, startedAt);
1080
- const requestListener = makeRequestListener(fixedPolicy, state);
1081
- yield* Effect.acquireRelease(Effect.try({
1082
- try: () => page.onRequest(requestListener),
1083
- catch: (cause) => protocolError("Installing the browser request listener failed", cause)
1084
- }), () => releaseBeforeManaged(syncCloseEntry(() => page.offRequest(requestListener), "Removing the browser request policy failed")));
1085
- closers.push(syncCloseEntry(() => page.offRequest(requestListener), "Removing the browser request policy failed"));
1086
- yield* withinDeadline(Effect.tryPromise({
1087
- try: () => page.setRequestInterception(true),
1088
- catch: (cause) => protocolError("Installing the browser request policy failed", cause)
1089
- }), fixedPolicy, startedAt);
1090
- yield* withinDeadline(awaitPendingRequests(state), fixedPolicy, startedAt);
1091
- const setupFailure = stateFailure(state);
1092
- if (setupFailure !== void 0) return yield* setupFailure;
1093
- const teardown = yield* Effect.uninterruptible(Effect.gen(function* () {
1094
- const cached = yield* Effect.cached(terminate(Redacted.make(sessionIdValue), closers));
1095
- lifecycle.managedTeardownInstalled = true;
1096
- yield* Effect.addFinalizer(() => Effect.uninterruptible(Effect.sync(() => {
1048
+ return lifecycle.managedTeardownInstalled ? Effect.void : terminate(Redacted.make(id), []).pipe(Effect.catch(() => Effect.logWarning("Whole-browser cleanup remains unconfirmed")));
1049
+ }), { interruptible: true });
1050
+ const connect = yield* Effect.cached(Effect.gen(function* () {
1051
+ const browser = yield* Effect.acquireRelease(withinDeadline(Effect.tryPromise({
1052
+ try: (signal) => closeLateAcquisition(signal, () => binding.connect(sessionIdValue), (acquired) => runCleanup(closeAcquired(acquired))),
1053
+ catch: (cause) => protocolError("Connecting to the Browser Run session failed", cause)
1054
+ }), fixedPolicy, startedAt), (acquired) => releaseBeforeManaged(closeEntry(acquired.close, "Closing the local browser connection failed")), { interruptible: true });
1055
+ closers.push(closeEntry(browser.close, "Closing the interactive browser failed"));
1056
+ const disconnected = () => {
1057
+ state.disconnected.value = true;
1058
+ };
1059
+ yield* Effect.acquireRelease(Effect.try({
1060
+ try: () => browser.onDisconnected(disconnected),
1061
+ catch: (cause) => protocolError("Installing the browser disconnect listener failed", cause)
1062
+ }), () => releaseBeforeManaged(syncCloseEntry(() => browser.offDisconnected(disconnected), "Removing the browser disconnect listener failed")));
1063
+ closers.push(syncCloseEntry(() => browser.offDisconnected(disconnected), "Removing the browser disconnect listener failed"));
1064
+ if (!(yield* Effect.try({
1065
+ try: browser.isConnected,
1066
+ catch: (cause) => protocolError("Reading the Browser Run connection state failed", cause)
1067
+ }))) {
1068
+ state.disconnected.value = true;
1069
+ return yield* expiredError();
1070
+ }
1071
+ const context = yield* Effect.acquireRelease(withinDeadline(Effect.tryPromise({
1072
+ try: (signal) => closeLateAcquisition(signal, browser.createContext, (acquired) => acquired.close()),
1073
+ catch: (cause) => state.disconnected.value || isRemoteClosure(cause) ? expiredError() : protocolError("Creating the browser context failed", cause)
1074
+ }), fixedPolicy, startedAt), (acquired) => releaseBeforeManaged(closeEntry(acquired.close, "Closing the interactive browser context failed")), { interruptible: true });
1075
+ closers.push(closeEntry(context.close, "Closing the interactive browser context failed"));
1076
+ const page = yield* Effect.acquireRelease(withinDeadline(Effect.tryPromise({
1077
+ try: (signal) => closeLateAcquisition(signal, context.newPage, (acquired) => acquired.close()),
1078
+ catch: (cause) => state.disconnected.value || isRemoteClosure(cause) ? expiredError() : protocolError("Creating the browser page failed", cause)
1079
+ }), fixedPolicy, startedAt), (acquired) => releaseBeforeManaged(closeEntry(acquired.close, "Closing the interactive browser page failed")), { interruptible: true });
1080
+ closers.push(closeEntry(page.close, "Closing the interactive browser page failed"));
1081
+ yield* withinDeadline(Effect.tryPromise({
1082
+ try: () => page.setBypassServiceWorker(true),
1083
+ catch: (cause) => protocolError("Bypassing browser service workers failed", cause)
1084
+ }), fixedPolicy, startedAt);
1085
+ const requestListener = makeRequestListener(fixedPolicy, state);
1086
+ yield* Effect.acquireRelease(Effect.try({
1087
+ try: () => page.onRequest(requestListener),
1088
+ catch: (cause) => protocolError("Installing the browser request listener failed", cause)
1089
+ }), () => releaseBeforeManaged(syncCloseEntry(() => page.offRequest(requestListener), "Removing the browser request policy failed")));
1090
+ closers.push(syncCloseEntry(() => page.offRequest(requestListener), "Removing the browser request policy failed"));
1091
+ yield* withinDeadline(Effect.tryPromise({
1092
+ try: () => page.setRequestInterception(true),
1093
+ catch: (cause) => protocolError("Installing the browser request policy failed", cause)
1094
+ }), fixedPolicy, startedAt);
1095
+ yield* withinDeadline(awaitPendingRequests(state), fixedPolicy, startedAt);
1096
+ const setupFailure = stateFailure(state);
1097
+ if (setupFailure !== void 0) return yield* setupFailure;
1098
+ const teardown = yield* Effect.uninterruptible(Effect.gen(function* () {
1099
+ const cached = yield* Effect.cached(terminate(Redacted.make(sessionIdValue), closers));
1100
+ lifecycle.managedTeardownInstalled = true;
1101
+ yield* Effect.addFinalizer(() => Effect.uninterruptible(Effect.sync(() => {
1102
+ state.closed.value = true;
1103
+ state.disconnected.value = true;
1104
+ }).pipe(Effect.andThen(cached), Effect.catch(() => Effect.logWarning("Whole-browser cleanup remains unconfirmed")))));
1105
+ return cached;
1106
+ }));
1107
+ const close = Effect.uninterruptible(Effect.sync(() => {
1097
1108
  state.closed.value = true;
1098
1109
  state.disconnected.value = true;
1099
- }).pipe(Effect.andThen(cached), Effect.catch(() => Effect.logWarning("Whole-browser cleanup remains unconfirmed")))));
1100
- return cached;
1101
- }));
1102
- const close = Effect.uninterruptible(Effect.sync(() => {
1103
- state.closed.value = true;
1104
- state.disconnected.value = true;
1105
- }).pipe(Effect.andThen(teardown)));
1106
- const runtime = yield* makeHandle(page, fixedPolicy, startedAt, state, close);
1107
- const currentPagePreflight = decodeActionResult(page, fixedPolicy).pipe(Effect.asVoid);
1108
- const requestFitsSession = (requestedMillis) => remainingMillis(fixedPolicy, startedAt).pipe(Effect.flatMap((remaining) => remaining > 0 && requestedMillis <= remaining ? Effect.void : Effect.fail(policyError("The host browser request exceeds the remaining session time"))));
1110
+ }).pipe(Effect.andThen(teardown)));
1111
+ const runtime = yield* makeHandle(page, fixedPolicy, startedAt, state, close);
1112
+ const currentPagePreflight = decodeActionResult(page, fixedPolicy).pipe(Effect.asVoid);
1113
+ const requestFitsSession = (requestedMillis) => remainingMillis(fixedPolicy, startedAt).pipe(Effect.flatMap((remaining) => remaining > 0 && requestedMillis <= remaining ? Effect.void : Effect.fail(policyError("The host browser request exceeds the remaining session time"))));
1114
+ return {
1115
+ handle: runtime.handle,
1116
+ sessionId: Redacted.make(sessionIdValue),
1117
+ resizeViewport: (viewport) => decodeViewport(viewport).pipe(Effect.flatMap((decoded) => runtime.run(Effect.tryPromise({
1118
+ try: () => page.setViewport(decoded),
1119
+ catch: (cause) => {
1120
+ if (state.disconnected.value || isRemoteClosure(cause)) {
1121
+ state.disconnected.value = true;
1122
+ return expiredError();
1123
+ }
1124
+ return protocolError("Resizing the browser viewport failed", cause);
1125
+ }
1126
+ }), currentPagePreflight, false))),
1127
+ getLiveView: (request) => Schema.decodeEffect(BrowserRunLiveViewRequest)(request).pipe(Effect.mapError(() => policyError("The Live View request is malformed")), Effect.flatMap((decoded) => runtime.run(cdpCommand(page, state, "Cloudflare.getLiveView", {
1128
+ mode: decoded.mode,
1129
+ expiresInMs: decoded.expiresInMs
1130
+ }, LiveViewObservation, "Cloudflare returned a malformed Live View response").pipe(Effect.flatMap((observation) => Schema.decodeEffect(BrowserRunLiveViewResult)({ devtoolsFrontendUrl: Redacted.make(observation.devtoolsFrontendUrl) }).pipe(Effect.mapError(() => protocolError("Cloudflare returned a malformed Live View response"))))), currentPagePreflight.pipe(Effect.andThen(requestFitsSession(decoded.expiresInMs)))))),
1131
+ handoff: (request) => Schema.decodeEffect(BrowserRunHandoffRequest)(request).pipe(Effect.mapError(() => policyError("The browser handoff request is malformed")), Effect.flatMap((decoded) => runtime.run(cdpCommand(page, state, "Cloudflare.handoff", {
1132
+ instructions: decoded.instructions,
1133
+ timeout: decoded.timeout
1134
+ }, HandoffObservation, "Cloudflare returned a malformed browser handoff response").pipe(Effect.flatMap((observation) => Schema.decodeEffect(BrowserRunHandoffResult)({ handoffId: Redacted.make(observation.handoffId) }).pipe(Effect.mapError(() => protocolError("Cloudflare returned a malformed browser handoff response"))))), currentPagePreflight.pipe(Effect.andThen(requestFitsSession(decoded.timeout)))))),
1135
+ getHandoffState: runtime.run(cdpCommand(page, state, "Cloudflare.getHandoffState", {}, HandoffStateObservation, "Cloudflare returned a malformed browser handoff state").pipe(Effect.flatMap((observation) => Schema.decodeEffect(BrowserRunHandoffState)({
1136
+ active: observation.active,
1137
+ ...observation.handoffId === void 0 ? {} : { handoffId: Redacted.make(observation.handoffId) },
1138
+ ...observation.durationMs === void 0 ? {} : { durationMs: observation.durationMs }
1139
+ }).pipe(Effect.mapError(() => protocolError("Cloudflare returned a malformed browser handoff state"))))), currentPagePreflight),
1140
+ close
1141
+ };
1142
+ }).pipe(Effect.provideService(Scope.Scope, scope)));
1109
1143
  return {
1110
- handle: runtime.handle,
1111
1144
  sessionId: Redacted.make(sessionIdValue),
1112
- resizeViewport: (viewport) => decodeViewport(viewport).pipe(Effect.flatMap((decoded) => runtime.run(Effect.tryPromise({
1113
- try: () => page.setViewport(decoded),
1114
- catch: (cause) => {
1115
- if (state.disconnected.value || isRemoteClosure(cause)) {
1116
- state.disconnected.value = true;
1117
- return expiredError();
1118
- }
1119
- return protocolError("Resizing the browser viewport failed", cause);
1120
- }
1121
- }), currentPagePreflight, false))),
1122
- getLiveView: (request) => Schema.decodeEffect(BrowserRunLiveViewRequest)(request).pipe(Effect.mapError(() => policyError("The Live View request is malformed")), Effect.flatMap((decoded) => runtime.run(cdpCommand(page, state, "Cloudflare.getLiveView", {
1123
- mode: decoded.mode,
1124
- expiresInMs: decoded.expiresInMs
1125
- }, LiveViewObservation, "Cloudflare returned a malformed Live View response").pipe(Effect.flatMap((observation) => Schema.decodeEffect(BrowserRunLiveViewResult)({ devtoolsFrontendUrl: Redacted.make(observation.devtoolsFrontendUrl) }).pipe(Effect.mapError(() => protocolError("Cloudflare returned a malformed Live View response"))))), currentPagePreflight.pipe(Effect.andThen(requestFitsSession(decoded.expiresInMs)))))),
1126
- handoff: (request) => Schema.decodeEffect(BrowserRunHandoffRequest)(request).pipe(Effect.mapError(() => policyError("The browser handoff request is malformed")), Effect.flatMap((decoded) => runtime.run(cdpCommand(page, state, "Cloudflare.handoff", {
1127
- instructions: decoded.instructions,
1128
- timeout: decoded.timeout
1129
- }, HandoffObservation, "Cloudflare returned a malformed browser handoff response").pipe(Effect.flatMap((observation) => Schema.decodeEffect(BrowserRunHandoffResult)({ handoffId: Redacted.make(observation.handoffId) }).pipe(Effect.mapError(() => protocolError("Cloudflare returned a malformed browser handoff response"))))), currentPagePreflight.pipe(Effect.andThen(requestFitsSession(decoded.timeout)))))),
1130
- getHandoffState: runtime.run(cdpCommand(page, state, "Cloudflare.getHandoffState", {}, HandoffStateObservation, "Cloudflare returned a malformed browser handoff state").pipe(Effect.flatMap((observation) => Schema.decodeEffect(BrowserRunHandoffState)({
1131
- active: observation.active,
1132
- ...observation.handoffId === void 0 ? {} : { handoffId: Redacted.make(observation.handoffId) },
1133
- ...observation.durationMs === void 0 ? {} : { durationMs: observation.durationMs }
1134
- }).pipe(Effect.mapError(() => protocolError("Cloudflare returned a malformed browser handoff state"))))), currentPagePreflight),
1135
- close
1145
+ connect: Effect.suspend(() => state.closed.value ? expiredError() : connect)
1136
1146
  };
1137
1147
  });
1138
1148
  return BrowserRunInteractiveHost.of({
1139
- open,
1149
+ acquire,
1150
+ open: (policy) => acquire(policy).pipe(Effect.flatMap((acquired) => acquired.connect)),
1140
1151
  closeSession,
1141
1152
  cleanupSemantics: "confirmed-terminal"
1142
1153
  });
@@ -1166,4 +1177,4 @@ const CloudflareInteractiveBrowser = {
1166
1177
  //#endregion
1167
1178
  export { BrowserRunInteractiveHost as a, BrowserRunViewport as c, browserRunInteractiveImplementation as d, browserRunInteractiveLayer as f, BrowserRunSessionLifecycle as h, BrowserRunInteractiveBinding as i, CloudflareInteractiveBrowser as l, BrowserRunCleanupError as m, BrowserRunHandoffResult as n, BrowserRunLiveViewRequest as o, isBrowserRunUndispatchedActionError as p, BrowserRunHandoffState as r, BrowserRunLiveViewResult as s, BrowserRunHandoffRequest as t, browserRunInteractiveHostLayer as u };
1168
1179
 
1169
- //# sourceMappingURL=InteractiveBrowser-DupDtfw2.mjs.map
1180
+ //# sourceMappingURL=InteractiveBrowser-BCS9g0tn.mjs.map