@effect-agent/platform-cloudflare 0.1.0-beta.38 → 0.1.0-beta.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bindings-BrVEOkfe.d.mts +102 -0
- package/dist/browser-quick-action.d.mts +18 -1
- package/dist/browser-quick-action.mjs +14 -1
- package/dist/browser-quick-action.mjs.map +1 -1
- package/dist/browser-rest-capture.d.mts +17 -2
- package/dist/browser-rest-capture.mjs +12 -1
- package/dist/browser-rest-capture.mjs.map +1 -1
- package/dist/browser-rest-crawl.mjs +2 -2
- package/dist/browser-rest-crawl.mjs.map +1 -1
- package/dist/index.d.mts +245 -237
- package/dist/index.mjs +168 -164
- package/dist/index.mjs.map +1 -1
- package/dist/interactive-browser.d.mts +160 -2
- package/dist/interactive-browser.mjs +1166 -2
- package/dist/interactive-browser.mjs.map +1 -0
- package/dist/{scheduling-B-OFqoS9.mjs → prepared-admission-BKp_Upw2.mjs} +134 -433
- package/dist/prepared-admission-BKp_Upw2.mjs.map +1 -0
- package/dist/rolldown-runtime-D7D4PA-g.mjs +13 -0
- package/dist/scheduling.d.mts +47 -2
- package/dist/scheduling.mjs +339 -1
- package/dist/scheduling.mjs.map +1 -0
- package/dist/subscriptions.d.mts +52 -0
- package/dist/subscriptions.mjs +346 -0
- package/dist/subscriptions.mjs.map +1 -0
- package/package.json +20 -13
- package/src/alarm.ts +264 -265
- package/src/bindings.ts +34 -30
- package/src/browser-quick-action.ts +31 -0
- package/src/browser-rest-capture.ts +27 -0
- package/src/client.ts +111 -105
- package/src/code-mode-executor.ts +19 -0
- package/src/config.ts +7 -7
- package/src/index.ts +10 -11
- package/src/interactive-browser.ts +29 -1
- package/src/layers.ts +178 -257
- package/src/prepared-admission.ts +90 -0
- package/src/scheduling.ts +19 -55
- package/src/subscriptions.ts +661 -0
- package/src/{conversation-object.ts → thread-object.ts} +167 -136
- package/src/transport.ts +15 -15
- package/src/wake-scheduler.ts +17 -22
- package/dist/interactive-browser-BRo-Bfvb.d.mts +0 -144
- package/dist/interactive-browser-Cy5q-ldl.mjs +0 -1154
- package/dist/interactive-browser-Cy5q-ldl.mjs.map +0 -1
- package/dist/scheduling-B-OFqoS9.mjs.map +0 -1
- package/dist/scheduling-BJs_kHTx.d.mts +0 -142
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { Context, Effect, Layer, Schema } from "effect";
|
|
2
|
+
import { ProducerId } from "@effect-agent/thread";
|
|
3
|
+
import { ThreadId } from "@effect-agent/core";
|
|
4
|
+
//#region src/bindings.d.ts
|
|
5
|
+
declare const CloudflareBindingError_base: Schema.Class<CloudflareBindingError, Schema.TaggedStruct<"CloudflareBindingError", {
|
|
6
|
+
readonly binding: Schema.String;
|
|
7
|
+
readonly message: Schema.String;
|
|
8
|
+
}>, import("effect/Cause").YieldableError>;
|
|
9
|
+
/**
|
|
10
|
+
* Cloudflare platform bindings as Effect services (DEPLOY-010: "Cloudflare platform bindings
|
|
11
|
+
* are supplied as Effect services/Layers"). Application code never reads `env` or touches a
|
|
12
|
+
* `DurableObjectState` directly — the Thread Object class constructs these Layers once
|
|
13
|
+
* per incarnation and everything downstream consumes the services.
|
|
14
|
+
*/
|
|
15
|
+
/** A Cloudflare platform binding was missing or carried the wrong shape (DEPLOY-003/010). */
|
|
16
|
+
declare class CloudflareBindingError extends CloudflareBindingError_base {}
|
|
17
|
+
/**
|
|
18
|
+
* The RPC surface one Thread Durable Object exposes to Workers and to sibling
|
|
19
|
+
* Thread Objects. `ThreadObject.make` implements it; the Worker-side client
|
|
20
|
+
* and the cross-Object transport call it through `DurableObjectNamespace` stubs. Every
|
|
21
|
+
* `encoded` value is a Schema-encoded envelope (`client.ts` wire schemas for host entry
|
|
22
|
+
* points, `@effect-agent/storage-cloudflare` port envelopes for `portCall`), so the RPC
|
|
23
|
+
* boundary carries only structured-cloneable JSON. The optional trailing trace context is
|
|
24
|
+
* transient native RPC metadata, stripped by an opted-in effect-cf receiver before decoding
|
|
25
|
+
* the host envelope. It never enters durable state.
|
|
26
|
+
*/
|
|
27
|
+
interface ThreadObjectRpc extends Rpc.DurableObjectBranded {
|
|
28
|
+
/** Admission-limits gate + `DurableAgentRuntime.submit`; answers a `SubmitResponse`. */
|
|
29
|
+
submitEncoded(encoded: unknown, traceContext?: unknown): Promise<unknown>;
|
|
30
|
+
/** Wake-hinted, poll-guaranteed settlement wait; answers an `AwaitSettlementResponse`. */
|
|
31
|
+
awaitSettlementEncoded(encoded: unknown, traceContext?: unknown): Promise<unknown>;
|
|
32
|
+
/** Event-driven durable progress wait; answers a `ProgressObserved` host response. */
|
|
33
|
+
awaitProgressEncoded(encoded: unknown, traceContext?: unknown): Promise<unknown>;
|
|
34
|
+
/** Best-effort cancellation for one in-flight progress wait. */
|
|
35
|
+
cancelProgressEncoded(encoded: unknown, traceContext?: unknown): Promise<unknown>;
|
|
36
|
+
/** One bounded page of canonical records; answers an `ObservePageResponse`. */
|
|
37
|
+
observePage(encoded: unknown, traceContext?: unknown): Promise<unknown>;
|
|
38
|
+
/** Durable abort intent; answers an `AbortResponse`. */
|
|
39
|
+
abortEncoded(encoded: unknown, traceContext?: unknown): Promise<unknown>;
|
|
40
|
+
/** Durable approval decision (plan §2.6); answers a `ResolveApprovalResponse`. */
|
|
41
|
+
resolveApprovalEncoded(encoded: unknown, traceContext?: unknown): Promise<unknown>;
|
|
42
|
+
/** Authorized DUR-017 Unknown-Outcome resolution; answers a `ResolveUnknownResponse`. */
|
|
43
|
+
resolveUnknownEncoded(encoded: unknown, traceContext?: unknown): Promise<unknown>;
|
|
44
|
+
/** Owner-side cross-Object port endpoint (WP2 envelopes, executed on LOCAL facets). */
|
|
45
|
+
portCall(encoded: unknown): Promise<unknown>;
|
|
46
|
+
/** Droppable liveness hint from another Object: arms an immediate alarm. */
|
|
47
|
+
wake(): Promise<void>;
|
|
48
|
+
}
|
|
49
|
+
declare const ThreadObjectNamespace_base: Context.ServiceClass<ThreadObjectNamespace, "@effect-agent/platform-cloudflare/ThreadObjectNamespace", {
|
|
50
|
+
readonly namespace: DurableObjectNamespace<ThreadObjectRpc>;
|
|
51
|
+
/** Stable binding name for opted-in native RPC tracing; absent by default. */
|
|
52
|
+
readonly rpcTracing?: string;
|
|
53
|
+
}>;
|
|
54
|
+
/**
|
|
55
|
+
* The `DurableObjectNamespace` binding that addresses Thread Objects. The Object
|
|
56
|
+
* identity rule is `namespace.idFromName(threadId)` (plan §1.2): Thread IDs are
|
|
57
|
+
* globally unique, so the mapping is total and deterministic and no directory service exists.
|
|
58
|
+
*/
|
|
59
|
+
declare class ThreadObjectNamespace extends ThreadObjectNamespace_base {
|
|
60
|
+
static layer(namespace: DurableObjectNamespace<ThreadObjectRpc>, options?: {
|
|
61
|
+
readonly rpcTracing?: string;
|
|
62
|
+
}): Layer.Layer<ThreadObjectNamespace>;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Narrow one `env` member to a `DurableObjectNamespace`. `env` is an untyped platform value,
|
|
66
|
+
* and a namespace binding is a host object no Schema can decode, so this is the documented
|
|
67
|
+
* narrowest-boundary check (structural probe for the namespace surface the transport uses);
|
|
68
|
+
* a missing or misshaped binding fails typed before any Layer is built.
|
|
69
|
+
*/
|
|
70
|
+
declare const threadNamespaceFromEnv: (env: unknown, binding: string) => Effect.Effect<DurableObjectNamespace<ThreadObjectRpc>, CloudflareBindingError, never>;
|
|
71
|
+
/**
|
|
72
|
+
* Build the namespace from Worker `env` (fails typed). Enable `rpcTracing` only when the
|
|
73
|
+
* receiver also opts into the effect-cf native RPC trace-context contract.
|
|
74
|
+
*/
|
|
75
|
+
declare const threadNamespaceLayer: (env: unknown, binding: string, options?: {
|
|
76
|
+
readonly rpcTracing?: boolean;
|
|
77
|
+
}) => Layer.Layer<ThreadObjectNamespace, CloudflareBindingError>;
|
|
78
|
+
declare const DurableObjectContext_base: Context.ServiceClass<DurableObjectContext, "@effect-agent/platform-cloudflare/DurableObjectContext", {
|
|
79
|
+
readonly ctx: DurableObjectState;
|
|
80
|
+
readonly env: unknown;
|
|
81
|
+
}>;
|
|
82
|
+
/**
|
|
83
|
+
* The live Durable Object execution context of THIS incarnation. Only Layer construction and
|
|
84
|
+
* the alarm service consume it; important state never lives on it (`ctx.storage` is truth,
|
|
85
|
+
* everything in memory is a cache — deployment spec §11).
|
|
86
|
+
*/
|
|
87
|
+
declare class DurableObjectContext extends DurableObjectContext_base {
|
|
88
|
+
static layer(ctx: DurableObjectState, env: unknown): Layer.Layer<DurableObjectContext>;
|
|
89
|
+
}
|
|
90
|
+
declare const ThreadObjectIdentity_base: Context.ServiceClass<ThreadObjectIdentity, "@effect-agent/platform-cloudflare/ThreadObjectIdentity", {
|
|
91
|
+
readonly threadId: ThreadId;
|
|
92
|
+
readonly producerId: ProducerId;
|
|
93
|
+
}>;
|
|
94
|
+
/**
|
|
95
|
+
* The Thread identity this Object serializes and the producer identity its Attempts
|
|
96
|
+
* write with (`{producerPrefix}:{threadId}`, plan §1.4). Derived once per incarnation
|
|
97
|
+
* from `ctx.id.name` — the Object identity rule guarantees the name IS the Thread ID.
|
|
98
|
+
*/
|
|
99
|
+
declare class ThreadObjectIdentity extends ThreadObjectIdentity_base {}
|
|
100
|
+
//#endregion
|
|
101
|
+
export { ThreadObjectRpc as a, ThreadObjectNamespace as i, DurableObjectContext as n, threadNamespaceFromEnv as o, ThreadObjectIdentity as r, threadNamespaceLayer as s, CloudflareBindingError as t };
|
|
102
|
+
//# sourceMappingURL=bindings-BrVEOkfe.d.mts.map
|
|
@@ -65,8 +65,25 @@ declare class BrowserQuickActionWorkersAi extends BrowserQuickActionWorkersAi_ba
|
|
|
65
65
|
declare const browserQuickActionCaptureLayer: () => Layer.Layer<PageCapture, never, BrowserQuickActionBrowserBinding>;
|
|
66
66
|
/** Structured Quick Actions require host-owned browser and Workers AI authority. */
|
|
67
67
|
declare const browserQuickActionWorkersAiCaptureLayer: () => Layer.Layer<PageCapture, never, BrowserQuickActionBrowserBinding | BrowserQuickActionWorkersAi>;
|
|
68
|
+
/** Host-owned Quick Action binding and optional, separately billed extraction authority. */
|
|
69
|
+
interface CloudflareBrowserOptions extends BrowserQuickActionCaptureOptions {
|
|
70
|
+
readonly workersAi?: BrowserQuickActionWorkersAiPolicy;
|
|
71
|
+
}
|
|
72
|
+
/** Compose WebCapture handlers with the Cloudflare Quick Action adapter. */
|
|
73
|
+
declare const CloudflareBrowser: {
|
|
74
|
+
/**
|
|
75
|
+
* Supply a WebCapture definition and the resolved Worker browser binding.
|
|
76
|
+
* Supports capture, scrape, and extraction definitions without importing capabilities.
|
|
77
|
+
* Only PageCapture is provided; other handler requirements and errors stay visible.
|
|
78
|
+
* Extraction fails closed unless workersAi explicitly authorizes and accounts for it.
|
|
79
|
+
* Capture limits, typed failures, tracing, and scoped response cleanup are unchanged.
|
|
80
|
+
*/
|
|
81
|
+
layer: <A, E, R>(definition: {
|
|
82
|
+
readonly handlers: Layer.Layer<A, E, R>;
|
|
83
|
+
}, options: CloudflareBrowserOptions) => Layer.Layer<A, E, Exclude<R, PageCapture>>;
|
|
84
|
+
};
|
|
68
85
|
/** Native Browser Run screenshot adapter. It retains PNG bytes only for the caller's result. */
|
|
69
86
|
declare const browserQuickActionScreenshotLayer: () => Layer.Layer<PageScreenshot, never, BrowserQuickActionBrowserBinding>;
|
|
70
87
|
//#endregion
|
|
71
|
-
export { BrowserQuickActionBrowserBinding, BrowserQuickActionCaptureOptions, BrowserQuickActionClient, BrowserQuickActionRpcError, BrowserQuickActionWorkersAi, BrowserQuickActionWorkersAiPolicy, BrowserQuickActionWorkersAiPolicyError, browserQuickActionCaptureLayer, browserQuickActionImplementation, browserQuickActionScreenshotLayer, browserQuickActionWorkersAiCaptureLayer };
|
|
88
|
+
export { BrowserQuickActionBrowserBinding, BrowserQuickActionCaptureOptions, BrowserQuickActionClient, BrowserQuickActionRpcError, BrowserQuickActionWorkersAi, BrowserQuickActionWorkersAiPolicy, BrowserQuickActionWorkersAiPolicyError, CloudflareBrowser, CloudflareBrowserOptions, browserQuickActionCaptureLayer, browserQuickActionImplementation, browserQuickActionScreenshotLayer, browserQuickActionWorkersAiCaptureLayer };
|
|
72
89
|
//# sourceMappingURL=browser-quick-action.d.mts.map
|
|
@@ -313,6 +313,19 @@ const browserQuickActionWorkersAiCaptureLayer = () => Layer.effect(PageCapture,
|
|
|
313
313
|
const workersAi = yield* BrowserQuickActionWorkersAi;
|
|
314
314
|
return PageCapture.of({ capture: makeCapture(browser, workersAi) });
|
|
315
315
|
}));
|
|
316
|
+
/** Compose WebCapture handlers with the Cloudflare Quick Action adapter. */
|
|
317
|
+
const CloudflareBrowser = {
|
|
318
|
+
/**
|
|
319
|
+
* Supply a WebCapture definition and the resolved Worker browser binding.
|
|
320
|
+
* Supports capture, scrape, and extraction definitions without importing capabilities.
|
|
321
|
+
* Only PageCapture is provided; other handler requirements and errors stay visible.
|
|
322
|
+
* Extraction fails closed unless workersAi explicitly authorizes and accounts for it.
|
|
323
|
+
* Capture limits, typed failures, tracing, and scoped response cleanup are unchanged.
|
|
324
|
+
*/
|
|
325
|
+
layer: (definition, options) => {
|
|
326
|
+
const capture = options.workersAi === void 0 ? browserQuickActionCaptureLayer() : browserQuickActionWorkersAiCaptureLayer().pipe(Layer.provide(BrowserQuickActionWorkersAi.layer(options.workersAi)));
|
|
327
|
+
return definition.handlers.pipe(Layer.provide(capture.pipe(Layer.provide(BrowserQuickActionBrowserBinding.layer(options)))));
|
|
328
|
+
} };
|
|
316
329
|
const screenshotOptions = (request) => {
|
|
317
330
|
const options = {};
|
|
318
331
|
if (request.navigation?.waitUntil !== void 0 || request.navigation?.timeoutMillis !== void 0) options.gotoOptions = {
|
|
@@ -434,6 +447,6 @@ const makeScreenshot = (browser) => Effect.fn("BrowserQuickActionScreenshot.capt
|
|
|
434
447
|
/** Native Browser Run screenshot adapter. It retains PNG bytes only for the caller's result. */
|
|
435
448
|
const browserQuickActionScreenshotLayer = () => Layer.effect(PageScreenshot, Effect.map(BrowserQuickActionBrowserBinding, (browser) => PageScreenshot.of({ capture: makeScreenshot(browser) })));
|
|
436
449
|
//#endregion
|
|
437
|
-
export { BrowserQuickActionBrowserBinding, BrowserQuickActionRpcError, BrowserQuickActionWorkersAi, BrowserQuickActionWorkersAiPolicyError, browserQuickActionCaptureLayer, browserQuickActionImplementation, browserQuickActionScreenshotLayer, browserQuickActionWorkersAiCaptureLayer };
|
|
450
|
+
export { BrowserQuickActionBrowserBinding, BrowserQuickActionRpcError, BrowserQuickActionWorkersAi, BrowserQuickActionWorkersAiPolicyError, CloudflareBrowser, browserQuickActionCaptureLayer, browserQuickActionImplementation, browserQuickActionScreenshotLayer, browserQuickActionWorkersAiCaptureLayer };
|
|
438
451
|
|
|
439
452
|
//# sourceMappingURL=browser-quick-action.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-quick-action.mjs","names":[],"sources":["../src/browser-quick-action.ts"],"sourcesContent":["/// <reference types=\"@cloudflare/workers-types\" />\n\nimport {\n PageCapture,\n PageCaptureInferenceUse,\n PageCaptureInferencePolicyError,\n PageCaptureNavigationError,\n PageCaptureOutputLimitError,\n PageCaptureProtocolError,\n PageCaptureRateLimitedError,\n PageCaptureResourceUse,\n PageCaptureResult,\n PageCaptureUnsupportedError,\n PageScreenshot,\n PageScreenshotOutputLimitError,\n PageScreenshotResult,\n type PageScreenshotCapture,\n type PageScreenshotError,\n type PageScreenshotRequest,\n PageContentCaptured,\n PageLinksCaptured,\n PageMarkdownCaptured,\n PageScrapeCaptured,\n PageStructuredCaptured,\n SandboxImplementation,\n type PageCaptureAction,\n type PageCaptureCapture,\n type PageCaptureError,\n type PageCaptureOutput,\n type PageCaptureRequest,\n} from \"@effect-agent/sandbox\";\nimport { Context, Effect, Layer, Option, Schema } from \"effect\";\n\n/**\n * The Cloudflare Browser Run Quick Action `PageCapture` adapter (capability\n * spec §9.2). Each capture is one stateless `quickAction()` RPC on the\n * Wrangler `browser` binding: the platform renders the target in a managed\n * headless browser and returns one bounded output; the adapter holds no\n * session and no state between passes. The binding requires a Worker\n * compatibility date of `2026-03-24` or later, and local `wrangler dev` needs\n * remote mode (`\"remote\": true` on the binding) because `quickAction` has no\n * local implementation.\n *\n * Rendered output is untrusted, attacker-influenced content; this adapter\n * only bounds and types it. Deployment class `E` only: no durability claim.\n */\nexport const browserQuickActionImplementation = SandboxImplementation.make({\n isolation: \"isolated\",\n identity: \"cloudflare-browser-quick-action\",\n});\n\n/**\n * Effect-native client captured by the binding service. Its option types come\n * directly from the pinned Workers declarations rather than a local copy.\n */\nexport interface BrowserQuickActionClient {\n readonly screenshot: (\n options: BrowserRunScreenshotOptions,\n ) => Effect.Effect<Response, BrowserQuickActionRpcError>;\n readonly content: (\n options: BrowserRunContentOptions,\n ) => Effect.Effect<Response, BrowserQuickActionRpcError>;\n readonly markdown: (\n options: BrowserRunMarkdownOptions,\n ) => Effect.Effect<Response, BrowserQuickActionRpcError>;\n readonly links: (\n options: BrowserRunLinksOptions,\n ) => Effect.Effect<Response, BrowserQuickActionRpcError>;\n readonly scrape: (\n options: BrowserRunScrapeOptions,\n ) => Effect.Effect<Response, BrowserQuickActionRpcError>;\n readonly json: (\n options: BrowserRunJsonOptions,\n ) => Effect.Effect<Response, BrowserQuickActionRpcError>;\n}\n\n/** A native binding RPC rejected before it returned an HTTP response. */\nexport class BrowserQuickActionRpcError extends Schema.TaggedError<BrowserQuickActionRpcError>()(\n \"BrowserQuickActionRpcError\",\n {\n action: Schema.Literals([\"screenshot\", \"content\", \"markdown\", \"links\", \"scrape\", \"json\"]),\n cause: Schema.Defect(),\n },\n) {}\n\nexport interface BrowserQuickActionCaptureOptions {\n /** The resolved Wrangler `browser` binding (DEPLOY-014: supplied, never ambient). */\n readonly browser: BrowserRun;\n}\n\n/** Host-owned browser binding authority, supplied explicitly at the composition root. */\nexport class BrowserQuickActionBrowserBinding extends Context.Service<\n BrowserQuickActionBrowserBinding,\n BrowserQuickActionClient\n>()(\"@effect-agent/platform-cloudflare/BrowserQuickActionBrowserBinding\") {\n static layer(\n options: BrowserQuickActionCaptureOptions,\n ): Layer.Layer<BrowserQuickActionBrowserBinding> {\n const browser = options.browser;\n const invoke = Effect.fn(\"BrowserQuickActionBrowserBinding.invoke\")(function* (\n action: \"screenshot\" | \"content\" | \"markdown\" | \"links\" | \"scrape\" | \"json\",\n evaluate: () => Promise<Response>,\n ): Effect.fn.Return<Response, BrowserQuickActionRpcError> {\n return yield* Effect.tryPromise({\n try: evaluate,\n catch: (cause) => BrowserQuickActionRpcError.make({ action, cause }),\n });\n });\n return Layer.succeed(BrowserQuickActionBrowserBinding)({\n screenshot: (request) =>\n invoke(\"screenshot\", () => browser.quickAction(\"screenshot\", request)),\n content: (request) => invoke(\"content\", () => browser.quickAction(\"content\", request)),\n markdown: (request) => invoke(\"markdown\", () => browser.quickAction(\"markdown\", request)),\n links: (request) => invoke(\"links\", () => browser.quickAction(\"links\", request)),\n scrape: (request) => invoke(\"scrape\", () => browser.quickAction(\"scrape\", request)),\n json: (request) => invoke(\"json\", () => browser.quickAction(\"json\", request)),\n });\n }\n}\n\n/** Host-owned authorization and accounting for one Workers AI extraction. */\nexport interface BrowserQuickActionWorkersAiPolicy {\n readonly authorizeAndAccount: (\n request: PageCaptureRequest,\n ) => Effect.Effect<void, BrowserQuickActionWorkersAiPolicyError>;\n}\n\n/** Host-only diagnostic for a denied or unaccounted Workers AI extraction. */\nexport class BrowserQuickActionWorkersAiPolicyError extends Schema.TaggedError<BrowserQuickActionWorkersAiPolicyError>()(\n \"BrowserQuickActionWorkersAiPolicyError\",\n {\n reason: Schema.Literals([\"authorization\", \"accounting\"]),\n message: Schema.String.check(Schema.isMaxLength(8_000)),\n cause: Schema.optionalKey(Schema.Defect()),\n },\n) {}\n\n/** Explicit host-owned authority and accounting for separately billed Workers AI extraction. */\nexport class BrowserQuickActionWorkersAi extends Context.Service<\n BrowserQuickActionWorkersAi,\n BrowserQuickActionWorkersAiPolicy\n>()(\"@effect-agent/platform-cloudflare/BrowserQuickActionWorkersAi\") {\n static layer(\n policy: BrowserQuickActionWorkersAiPolicy,\n ): Layer.Layer<BrowserQuickActionWorkersAi> {\n return Layer.succeed(BrowserQuickActionWorkersAi)(policy);\n }\n}\n\nconst MAX_DIAGNOSTIC_LENGTH = 8_000;\nconst boundedDiagnostic = (message: string): string => message.slice(0, MAX_DIAGNOSTIC_LENGTH);\n\nconst QuickActionSuccessEnvelope = Schema.Struct({\n success: Schema.Literal(true),\n result: Schema.Json,\n});\n\nconst QuickActionErrorEnvelope = Schema.Struct({\n success: Schema.Literal(false),\n errors: Schema.Array(\n Schema.Struct({\n message: Schema.String,\n code: Schema.optionalKey(Schema.Number),\n detail: Schema.optionalKey(Schema.String),\n path: Schema.optionalKey(Schema.String),\n }),\n ),\n rawAiResponse: Schema.optionalKey(Schema.String),\n});\n\nconst QuickActionEnvelope = Schema.Union([QuickActionSuccessEnvelope, QuickActionErrorEnvelope]);\nconst decodeEnvelope = Schema.decodeUnknownOption(Schema.fromJsonString(QuickActionEnvelope));\n\n/** Project the schema-validated request onto Cloudflare's native common options. */\nconst quickActionCommonOptions = (request: PageCaptureRequest): BrowserRunCommonOptions => {\n const options: BrowserRunBaseOptions = {};\n const navigation = request.navigation;\n if (navigation !== undefined) {\n const goto: NonNullable<BrowserRunBaseOptions[\"gotoOptions\"]> = {};\n if (navigation.waitUntil !== undefined) goto.waitUntil = navigation.waitUntil;\n if (navigation.timeoutMillis !== undefined) goto.timeout = navigation.timeoutMillis;\n if (Object.keys(goto).length > 0) options.gotoOptions = goto;\n if (navigation.waitForSelector !== undefined) {\n options.waitForSelector = {\n selector: navigation.waitForSelector.selector,\n ...(navigation.waitForSelector.timeoutMillis === undefined\n ? {}\n : { timeout: navigation.waitForSelector.timeoutMillis }),\n };\n }\n }\n if (request.viewport !== undefined) {\n options.viewport = { width: request.viewport.width, height: request.viewport.height };\n }\n if (request.resourcePolicy !== undefined) {\n if (request.resourcePolicy.rejectResourceTypes !== undefined) {\n options.rejectResourceTypes = [...request.resourcePolicy.rejectResourceTypes];\n }\n if (request.resourcePolicy.allowRequestPatterns !== undefined) {\n options.allowRequestPattern = [...request.resourcePolicy.allowRequestPatterns];\n }\n }\n return request.target._tag === \"PageUrlTarget\"\n ? { ...options, url: request.target.url }\n : { ...options, html: request.target.html };\n};\n\n/** Dispatch through Cloudflare's native action-specific overloads. */\nconst executeQuickAction = (\n browser: BrowserQuickActionClient,\n request: PageCaptureRequest,\n): Effect.Effect<Response, BrowserQuickActionRpcError> => {\n const options = quickActionCommonOptions(request);\n switch (request.action._tag) {\n case \"CapturePageContent\": {\n return browser.content(options);\n }\n case \"CapturePageMarkdown\": {\n return browser.markdown(options);\n }\n case \"CapturePageLinks\": {\n return browser.links({\n ...options,\n ...(request.action.visibleLinksOnly === undefined\n ? {}\n : { visibleLinksOnly: request.action.visibleLinksOnly }),\n });\n }\n case \"CapturePageScrape\": {\n return browser.scrape({\n ...options,\n elements: request.action.selectors.map((selector) => ({ selector })),\n });\n }\n case \"CapturePageStructured\": {\n return browser.json({\n ...options,\n response_format: {\n type: \"json_schema\",\n json_schema: request.action.responseFormat,\n },\n ...(request.action.prompt === undefined ? {} : { prompt: request.action.prompt }),\n });\n }\n }\n};\n\nconst protocolError = (message: string, cause?: unknown): PageCaptureProtocolError =>\n PageCaptureProtocolError.make({\n implementation: browserQuickActionImplementation,\n message: boundedDiagnostic(message),\n ...(cause === undefined ? {} : { cause }),\n });\n\nconst navigationError = (message: string, cause?: unknown): PageCaptureNavigationError =>\n PageCaptureNavigationError.make({\n implementation: browserQuickActionImplementation,\n message: boundedDiagnostic(message),\n ...(cause === undefined ? {} : { cause }),\n });\n\n/** Preserve bounded remote diagnostics for the host without exposing their text to a model. */\nconst privateResponseCause = (bodyText: string): Error | undefined =>\n bodyText.length === 0 ? undefined : new Error(boundedDiagnostic(bodyText));\n\nconst releaseResponseReader = (\n reader: ReadableStreamDefaultReader<Uint8Array>,\n): Effect.Effect<void> =>\n Effect.tryPromise({\n try: () => reader.cancel(),\n catch: (cause) => protocolError(\"Canceling the Quick Action response failed\", cause),\n }).pipe(\n Effect.catch((error) => Effect.logWarning(error.message)),\n Effect.ensuring(\n Effect.try({\n try: () => reader.releaseLock(),\n catch: (cause) => protocolError(\"Releasing the Quick Action response failed\", cause),\n }).pipe(Effect.catch((error) => Effect.logWarning(error.message))),\n ),\n );\n\nconst readBoundedResponse = Effect.fn(\"BrowserQuickActionCapture.readResponse\")(function* (\n response: Response,\n request: PageCaptureRequest,\n) {\n const body = response.body;\n if (body === null) return \"\";\n\n const reader = yield* Effect.acquireRelease(\n Effect.try({\n try: () => body.getReader(),\n catch: (cause) => protocolError(\"Opening the Quick Action response failed\", cause),\n }),\n releaseResponseReader,\n );\n const decoder = new TextDecoder(\"utf-8\", { fatal: true, ignoreBOM: false });\n let observedBytes = 0;\n let bodyText = \"\";\n\n while (true) {\n const chunk = yield* Effect.tryPromise({\n try: () => reader.read(),\n catch: (cause) => protocolError(\"Reading the Quick Action response failed\", cause),\n });\n if (chunk.done) break;\n\n observedBytes += chunk.value.byteLength;\n if (observedBytes > request.limits.maxOutputBytes) {\n return yield* PageCaptureOutputLimitError.make({\n implementation: browserQuickActionImplementation,\n limit: request.limits.maxOutputBytes,\n observed: observedBytes,\n });\n }\n\n bodyText += yield* Effect.try({\n try: () => decoder.decode(chunk.value, { stream: true }),\n catch: (cause) => protocolError(\"Decoding the Quick Action response failed\", cause),\n });\n }\n\n return (\n bodyText +\n (yield* Effect.try({\n try: () => decoder.decode(),\n catch: (cause) => protocolError(\"Decoding the Quick Action response failed\", cause),\n }))\n );\n}, Effect.scoped);\n\n/**\n * Retry-After arrives in whole seconds; a non-integer form (an HTTP date) is\n * dropped rather than guessed at.\n */\nconst retryAfterMillis = (response: Response): number | undefined => {\n const header = response.headers.get(\"Retry-After\");\n if (header === null) return undefined;\n const seconds = Number(header);\n if (!Number.isSafeInteger(seconds) || seconds < 0) return undefined;\n const millis = seconds * 1_000;\n return Number.isSafeInteger(millis) ? millis : undefined;\n};\n\nconst browserMillis = (response: Response): number | undefined => {\n const header = response.headers.get(\"X-Browser-Ms-Used\");\n if (header === null) return undefined;\n const millis = Number(header);\n return Number.isSafeInteger(millis) && millis >= 0 ? millis : undefined;\n};\n\n/** Only trusted response metadata chooses transport framing; page text never does. */\nconst isJsonResponse = (response: Response): boolean => {\n const contentType = response.headers.get(\"Content-Type\");\n if (contentType === null) return false;\n const mediaType = contentType.split(\";\", 1)[0]?.trim().toLowerCase();\n return mediaType === \"application/json\" || mediaType?.endsWith(\"+json\") === true;\n};\n\nconst parseOutput = (\n action: PageCaptureAction,\n bodyText: string,\n response: Response,\n): PageCaptureOutput | PageCaptureNavigationError | PageCaptureProtocolError => {\n if (!isJsonResponse(response)) {\n return protocolError(\n \"The Quick Action success response was not a JSON response envelope\",\n privateResponseCause(bodyText),\n );\n }\n const envelope = decodeEnvelope(bodyText);\n if (Option.isNone(envelope)) {\n return protocolError(\n \"The JSON Quick Action response did not carry a valid response envelope\",\n privateResponseCause(bodyText),\n );\n }\n if (!envelope.value.success) {\n return navigationError(\n \"The Quick Action reported a navigation failure\",\n privateResponseCause(bodyText),\n );\n }\n switch (action._tag) {\n case \"CapturePageContent\":\n case \"CapturePageMarkdown\": {\n if (typeof envelope.value.result !== \"string\") {\n return protocolError(\"The Quick Action envelope carried a non-text result\");\n }\n return action._tag === \"CapturePageContent\"\n ? PageContentCaptured.make({ html: envelope.value.result })\n : PageMarkdownCaptured.make({ markdown: envelope.value.result });\n }\n case \"CapturePageLinks\": {\n const decoded = Schema.decodeUnknownOption(PageLinksCaptured)({\n _tag: \"PageLinksCaptured\",\n links: envelope.value.result,\n });\n if (Option.isNone(decoded)) {\n return protocolError(\"The links Quick Action did not return a bounded array of valid URLs\");\n }\n return decoded.value;\n }\n case \"CapturePageScrape\": {\n const decoded = Schema.decodeUnknownOption(PageScrapeCaptured)({\n _tag: \"PageScrapeCaptured\",\n groups: envelope.value.result,\n });\n if (Option.isNone(decoded)) {\n return protocolError(\n \"The scrape Quick Action did not return bounded grouped element records\",\n );\n }\n return decoded.value;\n }\n case \"CapturePageStructured\": {\n return PageStructuredCaptured.make({ value: envelope.value.result });\n }\n }\n};\n\nconst isQuotaMessage = (text: string): boolean => /time limit|daily|quota/i.test(text);\n\nconst makeCapture = (\n browser: BrowserQuickActionClient,\n workersAi?: BrowserQuickActionWorkersAiPolicy,\n): PageCaptureCapture =>\n Effect.fn(\"BrowserQuickActionCapture.capture\")(function* (\n request: PageCaptureRequest,\n ): Effect.fn.Return<PageCaptureResult, PageCaptureError> {\n if (request.engine !== \"chromium\") {\n return yield* PageCaptureUnsupportedError.make({\n implementation: browserQuickActionImplementation,\n feature: \"engine\",\n message:\n \"The browser binding's quickAction() exposes no engine selector; kitesurf requires the REST or CDP surface\",\n });\n }\n\n const usesWorkersAi = request.action._tag === \"CapturePageStructured\";\n if (usesWorkersAi) {\n if (workersAi === undefined) {\n return yield* PageCaptureUnsupportedError.make({\n implementation: browserQuickActionImplementation,\n feature: \"action\",\n message:\n \"Structured capture invokes separately billed Workers AI and requires an explicit authorization and accounting policy\",\n });\n }\n yield* workersAi.authorizeAndAccount(request).pipe(\n Effect.mapError((cause) =>\n PageCaptureInferencePolicyError.make({\n implementation: browserQuickActionImplementation,\n provider: \"cloudflare-workers-ai\",\n reason: cause.reason,\n message:\n cause.reason === \"authorization\"\n ? \"Workers AI extraction was not authorized\"\n : \"Workers AI extraction could not be accounted for\",\n cause,\n }),\n ),\n );\n }\n\n const response = yield* executeQuickAction(browser, request).pipe(\n Effect.mapError((error) =>\n protocolError(\"The browser binding rejected the Quick Action\", error.cause),\n ),\n );\n const bodyText = yield* readBoundedResponse(response, request);\n if (response.status === 429) {\n const retryAfter = retryAfterMillis(response);\n const reason = isQuotaMessage(bodyText) ? \"quota\" : \"rate\";\n const cause = privateResponseCause(bodyText);\n return yield* PageCaptureRateLimitedError.make({\n implementation: browserQuickActionImplementation,\n reason,\n ...(retryAfter === undefined ? {} : { retryAfterMillis: retryAfter }),\n ...(cause === undefined ? {} : { cause }),\n message:\n reason === \"quota\"\n ? \"The Quick Action exceeded its browser quota\"\n : \"The Quick Action was rate limited\",\n });\n }\n if (!response.ok) {\n const message = `The Quick Action answered HTTP ${response.status}`;\n const cause = privateResponseCause(bodyText);\n if (response.status >= 500) {\n return yield* protocolError(message, cause);\n }\n return yield* navigationError(message, cause);\n }\n const output = parseOutput(request.action, bodyText, response);\n if (\n output._tag === \"PageCaptureNavigationError\" ||\n output._tag === \"PageCaptureProtocolError\"\n ) {\n return yield* output;\n }\n const millis = browserMillis(response);\n return PageCaptureResult.make({\n implementation: browserQuickActionImplementation,\n output,\n resourceUse: PageCaptureResourceUse.make({\n ...(millis === undefined ? {} : { browserMillis: millis }),\n ...(usesWorkersAi\n ? {\n inference: PageCaptureInferenceUse.make({\n provider: \"cloudflare-workers-ai\",\n modelCalls: 1,\n }),\n }\n : {}),\n }),\n });\n });\n\n/**\n * Ordinary Quick Actions require host-owned browser binding authority. Workers\n * AI stays unavailable unless the host deliberately selects its separate Layer.\n */\nexport const browserQuickActionCaptureLayer = (): Layer.Layer<\n PageCapture,\n never,\n BrowserQuickActionBrowserBinding\n> =>\n Layer.effect(\n PageCapture,\n Effect.map(BrowserQuickActionBrowserBinding, (browser) =>\n PageCapture.of({ capture: makeCapture(browser) }),\n ),\n );\n\n/** Structured Quick Actions require host-owned browser and Workers AI authority. */\nexport const browserQuickActionWorkersAiCaptureLayer = (): Layer.Layer<\n PageCapture,\n never,\n BrowserQuickActionBrowserBinding | BrowserQuickActionWorkersAi\n> =>\n Layer.effect(\n PageCapture,\n Effect.gen(function* () {\n const browser = yield* BrowserQuickActionBrowserBinding;\n const workersAi = yield* BrowserQuickActionWorkersAi;\n return PageCapture.of({ capture: makeCapture(browser, workersAi) });\n }),\n );\n\nconst screenshotOptions = (request: PageScreenshotRequest): BrowserRunScreenshotOptions => {\n const options: BrowserRunBaseOptions = {};\n if (\n request.navigation?.waitUntil !== undefined ||\n request.navigation?.timeoutMillis !== undefined\n ) {\n options.gotoOptions = {\n ...(request.navigation.waitUntil === undefined\n ? {}\n : { waitUntil: request.navigation.waitUntil }),\n ...(request.navigation.timeoutMillis === undefined\n ? {}\n : { timeout: request.navigation.timeoutMillis }),\n };\n }\n if (request.navigation?.waitForSelector !== undefined) {\n options.waitForSelector = {\n selector: request.navigation.waitForSelector.selector,\n ...(request.navigation.waitForSelector.timeoutMillis === undefined\n ? {}\n : { timeout: request.navigation.waitForSelector.timeoutMillis }),\n };\n }\n if (request.viewport !== undefined) {\n options.viewport = { width: request.viewport.width, height: request.viewport.height };\n }\n if (request.resourcePolicy?.rejectResourceTypes !== undefined) {\n options.rejectResourceTypes = [...request.resourcePolicy.rejectResourceTypes];\n }\n if (request.resourcePolicy?.allowRequestPatterns !== undefined) {\n options.allowRequestPattern = [...request.resourcePolicy.allowRequestPatterns];\n }\n return {\n ...options,\n ...(request.target._tag === \"PageUrlTarget\"\n ? { url: request.target.url }\n : { html: request.target.html }),\n screenshotOptions: { type: \"png\", encoding: \"binary\", fullPage: request.fullPage },\n };\n};\n\nconst cancelBody = (body: ReadableStream<Uint8Array>): Effect.Effect<void> =>\n Effect.tryPromise({\n try: () => body.cancel(),\n catch: () => undefined,\n }).pipe(Effect.catch(() => Effect.void));\n\nconst releaseScreenshotReader = (\n reader: ReadableStreamDefaultReader<Uint8Array>,\n): Effect.Effect<void> =>\n Effect.tryPromise({ try: () => reader.cancel(), catch: () => undefined }).pipe(\n Effect.catch(() => Effect.logWarning(\"Canceling the screenshot response failed\")),\n Effect.ensuring(\n Effect.try({\n try: () => reader.releaseLock(),\n catch: () => undefined,\n }).pipe(Effect.catch(() => Effect.logWarning(\"Releasing the screenshot response failed\"))),\n ),\n );\n\nconst pngResponse = (response: Response): boolean =>\n response.headers.get(\"Content-Type\")?.split(\";\", 1)[0]?.trim().toLowerCase() === \"image/png\";\n\nconst declaredLength = (response: Response): number | undefined => {\n const raw = response.headers.get(\"Content-Length\");\n if (raw === null || !/^(0|[1-9][0-9]*)$/.test(raw)) return undefined;\n const length = Number(raw);\n return Number.isSafeInteger(length) ? length : undefined;\n};\n\nconst readScreenshot = Effect.fn(\"BrowserQuickActionScreenshot.read\")(function* (\n response: Response,\n request: PageScreenshotRequest,\n) {\n const body = response.body;\n if (body === null) {\n return yield* protocolError(\"The screenshot response had no body\");\n }\n if (!pngResponse(response)) {\n yield* cancelBody(body);\n return yield* protocolError(\"The screenshot response was not image/png\");\n }\n const length = declaredLength(response);\n if (length !== undefined && length > request.limits.maxOutputBytes) {\n yield* cancelBody(body);\n return yield* PageScreenshotOutputLimitError.make({\n implementation: browserQuickActionImplementation,\n limit: request.limits.maxOutputBytes,\n observed: length,\n });\n }\n const reader = yield* Effect.acquireRelease(\n Effect.try({\n try: () => body.getReader(),\n catch: (cause) => protocolError(\"Opening the screenshot response failed\", cause),\n }),\n releaseScreenshotReader,\n );\n const chunks: Array<Uint8Array> = [];\n let observed = 0;\n while (true) {\n const next = yield* Effect.tryPromise({\n try: () => reader.read(),\n catch: (cause) => protocolError(\"Reading the screenshot response failed\", cause),\n });\n if (next.done) break;\n observed += next.value.byteLength;\n if (observed > request.limits.maxOutputBytes) {\n return yield* PageScreenshotOutputLimitError.make({\n implementation: browserQuickActionImplementation,\n limit: request.limits.maxOutputBytes,\n observed,\n });\n }\n chunks.push(next.value);\n }\n const bytes = new Uint8Array(observed);\n let offset = 0;\n for (const chunk of chunks) {\n bytes.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return bytes;\n}, Effect.scoped);\n\nconst makeScreenshot = (browser: BrowserQuickActionClient): PageScreenshotCapture =>\n Effect.fn(\"BrowserQuickActionScreenshot.capture\")(function* (\n request: PageScreenshotRequest,\n ): Effect.fn.Return<PageScreenshotResult, PageScreenshotError> {\n if (request.engine !== \"chromium\") {\n return yield* PageCaptureUnsupportedError.make({\n implementation: browserQuickActionImplementation,\n feature: \"engine\",\n message: \"The browser binding's screenshot action exposes no engine selector\",\n });\n }\n const response = yield* browser\n .screenshot(screenshotOptions(request))\n .pipe(\n Effect.mapError((error) =>\n protocolError(\"The browser binding rejected the screenshot\", error.cause),\n ),\n );\n if (response.status === 429) {\n const body = response.body;\n if (body !== null) yield* cancelBody(body);\n return yield* PageCaptureRateLimitedError.make({\n implementation: browserQuickActionImplementation,\n reason: \"rate\",\n ...(retryAfterMillis(response) === undefined\n ? {}\n : { retryAfterMillis: retryAfterMillis(response) }),\n message: \"The screenshot Quick Action was rate limited\",\n });\n }\n if (!response.ok) {\n const body = response.body;\n if (body !== null) yield* cancelBody(body);\n const message = `The screenshot Quick Action answered HTTP ${response.status}`;\n return yield* response.status >= 500 ? protocolError(message) : navigationError(message);\n }\n const bytes = yield* readScreenshot(response, request);\n return PageScreenshotResult.make({\n implementation: browserQuickActionImplementation,\n mediaType: \"image/png\",\n bytes,\n });\n });\n\n/** Native Browser Run screenshot adapter. It retains PNG bytes only for the caller's result. */\nexport const browserQuickActionScreenshotLayer = (): Layer.Layer<\n PageScreenshot,\n never,\n BrowserQuickActionBrowserBinding\n> =>\n Layer.effect(\n PageScreenshot,\n Effect.map(BrowserQuickActionBrowserBinding, (browser) =>\n PageScreenshot.of({ capture: makeScreenshot(browser) }),\n ),\n );\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"browser-quick-action.mjs","names":[],"sources":["../src/browser-quick-action.ts"],"sourcesContent":["/// <reference types=\"@cloudflare/workers-types\" />\n\nimport {\n PageCapture,\n PageCaptureInferenceUse,\n PageCaptureInferencePolicyError,\n PageCaptureNavigationError,\n PageCaptureOutputLimitError,\n PageCaptureProtocolError,\n PageCaptureRateLimitedError,\n PageCaptureResourceUse,\n PageCaptureResult,\n PageCaptureUnsupportedError,\n PageScreenshot,\n PageScreenshotOutputLimitError,\n PageScreenshotResult,\n type PageScreenshotCapture,\n type PageScreenshotError,\n type PageScreenshotRequest,\n PageContentCaptured,\n PageLinksCaptured,\n PageMarkdownCaptured,\n PageScrapeCaptured,\n PageStructuredCaptured,\n SandboxImplementation,\n type PageCaptureAction,\n type PageCaptureCapture,\n type PageCaptureError,\n type PageCaptureOutput,\n type PageCaptureRequest,\n} from \"@effect-agent/sandbox\";\nimport { Context, Effect, Layer, Option, Schema } from \"effect\";\n\n/**\n * The Cloudflare Browser Run Quick Action `PageCapture` adapter (capability\n * spec §9.2). Each capture is one stateless `quickAction()` RPC on the\n * Wrangler `browser` binding: the platform renders the target in a managed\n * headless browser and returns one bounded output; the adapter holds no\n * session and no state between passes. The binding requires a Worker\n * compatibility date of `2026-03-24` or later, and local `wrangler dev` needs\n * remote mode (`\"remote\": true` on the binding) because `quickAction` has no\n * local implementation.\n *\n * Rendered output is untrusted, attacker-influenced content; this adapter\n * only bounds and types it. Deployment class `E` only: no durability claim.\n */\nexport const browserQuickActionImplementation = SandboxImplementation.make({\n isolation: \"isolated\",\n identity: \"cloudflare-browser-quick-action\",\n});\n\n/**\n * Effect-native client captured by the binding service. Its option types come\n * directly from the pinned Workers declarations rather than a local copy.\n */\nexport interface BrowserQuickActionClient {\n readonly screenshot: (\n options: BrowserRunScreenshotOptions,\n ) => Effect.Effect<Response, BrowserQuickActionRpcError>;\n readonly content: (\n options: BrowserRunContentOptions,\n ) => Effect.Effect<Response, BrowserQuickActionRpcError>;\n readonly markdown: (\n options: BrowserRunMarkdownOptions,\n ) => Effect.Effect<Response, BrowserQuickActionRpcError>;\n readonly links: (\n options: BrowserRunLinksOptions,\n ) => Effect.Effect<Response, BrowserQuickActionRpcError>;\n readonly scrape: (\n options: BrowserRunScrapeOptions,\n ) => Effect.Effect<Response, BrowserQuickActionRpcError>;\n readonly json: (\n options: BrowserRunJsonOptions,\n ) => Effect.Effect<Response, BrowserQuickActionRpcError>;\n}\n\n/** A native binding RPC rejected before it returned an HTTP response. */\nexport class BrowserQuickActionRpcError extends Schema.TaggedError<BrowserQuickActionRpcError>()(\n \"BrowserQuickActionRpcError\",\n {\n action: Schema.Literals([\"screenshot\", \"content\", \"markdown\", \"links\", \"scrape\", \"json\"]),\n cause: Schema.Defect(),\n },\n) {}\n\nexport interface BrowserQuickActionCaptureOptions {\n /** The resolved Wrangler `browser` binding (DEPLOY-014: supplied, never ambient). */\n readonly browser: BrowserRun;\n}\n\n/** Host-owned browser binding authority, supplied explicitly at the composition root. */\nexport class BrowserQuickActionBrowserBinding extends Context.Service<\n BrowserQuickActionBrowserBinding,\n BrowserQuickActionClient\n>()(\"@effect-agent/platform-cloudflare/BrowserQuickActionBrowserBinding\") {\n static layer(\n options: BrowserQuickActionCaptureOptions,\n ): Layer.Layer<BrowserQuickActionBrowserBinding> {\n const browser = options.browser;\n const invoke = Effect.fn(\"BrowserQuickActionBrowserBinding.invoke\")(function* (\n action: \"screenshot\" | \"content\" | \"markdown\" | \"links\" | \"scrape\" | \"json\",\n evaluate: () => Promise<Response>,\n ): Effect.fn.Return<Response, BrowserQuickActionRpcError> {\n return yield* Effect.tryPromise({\n try: evaluate,\n catch: (cause) => BrowserQuickActionRpcError.make({ action, cause }),\n });\n });\n return Layer.succeed(BrowserQuickActionBrowserBinding)({\n screenshot: (request) =>\n invoke(\"screenshot\", () => browser.quickAction(\"screenshot\", request)),\n content: (request) => invoke(\"content\", () => browser.quickAction(\"content\", request)),\n markdown: (request) => invoke(\"markdown\", () => browser.quickAction(\"markdown\", request)),\n links: (request) => invoke(\"links\", () => browser.quickAction(\"links\", request)),\n scrape: (request) => invoke(\"scrape\", () => browser.quickAction(\"scrape\", request)),\n json: (request) => invoke(\"json\", () => browser.quickAction(\"json\", request)),\n });\n }\n}\n\n/** Host-owned authorization and accounting for one Workers AI extraction. */\nexport interface BrowserQuickActionWorkersAiPolicy {\n readonly authorizeAndAccount: (\n request: PageCaptureRequest,\n ) => Effect.Effect<void, BrowserQuickActionWorkersAiPolicyError>;\n}\n\n/** Host-only diagnostic for a denied or unaccounted Workers AI extraction. */\nexport class BrowserQuickActionWorkersAiPolicyError extends Schema.TaggedError<BrowserQuickActionWorkersAiPolicyError>()(\n \"BrowserQuickActionWorkersAiPolicyError\",\n {\n reason: Schema.Literals([\"authorization\", \"accounting\"]),\n message: Schema.String.check(Schema.isMaxLength(8_000)),\n cause: Schema.optionalKey(Schema.Defect()),\n },\n) {}\n\n/** Explicit host-owned authority and accounting for separately billed Workers AI extraction. */\nexport class BrowserQuickActionWorkersAi extends Context.Service<\n BrowserQuickActionWorkersAi,\n BrowserQuickActionWorkersAiPolicy\n>()(\"@effect-agent/platform-cloudflare/BrowserQuickActionWorkersAi\") {\n static layer(\n policy: BrowserQuickActionWorkersAiPolicy,\n ): Layer.Layer<BrowserQuickActionWorkersAi> {\n return Layer.succeed(BrowserQuickActionWorkersAi)(policy);\n }\n}\n\nconst MAX_DIAGNOSTIC_LENGTH = 8_000;\nconst boundedDiagnostic = (message: string): string => message.slice(0, MAX_DIAGNOSTIC_LENGTH);\n\nconst QuickActionSuccessEnvelope = Schema.Struct({\n success: Schema.Literal(true),\n result: Schema.Json,\n});\n\nconst QuickActionErrorEnvelope = Schema.Struct({\n success: Schema.Literal(false),\n errors: Schema.Array(\n Schema.Struct({\n message: Schema.String,\n code: Schema.optionalKey(Schema.Number),\n detail: Schema.optionalKey(Schema.String),\n path: Schema.optionalKey(Schema.String),\n }),\n ),\n rawAiResponse: Schema.optionalKey(Schema.String),\n});\n\nconst QuickActionEnvelope = Schema.Union([QuickActionSuccessEnvelope, QuickActionErrorEnvelope]);\nconst decodeEnvelope = Schema.decodeUnknownOption(Schema.fromJsonString(QuickActionEnvelope));\n\n/** Project the schema-validated request onto Cloudflare's native common options. */\nconst quickActionCommonOptions = (request: PageCaptureRequest): BrowserRunCommonOptions => {\n const options: BrowserRunBaseOptions = {};\n const navigation = request.navigation;\n if (navigation !== undefined) {\n const goto: NonNullable<BrowserRunBaseOptions[\"gotoOptions\"]> = {};\n if (navigation.waitUntil !== undefined) goto.waitUntil = navigation.waitUntil;\n if (navigation.timeoutMillis !== undefined) goto.timeout = navigation.timeoutMillis;\n if (Object.keys(goto).length > 0) options.gotoOptions = goto;\n if (navigation.waitForSelector !== undefined) {\n options.waitForSelector = {\n selector: navigation.waitForSelector.selector,\n ...(navigation.waitForSelector.timeoutMillis === undefined\n ? {}\n : { timeout: navigation.waitForSelector.timeoutMillis }),\n };\n }\n }\n if (request.viewport !== undefined) {\n options.viewport = { width: request.viewport.width, height: request.viewport.height };\n }\n if (request.resourcePolicy !== undefined) {\n if (request.resourcePolicy.rejectResourceTypes !== undefined) {\n options.rejectResourceTypes = [...request.resourcePolicy.rejectResourceTypes];\n }\n if (request.resourcePolicy.allowRequestPatterns !== undefined) {\n options.allowRequestPattern = [...request.resourcePolicy.allowRequestPatterns];\n }\n }\n return request.target._tag === \"PageUrlTarget\"\n ? { ...options, url: request.target.url }\n : { ...options, html: request.target.html };\n};\n\n/** Dispatch through Cloudflare's native action-specific overloads. */\nconst executeQuickAction = (\n browser: BrowserQuickActionClient,\n request: PageCaptureRequest,\n): Effect.Effect<Response, BrowserQuickActionRpcError> => {\n const options = quickActionCommonOptions(request);\n switch (request.action._tag) {\n case \"CapturePageContent\": {\n return browser.content(options);\n }\n case \"CapturePageMarkdown\": {\n return browser.markdown(options);\n }\n case \"CapturePageLinks\": {\n return browser.links({\n ...options,\n ...(request.action.visibleLinksOnly === undefined\n ? {}\n : { visibleLinksOnly: request.action.visibleLinksOnly }),\n });\n }\n case \"CapturePageScrape\": {\n return browser.scrape({\n ...options,\n elements: request.action.selectors.map((selector) => ({ selector })),\n });\n }\n case \"CapturePageStructured\": {\n return browser.json({\n ...options,\n response_format: {\n type: \"json_schema\",\n json_schema: request.action.responseFormat,\n },\n ...(request.action.prompt === undefined ? {} : { prompt: request.action.prompt }),\n });\n }\n }\n};\n\nconst protocolError = (message: string, cause?: unknown): PageCaptureProtocolError =>\n PageCaptureProtocolError.make({\n implementation: browserQuickActionImplementation,\n message: boundedDiagnostic(message),\n ...(cause === undefined ? {} : { cause }),\n });\n\nconst navigationError = (message: string, cause?: unknown): PageCaptureNavigationError =>\n PageCaptureNavigationError.make({\n implementation: browserQuickActionImplementation,\n message: boundedDiagnostic(message),\n ...(cause === undefined ? {} : { cause }),\n });\n\n/** Preserve bounded remote diagnostics for the host without exposing their text to a model. */\nconst privateResponseCause = (bodyText: string): Error | undefined =>\n bodyText.length === 0 ? undefined : new Error(boundedDiagnostic(bodyText));\n\nconst releaseResponseReader = (\n reader: ReadableStreamDefaultReader<Uint8Array>,\n): Effect.Effect<void> =>\n Effect.tryPromise({\n try: () => reader.cancel(),\n catch: (cause) => protocolError(\"Canceling the Quick Action response failed\", cause),\n }).pipe(\n Effect.catch((error) => Effect.logWarning(error.message)),\n Effect.ensuring(\n Effect.try({\n try: () => reader.releaseLock(),\n catch: (cause) => protocolError(\"Releasing the Quick Action response failed\", cause),\n }).pipe(Effect.catch((error) => Effect.logWarning(error.message))),\n ),\n );\n\nconst readBoundedResponse = Effect.fn(\"BrowserQuickActionCapture.readResponse\")(function* (\n response: Response,\n request: PageCaptureRequest,\n) {\n const body = response.body;\n if (body === null) return \"\";\n\n const reader = yield* Effect.acquireRelease(\n Effect.try({\n try: () => body.getReader(),\n catch: (cause) => protocolError(\"Opening the Quick Action response failed\", cause),\n }),\n releaseResponseReader,\n );\n const decoder = new TextDecoder(\"utf-8\", { fatal: true, ignoreBOM: false });\n let observedBytes = 0;\n let bodyText = \"\";\n\n while (true) {\n const chunk = yield* Effect.tryPromise({\n try: () => reader.read(),\n catch: (cause) => protocolError(\"Reading the Quick Action response failed\", cause),\n });\n if (chunk.done) break;\n\n observedBytes += chunk.value.byteLength;\n if (observedBytes > request.limits.maxOutputBytes) {\n return yield* PageCaptureOutputLimitError.make({\n implementation: browserQuickActionImplementation,\n limit: request.limits.maxOutputBytes,\n observed: observedBytes,\n });\n }\n\n bodyText += yield* Effect.try({\n try: () => decoder.decode(chunk.value, { stream: true }),\n catch: (cause) => protocolError(\"Decoding the Quick Action response failed\", cause),\n });\n }\n\n return (\n bodyText +\n (yield* Effect.try({\n try: () => decoder.decode(),\n catch: (cause) => protocolError(\"Decoding the Quick Action response failed\", cause),\n }))\n );\n}, Effect.scoped);\n\n/**\n * Retry-After arrives in whole seconds; a non-integer form (an HTTP date) is\n * dropped rather than guessed at.\n */\nconst retryAfterMillis = (response: Response): number | undefined => {\n const header = response.headers.get(\"Retry-After\");\n if (header === null) return undefined;\n const seconds = Number(header);\n if (!Number.isSafeInteger(seconds) || seconds < 0) return undefined;\n const millis = seconds * 1_000;\n return Number.isSafeInteger(millis) ? millis : undefined;\n};\n\nconst browserMillis = (response: Response): number | undefined => {\n const header = response.headers.get(\"X-Browser-Ms-Used\");\n if (header === null) return undefined;\n const millis = Number(header);\n return Number.isSafeInteger(millis) && millis >= 0 ? millis : undefined;\n};\n\n/** Only trusted response metadata chooses transport framing; page text never does. */\nconst isJsonResponse = (response: Response): boolean => {\n const contentType = response.headers.get(\"Content-Type\");\n if (contentType === null) return false;\n const mediaType = contentType.split(\";\", 1)[0]?.trim().toLowerCase();\n return mediaType === \"application/json\" || mediaType?.endsWith(\"+json\") === true;\n};\n\nconst parseOutput = (\n action: PageCaptureAction,\n bodyText: string,\n response: Response,\n): PageCaptureOutput | PageCaptureNavigationError | PageCaptureProtocolError => {\n if (!isJsonResponse(response)) {\n return protocolError(\n \"The Quick Action success response was not a JSON response envelope\",\n privateResponseCause(bodyText),\n );\n }\n const envelope = decodeEnvelope(bodyText);\n if (Option.isNone(envelope)) {\n return protocolError(\n \"The JSON Quick Action response did not carry a valid response envelope\",\n privateResponseCause(bodyText),\n );\n }\n if (!envelope.value.success) {\n return navigationError(\n \"The Quick Action reported a navigation failure\",\n privateResponseCause(bodyText),\n );\n }\n switch (action._tag) {\n case \"CapturePageContent\":\n case \"CapturePageMarkdown\": {\n if (typeof envelope.value.result !== \"string\") {\n return protocolError(\"The Quick Action envelope carried a non-text result\");\n }\n return action._tag === \"CapturePageContent\"\n ? PageContentCaptured.make({ html: envelope.value.result })\n : PageMarkdownCaptured.make({ markdown: envelope.value.result });\n }\n case \"CapturePageLinks\": {\n const decoded = Schema.decodeUnknownOption(PageLinksCaptured)({\n _tag: \"PageLinksCaptured\",\n links: envelope.value.result,\n });\n if (Option.isNone(decoded)) {\n return protocolError(\"The links Quick Action did not return a bounded array of valid URLs\");\n }\n return decoded.value;\n }\n case \"CapturePageScrape\": {\n const decoded = Schema.decodeUnknownOption(PageScrapeCaptured)({\n _tag: \"PageScrapeCaptured\",\n groups: envelope.value.result,\n });\n if (Option.isNone(decoded)) {\n return protocolError(\n \"The scrape Quick Action did not return bounded grouped element records\",\n );\n }\n return decoded.value;\n }\n case \"CapturePageStructured\": {\n return PageStructuredCaptured.make({ value: envelope.value.result });\n }\n }\n};\n\nconst isQuotaMessage = (text: string): boolean => /time limit|daily|quota/i.test(text);\n\nconst makeCapture = (\n browser: BrowserQuickActionClient,\n workersAi?: BrowserQuickActionWorkersAiPolicy,\n): PageCaptureCapture =>\n Effect.fn(\"BrowserQuickActionCapture.capture\")(function* (\n request: PageCaptureRequest,\n ): Effect.fn.Return<PageCaptureResult, PageCaptureError> {\n if (request.engine !== \"chromium\") {\n return yield* PageCaptureUnsupportedError.make({\n implementation: browserQuickActionImplementation,\n feature: \"engine\",\n message:\n \"The browser binding's quickAction() exposes no engine selector; kitesurf requires the REST or CDP surface\",\n });\n }\n\n const usesWorkersAi = request.action._tag === \"CapturePageStructured\";\n if (usesWorkersAi) {\n if (workersAi === undefined) {\n return yield* PageCaptureUnsupportedError.make({\n implementation: browserQuickActionImplementation,\n feature: \"action\",\n message:\n \"Structured capture invokes separately billed Workers AI and requires an explicit authorization and accounting policy\",\n });\n }\n yield* workersAi.authorizeAndAccount(request).pipe(\n Effect.mapError((cause) =>\n PageCaptureInferencePolicyError.make({\n implementation: browserQuickActionImplementation,\n provider: \"cloudflare-workers-ai\",\n reason: cause.reason,\n message:\n cause.reason === \"authorization\"\n ? \"Workers AI extraction was not authorized\"\n : \"Workers AI extraction could not be accounted for\",\n cause,\n }),\n ),\n );\n }\n\n const response = yield* executeQuickAction(browser, request).pipe(\n Effect.mapError((error) =>\n protocolError(\"The browser binding rejected the Quick Action\", error.cause),\n ),\n );\n const bodyText = yield* readBoundedResponse(response, request);\n if (response.status === 429) {\n const retryAfter = retryAfterMillis(response);\n const reason = isQuotaMessage(bodyText) ? \"quota\" : \"rate\";\n const cause = privateResponseCause(bodyText);\n return yield* PageCaptureRateLimitedError.make({\n implementation: browserQuickActionImplementation,\n reason,\n ...(retryAfter === undefined ? {} : { retryAfterMillis: retryAfter }),\n ...(cause === undefined ? {} : { cause }),\n message:\n reason === \"quota\"\n ? \"The Quick Action exceeded its browser quota\"\n : \"The Quick Action was rate limited\",\n });\n }\n if (!response.ok) {\n const message = `The Quick Action answered HTTP ${response.status}`;\n const cause = privateResponseCause(bodyText);\n if (response.status >= 500) {\n return yield* protocolError(message, cause);\n }\n return yield* navigationError(message, cause);\n }\n const output = parseOutput(request.action, bodyText, response);\n if (\n output._tag === \"PageCaptureNavigationError\" ||\n output._tag === \"PageCaptureProtocolError\"\n ) {\n return yield* output;\n }\n const millis = browserMillis(response);\n return PageCaptureResult.make({\n implementation: browserQuickActionImplementation,\n output,\n resourceUse: PageCaptureResourceUse.make({\n ...(millis === undefined ? {} : { browserMillis: millis }),\n ...(usesWorkersAi\n ? {\n inference: PageCaptureInferenceUse.make({\n provider: \"cloudflare-workers-ai\",\n modelCalls: 1,\n }),\n }\n : {}),\n }),\n });\n });\n\n/**\n * Ordinary Quick Actions require host-owned browser binding authority. Workers\n * AI stays unavailable unless the host deliberately selects its separate Layer.\n */\nexport const browserQuickActionCaptureLayer = (): Layer.Layer<\n PageCapture,\n never,\n BrowserQuickActionBrowserBinding\n> =>\n Layer.effect(\n PageCapture,\n Effect.map(BrowserQuickActionBrowserBinding, (browser) =>\n PageCapture.of({ capture: makeCapture(browser) }),\n ),\n );\n\n/** Structured Quick Actions require host-owned browser and Workers AI authority. */\nexport const browserQuickActionWorkersAiCaptureLayer = (): Layer.Layer<\n PageCapture,\n never,\n BrowserQuickActionBrowserBinding | BrowserQuickActionWorkersAi\n> =>\n Layer.effect(\n PageCapture,\n Effect.gen(function* () {\n const browser = yield* BrowserQuickActionBrowserBinding;\n const workersAi = yield* BrowserQuickActionWorkersAi;\n return PageCapture.of({ capture: makeCapture(browser, workersAi) });\n }),\n );\n\n/** Host-owned Quick Action binding and optional, separately billed extraction authority. */\nexport interface CloudflareBrowserOptions extends BrowserQuickActionCaptureOptions {\n readonly workersAi?: BrowserQuickActionWorkersAiPolicy;\n}\n\n/** Compose WebCapture handlers with the Cloudflare Quick Action adapter. */\nexport const CloudflareBrowser = {\n /**\n * Supply a WebCapture definition and the resolved Worker browser binding.\n * Supports capture, scrape, and extraction definitions without importing capabilities.\n * Only PageCapture is provided; other handler requirements and errors stay visible.\n * Extraction fails closed unless workersAi explicitly authorizes and accounts for it.\n * Capture limits, typed failures, tracing, and scoped response cleanup are unchanged.\n */\n layer: <A, E, R>(\n definition: { readonly handlers: Layer.Layer<A, E, R> },\n options: CloudflareBrowserOptions,\n ): Layer.Layer<A, E, Exclude<R, PageCapture>> => {\n const capture =\n options.workersAi === undefined\n ? browserQuickActionCaptureLayer()\n : browserQuickActionWorkersAiCaptureLayer().pipe(\n Layer.provide(BrowserQuickActionWorkersAi.layer(options.workersAi)),\n );\n\n return definition.handlers.pipe(\n Layer.provide(capture.pipe(Layer.provide(BrowserQuickActionBrowserBinding.layer(options)))),\n );\n },\n};\n\nconst screenshotOptions = (request: PageScreenshotRequest): BrowserRunScreenshotOptions => {\n const options: BrowserRunBaseOptions = {};\n if (\n request.navigation?.waitUntil !== undefined ||\n request.navigation?.timeoutMillis !== undefined\n ) {\n options.gotoOptions = {\n ...(request.navigation.waitUntil === undefined\n ? {}\n : { waitUntil: request.navigation.waitUntil }),\n ...(request.navigation.timeoutMillis === undefined\n ? {}\n : { timeout: request.navigation.timeoutMillis }),\n };\n }\n if (request.navigation?.waitForSelector !== undefined) {\n options.waitForSelector = {\n selector: request.navigation.waitForSelector.selector,\n ...(request.navigation.waitForSelector.timeoutMillis === undefined\n ? {}\n : { timeout: request.navigation.waitForSelector.timeoutMillis }),\n };\n }\n if (request.viewport !== undefined) {\n options.viewport = { width: request.viewport.width, height: request.viewport.height };\n }\n if (request.resourcePolicy?.rejectResourceTypes !== undefined) {\n options.rejectResourceTypes = [...request.resourcePolicy.rejectResourceTypes];\n }\n if (request.resourcePolicy?.allowRequestPatterns !== undefined) {\n options.allowRequestPattern = [...request.resourcePolicy.allowRequestPatterns];\n }\n return {\n ...options,\n ...(request.target._tag === \"PageUrlTarget\"\n ? { url: request.target.url }\n : { html: request.target.html }),\n screenshotOptions: { type: \"png\", encoding: \"binary\", fullPage: request.fullPage },\n };\n};\n\nconst cancelBody = (body: ReadableStream<Uint8Array>): Effect.Effect<void> =>\n Effect.tryPromise({\n try: () => body.cancel(),\n catch: () => undefined,\n }).pipe(Effect.catch(() => Effect.void));\n\nconst releaseScreenshotReader = (\n reader: ReadableStreamDefaultReader<Uint8Array>,\n): Effect.Effect<void> =>\n Effect.tryPromise({ try: () => reader.cancel(), catch: () => undefined }).pipe(\n Effect.catch(() => Effect.logWarning(\"Canceling the screenshot response failed\")),\n Effect.ensuring(\n Effect.try({\n try: () => reader.releaseLock(),\n catch: () => undefined,\n }).pipe(Effect.catch(() => Effect.logWarning(\"Releasing the screenshot response failed\"))),\n ),\n );\n\nconst pngResponse = (response: Response): boolean =>\n response.headers.get(\"Content-Type\")?.split(\";\", 1)[0]?.trim().toLowerCase() === \"image/png\";\n\nconst declaredLength = (response: Response): number | undefined => {\n const raw = response.headers.get(\"Content-Length\");\n if (raw === null || !/^(0|[1-9][0-9]*)$/.test(raw)) return undefined;\n const length = Number(raw);\n return Number.isSafeInteger(length) ? length : undefined;\n};\n\nconst readScreenshot = Effect.fn(\"BrowserQuickActionScreenshot.read\")(function* (\n response: Response,\n request: PageScreenshotRequest,\n) {\n const body = response.body;\n if (body === null) {\n return yield* protocolError(\"The screenshot response had no body\");\n }\n if (!pngResponse(response)) {\n yield* cancelBody(body);\n return yield* protocolError(\"The screenshot response was not image/png\");\n }\n const length = declaredLength(response);\n if (length !== undefined && length > request.limits.maxOutputBytes) {\n yield* cancelBody(body);\n return yield* PageScreenshotOutputLimitError.make({\n implementation: browserQuickActionImplementation,\n limit: request.limits.maxOutputBytes,\n observed: length,\n });\n }\n const reader = yield* Effect.acquireRelease(\n Effect.try({\n try: () => body.getReader(),\n catch: (cause) => protocolError(\"Opening the screenshot response failed\", cause),\n }),\n releaseScreenshotReader,\n );\n const chunks: Array<Uint8Array> = [];\n let observed = 0;\n while (true) {\n const next = yield* Effect.tryPromise({\n try: () => reader.read(),\n catch: (cause) => protocolError(\"Reading the screenshot response failed\", cause),\n });\n if (next.done) break;\n observed += next.value.byteLength;\n if (observed > request.limits.maxOutputBytes) {\n return yield* PageScreenshotOutputLimitError.make({\n implementation: browserQuickActionImplementation,\n limit: request.limits.maxOutputBytes,\n observed,\n });\n }\n chunks.push(next.value);\n }\n const bytes = new Uint8Array(observed);\n let offset = 0;\n for (const chunk of chunks) {\n bytes.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return bytes;\n}, Effect.scoped);\n\nconst makeScreenshot = (browser: BrowserQuickActionClient): PageScreenshotCapture =>\n Effect.fn(\"BrowserQuickActionScreenshot.capture\")(function* (\n request: PageScreenshotRequest,\n ): Effect.fn.Return<PageScreenshotResult, PageScreenshotError> {\n if (request.engine !== \"chromium\") {\n return yield* PageCaptureUnsupportedError.make({\n implementation: browserQuickActionImplementation,\n feature: \"engine\",\n message: \"The browser binding's screenshot action exposes no engine selector\",\n });\n }\n const response = yield* browser\n .screenshot(screenshotOptions(request))\n .pipe(\n Effect.mapError((error) =>\n protocolError(\"The browser binding rejected the screenshot\", error.cause),\n ),\n );\n if (response.status === 429) {\n const body = response.body;\n if (body !== null) yield* cancelBody(body);\n return yield* PageCaptureRateLimitedError.make({\n implementation: browserQuickActionImplementation,\n reason: \"rate\",\n ...(retryAfterMillis(response) === undefined\n ? {}\n : { retryAfterMillis: retryAfterMillis(response) }),\n message: \"The screenshot Quick Action was rate limited\",\n });\n }\n if (!response.ok) {\n const body = response.body;\n if (body !== null) yield* cancelBody(body);\n const message = `The screenshot Quick Action answered HTTP ${response.status}`;\n return yield* response.status >= 500 ? protocolError(message) : navigationError(message);\n }\n const bytes = yield* readScreenshot(response, request);\n return PageScreenshotResult.make({\n implementation: browserQuickActionImplementation,\n mediaType: \"image/png\",\n bytes,\n });\n });\n\n/** Native Browser Run screenshot adapter. It retains PNG bytes only for the caller's result. */\nexport const browserQuickActionScreenshotLayer = (): Layer.Layer<\n PageScreenshot,\n never,\n BrowserQuickActionBrowserBinding\n> =>\n Layer.effect(\n PageScreenshot,\n Effect.map(BrowserQuickActionBrowserBinding, (browser) =>\n PageScreenshot.of({ capture: makeScreenshot(browser) }),\n ),\n );\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BrowserQuickActionWorkersAi } from "./browser-quick-action.mjs";
|
|
1
|
+
import { BrowserQuickActionWorkersAi, BrowserQuickActionWorkersAiPolicy } from "./browser-quick-action.mjs";
|
|
2
2
|
import { Layer, Redacted } from "effect";
|
|
3
3
|
import { PageCapture, SandboxImplementation } from "@effect-agent/sandbox";
|
|
4
4
|
import { HttpClient } from "effect/unstable/http";
|
|
@@ -14,6 +14,21 @@ interface BrowserRestCaptureOptions {
|
|
|
14
14
|
declare const browserRestCaptureLayer: (options: BrowserRestCaptureOptions) => Layer.Layer<PageCapture, never, HttpClient.HttpClient>;
|
|
15
15
|
/** REST structured extraction additionally requires explicit Workers AI authorization/accounting. */
|
|
16
16
|
declare const browserRestWorkersAiCaptureLayer: (options: BrowserRestCaptureOptions) => Layer.Layer<PageCapture, never, HttpClient.HttpClient | BrowserQuickActionWorkersAi>;
|
|
17
|
+
/** Explicit REST credentials and optional authorization for separately billed extraction. */
|
|
18
|
+
interface CloudflareBrowserRestOptions extends BrowserRestCaptureOptions {
|
|
19
|
+
readonly workersAi?: BrowserQuickActionWorkersAiPolicy;
|
|
20
|
+
}
|
|
21
|
+
/** Node-safe WebCapture handler assembly; the application supplies its HttpClient. */
|
|
22
|
+
declare const CloudflareBrowserRest: {
|
|
23
|
+
/**
|
|
24
|
+
* Supports capture, scrape, and extraction definitions. Only PageCapture is supplied;
|
|
25
|
+
* handler errors and other services remain visible. Extraction fails closed without
|
|
26
|
+
* workersAi. Existing host policies, response limits, and scoped cleanup are unchanged.
|
|
27
|
+
*/
|
|
28
|
+
layer: <A, E, R>(definition: {
|
|
29
|
+
readonly handlers: Layer.Layer<A, E, R>;
|
|
30
|
+
}, options: CloudflareBrowserRestOptions) => Layer.Layer<A, E, Exclude<R, PageCapture> | HttpClient.HttpClient>;
|
|
31
|
+
};
|
|
17
32
|
//#endregion
|
|
18
|
-
export { BrowserRestCaptureOptions, browserRestCaptureImplementation, browserRestCaptureLayer, browserRestWorkersAiCaptureLayer };
|
|
33
|
+
export { BrowserRestCaptureOptions, CloudflareBrowserRest, CloudflareBrowserRestOptions, browserRestCaptureImplementation, browserRestCaptureLayer, browserRestWorkersAiCaptureLayer };
|
|
19
34
|
//# sourceMappingURL=browser-rest-capture.d.mts.map
|
|
@@ -220,7 +220,18 @@ const browserRestWorkersAiCaptureLayer = (options) => Layer.effect(PageCapture,
|
|
|
220
220
|
const workersAi = yield* BrowserQuickActionWorkersAi;
|
|
221
221
|
return PageCapture.of({ capture: makeCapture(client, options, workersAi) });
|
|
222
222
|
}));
|
|
223
|
+
/** Node-safe WebCapture handler assembly; the application supplies its HttpClient. */
|
|
224
|
+
const CloudflareBrowserRest = {
|
|
225
|
+
/**
|
|
226
|
+
* Supports capture, scrape, and extraction definitions. Only PageCapture is supplied;
|
|
227
|
+
* handler errors and other services remain visible. Extraction fails closed without
|
|
228
|
+
* workersAi. Existing host policies, response limits, and scoped cleanup are unchanged.
|
|
229
|
+
*/
|
|
230
|
+
layer: (definition, options) => {
|
|
231
|
+
const capture = options.workersAi === void 0 ? browserRestCaptureLayer(options) : browserRestWorkersAiCaptureLayer(options).pipe(Layer.provide(BrowserQuickActionWorkersAi.layer(options.workersAi)));
|
|
232
|
+
return definition.handlers.pipe(Layer.provide(capture));
|
|
233
|
+
} };
|
|
223
234
|
//#endregion
|
|
224
|
-
export { browserRestCaptureImplementation, browserRestCaptureLayer, browserRestWorkersAiCaptureLayer };
|
|
235
|
+
export { CloudflareBrowserRest, browserRestCaptureImplementation, browserRestCaptureLayer, browserRestWorkersAiCaptureLayer };
|
|
225
236
|
|
|
226
237
|
//# sourceMappingURL=browser-rest-capture.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-rest-capture.mjs","names":[],"sources":["../src/browser-rest-capture.ts"],"sourcesContent":["import {\n PageCapture,\n PageCaptureInferencePolicyError,\n PageCaptureInferenceUse,\n PageCaptureNavigationError,\n PageCaptureOutputLimitError,\n PageCaptureProtocolError,\n PageCaptureRateLimitedError,\n PageCaptureResourceUse,\n PageCaptureResult,\n PageContentCaptured,\n PageLinksCaptured,\n PageMarkdownCaptured,\n PageScrapeCaptured,\n PageStructuredCaptured,\n PageCaptureUnsupportedError,\n SandboxImplementation,\n type PageCaptureAction,\n type PageCaptureCapture,\n type PageCaptureError,\n type PageCaptureOutput,\n type PageCaptureRequest,\n} from \"@effect-agent/sandbox\";\nimport { Effect, Layer, Option, Redacted, Schema, Stream } from \"effect\";\nimport { HttpClient, HttpClientRequest, type HttpClientError } from \"effect/unstable/http\";\n\nimport {\n BrowserQuickActionWorkersAi,\n type BrowserQuickActionWorkersAiPolicy,\n} from \"./browser-quick-action.ts\";\n\n/** Node-safe REST PageCapture implementation; it never imports Worker runtime modules. */\nexport const browserRestCaptureImplementation = SandboxImplementation.make({\n isolation: \"isolated\",\n identity: \"cloudflare-browser-rest\",\n});\n\nconst API_ORIGIN = \"https://api.cloudflare.com\";\nconst MAX_DIAGNOSTIC_LENGTH = 8_000;\nconst boundedDiagnostic = (message: string): string => message.slice(0, MAX_DIAGNOSTIC_LENGTH);\n\n/** Explicit construction inputs; credentials are only projected into the fixed-origin Authorization header. */\nexport interface BrowserRestCaptureOptions {\n readonly accountId: string;\n readonly apiToken: Redacted.Redacted<string>;\n}\n\nconst RestSuccessEnvelope = Schema.Struct({\n success: Schema.Literal(true),\n result: Schema.Json,\n errors: Schema.optionalKey(Schema.Array(Schema.Unknown)),\n meta: Schema.optionalKey(Schema.Unknown),\n});\nconst RestErrorEnvelope = Schema.Struct({\n success: Schema.Literal(false),\n errors: Schema.Array(\n Schema.Struct({\n message: Schema.String,\n code: Schema.optionalKey(Schema.Number),\n }),\n ),\n result: Schema.optionalKey(Schema.Json),\n meta: Schema.optionalKey(Schema.Unknown),\n});\nconst RestEnvelope = Schema.Union([RestSuccessEnvelope, RestErrorEnvelope]);\nconst decodeEnvelope = Schema.decodeUnknownOption(Schema.fromJsonString(RestEnvelope));\n\nconst protocolError = (message: string, cause?: unknown): PageCaptureProtocolError =>\n PageCaptureProtocolError.make({\n implementation: browserRestCaptureImplementation,\n message: boundedDiagnostic(message),\n ...(cause === undefined ? {} : { cause }),\n });\n\nconst navigationError = (message: string, cause?: unknown): PageCaptureNavigationError =>\n PageCaptureNavigationError.make({\n implementation: browserRestCaptureImplementation,\n message: boundedDiagnostic(message),\n ...(cause === undefined ? {} : { cause }),\n });\n\nconst privateResponseCause = (\n bodyText: string,\n apiToken: Redacted.Redacted<string>,\n): Error | undefined => {\n if (bodyText.length === 0) return undefined;\n const token = Redacted.value(apiToken);\n const diagnostic = boundedDiagnostic(bodyText);\n return new Error(token.length === 0 ? diagnostic : diagnostic.replaceAll(token, \"[REDACTED]\"));\n};\n\nconst requestBody = (request: PageCaptureRequest): Record<string, unknown> => {\n const body: Record<string, unknown> =\n request.target._tag === \"PageUrlTarget\"\n ? { url: request.target.url }\n : { html: request.target.html };\n if (request.navigation !== undefined) {\n const goto: Record<string, unknown> = {};\n if (request.navigation.waitUntil !== undefined) goto.waitUntil = request.navigation.waitUntil;\n if (request.navigation.timeoutMillis !== undefined)\n goto.timeout = request.navigation.timeoutMillis;\n if (Object.keys(goto).length > 0) body.gotoOptions = goto;\n if (request.navigation.waitForSelector !== undefined) {\n body.waitForSelector = {\n selector: request.navigation.waitForSelector.selector,\n ...(request.navigation.waitForSelector.timeoutMillis === undefined\n ? {}\n : { timeout: request.navigation.waitForSelector.timeoutMillis }),\n };\n }\n }\n if (request.viewport !== undefined) body.viewport = request.viewport;\n if (request.resourcePolicy?.rejectResourceTypes !== undefined) {\n body.rejectResourceTypes = [...request.resourcePolicy.rejectResourceTypes];\n }\n if (request.resourcePolicy?.allowRequestPatterns !== undefined) {\n body.allowRequestPattern = [...request.resourcePolicy.allowRequestPatterns];\n }\n return body;\n};\n\nconst actionName = (\n action: PageCaptureAction,\n): \"content\" | \"markdown\" | \"links\" | \"scrape\" | \"json\" => {\n switch (action._tag) {\n case \"CapturePageContent\":\n return \"content\";\n case \"CapturePageMarkdown\":\n return \"markdown\";\n case \"CapturePageLinks\":\n return \"links\";\n case \"CapturePageScrape\":\n return \"scrape\";\n case \"CapturePageStructured\":\n return \"json\";\n }\n};\n\nconst actionBody = (request: PageCaptureRequest): Record<string, unknown> => {\n const body = requestBody(request);\n switch (request.action._tag) {\n case \"CapturePageContent\":\n case \"CapturePageMarkdown\":\n return body;\n case \"CapturePageLinks\":\n return {\n ...body,\n ...(request.action.visibleLinksOnly === undefined\n ? {}\n : { visibleLinksOnly: request.action.visibleLinksOnly }),\n };\n case \"CapturePageScrape\":\n return {\n ...body,\n elements: request.action.selectors.map((selector) => ({ selector })),\n };\n case \"CapturePageStructured\":\n return {\n ...body,\n response_format: { type: \"json_schema\", json_schema: request.action.responseFormat },\n ...(request.action.prompt === undefined ? {} : { prompt: request.action.prompt }),\n };\n }\n};\n\nconst retryAfterMillis = (\n headers: Readonly<Record<string, string | undefined>>,\n): number | undefined => {\n const seconds = Number(headers[\"retry-after\"]);\n if (!Number.isSafeInteger(seconds) || seconds < 0) return undefined;\n const millis = seconds * 1_000;\n return Number.isSafeInteger(millis) ? millis : undefined;\n};\n\nconst browserMillis = (\n headers: Readonly<Record<string, string | undefined>>,\n): number | undefined => {\n const millis = Number(headers[\"x-browser-ms-used\"]);\n return Number.isSafeInteger(millis) && millis >= 0 ? millis : undefined;\n};\n\n/** Response framing is provider metadata, never content controlled by the rendered page. */\nconst isJsonResponse = (headers: Readonly<Record<string, string | undefined>>): boolean => {\n const contentType = headers[\"content-type\"];\n if (contentType === undefined) return false;\n const mediaType = contentType.split(\";\", 1)[0]?.trim().toLowerCase();\n return mediaType === \"application/json\" || mediaType?.endsWith(\"+json\") === true;\n};\n\nconst readBoundedResponse = Effect.fn(\"BrowserRestCapture.readResponse\")(function* (\n response: { readonly stream: Stream.Stream<Uint8Array, HttpClientError.HttpClientError> },\n request: PageCaptureRequest,\n): Effect.fn.Return<string, PageCaptureError> {\n const decoder = new TextDecoder(\"utf-8\", { fatal: true, ignoreBOM: false });\n const chunks = yield* Stream.runFoldEffect<\n Uint8Array,\n HttpClientError.HttpClientError,\n never,\n { readonly observed: number; readonly text: string },\n PageCaptureOutputLimitError | PageCaptureProtocolError,\n never\n >(\n response.stream,\n () => ({ observed: 0, text: \"\" }),\n (state, chunk) => {\n const observed = state.observed + chunk.byteLength;\n if (observed > request.limits.maxOutputBytes) {\n return Effect.fail(\n PageCaptureOutputLimitError.make({\n implementation: browserRestCaptureImplementation,\n limit: request.limits.maxOutputBytes,\n observed,\n }),\n );\n }\n return Effect.try({\n try: () => ({ observed, text: state.text + decoder.decode(chunk, { stream: true }) }),\n catch: (cause) => protocolError(\"Decoding the Browser Run response failed\", cause),\n });\n },\n ).pipe(\n Effect.mapError((error) =>\n Schema.is(PageCaptureOutputLimitError)(error) || Schema.is(PageCaptureProtocolError)(error)\n ? error\n : protocolError(\"Reading the Browser Run response failed\", error),\n ),\n );\n return yield* Effect.try({\n try: () => chunks.text + decoder.decode(),\n catch: (cause) => protocolError(\"Decoding the Browser Run response failed\", cause),\n });\n});\n\nconst parseOutput = (\n action: PageCaptureAction,\n bodyText: string,\n apiToken: Redacted.Redacted<string>,\n): PageCaptureOutput | PageCaptureNavigationError | PageCaptureProtocolError => {\n const envelope = decodeEnvelope(bodyText);\n if (Option.isNone(envelope)) {\n return protocolError(\n \"The Browser Run response did not carry a valid response envelope\",\n privateResponseCause(bodyText, apiToken),\n );\n }\n if (!envelope.value.success) {\n return navigationError(\n \"Browser Run reported a navigation failure\",\n privateResponseCause(bodyText, apiToken),\n );\n }\n switch (action._tag) {\n case \"CapturePageContent\":\n case \"CapturePageMarkdown\":\n if (typeof envelope.value.result !== \"string\") {\n return protocolError(\"The Browser Run response envelope carried a non-text result\");\n }\n return action._tag === \"CapturePageContent\"\n ? PageContentCaptured.make({ html: envelope.value.result })\n : PageMarkdownCaptured.make({ markdown: envelope.value.result });\n case \"CapturePageLinks\": {\n const decoded = Schema.decodeUnknownOption(PageLinksCaptured)({\n _tag: \"PageLinksCaptured\",\n links: envelope.value.result,\n });\n return Option.isSome(decoded)\n ? decoded.value\n : protocolError(\"Browser Run links did not return a bounded array of valid URLs\");\n }\n case \"CapturePageScrape\": {\n const decoded = Schema.decodeUnknownOption(PageScrapeCaptured)({\n _tag: \"PageScrapeCaptured\",\n groups: envelope.value.result,\n });\n return Option.isSome(decoded)\n ? decoded.value\n : protocolError(\"Browser Run scrape did not return bounded grouped element records\");\n }\n case \"CapturePageStructured\":\n return PageStructuredCaptured.make({ value: envelope.value.result });\n }\n};\n\nconst isQuotaMessage = (text: string): boolean => /time limit|daily|quota/i.test(text);\n\nconst makeCapture = (\n client: HttpClient.HttpClient,\n options: BrowserRestCaptureOptions,\n workersAi?: BrowserQuickActionWorkersAiPolicy,\n): PageCaptureCapture =>\n Effect.fn(\"BrowserRestCapture.capture\")(function* (\n request: PageCaptureRequest,\n ): Effect.fn.Return<PageCaptureResult, PageCaptureError> {\n const usesWorkersAi = request.action._tag === \"CapturePageStructured\";\n if (usesWorkersAi) {\n if (workersAi === undefined) {\n return yield* PageCaptureUnsupportedError.make({\n implementation: browserRestCaptureImplementation,\n feature: \"action\",\n message:\n \"Structured capture invokes separately billed Workers AI and requires an explicit authorization and accounting policy\",\n });\n }\n yield* workersAi.authorizeAndAccount(request).pipe(\n Effect.mapError((cause) =>\n PageCaptureInferencePolicyError.make({\n implementation: browserRestCaptureImplementation,\n provider: \"cloudflare-workers-ai\",\n reason: cause.reason,\n message:\n cause.reason === \"authorization\"\n ? \"Workers AI extraction was not authorized\"\n : \"Workers AI extraction could not be accounted for\",\n cause,\n }),\n ),\n );\n }\n const action = actionName(request.action);\n const path = `${API_ORIGIN}/client/v4/accounts/${encodeURIComponent(options.accountId)}/browser-rendering/${action}`;\n const requestWithBody = yield* HttpClientRequest.post(path).pipe(\n request.engine === \"kitesurf\"\n ? HttpClientRequest.setUrlParam(\"browser\", \"kitesurf\")\n : (value) => value,\n HttpClientRequest.bearerToken(options.apiToken),\n HttpClientRequest.acceptJson,\n HttpClientRequest.bodyJson(actionBody(request)),\n Effect.mapError((cause) => protocolError(\"Encoding the Browser Run request failed\", cause)),\n );\n const response = yield* client\n .execute(requestWithBody)\n .pipe(\n Effect.mapError((cause) => protocolError(\"Calling the Browser Run REST API failed\", cause)),\n );\n const bodyText = yield* readBoundedResponse(response, request);\n if (response.status === 429) {\n const reason = isQuotaMessage(bodyText) ? \"quota\" : \"rate\";\n return yield* PageCaptureRateLimitedError.make({\n implementation: browserRestCaptureImplementation,\n reason,\n ...(retryAfterMillis(response.headers) === undefined\n ? {}\n : { retryAfterMillis: retryAfterMillis(response.headers) }),\n ...(privateResponseCause(bodyText, options.apiToken) === undefined\n ? {}\n : { cause: privateResponseCause(bodyText, options.apiToken) }),\n message:\n reason === \"quota\"\n ? \"Browser Run exceeded its browser quota\"\n : \"Browser Run was rate limited\",\n });\n }\n if (response.status < 200 || response.status >= 300) {\n const error =\n response.status >= 500\n ? protocolError(\n `Browser Run answered HTTP ${String(response.status)}`,\n privateResponseCause(bodyText, options.apiToken),\n )\n : navigationError(\n `Browser Run answered HTTP ${String(response.status)}`,\n privateResponseCause(bodyText, options.apiToken),\n );\n return yield* error;\n }\n if (!isJsonResponse(response.headers)) {\n return yield* protocolError(\n \"The Browser Run success response was not a JSON response envelope\",\n privateResponseCause(bodyText, options.apiToken),\n );\n }\n const output = parseOutput(request.action, bodyText, options.apiToken);\n if (\n output._tag === \"PageCaptureNavigationError\" ||\n output._tag === \"PageCaptureProtocolError\"\n ) {\n return yield* output;\n }\n return PageCaptureResult.make({\n implementation: browserRestCaptureImplementation,\n output,\n resourceUse: PageCaptureResourceUse.make({\n ...(browserMillis(response.headers) === undefined\n ? {}\n : { browserMillis: browserMillis(response.headers) }),\n ...(usesWorkersAi\n ? {\n inference: PageCaptureInferenceUse.make({\n provider: \"cloudflare-workers-ai\",\n modelCalls: 1,\n }),\n }\n : {}),\n }),\n });\n });\n\n/** REST PageCapture layer for Node and other non-Worker composition roots. */\nexport const browserRestCaptureLayer = (\n options: BrowserRestCaptureOptions,\n): Layer.Layer<PageCapture, never, HttpClient.HttpClient> =>\n Layer.effect(\n PageCapture,\n Effect.map(HttpClient.HttpClient, (client) =>\n PageCapture.of({ capture: makeCapture(client, options) }),\n ),\n );\n\n/** REST structured extraction additionally requires explicit Workers AI authorization/accounting. */\nexport const browserRestWorkersAiCaptureLayer = (\n options: BrowserRestCaptureOptions,\n): Layer.Layer<PageCapture, never, HttpClient.HttpClient | BrowserQuickActionWorkersAi> =>\n Layer.effect(\n PageCapture,\n Effect.gen(function* () {\n const client = yield* HttpClient.HttpClient;\n const workersAi = yield* BrowserQuickActionWorkersAi;\n return PageCapture.of({ capture: makeCapture(client, options, workersAi) });\n }),\n );\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"browser-rest-capture.mjs","names":[],"sources":["../src/browser-rest-capture.ts"],"sourcesContent":["import {\n PageCapture,\n PageCaptureInferencePolicyError,\n PageCaptureInferenceUse,\n PageCaptureNavigationError,\n PageCaptureOutputLimitError,\n PageCaptureProtocolError,\n PageCaptureRateLimitedError,\n PageCaptureResourceUse,\n PageCaptureResult,\n PageContentCaptured,\n PageLinksCaptured,\n PageMarkdownCaptured,\n PageScrapeCaptured,\n PageStructuredCaptured,\n PageCaptureUnsupportedError,\n SandboxImplementation,\n type PageCaptureAction,\n type PageCaptureCapture,\n type PageCaptureError,\n type PageCaptureOutput,\n type PageCaptureRequest,\n} from \"@effect-agent/sandbox\";\nimport { Effect, Layer, Option, Redacted, Schema, Stream } from \"effect\";\nimport { HttpClient, HttpClientRequest, type HttpClientError } from \"effect/unstable/http\";\n\nimport {\n BrowserQuickActionWorkersAi,\n type BrowserQuickActionWorkersAiPolicy,\n} from \"./browser-quick-action.ts\";\n\n/** Node-safe REST PageCapture implementation; it never imports Worker runtime modules. */\nexport const browserRestCaptureImplementation = SandboxImplementation.make({\n isolation: \"isolated\",\n identity: \"cloudflare-browser-rest\",\n});\n\nconst API_ORIGIN = \"https://api.cloudflare.com\";\nconst MAX_DIAGNOSTIC_LENGTH = 8_000;\nconst boundedDiagnostic = (message: string): string => message.slice(0, MAX_DIAGNOSTIC_LENGTH);\n\n/** Explicit construction inputs; credentials are only projected into the fixed-origin Authorization header. */\nexport interface BrowserRestCaptureOptions {\n readonly accountId: string;\n readonly apiToken: Redacted.Redacted<string>;\n}\n\nconst RestSuccessEnvelope = Schema.Struct({\n success: Schema.Literal(true),\n result: Schema.Json,\n errors: Schema.optionalKey(Schema.Array(Schema.Unknown)),\n meta: Schema.optionalKey(Schema.Unknown),\n});\nconst RestErrorEnvelope = Schema.Struct({\n success: Schema.Literal(false),\n errors: Schema.Array(\n Schema.Struct({\n message: Schema.String,\n code: Schema.optionalKey(Schema.Number),\n }),\n ),\n result: Schema.optionalKey(Schema.Json),\n meta: Schema.optionalKey(Schema.Unknown),\n});\nconst RestEnvelope = Schema.Union([RestSuccessEnvelope, RestErrorEnvelope]);\nconst decodeEnvelope = Schema.decodeUnknownOption(Schema.fromJsonString(RestEnvelope));\n\nconst protocolError = (message: string, cause?: unknown): PageCaptureProtocolError =>\n PageCaptureProtocolError.make({\n implementation: browserRestCaptureImplementation,\n message: boundedDiagnostic(message),\n ...(cause === undefined ? {} : { cause }),\n });\n\nconst navigationError = (message: string, cause?: unknown): PageCaptureNavigationError =>\n PageCaptureNavigationError.make({\n implementation: browserRestCaptureImplementation,\n message: boundedDiagnostic(message),\n ...(cause === undefined ? {} : { cause }),\n });\n\nconst privateResponseCause = (\n bodyText: string,\n apiToken: Redacted.Redacted<string>,\n): Error | undefined => {\n if (bodyText.length === 0) return undefined;\n const token = Redacted.value(apiToken);\n const diagnostic = boundedDiagnostic(bodyText);\n return new Error(token.length === 0 ? diagnostic : diagnostic.replaceAll(token, \"[REDACTED]\"));\n};\n\nconst requestBody = (request: PageCaptureRequest): Record<string, unknown> => {\n const body: Record<string, unknown> =\n request.target._tag === \"PageUrlTarget\"\n ? { url: request.target.url }\n : { html: request.target.html };\n if (request.navigation !== undefined) {\n const goto: Record<string, unknown> = {};\n if (request.navigation.waitUntil !== undefined) goto.waitUntil = request.navigation.waitUntil;\n if (request.navigation.timeoutMillis !== undefined)\n goto.timeout = request.navigation.timeoutMillis;\n if (Object.keys(goto).length > 0) body.gotoOptions = goto;\n if (request.navigation.waitForSelector !== undefined) {\n body.waitForSelector = {\n selector: request.navigation.waitForSelector.selector,\n ...(request.navigation.waitForSelector.timeoutMillis === undefined\n ? {}\n : { timeout: request.navigation.waitForSelector.timeoutMillis }),\n };\n }\n }\n if (request.viewport !== undefined) body.viewport = request.viewport;\n if (request.resourcePolicy?.rejectResourceTypes !== undefined) {\n body.rejectResourceTypes = [...request.resourcePolicy.rejectResourceTypes];\n }\n if (request.resourcePolicy?.allowRequestPatterns !== undefined) {\n body.allowRequestPattern = [...request.resourcePolicy.allowRequestPatterns];\n }\n return body;\n};\n\nconst actionName = (\n action: PageCaptureAction,\n): \"content\" | \"markdown\" | \"links\" | \"scrape\" | \"json\" => {\n switch (action._tag) {\n case \"CapturePageContent\":\n return \"content\";\n case \"CapturePageMarkdown\":\n return \"markdown\";\n case \"CapturePageLinks\":\n return \"links\";\n case \"CapturePageScrape\":\n return \"scrape\";\n case \"CapturePageStructured\":\n return \"json\";\n }\n};\n\nconst actionBody = (request: PageCaptureRequest): Record<string, unknown> => {\n const body = requestBody(request);\n switch (request.action._tag) {\n case \"CapturePageContent\":\n case \"CapturePageMarkdown\":\n return body;\n case \"CapturePageLinks\":\n return {\n ...body,\n ...(request.action.visibleLinksOnly === undefined\n ? {}\n : { visibleLinksOnly: request.action.visibleLinksOnly }),\n };\n case \"CapturePageScrape\":\n return {\n ...body,\n elements: request.action.selectors.map((selector) => ({ selector })),\n };\n case \"CapturePageStructured\":\n return {\n ...body,\n response_format: { type: \"json_schema\", json_schema: request.action.responseFormat },\n ...(request.action.prompt === undefined ? {} : { prompt: request.action.prompt }),\n };\n }\n};\n\nconst retryAfterMillis = (\n headers: Readonly<Record<string, string | undefined>>,\n): number | undefined => {\n const seconds = Number(headers[\"retry-after\"]);\n if (!Number.isSafeInteger(seconds) || seconds < 0) return undefined;\n const millis = seconds * 1_000;\n return Number.isSafeInteger(millis) ? millis : undefined;\n};\n\nconst browserMillis = (\n headers: Readonly<Record<string, string | undefined>>,\n): number | undefined => {\n const millis = Number(headers[\"x-browser-ms-used\"]);\n return Number.isSafeInteger(millis) && millis >= 0 ? millis : undefined;\n};\n\n/** Response framing is provider metadata, never content controlled by the rendered page. */\nconst isJsonResponse = (headers: Readonly<Record<string, string | undefined>>): boolean => {\n const contentType = headers[\"content-type\"];\n if (contentType === undefined) return false;\n const mediaType = contentType.split(\";\", 1)[0]?.trim().toLowerCase();\n return mediaType === \"application/json\" || mediaType?.endsWith(\"+json\") === true;\n};\n\nconst readBoundedResponse = Effect.fn(\"BrowserRestCapture.readResponse\")(function* (\n response: { readonly stream: Stream.Stream<Uint8Array, HttpClientError.HttpClientError> },\n request: PageCaptureRequest,\n): Effect.fn.Return<string, PageCaptureError> {\n const decoder = new TextDecoder(\"utf-8\", { fatal: true, ignoreBOM: false });\n const chunks = yield* Stream.runFoldEffect<\n Uint8Array,\n HttpClientError.HttpClientError,\n never,\n { readonly observed: number; readonly text: string },\n PageCaptureOutputLimitError | PageCaptureProtocolError,\n never\n >(\n response.stream,\n () => ({ observed: 0, text: \"\" }),\n (state, chunk) => {\n const observed = state.observed + chunk.byteLength;\n if (observed > request.limits.maxOutputBytes) {\n return Effect.fail(\n PageCaptureOutputLimitError.make({\n implementation: browserRestCaptureImplementation,\n limit: request.limits.maxOutputBytes,\n observed,\n }),\n );\n }\n return Effect.try({\n try: () => ({ observed, text: state.text + decoder.decode(chunk, { stream: true }) }),\n catch: (cause) => protocolError(\"Decoding the Browser Run response failed\", cause),\n });\n },\n ).pipe(\n Effect.mapError((error) =>\n Schema.is(PageCaptureOutputLimitError)(error) || Schema.is(PageCaptureProtocolError)(error)\n ? error\n : protocolError(\"Reading the Browser Run response failed\", error),\n ),\n );\n return yield* Effect.try({\n try: () => chunks.text + decoder.decode(),\n catch: (cause) => protocolError(\"Decoding the Browser Run response failed\", cause),\n });\n});\n\nconst parseOutput = (\n action: PageCaptureAction,\n bodyText: string,\n apiToken: Redacted.Redacted<string>,\n): PageCaptureOutput | PageCaptureNavigationError | PageCaptureProtocolError => {\n const envelope = decodeEnvelope(bodyText);\n if (Option.isNone(envelope)) {\n return protocolError(\n \"The Browser Run response did not carry a valid response envelope\",\n privateResponseCause(bodyText, apiToken),\n );\n }\n if (!envelope.value.success) {\n return navigationError(\n \"Browser Run reported a navigation failure\",\n privateResponseCause(bodyText, apiToken),\n );\n }\n switch (action._tag) {\n case \"CapturePageContent\":\n case \"CapturePageMarkdown\":\n if (typeof envelope.value.result !== \"string\") {\n return protocolError(\"The Browser Run response envelope carried a non-text result\");\n }\n return action._tag === \"CapturePageContent\"\n ? PageContentCaptured.make({ html: envelope.value.result })\n : PageMarkdownCaptured.make({ markdown: envelope.value.result });\n case \"CapturePageLinks\": {\n const decoded = Schema.decodeUnknownOption(PageLinksCaptured)({\n _tag: \"PageLinksCaptured\",\n links: envelope.value.result,\n });\n return Option.isSome(decoded)\n ? decoded.value\n : protocolError(\"Browser Run links did not return a bounded array of valid URLs\");\n }\n case \"CapturePageScrape\": {\n const decoded = Schema.decodeUnknownOption(PageScrapeCaptured)({\n _tag: \"PageScrapeCaptured\",\n groups: envelope.value.result,\n });\n return Option.isSome(decoded)\n ? decoded.value\n : protocolError(\"Browser Run scrape did not return bounded grouped element records\");\n }\n case \"CapturePageStructured\":\n return PageStructuredCaptured.make({ value: envelope.value.result });\n }\n};\n\nconst isQuotaMessage = (text: string): boolean => /time limit|daily|quota/i.test(text);\n\nconst makeCapture = (\n client: HttpClient.HttpClient,\n options: BrowserRestCaptureOptions,\n workersAi?: BrowserQuickActionWorkersAiPolicy,\n): PageCaptureCapture =>\n Effect.fn(\"BrowserRestCapture.capture\")(function* (\n request: PageCaptureRequest,\n ): Effect.fn.Return<PageCaptureResult, PageCaptureError> {\n const usesWorkersAi = request.action._tag === \"CapturePageStructured\";\n if (usesWorkersAi) {\n if (workersAi === undefined) {\n return yield* PageCaptureUnsupportedError.make({\n implementation: browserRestCaptureImplementation,\n feature: \"action\",\n message:\n \"Structured capture invokes separately billed Workers AI and requires an explicit authorization and accounting policy\",\n });\n }\n yield* workersAi.authorizeAndAccount(request).pipe(\n Effect.mapError((cause) =>\n PageCaptureInferencePolicyError.make({\n implementation: browserRestCaptureImplementation,\n provider: \"cloudflare-workers-ai\",\n reason: cause.reason,\n message:\n cause.reason === \"authorization\"\n ? \"Workers AI extraction was not authorized\"\n : \"Workers AI extraction could not be accounted for\",\n cause,\n }),\n ),\n );\n }\n const action = actionName(request.action);\n const path = `${API_ORIGIN}/client/v4/accounts/${encodeURIComponent(options.accountId)}/browser-rendering/${action}`;\n const requestWithBody = yield* HttpClientRequest.post(path).pipe(\n request.engine === \"kitesurf\"\n ? HttpClientRequest.setUrlParam(\"browser\", \"kitesurf\")\n : (value) => value,\n HttpClientRequest.bearerToken(options.apiToken),\n HttpClientRequest.acceptJson,\n HttpClientRequest.bodyJson(actionBody(request)),\n Effect.mapError((cause) => protocolError(\"Encoding the Browser Run request failed\", cause)),\n );\n const response = yield* client\n .execute(requestWithBody)\n .pipe(\n Effect.mapError((cause) => protocolError(\"Calling the Browser Run REST API failed\", cause)),\n );\n const bodyText = yield* readBoundedResponse(response, request);\n if (response.status === 429) {\n const reason = isQuotaMessage(bodyText) ? \"quota\" : \"rate\";\n return yield* PageCaptureRateLimitedError.make({\n implementation: browserRestCaptureImplementation,\n reason,\n ...(retryAfterMillis(response.headers) === undefined\n ? {}\n : { retryAfterMillis: retryAfterMillis(response.headers) }),\n ...(privateResponseCause(bodyText, options.apiToken) === undefined\n ? {}\n : { cause: privateResponseCause(bodyText, options.apiToken) }),\n message:\n reason === \"quota\"\n ? \"Browser Run exceeded its browser quota\"\n : \"Browser Run was rate limited\",\n });\n }\n if (response.status < 200 || response.status >= 300) {\n const error =\n response.status >= 500\n ? protocolError(\n `Browser Run answered HTTP ${String(response.status)}`,\n privateResponseCause(bodyText, options.apiToken),\n )\n : navigationError(\n `Browser Run answered HTTP ${String(response.status)}`,\n privateResponseCause(bodyText, options.apiToken),\n );\n return yield* error;\n }\n if (!isJsonResponse(response.headers)) {\n return yield* protocolError(\n \"The Browser Run success response was not a JSON response envelope\",\n privateResponseCause(bodyText, options.apiToken),\n );\n }\n const output = parseOutput(request.action, bodyText, options.apiToken);\n if (\n output._tag === \"PageCaptureNavigationError\" ||\n output._tag === \"PageCaptureProtocolError\"\n ) {\n return yield* output;\n }\n return PageCaptureResult.make({\n implementation: browserRestCaptureImplementation,\n output,\n resourceUse: PageCaptureResourceUse.make({\n ...(browserMillis(response.headers) === undefined\n ? {}\n : { browserMillis: browserMillis(response.headers) }),\n ...(usesWorkersAi\n ? {\n inference: PageCaptureInferenceUse.make({\n provider: \"cloudflare-workers-ai\",\n modelCalls: 1,\n }),\n }\n : {}),\n }),\n });\n });\n\n/** REST PageCapture layer for Node and other non-Worker composition roots. */\nexport const browserRestCaptureLayer = (\n options: BrowserRestCaptureOptions,\n): Layer.Layer<PageCapture, never, HttpClient.HttpClient> =>\n Layer.effect(\n PageCapture,\n Effect.map(HttpClient.HttpClient, (client) =>\n PageCapture.of({ capture: makeCapture(client, options) }),\n ),\n );\n\n/** REST structured extraction additionally requires explicit Workers AI authorization/accounting. */\nexport const browserRestWorkersAiCaptureLayer = (\n options: BrowserRestCaptureOptions,\n): Layer.Layer<PageCapture, never, HttpClient.HttpClient | BrowserQuickActionWorkersAi> =>\n Layer.effect(\n PageCapture,\n Effect.gen(function* () {\n const client = yield* HttpClient.HttpClient;\n const workersAi = yield* BrowserQuickActionWorkersAi;\n return PageCapture.of({ capture: makeCapture(client, options, workersAi) });\n }),\n );\n\n/** Explicit REST credentials and optional authorization for separately billed extraction. */\nexport interface CloudflareBrowserRestOptions extends BrowserRestCaptureOptions {\n readonly workersAi?: BrowserQuickActionWorkersAiPolicy;\n}\n\n/** Node-safe WebCapture handler assembly; the application supplies its HttpClient. */\nexport const CloudflareBrowserRest = {\n /**\n * Supports capture, scrape, and extraction definitions. Only PageCapture is supplied;\n * handler errors and other services remain visible. Extraction fails closed without\n * workersAi. Existing host policies, response limits, and scoped cleanup are unchanged.\n */\n layer: <A, E, R>(\n definition: { readonly handlers: Layer.Layer<A, E, R> },\n options: CloudflareBrowserRestOptions,\n ): Layer.Layer<A, E, Exclude<R, PageCapture> | HttpClient.HttpClient> => {\n const capture =\n options.workersAi === undefined\n ? browserRestCaptureLayer(options)\n : browserRestWorkersAiCaptureLayer(options).pipe(\n Layer.provide(BrowserQuickActionWorkersAi.layer(options.workersAi)),\n );\n\n return definition.handlers.pipe(Layer.provide(capture));\n },\n};\n"],"mappings":"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"}
|
|
@@ -10,8 +10,8 @@ const browserRestCrawlImplementation = SandboxImplementation.make({
|
|
|
10
10
|
const API_ORIGIN = "https://api.cloudflare.com";
|
|
11
11
|
const POLL_INTERVAL = Duration.seconds(1);
|
|
12
12
|
const CANCEL_TIMEOUT = Duration.seconds(30);
|
|
13
|
-
const MAX_CONTROL_RESPONSE_BYTES =
|
|
14
|
-
const MAX_RESULTS_RESPONSE_BYTES =
|
|
13
|
+
const MAX_CONTROL_RESPONSE_BYTES = 65536;
|
|
14
|
+
const MAX_RESULTS_RESPONSE_BYTES = 12582912;
|
|
15
15
|
const MAX_DIAGNOSTIC_LENGTH = 8e3;
|
|
16
16
|
const MAX_CURSOR_LENGTH = 1024;
|
|
17
17
|
const MAX_RECORDS_PER_RESPONSE = 1e4;
|