@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
@@ -399,10 +399,10 @@ const decodeLiveText = (
399
399
  let streamId: string | undefined;
400
400
  const models = new Map<string, { attemptId: string; parts: Set<string> }>();
401
401
 
402
- const accept = (frame: LiveTextFrame): boolean => {
402
+ const accept = Effect.fnUntraced(function* (frame: LiveTextFrame) {
403
403
  if (frame._tag === "Reset") {
404
404
  if (frame.streamId === streamId || frame.threadId !== threadId)
405
- throw liveTextProtocolFailure();
405
+ return yield* liveTextProtocolFailure();
406
406
  streamId = frame.streamId;
407
407
  expected = 1;
408
408
  models.clear();
@@ -416,7 +416,7 @@ const decodeLiveText = (
416
416
  frame.event.threadId !== threadId ||
417
417
  !isBoundedEvent(frame.event)
418
418
  )
419
- throw liveTextProtocolFailure();
419
+ return yield* liveTextProtocolFailure();
420
420
  const event = frame.event;
421
421
 
422
422
  if (event._tag === "AttemptEnded") {
@@ -435,12 +435,12 @@ const decodeLiveText = (
435
435
  let model = models.get(key);
436
436
 
437
437
  if (event.part.type === "text-start") {
438
- if (model?.parts.has(event.part.id)) throw liveTextProtocolFailure();
438
+ if (model?.parts.has(event.part.id)) return yield* liveTextProtocolFailure();
439
439
  if (
440
440
  [...models.values()].reduce((size, value) => size + value.parts.size, 0) >=
441
441
  MAX_DRAFT_PARTS
442
442
  )
443
- throw liveTextProtocolFailure();
443
+ return yield* liveTextProtocolFailure();
444
444
  if (model === undefined) {
445
445
  model = { attemptId: event.attemptId, parts: new Set() };
446
446
  models.set(key, model);
@@ -449,14 +449,14 @@ const decodeLiveText = (
449
449
 
450
450
  return true;
451
451
  }
452
- if (!model?.parts.has(event.part.id)) throw liveTextProtocolFailure();
452
+ if (!model?.parts.has(event.part.id)) return yield* liveTextProtocolFailure();
453
453
  if (event.part.type === "text-end") {
454
454
  model.parts.delete(event.part.id);
455
455
  if (model.parts.size === 0) models.delete(key);
456
456
  }
457
457
 
458
458
  return true;
459
- };
459
+ });
460
460
 
461
461
  return Stream.fromReadableStream({
462
462
  evaluate: () => source,
@@ -469,31 +469,35 @@ const decodeLiveText = (
469
469
  cause,
470
470
  }),
471
471
  }).pipe(
472
- Stream.mapEffect((chunk) =>
473
- Effect.try({
474
- try: () => {
475
- if (!(chunk instanceof Uint8Array)) throw liveTextProtocolFailure();
476
- const frames: LiveTextFrame[] = [];
477
-
478
- for (let offset = 0; offset < chunk.byteLength;) {
479
- const newline = chunk.indexOf(10, offset);
480
- const end = newline < 0 ? chunk.byteLength : newline;
481
-
482
- pendingBytes += end - offset;
483
- if (pendingBytes > MAX_FRAME_BYTES) throw liveTextProtocolFailure();
484
- pending += decoder.decode(chunk.subarray(offset, end), { stream: newline < 0 });
485
- offset = end + 1;
486
- if (newline < 0) break;
487
- const frame = decode(pending);
488
-
489
- pending = "";
490
- pendingBytes = 0;
491
- if (accept(frame)) frames.push(frame);
492
- }
493
-
494
- return frames;
495
- },
496
- catch: liveTextProtocolFailure,
472
+ Stream.mapEffect(
473
+ Effect.fnUntraced(function* (chunk) {
474
+ if (!(chunk instanceof Uint8Array)) return yield* liveTextProtocolFailure();
475
+ const frames: LiveTextFrame[] = [];
476
+
477
+ for (let offset = 0; offset < chunk.byteLength;) {
478
+ const newline = chunk.indexOf(10, offset);
479
+ const end = newline < 0 ? chunk.byteLength : newline;
480
+
481
+ pendingBytes += end - offset;
482
+ if (pendingBytes > MAX_FRAME_BYTES) return yield* liveTextProtocolFailure();
483
+ pending += yield* Effect.try({
484
+ try: () => decoder.decode(chunk.subarray(offset, end), { stream: newline < 0 }),
485
+ catch: liveTextProtocolFailure,
486
+ });
487
+ offset = end + 1;
488
+ if (newline < 0) break;
489
+
490
+ const frame = yield* Effect.try({
491
+ try: () => decode(pending),
492
+ catch: liveTextProtocolFailure,
493
+ });
494
+
495
+ pending = "";
496
+ pendingBytes = 0;
497
+ if (yield* accept(frame)) frames.push(frame);
498
+ }
499
+
500
+ return frames;
497
501
  }),
498
502
  ),
499
503
  Stream.flatMap(Stream.fromArray),
@@ -702,40 +706,37 @@ export class CloudflareThreadClient extends Context.Service<
702
706
  };
703
707
  };
704
708
 
705
- const readPage = (
709
+ const readPage = Effect.fnUntraced(function* (
706
710
  threadId: ThreadId,
707
711
  options?: {
708
712
  readonly afterSequence?: CanonicalSequence | undefined;
709
713
  readonly limit?: number | undefined;
710
714
  },
711
- ) =>
712
- Effect.gen(function* () {
713
- const request = ObservePageRequest.make({
714
- ...(options?.afterSequence === undefined
715
- ? {}
716
- : { afterSequence: options.afterSequence }),
717
- limit: options?.limit ?? 256,
718
- });
715
+ ) {
716
+ const request = ObservePageRequest.make({
717
+ ...(options?.afterSequence === undefined ? {} : { afterSequence: options.afterSequence }),
718
+ limit: options?.limit ?? 256,
719
+ });
719
720
 
720
- const encoded = yield* encodeObservePageRequest(request).pipe(
721
- Effect.mapError((error) =>
722
- HostProtocolError.make({
723
- message: boundHostDiagnostic(`observePage request encode failed: ${error.message}`),
724
- }),
725
- ),
726
- );
721
+ const encoded = yield* encodeObservePageRequest(request).pipe(
722
+ Effect.mapError((error) =>
723
+ HostProtocolError.make({
724
+ message: boundHostDiagnostic(`observePage request encode failed: ${error.message}`),
725
+ }),
726
+ ),
727
+ );
727
728
 
728
- const response = yield* call(threadId, "observePage", encoded);
729
+ const response = yield* call(threadId, "observePage", encoded);
729
730
 
730
- const page = yield* expect(
731
- threadId,
732
- "observePage",
733
- ObservedPage,
734
- ClientObserveHostFailure,
735
- )(response);
731
+ const page = yield* expect(
732
+ threadId,
733
+ "observePage",
734
+ ObservedPage,
735
+ ClientObserveHostFailure,
736
+ )(response);
736
737
 
737
- return page.records;
738
- });
738
+ return page.records;
739
+ });
739
740
 
740
741
  const cancelProgress = (threadId: ThreadId, waiterId: string): Effect.Effect<void> =>
741
742
  encodeCancelProgressRequest(CancelProgressRequest.make({ waiterId })).pipe(
@@ -779,156 +780,149 @@ export class CloudflareThreadClient extends Context.Service<
779
780
  });
780
781
 
781
782
  return CloudflareThreadClient.of({
782
- submit: <InputSchema extends Schema.Top>(
783
+ submit: Effect.fnUntraced(function* <InputSchema extends Schema.Top>(
783
784
  agent: DurableSubmitAgent<InputSchema>,
784
785
  input: InputSchema["Type"],
785
786
  options: DurableSubmitOptions,
786
- ) =>
787
- Effect.gen(function* () {
788
- // Client-side half of `DurableAgentRuntime.submit`'s input boundary: encode
789
- // through the Agent's input schema and prove the canonical persistence bounds.
790
- const encodedInput = yield* Schema.encodeEffect(agent.definition.input)(input).pipe(
791
- Effect.mapError((cause) =>
792
- AgentInputError.make({ message: `Unable to encode Agent input: ${cause.message}` }),
793
- ),
794
- );
787
+ ) {
788
+ // Client-side half of `DurableAgentRuntime.submit`'s input boundary: encode
789
+ // through the Agent's input schema and prove the canonical persistence bounds.
790
+ const encodedInput = yield* Schema.encodeEffect(agent.definition.input)(input).pipe(
791
+ Effect.mapError((cause) =>
792
+ AgentInputError.make({ message: `Unable to encode Agent input: ${cause.message}` }),
793
+ ),
794
+ );
795
795
 
796
- const inputPayload = yield* Schema.decodeUnknownEffect(PersistedJson)(
797
- encodedInput,
798
- ).pipe(
799
- Effect.mapError(() =>
800
- AgentInputError.make({
801
- message: "Agent input does not satisfy the canonical persistence bounds",
802
- }),
803
- ),
804
- );
796
+ const inputPayload = yield* Schema.decodeUnknownEffect(PersistedJson)(encodedInput).pipe(
797
+ Effect.mapError(() =>
798
+ AgentInputError.make({
799
+ message: "Agent input does not satisfy the canonical persistence bounds",
800
+ }),
801
+ ),
802
+ );
805
803
 
806
- const request = SubmitRequest.make({
807
- agentId: agent.definition.id,
808
- principal: options.principal,
809
- idempotencyKey: options.idempotencyKey,
810
- ...(options.admissionGroup === undefined
811
- ? {}
812
- : { admissionGroup: options.admissionGroup }),
813
- ...(options.admissionFence === undefined
814
- ? {}
815
- : { admissionFence: options.admissionFence }),
816
- ...(options.workerAdmission === undefined
817
- ? {}
818
- : { workerAdmission: options.workerAdmission }),
819
- ...(options.messageAdmission === undefined
820
- ? {}
821
- : { messageAdmission: options.messageAdmission }),
822
- definitions: options.definitions,
823
- inputPayload,
824
- });
804
+ const request = SubmitRequest.make({
805
+ agentId: agent.definition.id,
806
+ principal: options.principal,
807
+ idempotencyKey: options.idempotencyKey,
808
+ ...(options.admissionGroup === undefined
809
+ ? {}
810
+ : { admissionGroup: options.admissionGroup }),
811
+ ...(options.admissionFence === undefined
812
+ ? {}
813
+ : { admissionFence: options.admissionFence }),
814
+ ...(options.workerAdmission === undefined
815
+ ? {}
816
+ : { workerAdmission: options.workerAdmission }),
817
+ ...(options.messageAdmission === undefined
818
+ ? {}
819
+ : { messageAdmission: options.messageAdmission }),
820
+ definitions: options.definitions,
821
+ inputPayload,
822
+ });
825
823
 
826
- const encoded = yield* encodeSubmitRequest(request).pipe(
827
- Effect.mapError((error) =>
828
- HostProtocolError.make({
829
- message: boundHostDiagnostic(`submit request encode failed: ${error.message}`),
830
- }),
831
- ),
832
- );
824
+ const encoded = yield* encodeSubmitRequest(request).pipe(
825
+ Effect.mapError((error) =>
826
+ HostProtocolError.make({
827
+ message: boundHostDiagnostic(`submit request encode failed: ${error.message}`),
828
+ }),
829
+ ),
830
+ );
833
831
 
834
- const response = yield* call(options.threadId, "submit", encoded);
832
+ const response = yield* call(options.threadId, "submit", encoded);
835
833
 
836
- const succeeded = yield* expect(
837
- options.threadId,
838
- "submit",
839
- SubmitSucceeded,
840
- ClientSubmitHostFailure,
841
- )(response);
834
+ const succeeded = yield* expect(
835
+ options.threadId,
836
+ "submit",
837
+ SubmitSucceeded,
838
+ ClientSubmitHostFailure,
839
+ )(response);
842
840
 
843
- return succeeded.receipt;
844
- }),
841
+ return succeeded.receipt;
842
+ }),
845
843
 
846
- submissionStatus: (receipt) =>
847
- Effect.gen(function* () {
848
- const encoded = yield* encodeReceipt(receipt).pipe(
849
- Effect.mapError(() => HostProtocolError.make({ message: "Invalid receipt" })),
850
- );
844
+ submissionStatus: Effect.fnUntraced(function* (receipt) {
845
+ const encoded = yield* encodeReceipt(receipt).pipe(
846
+ Effect.mapError(() => HostProtocolError.make({ message: "Invalid receipt" })),
847
+ );
851
848
 
852
- const response = yield* call(receipt.threadId, "submissionStatus", encoded);
853
-
854
- const result = yield* expect(
855
- receipt.threadId,
856
- "submissionStatus",
857
- SubmissionStatusResponse,
858
- ClientAwaitHostFailure,
859
- )(response);
860
-
861
- return result.status;
862
- }),
863
- awaitSettlement: (receipt) =>
864
- Effect.gen(function* () {
865
- const response = yield* awaitSettlementCall(receipt, "awaitSettlement");
866
-
867
- const settled = yield* expect(
868
- receipt.threadId,
869
- "awaitSettlement",
870
- SettlementReached,
871
- ClientAwaitHostFailure,
872
- )(response);
873
-
874
- return settled.settlement;
875
- }),
876
-
877
- awaitSettlementRecord: (receipt) =>
878
- Effect.gen(function* () {
879
- const response = yield* awaitSettlementCall(receipt, "awaitSettlementRecord");
880
-
881
- const settled = yield* expect(
882
- receipt.threadId,
883
- "awaitSettlementRecord",
884
- SettlementRecordReached,
885
- ClientAwaitHostFailure,
886
- )(response);
887
-
888
- return settled.record;
889
- }),
890
-
891
- awaitProgress: (threadId, afterSequence) =>
892
- Effect.gen(function* () {
893
- const waiterId = yield* crypto.randomUUIDv4().pipe(
894
- Effect.mapError((error) =>
895
- HostProtocolError.make({
896
- message: boundHostDiagnostic(
897
- `awaitProgress cancellation identity generation failed: ${error.message}`,
898
- ),
899
- }),
900
- ),
901
- );
849
+ const response = yield* call(receipt.threadId, "submissionStatus", encoded);
902
850
 
903
- const request = AwaitProgressRequest.make({ afterSequence, waiterId });
851
+ const result = yield* expect(
852
+ receipt.threadId,
853
+ "submissionStatus",
854
+ SubmissionStatusResponse,
855
+ ClientAwaitHostFailure,
856
+ )(response);
904
857
 
905
- const encoded = yield* encodeAwaitProgressRequest(request).pipe(
906
- Effect.mapError((error) =>
907
- HostProtocolError.make({
908
- message: boundHostDiagnostic(
909
- `awaitProgress request encode failed: ${error.message}`,
910
- ),
911
- }),
912
- ),
913
- );
858
+ return result.status;
859
+ }),
860
+ awaitSettlement: Effect.fnUntraced(function* (receipt) {
861
+ const response = yield* awaitSettlementCall(receipt, "awaitSettlement");
862
+
863
+ const settled = yield* expect(
864
+ receipt.threadId,
865
+ "awaitSettlement",
866
+ SettlementReached,
867
+ ClientAwaitHostFailure,
868
+ )(response);
869
+
870
+ return settled.settlement;
871
+ }),
914
872
 
915
- const attempt = (retry: number): Effect.Effect<void, ClientProgressFailure> =>
916
- call(threadId, "awaitProgress", encoded).pipe(
917
- Effect.flatMap(
918
- expect(threadId, "awaitProgress", ProgressObserved, ClientObserveHostFailure),
873
+ awaitSettlementRecord: Effect.fnUntraced(function* (receipt) {
874
+ const response = yield* awaitSettlementCall(receipt, "awaitSettlementRecord");
875
+
876
+ const settled = yield* expect(
877
+ receipt.threadId,
878
+ "awaitSettlementRecord",
879
+ SettlementRecordReached,
880
+ ClientAwaitHostFailure,
881
+ )(response);
882
+
883
+ return settled.record;
884
+ }),
885
+
886
+ awaitProgress: Effect.fnUntraced(function* (threadId, afterSequence) {
887
+ const waiterId = yield* crypto.randomUUIDv4().pipe(
888
+ Effect.mapError((error) =>
889
+ HostProtocolError.make({
890
+ message: boundHostDiagnostic(
891
+ `awaitProgress cancellation identity generation failed: ${error.message}`,
919
892
  ),
920
- Effect.asVoid,
921
- Effect.catchTag("ThreadClientError", (error) =>
922
- error.retryable === true && error.overloaded !== true && retry < 5
923
- ? Effect.sleep(Duration.millis(10 * 2 ** retry)).pipe(
924
- Effect.andThen(attempt(retry + 1)),
925
- )
926
- : Effect.fail(error),
893
+ }),
894
+ ),
895
+ );
896
+
897
+ const request = AwaitProgressRequest.make({ afterSequence, waiterId });
898
+
899
+ const encoded = yield* encodeAwaitProgressRequest(request).pipe(
900
+ Effect.mapError((error) =>
901
+ HostProtocolError.make({
902
+ message: boundHostDiagnostic(
903
+ `awaitProgress request encode failed: ${error.message}`,
927
904
  ),
928
- );
905
+ }),
906
+ ),
907
+ );
929
908
 
930
- yield* attempt(0).pipe(Effect.onInterrupt(() => cancelProgress(threadId, waiterId)));
931
- }),
909
+ const attempt = (retry: number): Effect.Effect<void, ClientProgressFailure> =>
910
+ call(threadId, "awaitProgress", encoded).pipe(
911
+ Effect.flatMap(
912
+ expect(threadId, "awaitProgress", ProgressObserved, ClientObserveHostFailure),
913
+ ),
914
+ Effect.asVoid,
915
+ Effect.catchTag("ThreadClientError", (error) =>
916
+ error.retryable === true && error.overloaded !== true && retry < 5
917
+ ? Effect.sleep(Duration.millis(10 * 2 ** retry)).pipe(
918
+ Effect.andThen(attempt(retry + 1)),
919
+ )
920
+ : Effect.fail(error),
921
+ ),
922
+ );
923
+
924
+ yield* attempt(0).pipe(Effect.onInterrupt(() => cancelProgress(threadId, waiterId)));
925
+ }),
932
926
 
933
927
  watchText: (threadId) =>
934
928
  Stream.unwrap(
@@ -1027,89 +1021,83 @@ export class CloudflareThreadClient extends Context.Service<
1027
1021
 
1028
1022
  readPage,
1029
1023
 
1030
- readAll: (threadId) =>
1031
- Effect.gen(function* () {
1032
- const all: Array<CanonicalRecordEnvelope> = [];
1033
- let after: CanonicalSequence | undefined;
1034
-
1035
- for (;;) {
1036
- const page = yield* readPage(threadId, { afterSequence: after, limit: 1_024 });
1037
-
1038
- all.push(...page);
1039
- const last = page.at(-1);
1040
-
1041
- if (page.length < 1_024 || last === undefined) return all;
1042
- after = last.sequence;
1043
- }
1044
- }),
1045
-
1046
- abort: (threadId, command) =>
1047
- Effect.gen(function* () {
1048
- const encoded = yield* encodeAbortCommand(command).pipe(
1049
- Effect.mapError((error) =>
1050
- HostProtocolError.make({
1051
- message: boundHostDiagnostic(`abort command encode failed: ${error.message}`),
1052
- }),
1053
- ),
1054
- );
1024
+ readAll: Effect.fnUntraced(function* (threadId) {
1025
+ const all: Array<CanonicalRecordEnvelope> = [];
1026
+ let after: CanonicalSequence | undefined;
1055
1027
 
1056
- const response = yield* call(threadId, "abort", encoded);
1057
-
1058
- const recorded = yield* expect(
1059
- threadId,
1060
- "abort",
1061
- AbortRecorded,
1062
- ClientAbortHostFailure,
1063
- )(response);
1064
-
1065
- return recorded.intent;
1066
- }),
1067
-
1068
- resolveApproval: (threadId, command) =>
1069
- Effect.gen(function* () {
1070
- const encoded = yield* encodeApprovalDecisionCommand(command).pipe(
1071
- Effect.mapError((error) =>
1072
- HostProtocolError.make({
1073
- message: boundHostDiagnostic(`approval command encode failed: ${error.message}`),
1074
- }),
1075
- ),
1076
- );
1028
+ for (;;) {
1029
+ const page = yield* readPage(threadId, { afterSequence: after, limit: 1_024 });
1077
1030
 
1078
- const response = yield* call(threadId, "resolveApproval", encoded);
1079
-
1080
- const recorded = yield* expect(
1081
- threadId,
1082
- "resolveApproval",
1083
- ApprovalRecorded,
1084
- ClientApprovalHostFailure,
1085
- )(response);
1086
-
1087
- return recorded.intent;
1088
- }),
1089
-
1090
- resolveUnknown: (threadId, command) =>
1091
- Effect.gen(function* () {
1092
- const encoded = yield* encodeUnknownResolutionCommand(command).pipe(
1093
- Effect.mapError((error) =>
1094
- HostProtocolError.make({
1095
- message: boundHostDiagnostic(
1096
- `resolution command encode failed: ${error.message}`,
1097
- ),
1098
- }),
1099
- ),
1100
- );
1031
+ all.push(...page);
1032
+ const last = page.at(-1);
1033
+
1034
+ if (page.length < 1_024 || last === undefined) return all;
1035
+ after = last.sequence;
1036
+ }
1037
+ }),
1038
+
1039
+ abort: Effect.fnUntraced(function* (threadId, command) {
1040
+ const encoded = yield* encodeAbortCommand(command).pipe(
1041
+ Effect.mapError((error) =>
1042
+ HostProtocolError.make({
1043
+ message: boundHostDiagnostic(`abort command encode failed: ${error.message}`),
1044
+ }),
1045
+ ),
1046
+ );
1047
+
1048
+ const response = yield* call(threadId, "abort", encoded);
1049
+
1050
+ const recorded = yield* expect(
1051
+ threadId,
1052
+ "abort",
1053
+ AbortRecorded,
1054
+ ClientAbortHostFailure,
1055
+ )(response);
1056
+
1057
+ return recorded.intent;
1058
+ }),
1059
+
1060
+ resolveApproval: Effect.fnUntraced(function* (threadId, command) {
1061
+ const encoded = yield* encodeApprovalDecisionCommand(command).pipe(
1062
+ Effect.mapError((error) =>
1063
+ HostProtocolError.make({
1064
+ message: boundHostDiagnostic(`approval command encode failed: ${error.message}`),
1065
+ }),
1066
+ ),
1067
+ );
1068
+
1069
+ const response = yield* call(threadId, "resolveApproval", encoded);
1070
+
1071
+ const recorded = yield* expect(
1072
+ threadId,
1073
+ "resolveApproval",
1074
+ ApprovalRecorded,
1075
+ ClientApprovalHostFailure,
1076
+ )(response);
1077
+
1078
+ return recorded.intent;
1079
+ }),
1080
+
1081
+ resolveUnknown: Effect.fnUntraced(function* (threadId, command) {
1082
+ const encoded = yield* encodeUnknownResolutionCommand(command).pipe(
1083
+ Effect.mapError((error) =>
1084
+ HostProtocolError.make({
1085
+ message: boundHostDiagnostic(`resolution command encode failed: ${error.message}`),
1086
+ }),
1087
+ ),
1088
+ );
1101
1089
 
1102
- const response = yield* call(threadId, "resolveUnknown", encoded);
1090
+ const response = yield* call(threadId, "resolveUnknown", encoded);
1103
1091
 
1104
- const recorded = yield* expect(
1105
- threadId,
1106
- "resolveUnknown",
1107
- UnknownResolutionRecorded,
1108
- ClientUnknownHostFailure,
1109
- )(response);
1092
+ const recorded = yield* expect(
1093
+ threadId,
1094
+ "resolveUnknown",
1095
+ UnknownResolutionRecorded,
1096
+ ClientUnknownHostFailure,
1097
+ )(response);
1110
1098
 
1111
- return recorded.intent;
1112
- }),
1099
+ return recorded.intent;
1100
+ }),
1113
1101
  });
1114
1102
  }),
1115
1103
  );