@yielded/agent-platform-cloudflare 0.1.0-beta.172 → 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.
Files changed (70) hide show
  1. package/dist/{Alarm-BMEAZo3p.mjs → Alarm-4J9B8Fg8.mjs} +54 -32
  2. package/dist/Alarm-4J9B8Fg8.mjs.map +1 -0
  3. package/dist/Alarm.mjs +1 -1
  4. package/dist/BrowserRestCapture.mjs.map +1 -1
  5. package/dist/BrowserRestCrawl.mjs.map +1 -1
  6. package/dist/{BrowserSession-Bx0V1-6_.d.mts → BrowserSession-Cojp7nth.d.mts} +3 -2
  7. package/dist/{BrowserSession-BfNmyayH.mjs → BrowserSession-aovMjfL4.mjs} +14 -14
  8. package/dist/BrowserSession-aovMjfL4.mjs.map +1 -0
  9. package/dist/BrowserSession.d.mts +1 -1
  10. package/dist/BrowserSession.mjs +2 -2
  11. package/dist/BrowserUse.d.mts +40 -64
  12. package/dist/BrowserUse.mjs +223 -2
  13. package/dist/BrowserUse.mjs.map +1 -0
  14. package/dist/CloudflareBrowser-Vt8qTdYW.mjs.map +1 -1
  15. package/dist/CloudflareCodeMode.mjs.map +1 -1
  16. package/dist/CloudflareScheduling.mjs +9 -9
  17. package/dist/CloudflareScheduling.mjs.map +1 -1
  18. package/dist/CloudflareSubscriptions.mjs +15 -15
  19. package/dist/CloudflareSubscriptions.mjs.map +1 -1
  20. package/dist/{CloudflareThreadClient-DgZVrZzF.mjs → CloudflareThreadClient-DU548EEj.mjs} +42 -39
  21. package/dist/CloudflareThreadClient-DU548EEj.mjs.map +1 -0
  22. package/dist/{CloudflareThreadClient-DuRG0MLd.d.mts → CloudflareThreadClient-lTm6baDP.d.mts} +353 -353
  23. package/dist/CloudflareThreadClient.d.mts +1 -1
  24. package/dist/CloudflareThreadClient.mjs +1 -1
  25. package/dist/{InteractiveBrowser-LdKzQeLR.mjs → InteractiveBrowser-BHNlwjZL.mjs} +40 -31
  26. package/dist/InteractiveBrowser-BHNlwjZL.mjs.map +1 -0
  27. package/dist/InteractiveBrowser.mjs +1 -1
  28. package/dist/{ThreadObject-CugPnWsJ.d.mts → ThreadObject-BLYgzcdT.d.mts} +6 -6
  29. package/dist/{ThreadObject-CGIaz6Jv.mjs → ThreadObject-C2LF3btz.mjs} +13 -14
  30. package/dist/ThreadObject-C2LF3btz.mjs.map +1 -0
  31. package/dist/ThreadObject.d.mts +1 -1
  32. package/dist/ThreadObject.mjs +1 -1
  33. package/dist/WakeScheduler.d.mts +1 -1
  34. package/dist/WakeScheduler.mjs +8 -3
  35. package/dist/WakeScheduler.mjs.map +1 -1
  36. package/dist/index.d.mts +3 -3
  37. package/dist/index.mjs +5 -5
  38. package/dist/{prepared-admission-CSdzFM_v.mjs → prepared-admission-BoUPHSNQ.mjs} +2 -2
  39. package/dist/{prepared-admission-CSdzFM_v.mjs.map → prepared-admission-BoUPHSNQ.mjs.map} +1 -1
  40. package/package.json +1 -1
  41. package/src/Alarm.ts +82 -39
  42. package/src/BrowserRestCapture.ts +1 -0
  43. package/src/BrowserRestCrawl.ts +1 -0
  44. package/src/BrowserSession.ts +3 -2
  45. package/src/BrowserUse.ts +287 -1504
  46. package/src/CloudflareCodeMode.ts +6 -0
  47. package/src/CloudflareScheduling.ts +103 -103
  48. package/src/CloudflareSubscriptions.ts +192 -199
  49. package/src/CloudflareThreadClient.ts +256 -268
  50. package/src/InteractiveBrowser.ts +43 -17
  51. package/src/ThreadObject.ts +35 -24
  52. package/src/WakeScheduler.ts +12 -9
  53. package/src/internal/browser-binding.ts +8 -0
  54. package/src/internal/browser-credentials.ts +18 -13
  55. package/src/internal/browser-file-selection.ts +13 -2
  56. package/src/internal/browser-quick-action.ts +1 -0
  57. package/src/internal/browser-session-lifecycle.ts +32 -36
  58. package/src/internal/due-queue.ts +38 -19
  59. package/src/internal/layers.ts +53 -53
  60. package/dist/Alarm-BMEAZo3p.mjs.map +0 -1
  61. package/dist/BrowserSession-BfNmyayH.mjs.map +0 -1
  62. package/dist/BrowserUse-Bc2JdLW2.mjs +0 -1528
  63. package/dist/BrowserUse-Bc2JdLW2.mjs.map +0 -1
  64. package/dist/CloudflareThreadClient-DgZVrZzF.mjs.map +0 -1
  65. package/dist/InteractiveBrowser-LdKzQeLR.mjs.map +0 -1
  66. package/dist/ThreadObject-CGIaz6Jv.mjs.map +0 -1
  67. package/dist/page-function-CmUCcyNP.mjs +0 -11
  68. package/dist/page-function-CmUCcyNP.mjs.map +0 -1
  69. package/src/internal/browser-dom.ts +0 -886
  70. package/src/internal/browser-jev-dom.ts +0 -362
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
- import { DurableObjectContext } from "./CloudflareBindings.mjs";
2
+ import { DurableObjectContext, ThreadObjectPlacement } from "./CloudflareBindings.mjs";
3
3
  import { AuxiliaryDispatchMillis, CloudflareDurableRuntimeConfig } from "./CloudflareConfig.mjs";
4
4
  import { r as safeCauseMessage } from "./boundary-BguazVkh.mjs";
5
5
  import { CurrentNativeSource } from "@yielded/agent-storage-cloudflare/port-routing";
@@ -108,7 +108,7 @@ const make = (storage) => {
108
108
  }
109
109
  };
110
110
  const write = (changes) => {
111
- if (decode(sql.exec(`WITH changes (id, revision, dueAt, stalls, progressKey, notBefore, state, reported, expected_revision) AS (
111
+ if (sql.exec(`WITH changes (id, revision, dueAt, stalls, progressKey, notBefore, state, reported, expected_revision) AS (
112
112
  VALUES ${changes.map(() => "(?, ?, ?, ?, ?, ?, ?, ?, ?)").join(", ")}
113
113
  ) INSERT INTO platform_cloudflare_due_queue
114
114
  (id, revision, dueAt, stalls, progressKey, notBefore, state, reported)
@@ -118,7 +118,7 @@ const make = (storage) => {
118
118
  notBefore = excluded.notBefore, state = excluded.state, reported = excluded.reported
119
119
  WHERE platform_cloudflare_due_queue.revision = (
120
120
  SELECT expected_revision FROM changes WHERE changes.id = excluded.id
121
- ) RETURNING id, revision, dueAt, stalls, progressKey, notBefore, state, reported`, ...changes.flatMap(({ before, after }) => [
121
+ ) RETURNING 1`, ...changes.flatMap(({ before, after }) => [
122
122
  after.id,
123
123
  after.revision,
124
124
  after.dueAt,
@@ -128,7 +128,7 @@ const make = (storage) => {
128
128
  after.state,
129
129
  after.reported,
130
130
  before?.revision ?? -1
131
- ])).toArray()).length !== changes.length) throw new Error("Maintenance due revision changed during transaction");
131
+ ])).toArray().length !== changes.length) throw new Error("Maintenance due revision changed during transaction");
132
132
  };
133
133
  const flush = (frame) => {
134
134
  if (frame.parent !== void 0) return;
@@ -205,6 +205,14 @@ const make = (storage) => {
205
205
  progressKey: progressKey ?? row?.progressKey ?? null
206
206
  }));
207
207
  };
208
+ /** Native checkpoints fence the generation, not each source commit. Once progress
209
+ * resets a claimed lane, further native commits owe the same recovery opportunity.
210
+ * A new claim, deadline, or retry budget makes the next commit advance it again. */
211
+ const progressNative = (dueAt) => {
212
+ const row = read().find((row) => row.id === Native);
213
+ if (row?.state === "pending" && row.dueAt !== null && row.dueAt <= dueAt && row.stalls === 0 && row.notBefore === 0 && row.reported === 0) return;
214
+ dirty(Native, dueAt, true);
215
+ };
208
216
  /** A strictly increasing source cursor; old or repeated notices cannot renew a budget. */
209
217
  const progress = (id, dueAt, cursor) => {
210
218
  Schema.decodeSync(Schema.BigInt.check(Schema.isGreaterThanOrEqualToBigInt(0n)))(cursor);
@@ -287,6 +295,7 @@ const make = (storage) => {
287
295
  transaction,
288
296
  read,
289
297
  dirty,
298
+ progressNative,
290
299
  progress,
291
300
  register,
292
301
  claim,
@@ -384,8 +393,8 @@ var DurableAlarmService = class DurableAlarmService extends Context.Service()("@
384
393
  ensureScheduledBy: (at) => wrap("advance maintenance checkpoint", alarms.scheduleAlarmEarlier(maintenanceAlarmInput(at))),
385
394
  scheduleNow: Ref.get(inlineWork).pipe(Effect.flatMap((active) => active > 0 ? Effect.void : wrap("hint maintenance checkpoint", alarms.transaction((tx) => Effect.gen(function* () {
386
395
  const now = yield* Clock.currentTimeMillis;
387
- const next$4 = next(make(ctx.storage).read());
388
- if (Number.isFinite(next$4)) yield* tx.scheduleAlarmEarlier(maintenanceAlarmInput(Math.max(now, next$4)));
396
+ const next$6 = next(make(ctx.storage).read());
397
+ if (Number.isFinite(next$6)) yield* tx.scheduleAlarmEarlier(maintenanceAlarmInput(Math.max(now, next$6)));
389
398
  }))))),
390
399
  withHintsDeferred: (body) => Effect.acquireUseRelease(Ref.update(inlineWork, (active) => active + 1), () => body, () => Ref.update(inlineWork, (active) => active - 1)),
391
400
  cancel: wrap("cancel maintenance checkpoint", alarms.cancelAlarm(maintenanceAlarmRef))
@@ -420,12 +429,16 @@ const makeAlarmOperation = Effect.gen(function* () {
420
429
  if (ambient._tag === "Some" && !ownsTransaction(ctx.storage, ambient.value[1])) return Effect.fail(SqlError.make({ reason: UnknownError.make({
421
430
  operation: "begin maintenance source transaction",
422
431
  message: "Use ThreadMutationGate.withTransaction at the outermost source transaction",
423
- cause: /* @__PURE__ */ new Error("Unwrapped SQL transaction cannot own buffered maintenance intent")
432
+ cause: "Unwrapped SQL transaction cannot own buffered maintenance intent"
424
433
  }) }));
425
434
  return Effect.uninterruptibleMask((restore) => Effect.suspend(() => {
426
435
  let frame;
427
- return transaction(Effect.flatMap(Effect.serviceOption(sql.transactionService), (transaction) => Effect.sync(() => {
428
- if (transaction._tag === "None") throw new Error("SQL transaction unavailable");
436
+ return transaction(Effect.flatMap(Effect.serviceOption(sql.transactionService), (transaction) => Effect.gen(function* () {
437
+ if (transaction._tag === "None") return yield* SqlError.make({ reason: UnknownError.make({
438
+ operation: "begin maintenance source transaction",
439
+ message: "SQL transaction unavailable",
440
+ cause: "SQL transaction unavailable"
441
+ }) });
429
442
  frame = queue.begin(transaction.value[1]);
430
443
  })).pipe(Effect.andThen(restore(body)), Effect.tap(() => Effect.try({
431
444
  try: () => {
@@ -442,8 +455,12 @@ const makeAlarmOperation = Effect.gen(function* () {
442
455
  }));
443
456
  }).pipe(Effect.provideService(SqlClient, sql));
444
457
  const run = (operation, execute) => {
445
- const commit = Effect.flatMap(CurrentCheckpoint, (tx) => {
446
- if (tx === void 0) return Effect.die(/* @__PURE__ */ new Error("Maintenance checkpoint transaction unavailable"));
458
+ const commit = Effect.withFiber((fiber) => {
459
+ const tx = fiber.getRef(CurrentCheckpoint);
460
+ if (tx === void 0) return Effect.die(DurableAlarmError.make({
461
+ operation: "checkpoint",
462
+ message: "Maintenance checkpoint transaction unavailable"
463
+ }));
447
464
  return tx.requireActive.pipe(Effect.andThen(Effect.suspend(() => {
448
465
  let checkpoint = Effect.void;
449
466
  const intent = {
@@ -463,9 +480,9 @@ const makeAlarmOperation = Effect.gen(function* () {
463
480
  }).pipe(Effect.tap(() => checkpoint));
464
481
  })));
465
482
  });
466
- return Effect.gen(function* () {
467
- if ((yield* CurrentCheckpoint) !== void 0) return yield* commit;
468
- return yield* (yield* Effect.serviceOption(sql.transactionService))._tag === "Some" && !buffering(ctx.storage) ? transaction(commit).pipe(Effect.ensuring(Effect.sync(() => invalidate(ctx.storage)))) : withTransaction(commit);
483
+ return Effect.withFiber((fiber) => {
484
+ if (fiber.getRef(CurrentCheckpoint) !== void 0) return commit;
485
+ return Context.getOption(fiber.context, sql.transactionService)._tag === "Some" && !buffering(ctx.storage) ? transaction(commit).pipe(Effect.ensuring(Effect.sync(() => invalidate(ctx.storage)))) : withTransaction(commit);
469
486
  }).pipe(Effect.uninterruptible, Effect.mapError(alarmFailure(operation)));
470
487
  };
471
488
  return {
@@ -684,6 +701,8 @@ var ThreadMutationGate = class ThreadMutationGate extends Context.Service()("@ef
684
701
  const { ctx } = yield* DurableObjectContext;
685
702
  const sql = yield* SqlClient;
686
703
  const dueQueue = make(ctx.storage);
704
+ const placement = yield* Effect.serviceOption(ThreadObjectPlacement);
705
+ const singleThread = Option.isSome(placement) && placement.value.threadId !== void 0;
687
706
  const config = yield* CloudflareDurableRuntimeConfig;
688
707
  const failpoint = yield* ThreadMaintenanceFailpoint;
689
708
  const activeMutations = yield* Ref.make(0);
@@ -721,8 +740,8 @@ var ThreadMutationGate = class ThreadMutationGate extends Context.Service()("@ef
721
740
  dirty: state.dirty + 1n
722
741
  })));
723
742
  }
724
- const next$6 = next(dueQueue.read());
725
- if (Number.isFinite(next$6)) checkpoint.earlier(Math.max(next$6, now + minimumAlarmDelay));
743
+ const next$4 = next(dueQueue.read());
744
+ if (Number.isFinite(next$4)) checkpoint.earlier(Math.max(next$4, now + minimumAlarmDelay));
726
745
  };
727
746
  yield* runAlarmTransaction("schedule maintenance lane", enroll);
728
747
  yield* notify;
@@ -779,7 +798,8 @@ var ThreadMutationGate = class ThreadMutationGate extends Context.Service()("@ef
779
798
  const now = yield* Clock.currentTimeMillis;
780
799
  const nativeSource = yield* CurrentNativeSource;
781
800
  yield* runAlarmTransaction("record maintenance producer progress", async (transaction, checkpoint) => {
782
- for (const id of affected) dueQueue.dirty(id, now, true);
801
+ for (const id of affected) if (singleThread && nativeSource && id === "effect-agent:native") dueQueue.progressNative(now);
802
+ else dueQueue.dirty(id, now, true);
783
803
  if (affected.has("effect-agent:native")) {
784
804
  const { state, initialized } = await readMaintenanceState(transaction);
785
805
  if (!initialized || !nativeSource || state.retry !== void 0) await transaction.put(MAINTENANCE_STATE_KEY, encodeMaintenanceState(ThreadMaintenanceState.make({
@@ -789,7 +809,7 @@ var ThreadMutationGate = class ThreadMutationGate extends Context.Service()("@ef
789
809
  }
790
810
  checkpoint.earlier(now + minimumAlarmDelay);
791
811
  });
792
- yield* notify;
812
+ if (!(singleThread && nativeSource && affected.size === 1 && affected.has("effect-agent:native"))) yield* notify;
793
813
  });
794
814
  return ThreadMutationGate.of({
795
815
  withTransaction,
@@ -956,10 +976,10 @@ var ThreadMaintenance = class ThreadMaintenance extends Context.Service()("@effe
956
976
  };
957
977
  }));
958
978
  for (let sequence = range.next; sequence <= range.through; sequence++) {
959
- const event = yield* runTransaction("read recovery event", async () => {
960
- const event = decodeRecoveryEvent(await ctx.storage.get(recoveryEventKey(sequence)));
961
- if (event.sequence !== sequence) throw new Error("Recovery event does not match its sequence key");
962
- return event;
979
+ const event = yield* runTransaction("read recovery event", async () => decodeRecoveryEvent(await ctx.storage.get(recoveryEventKey(sequence))));
980
+ if (event.sequence !== sequence) return yield* DurableAlarmError.make({
981
+ operation: "read recovery event",
982
+ message: "Recovery event does not match its sequence key"
963
983
  });
964
984
  yield* recoveryEvents.publish(event);
965
985
  const acknowledgedAt = yield* Clock.currentTimeMillis;
@@ -986,7 +1006,7 @@ var ThreadMaintenance = class ThreadMaintenance extends Context.Service()("@effe
986
1006
  for (const report of result.reports) threads.set(report.threadId, void 0);
987
1007
  for (const report of result.workReports ?? []) threads.set(report.threadId, void 0);
988
1008
  for (const blocked of result.blocked) threads.set(blocked.threadId, blocked.failure);
989
- if (threads.size === 0) return /* @__PURE__ */ new Map();
1009
+ if (threads.size === 0 || [...threads].every(([threadId, failure]) => failure === void 0 && recovery.loaded.has(threadId) && !recovery.faults.has(threadId))) return /* @__PURE__ */ new Map();
990
1010
  const now = yield* Clock.currentTimeMillis;
991
1011
  const submissions = current ?? (result.blocked.length === 0 ? [] : yield* Stream.runCollect(ledger.scanNonterminal));
992
1012
  yield* failpoint.hit("maintenance:recovery-status:before");
@@ -1046,20 +1066,22 @@ var ThreadMaintenance = class ThreadMaintenance extends Context.Service()("@effe
1046
1066
  return retained.faults;
1047
1067
  });
1048
1068
  const recoverThread = Effect.fnUntraced(function* (threadId, recovery) {
1049
- let cursor = yield* runTransaction("read work recovery cursor", async () => {
1050
- const retained = await ctx.storage.get(workCursorKey(threadId));
1051
- if (retained === void 0) return void 0;
1052
- const decoded = Schema.decodeUnknownSync(NativeWorkCursor)(retained);
1053
- if (decoded.threadId !== threadId) throw new Error("Work cursor belongs to another Thread");
1054
- return decoded.cursor;
1069
+ const retained = yield* runTransaction("read work recovery cursor", async () => {
1070
+ const value = await ctx.storage.get(workCursorKey(threadId));
1071
+ return value === void 0 ? void 0 : Schema.decodeUnknownSync(NativeWorkCursor)(value);
1072
+ });
1073
+ if (retained !== void 0 && retained.threadId !== threadId) return yield* DurableAlarmError.make({
1074
+ operation: "read work recovery cursor",
1075
+ message: "Work cursor belongs to another Thread"
1055
1076
  });
1077
+ let cursor = retained?.cursor;
1056
1078
  do {
1057
1079
  const result = yield* runtime.runRecovery({
1058
1080
  threadId,
1059
1081
  ...cursor === void 0 ? {} : { cursor }
1060
1082
  }).pipe(Effect.provideService(CurrentNativeSource, true));
1061
1083
  const faults = yield* recordRecoveryFaults(result, recovery, void 0, threadId);
1062
- yield* runTransaction("checkpoint work recovery cursor", async () => {
1084
+ if (cursor !== void 0 || result.cursor !== void 0) yield* runTransaction("checkpoint work recovery cursor", async () => {
1063
1085
  if (result.cursor === void 0) await ctx.storage.delete(workCursorKey(threadId));
1064
1086
  else await ctx.storage.put(workCursorKey(threadId), Schema.encodeSync(NativeWorkCursor)({
1065
1087
  threadId,
@@ -1360,7 +1382,7 @@ var ThreadMaintenance = class ThreadMaintenance extends Context.Service()("@effe
1360
1382
  const pivot = Math.max(0, runnable.findIndex((threadId) => state.lastServedThreadId === void 0 || threadId > state.lastServedThreadId));
1361
1383
  const selected = dispatch ? [...runnable.slice(pivot), ...runnable.slice(0, pivot)].slice(0, nativeDispatchConcurrency() - reserved.size) : [];
1362
1384
  const next = selected.at(-1);
1363
- if (next !== void 0) await transaction.put(MAINTENANCE_STATE_KEY, encodeMaintenanceState(ThreadMaintenanceState.make({
1385
+ if (next !== void 0 && next !== state.lastServedThreadId) await transaction.put(MAINTENANCE_STATE_KEY, encodeMaintenanceState(ThreadMaintenanceState.make({
1364
1386
  ...state,
1365
1387
  lastServedThreadId: next
1366
1388
  })));
@@ -1837,4 +1859,4 @@ var ThreadMaintenance = class ThreadMaintenance extends Context.Service()("@effe
1837
1859
  //#endregion
1838
1860
  export { Lifecycle as _, ThreadHostMaintenance as a, Projection as b, ThreadMaintenanceFailpoint as c, ThreadNativeMaintenance as d, ThreadPublication as f, HostLaneId as g, publishCommitted as h, MaintenancePassReport as i, ThreadMessageDelivery as l, ThreadRecoveryFaultEvent as m, DurableAlarmError as n, ThreadMaintenance as o, ThreadRecoveryEvents as p, DurableAlarmService as r, ThreadMaintenanceAlarm as s, Alarm_exports as t, ThreadMutationGate as u, Messages as v, Publication as x, Native as y };
1839
1861
 
1840
- //# sourceMappingURL=Alarm-BMEAZo3p.mjs.map
1862
+ //# sourceMappingURL=Alarm-4J9B8Fg8.mjs.map