@effect-agent/platform-cloudflare 0.1.0-beta.106 → 0.1.0-beta.107

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.
@@ -475,13 +475,13 @@ export declare const encodeUnknownResolutionCommand: (input: UnknownResolutionCo
475
475
  readonly author: string;
476
476
  readonly reason: string;
477
477
  readonly resolution: {
478
+ readonly _tag: "SafeToRetry";
479
+ } | {
478
480
  readonly _tag: "CompletedWithResult";
479
481
  readonly result: Schema.Json;
480
482
  readonly isFailure: boolean;
481
483
  } | {
482
484
  readonly _tag: "NeverHappened";
483
- } | {
484
- readonly _tag: "SafeToRetry";
485
485
  } | {
486
486
  readonly _tag: "AbortSubmission";
487
487
  };
@@ -645,6 +645,11 @@ export declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorde
645
645
  readonly createdAt: string;
646
646
  readonly deploymentId: string;
647
647
  readonly payload: {
648
+ readonly _tag: "AbortRequested";
649
+ readonly submissionId: string;
650
+ readonly author: string;
651
+ readonly reason: string;
652
+ } | {
648
653
  readonly _tag: "ThreadCreated";
649
654
  readonly agentId: string;
650
655
  readonly definitions: {
@@ -922,11 +927,6 @@ export declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorde
922
927
  readonly runDisposition?: Schema.Json | undefined;
923
928
  readonly finishReason?: "budget-exhausted" | undefined;
924
929
  readonly exhausted?: "tokens" | "tool-calls" | "turns" | undefined;
925
- } | {
926
- readonly _tag: "AbortRequested";
927
- readonly submissionId: string;
928
- readonly author: string;
929
- readonly reason: string;
930
930
  } | {
931
931
  readonly _tag: "SubmissionSettled";
932
932
  readonly submissionId: string;
@@ -1465,13 +1465,13 @@ export declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorde
1465
1465
  readonly author: string;
1466
1466
  readonly reason: string;
1467
1467
  readonly resolution: {
1468
+ readonly _tag: "SafeToRetry";
1469
+ } | {
1468
1470
  readonly _tag: "CompletedWithResult";
1469
1471
  readonly result: Schema.Json;
1470
1472
  readonly isFailure: boolean;
1471
1473
  } | {
1472
1474
  readonly _tag: "NeverHappened";
1473
- } | {
1474
- readonly _tag: "SafeToRetry";
1475
1475
  } | {
1476
1476
  readonly _tag: "AbortSubmission";
1477
1477
  };
@@ -1481,10 +1481,31 @@ export declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorde
1481
1481
  } | {
1482
1482
  readonly _tag: "HostFailed";
1483
1483
  readonly failure: {
1484
- readonly _tag: "DurableAlarmError";
1484
+ readonly _tag: "AdmissionConflict";
1485
+ readonly threadId: string;
1486
+ readonly principal: string;
1487
+ readonly idempotencyKey: string;
1488
+ readonly existingInputDigest: string;
1489
+ readonly attemptedInputDigest: string;
1490
+ } | {
1491
+ readonly _tag: "AdmissionPolicyError";
1492
+ readonly reason: "occupied" | "refused" | "unavailable";
1493
+ readonly code: string;
1494
+ readonly cause?: import("effect-agent/failure-diagnostic").Diagnostic | undefined;
1495
+ readonly stack?: string | undefined;
1496
+ } | {
1497
+ readonly _tag: "SettlementConflict";
1498
+ readonly submissionId: string;
1499
+ readonly existingOutcome: "aborted" | "completed" | "failed";
1500
+ } | {
1501
+ readonly _tag: "JoinedToHost";
1502
+ readonly submissionId: string;
1503
+ readonly hostSubmissionId: string;
1504
+ } | {
1505
+ readonly _tag: "LedgerError";
1485
1506
  readonly operation: string;
1486
1507
  readonly message: string;
1487
- readonly cause?: Schema.Json | undefined;
1508
+ readonly cause?: import("effect-agent/failure-diagnostic").Diagnostic | undefined;
1488
1509
  } | {
1489
1510
  readonly _tag: "ThreadStoreError";
1490
1511
  readonly operation: string;
@@ -1493,11 +1514,6 @@ export declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorde
1493
1514
  } | {
1494
1515
  readonly _tag: "ThreadNotMaterialized";
1495
1516
  readonly threadId: string;
1496
- } | {
1497
- readonly _tag: "LedgerError";
1498
- readonly operation: string;
1499
- readonly message: string;
1500
- readonly cause?: import("effect-agent/failure-diagnostic").Diagnostic | undefined;
1501
1517
  } | {
1502
1518
  readonly _tag: "AppendConflict";
1503
1519
  readonly threadId: string;
@@ -1511,24 +1527,8 @@ export declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorde
1511
1527
  readonly actualEpoch: number;
1512
1528
  readonly attemptedEpoch: number;
1513
1529
  } | {
1514
- readonly _tag: "OperationDenied";
1515
- readonly operation: "abort" | "awaitSettlement" | "explain" | "observe" | "resolveApproval" | "resolveUnknown" | "retry" | "scanObligations" | "verify" | "wake";
1516
- readonly reason: string;
1517
- readonly threadId?: string | undefined;
1518
- readonly submissionId?: string | undefined;
1519
- } | {
1520
- readonly _tag: "AdmissionConflict";
1521
- readonly threadId: string;
1522
- readonly principal: string;
1523
- readonly idempotencyKey: string;
1524
- readonly existingInputDigest: string;
1525
- readonly attemptedInputDigest: string;
1526
- } | {
1527
- readonly _tag: "AdmissionPolicyError";
1528
- readonly reason: "occupied" | "refused" | "unavailable";
1529
- readonly code: string;
1530
- readonly cause?: import("effect-agent/failure-diagnostic").Diagnostic | undefined;
1531
- readonly stack?: string | undefined;
1530
+ readonly _tag: "HostProtocolError";
1531
+ readonly message: string;
1532
1532
  } | {
1533
1533
  readonly _tag: "AgentInputError";
1534
1534
  readonly message: string;
@@ -1537,33 +1537,33 @@ export declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorde
1537
1537
  readonly message: string;
1538
1538
  readonly cause?: Schema.Json | undefined;
1539
1539
  } | {
1540
- readonly _tag: "DurableRuntimeFailpointError";
1541
- 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-duration-append" | "run:after-start-append" | "run:before-duration-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:after-unavailable-append" | "tools:before-prepared-append" | "tools:before-unavailable-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";
1542
- } | {
1543
- readonly _tag: "SettlementConflict";
1540
+ readonly _tag: "ApprovalConflict";
1544
1541
  readonly submissionId: string;
1545
- readonly existingOutcome: "aborted" | "completed" | "failed";
1542
+ readonly toolCallId: string;
1543
+ readonly existingDecision: "approved" | "denied";
1546
1544
  } | {
1547
- readonly _tag: "JoinedToHost";
1545
+ readonly _tag: "UnknownResolutionConflict";
1548
1546
  readonly submissionId: string;
1549
- readonly hostSubmissionId: string;
1547
+ readonly toolCallId: string;
1548
+ } | {
1549
+ readonly _tag: "DurableRuntimeFailpointError";
1550
+ 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-duration-append" | "run:after-start-append" | "run:before-duration-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:after-unavailable-append" | "tools:before-prepared-append" | "tools:before-unavailable-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";
1550
1551
  } | {
1551
1552
  readonly _tag: "AdmissionLimitExceeded";
1552
1553
  readonly limit: "database-bytes" | "input-bytes" | "queue-depth";
1553
1554
  readonly actual: number;
1554
1555
  readonly maximum: number;
1555
1556
  } | {
1556
- readonly _tag: "HostProtocolError";
1557
+ readonly _tag: "DurableAlarmError";
1558
+ readonly operation: string;
1557
1559
  readonly message: string;
1560
+ readonly cause?: Schema.Json | undefined;
1558
1561
  } | {
1559
- readonly _tag: "ApprovalConflict";
1560
- readonly submissionId: string;
1561
- readonly toolCallId: string;
1562
- readonly existingDecision: "approved" | "denied";
1563
- } | {
1564
- readonly _tag: "UnknownResolutionConflict";
1565
- readonly submissionId: string;
1566
- readonly toolCallId: string;
1562
+ readonly _tag: "OperationDenied";
1563
+ readonly operation: "abort" | "awaitSettlement" | "explain" | "observe" | "resolveApproval" | "resolveUnknown" | "retry" | "scanObligations" | "verify" | "wake";
1564
+ readonly reason: string;
1565
+ readonly threadId?: string | undefined;
1566
+ readonly submissionId?: string | undefined;
1567
1567
  };
1568
1568
  }, Schema.SchemaError, never>;
1569
1569
  export 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,7 +1,7 @@
1
1
  import { Context, Effect, Layer, Redacted, Schema, Scope } from "effect";
2
2
  import { SandboxImplementation } from "effect-agent/sandbox";
3
3
  import { HttpClient } from "effect/unstable/http";
4
- import { BrowserHandle, InteractiveBrowser, InteractiveBrowserError, InteractiveBrowserPolicy, InteractiveBrowserPolicyDeniedError } from "effect-agent/interactive-browser";
4
+ import { BrowserHandle, BrowserSelectFileRequest, InteractiveBrowser, InteractiveBrowserError, InteractiveBrowserPolicy, InteractiveBrowserPolicyDeniedError } from "effect-agent/interactive-browser";
5
5
  //#region src/internal/browser-session-lifecycle.d.ts
6
6
  declare const BrowserRunCleanupError_base: Schema.Class<BrowserRunCleanupError, Schema.TaggedStruct<"BrowserRunCleanupError", {
7
7
  readonly reason: Schema.Literals<readonly ["configuration", "authorization", "rate-limited", "provider", "malformed", "timeout", "pending"]>;
@@ -83,6 +83,7 @@ interface BrowserRunInteractivePage {
83
83
  readonly readText: (selector: string | undefined, maximumBytes: number) => Promise<unknown>;
84
84
  readonly fill: (selector: string, value: string, signal: AbortSignal, onDispatch: () => void) => Promise<unknown>;
85
85
  readonly click: (selector: string, signal: AbortSignal, onDispatch: () => void) => Promise<unknown>;
86
+ readonly selectFile: (request: BrowserSelectFileRequest, signal: AbortSignal, onDispatch: () => void) => Promise<unknown>;
86
87
  readonly screenshot: (fullPage: boolean) => Promise<unknown>;
87
88
  readonly scroll: (deltaX: number, deltaY: number) => Promise<void>;
88
89
  readonly setViewport: (viewport: BrowserRunViewport) => Promise<void>;
@@ -166,4 +167,4 @@ declare const CloudflareInteractiveBrowser: {
166
167
  };
167
168
  //#endregion
168
169
  export { isBrowserRunUndispatchedActionError as C, browserRunInteractiveLayer as S, BrowserRunSessionLifecycle as T, BrowserRunViewport as _, BrowserRunInteractiveAcquisition as a, browserRunInteractiveHostLayer as b, BrowserRunInteractiveCdpSession as c, BrowserRunInteractivePage as d, BrowserRunInteractiveRequest as f, BrowserRunLiveViewResult as g, BrowserRunLiveViewRequest as h, BrowserRunHandoffState as i, BrowserRunInteractiveContext as l, BrowserRunInteractiveSession as m, BrowserRunHandoffRequest as n, BrowserRunInteractiveBinding as o, BrowserRunInteractiveRequestListener as p, BrowserRunHandoffResult as r, BrowserRunInteractiveBrowser as s, BrowserRunCloudflareCommand as t, BrowserRunInteractiveHost as u, CloudflareInteractiveBrowser as v, BrowserRunCleanupError as w, browserRunInteractiveImplementation as x, CloudflareInteractiveBrowserOptions as y };
169
- //# sourceMappingURL=InteractiveBrowser-BR16UPbF.d.mts.map
170
+ //# sourceMappingURL=InteractiveBrowser-B3S8if51.d.mts.map
@@ -1,9 +1,80 @@
1
- import { Clock, Context, Duration, Effect, Layer, Option, Redacted, Ref, Schema, Scope, Semaphore, Stream } from "effect";
1
+ import { Clock, Context, Duration, Effect, Encoding, 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";
5
5
  import puppeteer from "@cloudflare/puppeteer";
6
- import { BrowserActionResult, BrowserNavigationResult, BrowserScreenshotRequest, BrowserScrollRequest, BrowserTextResult, InteractiveBrowser, InteractiveBrowserActionError, InteractiveBrowserBusyError, InteractiveBrowserCapacityError, InteractiveBrowserExpiredError, InteractiveBrowserLimitError, InteractiveBrowserPolicy, InteractiveBrowserPolicyDeniedError, InteractiveBrowserProtocolError, InteractiveBrowserTargetUrl, InteractiveBrowserUnsupportedError } from "effect-agent/interactive-browser";
6
+ import { BrowserActionResult, BrowserFileSelectionResult, BrowserNavigationResult, BrowserScreenshotRequest, BrowserScrollRequest, BrowserSelectFileRequest, BrowserTextResult, InteractiveBrowser, InteractiveBrowserActionError, InteractiveBrowserBusyError, InteractiveBrowserCapacityError, InteractiveBrowserExpiredError, InteractiveBrowserLimitError, InteractiveBrowserPolicy, InteractiveBrowserPolicyDeniedError, InteractiveBrowserProtocolError, InteractiveBrowserTargetUrl, InteractiveBrowserUnsupportedError } from "effect-agent/interactive-browser";
7
+ //#region src/internal/browser-file-selection.ts
8
+ function setFileSelection(element, encoded, name, type) {
9
+ if (Reflect.get(element, "type") !== "file" || Reflect.get(element, "disabled") || Reflect.get(element, "webkitdirectory")) throw new Error("The target is not an enabled file input");
10
+ const bytes = Uint8Array.from(atob(encoded), (character) => character.charCodeAt(0));
11
+ const transfer = new (Reflect.get(globalThis, "DataTransfer"))();
12
+ transfer.items.add(new File([bytes], name, { type }));
13
+ Reflect.set(element, "files", transfer.files);
14
+ const selected = Reflect.get(element, "files");
15
+ if (selected?.length !== 1 || selected[0]?.size !== bytes.length || selected[0]?.name !== name || selected[0]?.type !== type) throw new Error("The input did not retain the selected file");
16
+ const dispatch = Reflect.get(element, "dispatchEvent");
17
+ Reflect.apply(dispatch, element, [new Event("input", { bubbles: true })]);
18
+ Reflect.apply(dispatch, element, [new Event("change", { bubbles: true })]);
19
+ }
20
+ const makeFileSelection = (page) => async (request, signal) => {
21
+ const encoded = Encoding.encodeBase64(request.bytes);
22
+ const session = request.target === "chooser" ? await page.createCDPSession() : void 0;
23
+ if (session !== void 0) try {
24
+ await session.send("Page.enable");
25
+ await session.send("Page.setInterceptFileChooserDialog", { enabled: true });
26
+ } catch (cause) {
27
+ await session.detach();
28
+ throw cause;
29
+ }
30
+ const select = async (element) => {
31
+ if (session === void 0) return element.evaluate(setFileSelection, encoded, request.fileName, request.mediaType);
32
+ let onOpened = () => {};
33
+ let onAbort = () => {};
34
+ let timer;
35
+ const opened = new Promise((resolve, reject) => {
36
+ onOpened = (event) => event.backendNodeId === void 0 ? reject(/* @__PURE__ */ new Error("The chooser has no file input")) : resolve(event.backendNodeId);
37
+ onAbort = () => reject(/* @__PURE__ */ new Error("File selection interrupted"));
38
+ session.on("Page.fileChooserOpened", onOpened);
39
+ signal.addEventListener("abort", onAbort, { once: true });
40
+ timer = setTimeout(() => reject(/* @__PURE__ */ new Error("No file chooser opened")), 5e3);
41
+ if (signal.aborted) onAbort();
42
+ });
43
+ try {
44
+ const [backendNodeId] = await Promise.all([opened, element.click()]);
45
+ if (signal.aborted) throw new Error("File selection interrupted");
46
+ const objectId = (await session.send("DOM.resolveNode", { backendNodeId })).object.objectId;
47
+ if (objectId === void 0) throw new Error("The chooser has no file input");
48
+ if (signal.aborted) throw new Error("File selection interrupted");
49
+ if ((await session.send("Runtime.callFunctionOn", {
50
+ objectId,
51
+ functionDeclaration: `function(encoded, name, type) { (${setFileSelection.toString()})(this, encoded, name, type); }`,
52
+ arguments: [
53
+ { value: encoded },
54
+ { value: request.fileName },
55
+ { value: request.mediaType }
56
+ ],
57
+ returnByValue: true
58
+ })).exceptionDetails !== void 0) throw new Error("The chooser did not select the file");
59
+ } finally {
60
+ clearTimeout(timer);
61
+ session.off("Page.fileChooserOpened", onOpened);
62
+ signal.removeEventListener("abort", onAbort);
63
+ }
64
+ };
65
+ return {
66
+ validate: async (element) => request.target === "chooser" || await element.evaluate((input) => Reflect.get(input, "type") === "file" && !Reflect.get(input, "disabled") && !Reflect.get(input, "webkitdirectory")),
67
+ select,
68
+ close: async () => {
69
+ if (session !== void 0) try {
70
+ await session.send("Page.setInterceptFileChooserDialog", { enabled: false });
71
+ } finally {
72
+ await session.detach();
73
+ }
74
+ }
75
+ };
76
+ };
77
+ //#endregion
7
78
  //#region src/internal/browser-session-lifecycle.ts
8
79
  var BrowserRunCleanupError = class extends Schema.TaggedError()("BrowserRunCleanupError", {
9
80
  reason: Schema.Literals([
@@ -413,7 +484,7 @@ const makeActionRequestTracker = (page, signal) => {
413
484
  const disposeActionHandles = async (handles) => {
414
485
  await boundedBestEffort(Promise.allSettled(handles.map(async (handle) => handle.dispose())), ACTION_POST_STATE_MILLIS);
415
486
  };
416
- const runObservedPageAction = async (page, selector, signal, onDispatch, action) => {
487
+ const runObservedPageAction = async (page, selector, signal, onDispatch, action, validate) => {
417
488
  if (signal.aborted) throw new BrowserRunActionUndispatched(0);
418
489
  const before = Schema.decodeUnknownSync(ActionTargetState)(await readActionTarget(page, selector));
419
490
  if (before.matchCount !== 1 || before.invalidSelector === true) throw new BrowserRunActionUndispatched(before.matchCount);
@@ -434,6 +505,7 @@ const runObservedPageAction = async (page, selector, signal, onDispatch, action)
434
505
  };
435
506
  signal.addEventListener("abort", onAbort, { once: true });
436
507
  try {
508
+ if (validate !== void 0 && !await validate(matches[0])) throw new BrowserRunActionUndispatched(1);
437
509
  tracker = makeActionRequestTracker(page, signal);
438
510
  if (signal.aborted) throw new BrowserRunActionUndispatched(1);
439
511
  onDispatch();
@@ -454,6 +526,7 @@ const runObservedPageAction = async (page, selector, signal, onDispatch, action)
454
526
  }
455
527
  };
456
528
  const makeProductionPage = (page) => {
529
+ const prepareFileSelection = makeFileSelection(page);
457
530
  const listeners = /* @__PURE__ */ new Map();
458
531
  return {
459
532
  close: () => page.close(),
@@ -613,6 +686,14 @@ const makeProductionPage = (page) => {
613
686
  }
614
687
  }, value)),
615
688
  click: (selector, signal, onDispatch) => runObservedPageAction(page, selector, signal, onDispatch, (element) => element.click()),
689
+ selectFile: async (request, signal, onDispatch) => {
690
+ const selection = await prepareFileSelection(request, signal);
691
+ try {
692
+ return await runObservedPageAction(page, request.selector, signal, onDispatch, selection.select, selection.validate);
693
+ } finally {
694
+ await selection.close();
695
+ }
696
+ },
616
697
  screenshot: (fullPage) => page.screenshot({
617
698
  type: "png",
618
699
  fullPage
@@ -941,6 +1022,17 @@ const makeHandle = Effect.fn("BrowserRunInteractive.makeHandle")(function* (page
941
1022
  yield* logActionObservation("click", observation);
942
1023
  return yield* decodeActionResult(page, policy);
943
1024
  })),
1025
+ selectFile: (request) => Schema.decodeEffect(BrowserSelectFileRequest)(request).pipe(Effect.mapError(() => policyError("The browser file selection request is malformed")), Effect.flatMap((decoded) => run(Effect.gen(function* () {
1026
+ const observation = yield* observedAction("select-file", (signal, onDispatch) => page.selectFile(decoded, signal, onDispatch)).pipe(Effect.flatMap(decodeActionObservation));
1027
+ yield* logActionObservation("select-file", observation);
1028
+ const result = yield* decodeActionResult(page, policy);
1029
+ return BrowserFileSelectionResult.make({
1030
+ url: result.url,
1031
+ fileName: decoded.fileName,
1032
+ mediaType: decoded.mediaType,
1033
+ size: decoded.bytes.length
1034
+ });
1035
+ })))),
944
1036
  screenshot: (request) => Schema.decodeEffect(BrowserScreenshotRequest)(request).pipe(Effect.mapError(() => policyError("The browser screenshot request is malformed")), Effect.flatMap((decoded) => run(Effect.gen(function* () {
945
1037
  const raw = yield* remote("screenshot", () => page.screenshot(decoded.fullPage));
946
1038
  const bytes = yield* Schema.decodeUnknownEffect(PngBytes)(raw).pipe(Effect.mapError(() => protocolError("The browser returned a malformed PNG screenshot")));
@@ -1177,4 +1269,4 @@ const CloudflareInteractiveBrowser = {
1177
1269
  //#endregion
1178
1270
  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 };
1179
1271
 
1180
- //# sourceMappingURL=InteractiveBrowser-BCS9g0tn.mjs.map
1272
+ //# sourceMappingURL=InteractiveBrowser-xVNX7ARl.mjs.map