@effect-agent/platform-cloudflare 0.1.0-beta.8 → 0.1.0-beta.81

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/dist/Alarm.d.mts +184 -0
  2. package/dist/Alarm.mjs +451 -0
  3. package/dist/Alarm.mjs.map +1 -0
  4. package/dist/BrowserRestCapture.d.mts +35 -0
  5. package/dist/BrowserRestCapture.mjs +238 -0
  6. package/dist/BrowserRestCapture.mjs.map +1 -0
  7. package/dist/BrowserRestCrawl.d.mts +17 -0
  8. package/dist/BrowserRestCrawl.mjs +244 -0
  9. package/dist/BrowserRestCrawl.mjs.map +1 -0
  10. package/dist/CloudflareAiGateway.d.mts +64 -0
  11. package/dist/CloudflareAiGateway.mjs +70 -0
  12. package/dist/CloudflareAiGateway.mjs.map +1 -0
  13. package/dist/CloudflareBindings.d.mts +112 -0
  14. package/dist/CloudflareBindings.mjs +101 -0
  15. package/dist/CloudflareBindings.mjs.map +1 -0
  16. package/dist/CloudflareBrowser-D4YqaTAl.mjs +495 -0
  17. package/dist/CloudflareBrowser-D4YqaTAl.mjs.map +1 -0
  18. package/dist/CloudflareBrowser-DJq53niJ.d.mts +80 -0
  19. package/dist/CloudflareBrowser.d.mts +2 -0
  20. package/dist/CloudflareBrowser.mjs +2 -0
  21. package/dist/CloudflareCodeMode.d.mts +44 -0
  22. package/dist/CloudflareCodeMode.mjs +616 -0
  23. package/dist/CloudflareCodeMode.mjs.map +1 -0
  24. package/dist/CloudflareConfig-f3CqTel1.d.mts +101 -0
  25. package/dist/CloudflareConfig.d.mts +2 -0
  26. package/dist/CloudflareConfig.mjs +122 -0
  27. package/dist/CloudflareConfig.mjs.map +1 -0
  28. package/dist/CloudflareMemory.d.mts +142 -0
  29. package/dist/CloudflareMemory.mjs +195 -0
  30. package/dist/CloudflareMemory.mjs.map +1 -0
  31. package/dist/CloudflareScheduling.d.mts +52 -0
  32. package/dist/CloudflareScheduling.mjs +389 -0
  33. package/dist/CloudflareScheduling.mjs.map +1 -0
  34. package/dist/CloudflareSubscriptions.d.mts +87 -0
  35. package/dist/CloudflareSubscriptions.mjs +524 -0
  36. package/dist/CloudflareSubscriptions.mjs.map +1 -0
  37. package/dist/CloudflareThreadClient.d.mts +1286 -0
  38. package/dist/CloudflareThreadClient.mjs +386 -0
  39. package/dist/CloudflareThreadClient.mjs.map +1 -0
  40. package/dist/InteractiveBrowser.d.mts +144 -0
  41. package/dist/InteractiveBrowser.mjs +1090 -0
  42. package/dist/InteractiveBrowser.mjs.map +1 -0
  43. package/dist/ProtectedBrowser.d.mts +65 -0
  44. package/dist/ProtectedBrowser.mjs +859 -0
  45. package/dist/ProtectedBrowser.mjs.map +1 -0
  46. package/dist/ThreadObject-BpwkEc5E.mjs +836 -0
  47. package/dist/ThreadObject-BpwkEc5E.mjs.map +1 -0
  48. package/dist/ThreadObject-NbFOWK1I.d.mts +816 -0
  49. package/dist/ThreadObject.d.mts +2 -0
  50. package/dist/ThreadObject.mjs +3 -0
  51. package/dist/WakeScheduler.d.mts +23 -0
  52. package/dist/WakeScheduler.mjs +60 -0
  53. package/dist/WakeScheduler.mjs.map +1 -0
  54. package/dist/boundary-BguazVkh.mjs +42 -0
  55. package/dist/boundary-BguazVkh.mjs.map +1 -0
  56. package/dist/browser-session-lifecycle-CUbVfEgP.mjs +84 -0
  57. package/dist/browser-session-lifecycle-CUbVfEgP.mjs.map +1 -0
  58. package/dist/browser-session-lifecycle-DJpqLXy_.d.mts +21 -0
  59. package/dist/index.d.mts +13 -1547
  60. package/dist/index.mjs +13 -1636
  61. package/dist/prepared-admission-DSi55W-7.mjs +73 -0
  62. package/dist/prepared-admission-DSi55W-7.mjs.map +1 -0
  63. package/dist/rolldown-runtime-D7D4PA-g.mjs +13 -0
  64. package/package.json +1 -53
  65. package/src/Alarm.ts +967 -0
  66. package/src/BrowserRestCapture.ts +477 -0
  67. package/src/BrowserRestCrawl.ts +540 -0
  68. package/src/CloudflareAiGateway.ts +170 -0
  69. package/src/CloudflareBindings.ts +180 -0
  70. package/src/CloudflareBrowser.ts +15 -0
  71. package/src/{code-mode-executor.ts → CloudflareCodeMode.ts} +372 -204
  72. package/src/{config.ts → CloudflareConfig.ts} +9 -8
  73. package/src/CloudflareMemory.ts +406 -0
  74. package/src/CloudflareScheduling.ts +733 -0
  75. package/src/CloudflareSubscriptions.ts +1045 -0
  76. package/src/CloudflareThreadClient.ts +807 -0
  77. package/src/InteractiveBrowser.ts +2357 -0
  78. package/src/ProtectedBrowser.ts +2 -0
  79. package/src/ThreadObject.ts +1179 -0
  80. package/src/{wake-scheduler.ts → WakeScheduler.ts} +23 -23
  81. package/src/index.ts +12 -23
  82. package/src/internal/boundary.ts +55 -0
  83. package/src/internal/browser-quick-action.ts +857 -0
  84. package/src/internal/browser-session-lifecycle.ts +160 -0
  85. package/src/internal/layers.ts +751 -0
  86. package/src/internal/message-delivery.ts +148 -0
  87. package/src/internal/prepared-admission.ts +116 -0
  88. package/src/internal/progress-wait.ts +121 -0
  89. package/src/internal/transport.ts +42 -0
  90. package/src/protected-browser/binding.ts +187 -0
  91. package/src/protected-browser/inspect-frame.ts +125 -0
  92. package/src/protected-browser/native.ts +429 -0
  93. package/src/protected-browser/policy.ts +719 -0
  94. package/dist/index.mjs.map +0 -1
  95. package/src/alarm.ts +0 -334
  96. package/src/bindings.ts +0 -145
  97. package/src/client.ts +0 -646
  98. package/src/conversation-object.ts +0 -768
  99. package/src/layers.ts +0 -376
  100. package/src/transport.ts +0 -38
@@ -0,0 +1,160 @@
1
+ import { Context, Effect, Layer, Option, Redacted, Schema, Stream } from "effect";
2
+ import { FetchHttpClient, HttpClient, HttpClientRequest } from "effect/unstable/http";
3
+
4
+ export class BrowserRunCleanupError extends Schema.TaggedError<BrowserRunCleanupError>()(
5
+ "BrowserRunCleanupError",
6
+ {
7
+ reason: Schema.Literals([
8
+ "configuration",
9
+ "authorization",
10
+ "rate-limited",
11
+ "provider",
12
+ "malformed",
13
+ "timeout",
14
+ "pending",
15
+ ]),
16
+ status: Schema.optionalKey(Schema.Int),
17
+ },
18
+ ) {}
19
+
20
+ export interface BrowserRunLifecycleOptions {
21
+ readonly accountId: string;
22
+ readonly apiToken: Redacted.Redacted<string>;
23
+ }
24
+
25
+ const Identity = Schema.String.check(Schema.isUUID());
26
+ const Account = Schema.String.check(Schema.isPattern(/^[a-f0-9]{32}$/));
27
+ const Closed = Schema.Struct({ status: Schema.Literals(["closing", "closed"]) });
28
+ const Metadata = Schema.Struct({ sessionId: Identity, endTime: Schema.optionalKey(Schema.Finite) });
29
+ // This exact provider response is accepted only on a fixed-origin, authenticated,
30
+ // exact-session request. An arbitrary 404 or a listing omission is never absence.
31
+ const Absent = Schema.Struct({ error: Schema.Literal("Session not found") });
32
+
33
+ export class BrowserRunSessionLifecycle extends Context.Service<
34
+ BrowserRunSessionLifecycle,
35
+ {
36
+ readonly close: (
37
+ sessionId: Redacted.Redacted<string>,
38
+ ) => Effect.Effect<void, BrowserRunCleanupError>;
39
+ }
40
+ >()("@effect-agent/platform-cloudflare/BrowserRunSessionLifecycle") {
41
+ static layer(options: BrowserRunLifecycleOptions) {
42
+ return Layer.effect(
43
+ this,
44
+ Effect.gen(function* () {
45
+ if (
46
+ !Schema.is(Account)(options.accountId) ||
47
+ Redacted.value(options.apiToken).length === 0
48
+ ) {
49
+ return yield* new BrowserRunCleanupError({ reason: "configuration" });
50
+ }
51
+ const client = yield* HttpClient.HttpClient;
52
+
53
+ const request = Effect.fn("BrowserRunSessionLifecycle.request")(function* (
54
+ method: "GET" | "DELETE",
55
+ sessionId: string,
56
+ ) {
57
+ const path = method === "DELETE" ? "browser" : "session";
58
+
59
+ const response = yield* client
60
+ .execute(
61
+ HttpClientRequest.make(method)(
62
+ `https://api.cloudflare.com/client/v4/accounts/${options.accountId}/browser-rendering/devtools/${path}/${sessionId}`,
63
+ ).pipe(HttpClientRequest.bearerToken(options.apiToken)),
64
+ )
65
+ .pipe(
66
+ // workerd supports manual/follow, not error. Reject every redirect below.
67
+ Effect.provideService(FetchHttpClient.RequestInit, { redirect: "manual" }),
68
+ Effect.mapError(() => new BrowserRunCleanupError({ reason: "provider" })),
69
+ );
70
+
71
+ if (response.status === 401 || response.status === 403)
72
+ return yield* new BrowserRunCleanupError({
73
+ reason: "authorization",
74
+ status: response.status,
75
+ });
76
+ if (response.status === 429)
77
+ return yield* new BrowserRunCleanupError({
78
+ reason: "rate-limited",
79
+ status: response.status,
80
+ });
81
+ if (response.status !== 200 && response.status !== 404)
82
+ return yield* new BrowserRunCleanupError({
83
+ reason: "provider",
84
+ status: response.status,
85
+ });
86
+ if (response.headers["content-type"]?.split(";", 1)[0]?.trim() !== "application/json")
87
+ return yield* new BrowserRunCleanupError({ reason: "malformed" });
88
+
89
+ const bytes = yield* Stream.runFoldEffect(
90
+ response.stream,
91
+ () => new Uint8Array(),
92
+ (body, chunk) => {
93
+ if (body.byteLength + chunk.byteLength > 16_384)
94
+ return Effect.fail(new BrowserRunCleanupError({ reason: "malformed" }));
95
+ const combined = new Uint8Array(body.byteLength + chunk.byteLength);
96
+
97
+ combined.set(body);
98
+ combined.set(chunk, body.byteLength);
99
+
100
+ return Effect.succeed(combined);
101
+ },
102
+ ).pipe(Effect.mapError(() => new BrowserRunCleanupError({ reason: "malformed" })));
103
+
104
+ const body = yield* Effect.try({
105
+ try: () => new TextDecoder("utf-8", { fatal: true, ignoreBOM: false }).decode(bytes),
106
+ catch: () => new BrowserRunCleanupError({ reason: "malformed" }),
107
+ });
108
+
109
+ if (response.status === 404) {
110
+ const absent = Schema.decodeUnknownOption(Schema.fromJsonString(Absent))(body, {
111
+ onExcessProperty: "error",
112
+ });
113
+
114
+ if (Option.isSome(absent)) return true;
115
+
116
+ return yield* new BrowserRunCleanupError({ reason: "malformed" });
117
+ }
118
+ if (method === "DELETE") {
119
+ const result = yield* Schema.decodeUnknownEffect(Schema.fromJsonString(Closed))(
120
+ body,
121
+ ).pipe(Effect.mapError(() => new BrowserRunCleanupError({ reason: "malformed" })));
122
+
123
+ return result.status === "closed";
124
+ }
125
+
126
+ const result = yield* Schema.decodeUnknownEffect(Schema.fromJsonString(Metadata))(
127
+ body,
128
+ ).pipe(Effect.mapError(() => new BrowserRunCleanupError({ reason: "malformed" })));
129
+
130
+ if (result.sessionId !== sessionId)
131
+ return yield* new BrowserRunCleanupError({ reason: "malformed" });
132
+
133
+ return result.endTime !== undefined && result.endTime > 0;
134
+ });
135
+
136
+ const close = Effect.fn("BrowserRunSessionLifecycle.close")(
137
+ function* (sessionId: Redacted.Redacted<string>) {
138
+ const id = yield* Schema.decodeUnknownEffect(Identity)(Redacted.value(sessionId)).pipe(
139
+ Effect.mapError(() => new BrowserRunCleanupError({ reason: "configuration" })),
140
+ );
141
+
142
+ if (yield* request("DELETE", id)) return;
143
+ for (let read = 0; read < 2; read++) {
144
+ if (yield* request("GET", id)) return;
145
+ }
146
+
147
+ return yield* new BrowserRunCleanupError({ reason: "pending" });
148
+ },
149
+ Effect.timeoutOrElse({
150
+ duration: "10 seconds",
151
+ orElse: () => Effect.fail(new BrowserRunCleanupError({ reason: "timeout" })),
152
+ }),
153
+ Effect.withTracerEnabled(false),
154
+ );
155
+
156
+ return { close };
157
+ }),
158
+ );
159
+ }
160
+ }