@yielded/agent-platform-cloudflare 0.1.0-beta.173 → 0.1.0-beta.175

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-B44efvB1.mjs} +162 -103
  2. package/dist/Alarm-B44efvB1.mjs.map +1 -0
  3. package/dist/Alarm.d.mts +2 -0
  4. package/dist/Alarm.mjs +1 -1
  5. package/dist/BrowserRestCapture.mjs.map +1 -1
  6. package/dist/BrowserRestCrawl.mjs.map +1 -1
  7. package/dist/{BrowserSession-Bx0V1-6_.d.mts → BrowserSession-Cojp7nth.d.mts} +3 -2
  8. package/dist/{BrowserSession-BfNmyayH.mjs → BrowserSession-aovMjfL4.mjs} +14 -14
  9. package/dist/BrowserSession-aovMjfL4.mjs.map +1 -0
  10. package/dist/BrowserSession.d.mts +1 -1
  11. package/dist/BrowserSession.mjs +2 -2
  12. package/dist/BrowserUse.d.mts +40 -64
  13. package/dist/BrowserUse.mjs +223 -2
  14. package/dist/BrowserUse.mjs.map +1 -0
  15. package/dist/CloudflareBrowser-Vt8qTdYW.mjs.map +1 -1
  16. package/dist/CloudflareCodeMode.mjs.map +1 -1
  17. package/dist/CloudflareScheduling.mjs +9 -9
  18. package/dist/CloudflareScheduling.mjs.map +1 -1
  19. package/dist/CloudflareSubscriptions.mjs +15 -15
  20. package/dist/CloudflareSubscriptions.mjs.map +1 -1
  21. package/dist/{CloudflareThreadClient-DgZVrZzF.mjs → CloudflareThreadClient-Ai3MTs3X.mjs} +43 -40
  22. package/dist/CloudflareThreadClient-Ai3MTs3X.mjs.map +1 -0
  23. package/dist/CloudflareThreadClient.mjs +1 -1
  24. package/dist/{InteractiveBrowser-LdKzQeLR.mjs → InteractiveBrowser-BHNlwjZL.mjs} +40 -31
  25. package/dist/InteractiveBrowser-BHNlwjZL.mjs.map +1 -0
  26. package/dist/InteractiveBrowser.mjs +1 -1
  27. package/dist/{ThreadObject-CRbLbdXM.d.mts → ThreadObject-CxNlhoPL.d.mts} +3 -3
  28. package/dist/{ThreadObject-CGIaz6Jv.mjs → ThreadObject-DGvlHWYi.mjs} +50 -52
  29. package/dist/ThreadObject-DGvlHWYi.mjs.map +1 -0
  30. package/dist/ThreadObject.d.mts +1 -1
  31. package/dist/ThreadObject.mjs +1 -1
  32. package/dist/WakeScheduler.d.mts +1 -1
  33. package/dist/WakeScheduler.mjs +8 -3
  34. package/dist/WakeScheduler.mjs.map +1 -1
  35. package/dist/index.d.mts +2 -2
  36. package/dist/index.mjs +5 -5
  37. package/dist/{prepared-admission-CSdzFM_v.mjs → prepared-admission-DYdffQ8K.mjs} +2 -2
  38. package/dist/{prepared-admission-CSdzFM_v.mjs.map → prepared-admission-DYdffQ8K.mjs.map} +1 -1
  39. package/package.json +1 -1
  40. package/src/Alarm.ts +293 -155
  41. package/src/BrowserRestCapture.ts +1 -0
  42. package/src/BrowserRestCrawl.ts +1 -0
  43. package/src/BrowserSession.ts +3 -2
  44. package/src/BrowserUse.ts +287 -1504
  45. package/src/CloudflareCodeMode.ts +6 -0
  46. package/src/CloudflareScheduling.ts +103 -103
  47. package/src/CloudflareSubscriptions.ts +192 -199
  48. package/src/CloudflareThreadClient.ts +258 -269
  49. package/src/InteractiveBrowser.ts +43 -17
  50. package/src/ThreadObject.ts +51 -45
  51. package/src/WakeScheduler.ts +12 -9
  52. package/src/internal/browser-binding.ts +8 -0
  53. package/src/internal/browser-credentials.ts +18 -13
  54. package/src/internal/browser-file-selection.ts +13 -2
  55. package/src/internal/browser-quick-action.ts +1 -0
  56. package/src/internal/browser-session-lifecycle.ts +32 -36
  57. package/src/internal/due-queue.ts +38 -19
  58. package/src/internal/layers.ts +108 -87
  59. package/src/internal/message-delivery.ts +61 -37
  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
@@ -386,23 +386,24 @@ const liveTextProtocolFailure = () =>
386
386
  message: "Provisional text is incomplete or invalid; discard drafts and read canonical records",
387
387
  });
388
388
 
389
+ const decodeLiveTextFrame = Schema.decodeUnknownSync(Schema.fromJsonString(LiveTextFrame));
390
+
389
391
  const decodeLiveText = (
390
392
  threadId: ThreadId,
391
393
  source: ReadableStream<unknown>,
392
394
  ): Stream.Stream<LiveTextFrame, HostProtocolError | ThreadClientError> =>
393
395
  Stream.suspend(() => {
394
396
  const decoder = new TextDecoder("utf-8", { fatal: true, ignoreBOM: false });
395
- const decode = Schema.decodeUnknownSync(Schema.fromJsonString(LiveTextFrame));
396
397
  let pending = "";
397
398
  let pendingBytes = 0;
398
399
  let expected = 0;
399
400
  let streamId: string | undefined;
400
401
  const models = new Map<string, { attemptId: string; parts: Set<string> }>();
401
402
 
402
- const accept = (frame: LiveTextFrame): boolean => {
403
+ const accept = Effect.fnUntraced(function* (frame: LiveTextFrame) {
403
404
  if (frame._tag === "Reset") {
404
405
  if (frame.streamId === streamId || frame.threadId !== threadId)
405
- throw liveTextProtocolFailure();
406
+ return yield* liveTextProtocolFailure();
406
407
  streamId = frame.streamId;
407
408
  expected = 1;
408
409
  models.clear();
@@ -416,7 +417,7 @@ const decodeLiveText = (
416
417
  frame.event.threadId !== threadId ||
417
418
  !isBoundedEvent(frame.event)
418
419
  )
419
- throw liveTextProtocolFailure();
420
+ return yield* liveTextProtocolFailure();
420
421
  const event = frame.event;
421
422
 
422
423
  if (event._tag === "AttemptEnded") {
@@ -435,12 +436,12 @@ const decodeLiveText = (
435
436
  let model = models.get(key);
436
437
 
437
438
  if (event.part.type === "text-start") {
438
- if (model?.parts.has(event.part.id)) throw liveTextProtocolFailure();
439
+ if (model?.parts.has(event.part.id)) return yield* liveTextProtocolFailure();
439
440
  if (
440
441
  [...models.values()].reduce((size, value) => size + value.parts.size, 0) >=
441
442
  MAX_DRAFT_PARTS
442
443
  )
443
- throw liveTextProtocolFailure();
444
+ return yield* liveTextProtocolFailure();
444
445
  if (model === undefined) {
445
446
  model = { attemptId: event.attemptId, parts: new Set() };
446
447
  models.set(key, model);
@@ -449,14 +450,14 @@ const decodeLiveText = (
449
450
 
450
451
  return true;
451
452
  }
452
- if (!model?.parts.has(event.part.id)) throw liveTextProtocolFailure();
453
+ if (!model?.parts.has(event.part.id)) return yield* liveTextProtocolFailure();
453
454
  if (event.part.type === "text-end") {
454
455
  model.parts.delete(event.part.id);
455
456
  if (model.parts.size === 0) models.delete(key);
456
457
  }
457
458
 
458
459
  return true;
459
- };
460
+ });
460
461
 
461
462
  return Stream.fromReadableStream({
462
463
  evaluate: () => source,
@@ -469,31 +470,35 @@ const decodeLiveText = (
469
470
  cause,
470
471
  }),
471
472
  }).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,
473
+ Stream.mapEffect(
474
+ Effect.fnUntraced(function* (chunk) {
475
+ if (!(chunk instanceof Uint8Array)) return yield* 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) return yield* liveTextProtocolFailure();
484
+ pending += yield* Effect.try({
485
+ try: () => decoder.decode(chunk.subarray(offset, end), { stream: newline < 0 }),
486
+ catch: liveTextProtocolFailure,
487
+ });
488
+ offset = end + 1;
489
+ if (newline < 0) break;
490
+
491
+ const frame = yield* Effect.try({
492
+ try: () => decodeLiveTextFrame(pending),
493
+ catch: liveTextProtocolFailure,
494
+ });
495
+
496
+ pending = "";
497
+ pendingBytes = 0;
498
+ if (yield* accept(frame)) frames.push(frame);
499
+ }
500
+
501
+ return frames;
497
502
  }),
498
503
  ),
499
504
  Stream.flatMap(Stream.fromArray),
@@ -702,40 +707,37 @@ export class CloudflareThreadClient extends Context.Service<
702
707
  };
703
708
  };
704
709
 
705
- const readPage = (
710
+ const readPage = Effect.fnUntraced(function* (
706
711
  threadId: ThreadId,
707
712
  options?: {
708
713
  readonly afterSequence?: CanonicalSequence | undefined;
709
714
  readonly limit?: number | undefined;
710
715
  },
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
- });
716
+ ) {
717
+ const request = ObservePageRequest.make({
718
+ ...(options?.afterSequence === undefined ? {} : { afterSequence: options.afterSequence }),
719
+ limit: options?.limit ?? 256,
720
+ });
719
721
 
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
- );
722
+ const encoded = yield* encodeObservePageRequest(request).pipe(
723
+ Effect.mapError((error) =>
724
+ HostProtocolError.make({
725
+ message: boundHostDiagnostic(`observePage request encode failed: ${error.message}`),
726
+ }),
727
+ ),
728
+ );
727
729
 
728
- const response = yield* call(threadId, "observePage", encoded);
730
+ const response = yield* call(threadId, "observePage", encoded);
729
731
 
730
- const page = yield* expect(
731
- threadId,
732
- "observePage",
733
- ObservedPage,
734
- ClientObserveHostFailure,
735
- )(response);
732
+ const page = yield* expect(
733
+ threadId,
734
+ "observePage",
735
+ ObservedPage,
736
+ ClientObserveHostFailure,
737
+ )(response);
736
738
 
737
- return page.records;
738
- });
739
+ return page.records;
740
+ });
739
741
 
740
742
  const cancelProgress = (threadId: ThreadId, waiterId: string): Effect.Effect<void> =>
741
743
  encodeCancelProgressRequest(CancelProgressRequest.make({ waiterId })).pipe(
@@ -779,156 +781,149 @@ export class CloudflareThreadClient extends Context.Service<
779
781
  });
780
782
 
781
783
  return CloudflareThreadClient.of({
782
- submit: <InputSchema extends Schema.Top>(
784
+ submit: Effect.fnUntraced(function* <InputSchema extends Schema.Top>(
783
785
  agent: DurableSubmitAgent<InputSchema>,
784
786
  input: InputSchema["Type"],
785
787
  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
- );
788
+ ) {
789
+ // Client-side half of `DurableAgentRuntime.submit`'s input boundary: encode
790
+ // through the Agent's input schema and prove the canonical persistence bounds.
791
+ const encodedInput = yield* Schema.encodeEffect(agent.definition.input)(input).pipe(
792
+ Effect.mapError((cause) =>
793
+ AgentInputError.make({ message: `Unable to encode Agent input: ${cause.message}` }),
794
+ ),
795
+ );
795
796
 
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
- );
797
+ const inputPayload = yield* Schema.decodeUnknownEffect(PersistedJson)(encodedInput).pipe(
798
+ Effect.mapError(() =>
799
+ AgentInputError.make({
800
+ message: "Agent input does not satisfy the canonical persistence bounds",
801
+ }),
802
+ ),
803
+ );
805
804
 
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
- });
805
+ const request = SubmitRequest.make({
806
+ agentId: agent.definition.id,
807
+ principal: options.principal,
808
+ idempotencyKey: options.idempotencyKey,
809
+ ...(options.admissionGroup === undefined
810
+ ? {}
811
+ : { admissionGroup: options.admissionGroup }),
812
+ ...(options.admissionFence === undefined
813
+ ? {}
814
+ : { admissionFence: options.admissionFence }),
815
+ ...(options.workerAdmission === undefined
816
+ ? {}
817
+ : { workerAdmission: options.workerAdmission }),
818
+ ...(options.messageAdmission === undefined
819
+ ? {}
820
+ : { messageAdmission: options.messageAdmission }),
821
+ definitions: options.definitions,
822
+ inputPayload,
823
+ });
825
824
 
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
- );
825
+ const encoded = yield* encodeSubmitRequest(request).pipe(
826
+ Effect.mapError((error) =>
827
+ HostProtocolError.make({
828
+ message: boundHostDiagnostic(`submit request encode failed: ${error.message}`),
829
+ }),
830
+ ),
831
+ );
832
+
833
+ const response = yield* call(options.threadId, "submit", encoded);
834
+
835
+ const succeeded = yield* expect(
836
+ options.threadId,
837
+ "submit",
838
+ SubmitSucceeded,
839
+ ClientSubmitHostFailure,
840
+ )(response);
833
841
 
834
- const response = yield* call(options.threadId, "submit", encoded);
842
+ return succeeded.receipt;
843
+ }),
835
844
 
836
- const succeeded = yield* expect(
837
- options.threadId,
838
- "submit",
839
- SubmitSucceeded,
840
- ClientSubmitHostFailure,
841
- )(response);
845
+ submissionStatus: Effect.fnUntraced(function* (receipt) {
846
+ const encoded = yield* encodeReceipt(receipt).pipe(
847
+ Effect.mapError(() => HostProtocolError.make({ message: "Invalid receipt" })),
848
+ );
842
849
 
843
- return succeeded.receipt;
844
- }),
850
+ const response = yield* call(receipt.threadId, "submissionStatus", encoded);
845
851
 
846
- submissionStatus: (receipt) =>
847
- Effect.gen(function* () {
848
- const encoded = yield* encodeReceipt(receipt).pipe(
849
- Effect.mapError(() => HostProtocolError.make({ message: "Invalid receipt" })),
850
- );
852
+ const result = yield* expect(
853
+ receipt.threadId,
854
+ "submissionStatus",
855
+ SubmissionStatusResponse,
856
+ ClientAwaitHostFailure,
857
+ )(response);
851
858
 
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
- );
859
+ return result.status;
860
+ }),
861
+ awaitSettlement: Effect.fnUntraced(function* (receipt) {
862
+ const response = yield* awaitSettlementCall(receipt, "awaitSettlement");
863
+
864
+ const settled = yield* expect(
865
+ receipt.threadId,
866
+ "awaitSettlement",
867
+ SettlementReached,
868
+ ClientAwaitHostFailure,
869
+ )(response);
902
870
 
903
- const request = AwaitProgressRequest.make({ afterSequence, waiterId });
871
+ return settled.settlement;
872
+ }),
904
873
 
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
- );
874
+ awaitSettlementRecord: Effect.fnUntraced(function* (receipt) {
875
+ const response = yield* awaitSettlementCall(receipt, "awaitSettlementRecord");
876
+
877
+ const settled = yield* expect(
878
+ receipt.threadId,
879
+ "awaitSettlementRecord",
880
+ SettlementRecordReached,
881
+ ClientAwaitHostFailure,
882
+ )(response);
914
883
 
915
- const attempt = (retry: number): Effect.Effect<void, ClientProgressFailure> =>
916
- call(threadId, "awaitProgress", encoded).pipe(
917
- Effect.flatMap(
918
- expect(threadId, "awaitProgress", ProgressObserved, ClientObserveHostFailure),
884
+ return settled.record;
885
+ }),
886
+
887
+ awaitProgress: Effect.fnUntraced(function* (threadId, afterSequence) {
888
+ const waiterId = yield* crypto.randomUUIDv4().pipe(
889
+ Effect.mapError((error) =>
890
+ HostProtocolError.make({
891
+ message: boundHostDiagnostic(
892
+ `awaitProgress cancellation identity generation failed: ${error.message}`,
919
893
  ),
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),
894
+ }),
895
+ ),
896
+ );
897
+
898
+ const request = AwaitProgressRequest.make({ afterSequence, waiterId });
899
+
900
+ const encoded = yield* encodeAwaitProgressRequest(request).pipe(
901
+ Effect.mapError((error) =>
902
+ HostProtocolError.make({
903
+ message: boundHostDiagnostic(
904
+ `awaitProgress request encode failed: ${error.message}`,
927
905
  ),
928
- );
906
+ }),
907
+ ),
908
+ );
929
909
 
930
- yield* attempt(0).pipe(Effect.onInterrupt(() => cancelProgress(threadId, waiterId)));
931
- }),
910
+ const attempt = (retry: number): Effect.Effect<void, ClientProgressFailure> =>
911
+ call(threadId, "awaitProgress", encoded).pipe(
912
+ Effect.flatMap(
913
+ expect(threadId, "awaitProgress", ProgressObserved, ClientObserveHostFailure),
914
+ ),
915
+ Effect.asVoid,
916
+ Effect.catchTag("ThreadClientError", (error) =>
917
+ error.retryable === true && error.overloaded !== true && retry < 5
918
+ ? Effect.sleep(Duration.millis(10 * 2 ** retry)).pipe(
919
+ Effect.andThen(attempt(retry + 1)),
920
+ )
921
+ : Effect.fail(error),
922
+ ),
923
+ );
924
+
925
+ yield* attempt(0).pipe(Effect.onInterrupt(() => cancelProgress(threadId, waiterId)));
926
+ }),
932
927
 
933
928
  watchText: (threadId) =>
934
929
  Stream.unwrap(
@@ -1027,89 +1022,83 @@ export class CloudflareThreadClient extends Context.Service<
1027
1022
 
1028
1023
  readPage,
1029
1024
 
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
- );
1025
+ readAll: Effect.fnUntraced(function* (threadId) {
1026
+ const all: Array<CanonicalRecordEnvelope> = [];
1027
+ let after: CanonicalSequence | undefined;
1055
1028
 
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
- );
1029
+ for (;;) {
1030
+ const page = yield* readPage(threadId, { afterSequence: after, limit: 1_024 });
1077
1031
 
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
- );
1032
+ all.push(...page);
1033
+ const last = page.at(-1);
1101
1034
 
1102
- const response = yield* call(threadId, "resolveUnknown", encoded);
1035
+ if (page.length < 1_024 || last === undefined) return all;
1036
+ after = last.sequence;
1037
+ }
1038
+ }),
1103
1039
 
1104
- const recorded = yield* expect(
1105
- threadId,
1106
- "resolveUnknown",
1107
- UnknownResolutionRecorded,
1108
- ClientUnknownHostFailure,
1109
- )(response);
1040
+ abort: Effect.fnUntraced(function* (threadId, command) {
1041
+ const encoded = yield* encodeAbortCommand(command).pipe(
1042
+ Effect.mapError((error) =>
1043
+ HostProtocolError.make({
1044
+ message: boundHostDiagnostic(`abort command encode failed: ${error.message}`),
1045
+ }),
1046
+ ),
1047
+ );
1048
+
1049
+ const response = yield* call(threadId, "abort", encoded);
1050
+
1051
+ const recorded = yield* expect(
1052
+ threadId,
1053
+ "abort",
1054
+ AbortRecorded,
1055
+ ClientAbortHostFailure,
1056
+ )(response);
1057
+
1058
+ return recorded.intent;
1059
+ }),
1060
+
1061
+ resolveApproval: Effect.fnUntraced(function* (threadId, command) {
1062
+ const encoded = yield* encodeApprovalDecisionCommand(command).pipe(
1063
+ Effect.mapError((error) =>
1064
+ HostProtocolError.make({
1065
+ message: boundHostDiagnostic(`approval command encode failed: ${error.message}`),
1066
+ }),
1067
+ ),
1068
+ );
1069
+
1070
+ const response = yield* call(threadId, "resolveApproval", encoded);
1110
1071
 
1111
- return recorded.intent;
1112
- }),
1072
+ const recorded = yield* expect(
1073
+ threadId,
1074
+ "resolveApproval",
1075
+ ApprovalRecorded,
1076
+ ClientApprovalHostFailure,
1077
+ )(response);
1078
+
1079
+ return recorded.intent;
1080
+ }),
1081
+
1082
+ resolveUnknown: Effect.fnUntraced(function* (threadId, command) {
1083
+ const encoded = yield* encodeUnknownResolutionCommand(command).pipe(
1084
+ Effect.mapError((error) =>
1085
+ HostProtocolError.make({
1086
+ message: boundHostDiagnostic(`resolution command encode failed: ${error.message}`),
1087
+ }),
1088
+ ),
1089
+ );
1090
+
1091
+ const response = yield* call(threadId, "resolveUnknown", encoded);
1092
+
1093
+ const recorded = yield* expect(
1094
+ threadId,
1095
+ "resolveUnknown",
1096
+ UnknownResolutionRecorded,
1097
+ ClientUnknownHostFailure,
1098
+ )(response);
1099
+
1100
+ return recorded.intent;
1101
+ }),
1113
1102
  });
1114
1103
  }),
1115
1104
  );