@yielded/agent-platform-cloudflare 0.1.0-beta.173 → 0.1.0-beta.174
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/{Alarm-BMEAZo3p.mjs → Alarm-4J9B8Fg8.mjs} +54 -32
- package/dist/Alarm-4J9B8Fg8.mjs.map +1 -0
- package/dist/Alarm.mjs +1 -1
- package/dist/BrowserRestCapture.mjs.map +1 -1
- package/dist/BrowserRestCrawl.mjs.map +1 -1
- package/dist/{BrowserSession-Bx0V1-6_.d.mts → BrowserSession-Cojp7nth.d.mts} +3 -2
- package/dist/{BrowserSession-BfNmyayH.mjs → BrowserSession-aovMjfL4.mjs} +14 -14
- package/dist/BrowserSession-aovMjfL4.mjs.map +1 -0
- package/dist/BrowserSession.d.mts +1 -1
- package/dist/BrowserSession.mjs +2 -2
- package/dist/BrowserUse.d.mts +40 -64
- package/dist/BrowserUse.mjs +223 -2
- package/dist/BrowserUse.mjs.map +1 -0
- package/dist/CloudflareBrowser-Vt8qTdYW.mjs.map +1 -1
- package/dist/CloudflareCodeMode.mjs.map +1 -1
- package/dist/CloudflareScheduling.mjs +9 -9
- package/dist/CloudflareScheduling.mjs.map +1 -1
- package/dist/CloudflareSubscriptions.mjs +15 -15
- package/dist/CloudflareSubscriptions.mjs.map +1 -1
- package/dist/{CloudflareThreadClient-DgZVrZzF.mjs → CloudflareThreadClient-DU548EEj.mjs} +42 -39
- package/dist/CloudflareThreadClient-DU548EEj.mjs.map +1 -0
- package/dist/{CloudflareThreadClient-HO_3rkM7.d.mts → CloudflareThreadClient-lTm6baDP.d.mts} +362 -362
- package/dist/CloudflareThreadClient.d.mts +1 -1
- package/dist/CloudflareThreadClient.mjs +1 -1
- package/dist/{InteractiveBrowser-LdKzQeLR.mjs → InteractiveBrowser-BHNlwjZL.mjs} +40 -31
- package/dist/InteractiveBrowser-BHNlwjZL.mjs.map +1 -0
- package/dist/InteractiveBrowser.mjs +1 -1
- package/dist/{ThreadObject-CRbLbdXM.d.mts → ThreadObject-BLYgzcdT.d.mts} +15 -15
- package/dist/{ThreadObject-CGIaz6Jv.mjs → ThreadObject-C2LF3btz.mjs} +13 -14
- package/dist/ThreadObject-C2LF3btz.mjs.map +1 -0
- package/dist/ThreadObject.d.mts +1 -1
- package/dist/ThreadObject.mjs +1 -1
- package/dist/WakeScheduler.d.mts +1 -1
- package/dist/WakeScheduler.mjs +8 -3
- package/dist/WakeScheduler.mjs.map +1 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +5 -5
- package/dist/{prepared-admission-CSdzFM_v.mjs → prepared-admission-BoUPHSNQ.mjs} +2 -2
- package/dist/{prepared-admission-CSdzFM_v.mjs.map → prepared-admission-BoUPHSNQ.mjs.map} +1 -1
- package/package.json +1 -1
- package/src/Alarm.ts +82 -39
- package/src/BrowserRestCapture.ts +1 -0
- package/src/BrowserRestCrawl.ts +1 -0
- package/src/BrowserSession.ts +3 -2
- package/src/BrowserUse.ts +287 -1504
- package/src/CloudflareCodeMode.ts +6 -0
- package/src/CloudflareScheduling.ts +103 -103
- package/src/CloudflareSubscriptions.ts +192 -199
- package/src/CloudflareThreadClient.ts +256 -268
- package/src/InteractiveBrowser.ts +43 -17
- package/src/ThreadObject.ts +35 -24
- package/src/WakeScheduler.ts +12 -9
- package/src/internal/browser-binding.ts +8 -0
- package/src/internal/browser-credentials.ts +18 -13
- package/src/internal/browser-file-selection.ts +13 -2
- package/src/internal/browser-quick-action.ts +1 -0
- package/src/internal/browser-session-lifecycle.ts +32 -36
- package/src/internal/due-queue.ts +38 -19
- package/src/internal/layers.ts +53 -53
- package/dist/Alarm-BMEAZo3p.mjs.map +0 -1
- package/dist/BrowserSession-BfNmyayH.mjs.map +0 -1
- package/dist/BrowserUse-Bc2JdLW2.mjs +0 -1528
- package/dist/BrowserUse-Bc2JdLW2.mjs.map +0 -1
- package/dist/CloudflareThreadClient-DgZVrZzF.mjs.map +0 -1
- package/dist/InteractiveBrowser-LdKzQeLR.mjs.map +0 -1
- package/dist/ThreadObject-CGIaz6Jv.mjs.map +0 -1
- package/dist/page-function-CmUCcyNP.mjs +0 -11
- package/dist/page-function-CmUCcyNP.mjs.map +0 -1
- package/src/internal/browser-dom.ts +0 -886
- package/src/internal/browser-jev-dom.ts +0 -362
|
@@ -49,7 +49,7 @@ export class BrowserRunSessionLifecycle extends Context.Service<
|
|
|
49
49
|
!Schema.is(Account)(options.accountId) ||
|
|
50
50
|
Redacted.value(options.apiToken).length === 0
|
|
51
51
|
) {
|
|
52
|
-
return yield*
|
|
52
|
+
return yield* BrowserRunCleanupError.make({ reason: "configuration" });
|
|
53
53
|
}
|
|
54
54
|
const client = yield* HttpClient.HttpClient;
|
|
55
55
|
|
|
@@ -65,39 +65,38 @@ export class BrowserRunSessionLifecycle extends Context.Service<
|
|
|
65
65
|
.pipe(
|
|
66
66
|
// workerd supports manual/follow, not error. Reject every redirect below.
|
|
67
67
|
Effect.provideService(FetchHttpClient.RequestInit, { redirect: "manual" }),
|
|
68
|
-
Effect.mapError(
|
|
69
|
-
(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}),
|
|
68
|
+
Effect.mapError((cause) =>
|
|
69
|
+
BrowserRunCleanupError.make({
|
|
70
|
+
reason: "provider",
|
|
71
|
+
cause: browserFailure("browser.close.request", cause),
|
|
72
|
+
}),
|
|
74
73
|
),
|
|
75
74
|
);
|
|
76
75
|
|
|
77
76
|
if (response.status === 401 || response.status === 403)
|
|
78
|
-
return yield*
|
|
77
|
+
return yield* BrowserRunCleanupError.make({
|
|
79
78
|
reason: "authorization",
|
|
80
79
|
status: response.status,
|
|
81
80
|
});
|
|
82
81
|
if (response.status === 429)
|
|
83
|
-
return yield*
|
|
82
|
+
return yield* BrowserRunCleanupError.make({
|
|
84
83
|
reason: "rate-limited",
|
|
85
84
|
status: response.status,
|
|
86
85
|
});
|
|
87
86
|
if (response.status !== 200 && response.status !== 404)
|
|
88
|
-
return yield*
|
|
87
|
+
return yield* BrowserRunCleanupError.make({
|
|
89
88
|
reason: "provider",
|
|
90
89
|
status: response.status,
|
|
91
90
|
});
|
|
92
91
|
if (response.headers["content-type"]?.split(";", 1)[0]?.trim() !== "application/json")
|
|
93
|
-
return yield*
|
|
92
|
+
return yield* BrowserRunCleanupError.make({ reason: "malformed" });
|
|
94
93
|
|
|
95
94
|
const bytes = yield* Stream.runFoldEffect(
|
|
96
95
|
response.stream,
|
|
97
96
|
() => new Uint8Array(),
|
|
98
97
|
(body, chunk) => {
|
|
99
98
|
if (body.byteLength + chunk.byteLength > 16_384)
|
|
100
|
-
return Effect.fail(
|
|
99
|
+
return Effect.fail(BrowserRunCleanupError.make({ reason: "malformed" }));
|
|
101
100
|
const combined = new Uint8Array(body.byteLength + chunk.byteLength);
|
|
102
101
|
|
|
103
102
|
combined.set(body);
|
|
@@ -106,19 +105,18 @@ export class BrowserRunSessionLifecycle extends Context.Service<
|
|
|
106
105
|
return Effect.succeed(combined);
|
|
107
106
|
},
|
|
108
107
|
).pipe(
|
|
109
|
-
Effect.mapError(
|
|
110
|
-
(
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}),
|
|
108
|
+
Effect.mapError((cause) =>
|
|
109
|
+
BrowserRunCleanupError.make({
|
|
110
|
+
reason: "malformed",
|
|
111
|
+
cause: browserFailure("browser.close.response", cause),
|
|
112
|
+
}),
|
|
115
113
|
),
|
|
116
114
|
);
|
|
117
115
|
|
|
118
116
|
const body = yield* Effect.try({
|
|
119
117
|
try: () => new TextDecoder("utf-8", { fatal: true, ignoreBOM: false }).decode(bytes),
|
|
120
118
|
catch: (cause) =>
|
|
121
|
-
|
|
119
|
+
BrowserRunCleanupError.make({
|
|
122
120
|
reason: "malformed",
|
|
123
121
|
cause: browserFailure("browser.close.decode", cause),
|
|
124
122
|
}),
|
|
@@ -131,16 +129,15 @@ export class BrowserRunSessionLifecycle extends Context.Service<
|
|
|
131
129
|
|
|
132
130
|
if (Option.isSome(absent)) return true;
|
|
133
131
|
|
|
134
|
-
return yield*
|
|
132
|
+
return yield* BrowserRunCleanupError.make({ reason: "malformed" });
|
|
135
133
|
}
|
|
136
134
|
if (method === "DELETE") {
|
|
137
135
|
const result = yield* Schema.decodeEffect(Schema.fromJsonString(Closed))(body).pipe(
|
|
138
|
-
Effect.mapError(
|
|
139
|
-
(
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}),
|
|
136
|
+
Effect.mapError((cause) =>
|
|
137
|
+
BrowserRunCleanupError.make({
|
|
138
|
+
reason: "malformed",
|
|
139
|
+
cause: browserFailure("browser.close.response", cause),
|
|
140
|
+
}),
|
|
144
141
|
),
|
|
145
142
|
);
|
|
146
143
|
|
|
@@ -148,17 +145,16 @@ export class BrowserRunSessionLifecycle extends Context.Service<
|
|
|
148
145
|
}
|
|
149
146
|
|
|
150
147
|
const result = yield* Schema.decodeEffect(Schema.fromJsonString(Metadata))(body).pipe(
|
|
151
|
-
Effect.mapError(
|
|
152
|
-
(
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}),
|
|
148
|
+
Effect.mapError((cause) =>
|
|
149
|
+
BrowserRunCleanupError.make({
|
|
150
|
+
reason: "malformed",
|
|
151
|
+
cause: browserFailure("browser.close.response", cause),
|
|
152
|
+
}),
|
|
157
153
|
),
|
|
158
154
|
);
|
|
159
155
|
|
|
160
156
|
if (result.sessionId !== sessionId)
|
|
161
|
-
return yield*
|
|
157
|
+
return yield* BrowserRunCleanupError.make({ reason: "malformed" });
|
|
162
158
|
|
|
163
159
|
return result.endTime !== undefined && result.endTime > 0;
|
|
164
160
|
});
|
|
@@ -166,7 +162,7 @@ export class BrowserRunSessionLifecycle extends Context.Service<
|
|
|
166
162
|
const close = Effect.fnUntraced(
|
|
167
163
|
function* (sessionId: Redacted.Redacted<string>) {
|
|
168
164
|
const id = yield* Schema.decodeEffect(Identity)(Redacted.value(sessionId)).pipe(
|
|
169
|
-
Effect.mapError(() =>
|
|
165
|
+
Effect.mapError(() => BrowserRunCleanupError.make({ reason: "configuration" })),
|
|
170
166
|
);
|
|
171
167
|
|
|
172
168
|
if (yield* request("DELETE", id)) return;
|
|
@@ -174,11 +170,11 @@ export class BrowserRunSessionLifecycle extends Context.Service<
|
|
|
174
170
|
if (yield* request("GET", id)) return;
|
|
175
171
|
}
|
|
176
172
|
|
|
177
|
-
return yield*
|
|
173
|
+
return yield* BrowserRunCleanupError.make({ reason: "pending" });
|
|
178
174
|
},
|
|
179
175
|
Effect.timeoutOrElse({
|
|
180
176
|
duration: "10 seconds",
|
|
181
|
-
orElse: () => Effect.fail(
|
|
177
|
+
orElse: () => Effect.fail(BrowserRunCleanupError.make({ reason: "timeout" })),
|
|
182
178
|
}),
|
|
183
179
|
Effect.withTracerEnabled(false),
|
|
184
180
|
);
|
|
@@ -139,10 +139,9 @@ export const make = (storage: DurableObjectStorage) => {
|
|
|
139
139
|
|
|
140
140
|
// Nine bindings per lane stay below Durable Object SQLite's 100-parameter limit.
|
|
141
141
|
const write = (changes: ReadonlyArray<Change>) => {
|
|
142
|
-
const rows =
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
`WITH changes (id, revision, dueAt, stalls, progressKey, notBefore, state, reported, expected_revision) AS (
|
|
142
|
+
const rows = sql
|
|
143
|
+
.exec(
|
|
144
|
+
`WITH changes (id, revision, dueAt, stalls, progressKey, notBefore, state, reported, expected_revision) AS (
|
|
146
145
|
VALUES ${changes.map(() => "(?, ?, ?, ?, ?, ?, ?, ?, ?)").join(", ")}
|
|
147
146
|
) INSERT INTO platform_cloudflare_due_queue
|
|
148
147
|
(id, revision, dueAt, stalls, progressKey, notBefore, state, reported)
|
|
@@ -152,24 +151,24 @@ export const make = (storage: DurableObjectStorage) => {
|
|
|
152
151
|
notBefore = excluded.notBefore, state = excluded.state, reported = excluded.reported
|
|
153
152
|
WHERE platform_cloudflare_due_queue.revision = (
|
|
154
153
|
SELECT expected_revision FROM changes WHERE changes.id = excluded.id
|
|
155
|
-
) RETURNING
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
);
|
|
154
|
+
) RETURNING 1`,
|
|
155
|
+
...changes.flatMap(({ before, after }) => [
|
|
156
|
+
after.id,
|
|
157
|
+
after.revision,
|
|
158
|
+
after.dueAt,
|
|
159
|
+
after.stalls,
|
|
160
|
+
after.progressKey,
|
|
161
|
+
after.notBefore,
|
|
162
|
+
after.state,
|
|
163
|
+
after.reported,
|
|
164
|
+
before?.revision ?? -1,
|
|
165
|
+
]),
|
|
166
|
+
)
|
|
167
|
+
.toArray();
|
|
170
168
|
|
|
171
169
|
// Partial revision acceptance must reject the enclosing source transaction.
|
|
172
170
|
if (rows.length !== changes.length)
|
|
171
|
+
// oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- Native storage transaction must roll back partial revision acceptance; its Effect adapter maps the cause.
|
|
173
172
|
throw new Error("Maintenance due revision changed during transaction");
|
|
174
173
|
};
|
|
175
174
|
|
|
@@ -204,6 +203,7 @@ export const make = (storage: DurableObjectStorage) => {
|
|
|
204
203
|
return result;
|
|
205
204
|
} catch (cause) {
|
|
206
205
|
if (frame !== undefined) finish(frame, false);
|
|
206
|
+
// oxlint-disable-next-line effect/no-untyped-throw -- Native transaction Promise must reject with the original failure after invalidating speculative state.
|
|
207
207
|
throw cause;
|
|
208
208
|
}
|
|
209
209
|
};
|
|
@@ -302,6 +302,24 @@ export const make = (storage: DurableObjectStorage) => {
|
|
|
302
302
|
);
|
|
303
303
|
};
|
|
304
304
|
|
|
305
|
+
/** Native checkpoints fence the generation, not each source commit. Once progress
|
|
306
|
+
* resets a claimed lane, further native commits owe the same recovery opportunity.
|
|
307
|
+
* A new claim, deadline, or retry budget makes the next commit advance it again. */
|
|
308
|
+
const progressNative = (dueAt: number) => {
|
|
309
|
+
const row = read().find((row) => row.id === Native);
|
|
310
|
+
|
|
311
|
+
if (
|
|
312
|
+
row?.state === "pending" &&
|
|
313
|
+
row.dueAt !== null &&
|
|
314
|
+
row.dueAt <= dueAt &&
|
|
315
|
+
row.stalls === 0 &&
|
|
316
|
+
row.notBefore === 0 &&
|
|
317
|
+
row.reported === 0
|
|
318
|
+
)
|
|
319
|
+
return;
|
|
320
|
+
dirty(Native, dueAt, true);
|
|
321
|
+
};
|
|
322
|
+
|
|
305
323
|
/** A strictly increasing source cursor; old or repeated notices cannot renew a budget. */
|
|
306
324
|
const progress = (id: string, dueAt: number, cursor: bigint) => {
|
|
307
325
|
Schema.decodeSync(Schema.BigInt.check(Schema.isGreaterThanOrEqualToBigInt(0n)))(cursor);
|
|
@@ -416,6 +434,7 @@ export const make = (storage: DurableObjectStorage) => {
|
|
|
416
434
|
transaction,
|
|
417
435
|
read,
|
|
418
436
|
dirty,
|
|
437
|
+
progressNative,
|
|
419
438
|
progress,
|
|
420
439
|
register,
|
|
421
440
|
claim,
|
package/src/internal/layers.ts
CHANGED
|
@@ -638,6 +638,7 @@ const sharedLayer = <A, E, R, PE = never, PR = never>(
|
|
|
638
638
|
const owner = yield* SqlStorageOwner;
|
|
639
639
|
const mutations = yield* ThreadMutationGate;
|
|
640
640
|
|
|
641
|
+
// oxlint-disable-next-line effect/no-native-error -- Missing host SQL ownership is an assembly defect, not a recoverable workflow failure.
|
|
641
642
|
if (owner === undefined) return yield* Effect.die(new Error("SQL owner unavailable"));
|
|
642
643
|
|
|
643
644
|
return {
|
|
@@ -889,61 +890,60 @@ const sharedLayer = <A, E, R, PE = never, PR = never>(
|
|
|
889
890
|
return Context.make(ThreadStore, observedStore).pipe(
|
|
890
891
|
Context.add(StorageOwner, storageOwner),
|
|
891
892
|
Context.add(SettlementPublisher, {
|
|
892
|
-
publish: (input)
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
.
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
.
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
.
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
),
|
|
922
|
-
),
|
|
893
|
+
publish: Effect.fnUntraced(function* (input) {
|
|
894
|
+
const { request } = yield* validatePublication(input);
|
|
895
|
+
|
|
896
|
+
return yield* mutations
|
|
897
|
+
.withMutation(
|
|
898
|
+
sourceCommits
|
|
899
|
+
.withPermit(
|
|
900
|
+
settlementPublisher.publish(request).pipe(
|
|
901
|
+
Effect.tap((result) =>
|
|
902
|
+
result.replayed
|
|
903
|
+
? Effect.void
|
|
904
|
+
: index
|
|
905
|
+
.applyCommitted(
|
|
906
|
+
request.append,
|
|
907
|
+
AppendResult.make({
|
|
908
|
+
firstSequence: result.tailSequence,
|
|
909
|
+
lastSequence: result.tailSequence,
|
|
910
|
+
|
|
911
|
+
replayed: false,
|
|
912
|
+
}),
|
|
913
|
+
)
|
|
914
|
+
.pipe(
|
|
915
|
+
Effect.catchCause((cause) =>
|
|
916
|
+
Cause.hasInterrupts(cause)
|
|
917
|
+
? Effect.interrupt
|
|
918
|
+
: Effect.logError(
|
|
919
|
+
"Thread projection deferred after settlement publication",
|
|
920
|
+
cause,
|
|
921
|
+
),
|
|
923
922
|
),
|
|
924
|
-
|
|
923
|
+
),
|
|
925
924
|
),
|
|
926
|
-
)
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
),
|
|
945
|
-
)
|
|
946
|
-
|
|
925
|
+
),
|
|
926
|
+
)
|
|
927
|
+
.pipe(Effect.tap(() => afterCommit)),
|
|
928
|
+
{
|
|
929
|
+
lanes: [
|
|
930
|
+
...(options.projection === undefined ? [] : [DueQueue.Projection]),
|
|
931
|
+
...(options.lifecyclePublication === undefined
|
|
932
|
+
? []
|
|
933
|
+
: [DueQueue.Lifecycle]),
|
|
934
|
+
],
|
|
935
|
+
},
|
|
936
|
+
)
|
|
937
|
+
.pipe(
|
|
938
|
+
Effect.catchTag("DurableAlarmError", (cause) =>
|
|
939
|
+
ThreadStoreError.make({
|
|
940
|
+
operation: "prearm settlement publication",
|
|
941
|
+
message: cause.message,
|
|
942
|
+
cause,
|
|
943
|
+
}),
|
|
944
|
+
),
|
|
945
|
+
);
|
|
946
|
+
}),
|
|
947
947
|
}),
|
|
948
948
|
Context.add(SubmissionLedger, {
|
|
949
949
|
...ledger,
|