@effect-agent/platform-cloudflare 0.1.0-beta.22 → 0.1.0-beta.24

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/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { Cause, Clock, Context, Crypto, Deferred, Duration, Effect, Exit, Fiber, Layer, Option, PubSub, Random, Ref, Schema, Semaphore, Stream } from "effect";
1
+ import { Clock, Context, Crypto, Deferred, Duration, Effect, Exit, Fiber, Layer, Option, PubSub, Queue, Random, Ref, Schema, Semaphore, Stream } from "effect";
2
2
  import { AbortCommand, AbortIntent, AdmissionConflict, AgentBindingResolver, AppendConflict, ApprovalConflict, ApprovalDecisionCommand, ApprovalDecisionIntent, CanonicalRecordEnvelope, CanonicalSequence, ConversationNotMaterialized, ConversationRead, ConversationStore, ConversationStoreError, DEFAULT_OWNERSHIP_LEASE_DURATION, DefinitionDigests, DeploymentId, DigestError, DurableAgentRuntime, DurableRuntimeConfig, DurableRuntimeFailpoint, DurableRuntimeFailpointError, FenceRejected, IdempotencyKey, IntegrityReport, JoinedToHost, LedgerError, ObligationReport, ObligationThresholds, OperationAuthorizationRequest, OperationAuthorizer, OperationDenied, OwnershipLost, PersistedJson, Principal, ProducerId, Receipt, RecoveryExplanation, RecoveryReport, RetryCommand, RetryRefused, RunJournalError, Settlement, SettlementConflict, SubmissionLedger, SubmissionLookupByKey, ToolReconciler, UnknownResolutionCommand, UnknownResolutionConflict, UnknownResolutionIntent, WakeScheduler, makeWakeSubscriptionHub, operationAuthorizerLayer } from "@effect-agent/session";
3
3
  import { ConversationPortTransport, DEFAULT_MAX_STORED_VALUE_BYTES, conversationStoreLayer, handleEncodedPortRequest, portTransportFailure, routedConversationStoreLayer, routedSubmissionLedgerLayer, storageConfigLayer, storageFailpointLayer, submissionLedgerLayer } from "@effect-agent/storage-cloudflare";
4
4
  import { AgentId, AgentInputError, ConversationId, SubmissionId } from "@effect-agent/core";
@@ -1659,143 +1659,109 @@ const makeExecute = (options) => Effect.fn("DynamicWorkerCodeExecutor.execute")(
1659
1659
  let issuedHostCalls = 0;
1660
1660
  let passOpen = true;
1661
1661
  const queuedHostCalls = [];
1662
- let activeHostCall;
1663
- let hostDispatchFailure;
1664
- let propagatedHostDispatchFailure;
1665
- let signalHostDispatchFailure = (_failure) => void 0;
1666
- const hostDispatchFailureSignal = new Promise((resolve) => {
1667
- signalHostDispatchFailure = resolve;
1668
- });
1662
+ let passFailure;
1663
+ const failPass = (error) => {
1664
+ if (passFailure === void 0) passFailure = error;
1665
+ };
1669
1666
  const rejectQueuedHostCalls = (reason) => {
1670
1667
  for (const queued of queuedHostCalls.splice(0)) queued.reject(reason);
1671
1668
  };
1672
- const recordHostDispatchFailure = (failure) => {
1673
- if (hostDispatchFailure !== void 0) return;
1674
- hostDispatchFailure = failure;
1675
- signalHostDispatchFailure(failure);
1676
- rejectQueuedHostCalls(/* @__PURE__ */ new Error("Code Mode pass failed"));
1677
- };
1678
- const failHostDispatch = (failure) => {
1679
- switch (failure._tag) {
1680
- case "host-call-limit": return Effect.fail(CodeHostCallLimitError.make({
1669
+ const queue = yield* Queue.unbounded();
1670
+ const deliverHostOutcome = (queued, outcome) => Effect.gen(function* () {
1671
+ const decoded = decodeHostCallResult(outcome);
1672
+ if (Option.isNone(decoded)) {
1673
+ const error = CodeExecutionProtocolError.make({
1681
1674
  implementation: dynamicWorkerImplementation,
1682
- limit: request.limits.maxHostCalls,
1683
- logs: []
1684
- }));
1685
- case "host-call-result-limit": return Effect.fail(CodeOutputLimitError.make({
1675
+ message: "The execution host returned a value outside the CodeHostCallResult schema"
1676
+ });
1677
+ failPass(error);
1678
+ return yield* error;
1679
+ }
1680
+ const encoded = encodeHostResultPayload(decoded.value);
1681
+ if (encoded === void 0 || encoded.resultBytes > request.limits.maxHostCallResultBytes) {
1682
+ const error = CodeOutputLimitError.make({
1686
1683
  implementation: dynamicWorkerImplementation,
1687
1684
  surface: "host-call-result",
1688
1685
  limit: request.limits.maxHostCallResultBytes,
1689
- observed: failure.observed,
1686
+ observed: encoded?.resultBytes ?? 0,
1690
1687
  logs: []
1691
- }));
1692
- case "host-call-protocol": return Effect.fail(CodeExecutionProtocolError.make({
1693
- implementation: dynamicWorkerImplementation,
1694
- message: "The execution host returned a value outside the CodeHostCallResult schema"
1695
- }));
1696
- case "wall-clock-timeout": return Effect.fail(CodeExecutionTimeoutError.make({
1697
- implementation: dynamicWorkerImplementation,
1698
- kind: "wall-clock",
1699
- maxWallTime: request.limits.maxWallTime,
1700
- logs: []
1701
- }));
1702
- case "host-call-defect": return Effect.failCause(failure.cause);
1688
+ });
1689
+ failPass(error);
1690
+ return yield* error;
1703
1691
  }
1704
- };
1705
- const propagateHostDispatchFailure = (failure) => Effect.gen(function* () {
1706
- propagatedHostDispatchFailure = failure;
1707
- return yield* failHostDispatch(failure);
1692
+ const normalizedPayload = JSON.parse(encoded.encodedPayload);
1693
+ queued.resolve(decoded.value._tag === "CodeHostCallSuccess" ? {
1694
+ _tag: "CodeHostCallSuccess",
1695
+ value: normalizedPayload
1696
+ } : {
1697
+ _tag: "CodeHostCallFailure",
1698
+ error: normalizedPayload
1699
+ });
1708
1700
  });
1709
- const startNextHostCall = () => {
1710
- if (!passOpen || hostDispatchFailure !== void 0 || activeHostCall !== void 0) return;
1711
- const queued = queuedHostCalls.shift();
1712
- if (queued === void 0) return;
1713
- const fiber = Effect.runFork(Effect.yieldNow.pipe(Effect.andThen(host.call(queued.call)), Effect.timeoutOrElse({
1714
- duration: remainingPassWallTime(),
1715
- orElse: () => Effect.sync(() => {
1716
- recordHostDispatchFailure({ _tag: "wall-clock-timeout" });
1717
- throw new Error("code-mode host call exceeded the pass wall-clock limit");
1718
- })
1719
- }), Effect.map((outcome) => {
1720
- const decoded = decodeHostCallResult(outcome);
1721
- if (Option.isNone(decoded)) {
1722
- recordHostDispatchFailure({ _tag: "host-call-protocol" });
1723
- throw new Error("host-call protocol violation");
1724
- }
1725
- const encoded = encodeHostResultPayload(decoded.value);
1726
- if (encoded === void 0 || encoded.resultBytes > request.limits.maxHostCallResultBytes) {
1727
- recordHostDispatchFailure({
1728
- _tag: "host-call-result-limit",
1729
- observed: encoded?.resultBytes ?? 0
1701
+ const server = yield* Effect.gen(function* () {
1702
+ while (true) {
1703
+ const work = yield* Queue.take(queue);
1704
+ if (work._tag === "limit") {
1705
+ const error = CodeHostCallLimitError.make({
1706
+ implementation: dynamicWorkerImplementation,
1707
+ limit: request.limits.maxHostCalls,
1708
+ logs: []
1730
1709
  });
1731
- throw new Error("host-call result limit exceeded");
1710
+ failPass(error);
1711
+ return yield* error;
1732
1712
  }
1733
- const normalizedPayload = JSON.parse(encoded.encodedPayload);
1734
- return decoded.value._tag === "CodeHostCallSuccess" ? {
1735
- _tag: "CodeHostCallSuccess",
1736
- value: normalizedPayload
1737
- } : {
1738
- _tag: "CodeHostCallFailure",
1739
- error: normalizedPayload
1740
- };
1741
- })));
1742
- activeHostCall = {
1743
- fiber,
1744
- settlement: Effect.runPromise(Fiber.await(fiber)).then((exit) => {
1745
- if (Exit.isSuccess(exit)) {
1746
- queued.resolve(exit.value);
1747
- return;
1713
+ const queued = work.queued;
1714
+ yield* host.call(queued.call).pipe(Effect.timeoutOrElse({
1715
+ duration: remainingPassWallTime(),
1716
+ orElse: () => {
1717
+ const error = CodeExecutionTimeoutError.make({
1718
+ implementation: dynamicWorkerImplementation,
1719
+ kind: "wall-clock",
1720
+ maxWallTime: request.limits.maxWallTime,
1721
+ logs: []
1722
+ });
1723
+ failPass(error);
1724
+ return error;
1748
1725
  }
1749
- if (!Cause.hasInterruptsOnly(exit.cause)) recordHostDispatchFailure({
1750
- _tag: "host-call-defect",
1751
- cause: exit.cause
1752
- });
1753
- queued.reject(/* @__PURE__ */ new Error("Code Mode host call failed"));
1754
- }).finally(() => {
1755
- if (activeHostCall?.fiber === fiber) activeHostCall = void 0;
1756
- startNextHostCall();
1757
- })
1758
- };
1759
- };
1726
+ }), Effect.flatMap((outcome) => deliverHostOutcome(queued, outcome)), Effect.tapError(() => Effect.sync(() => queued.reject(/* @__PURE__ */ new Error("Code Mode host call failed")))), Effect.onInterrupt(() => Effect.sync(() => queued.reject(/* @__PURE__ */ new Error("Code Mode pass is closing")))));
1727
+ }
1728
+ }).pipe(Effect.forkScoped);
1760
1729
  const dispatch = (hostCall) => {
1761
1730
  if (!passOpen) return Promise.reject(/* @__PURE__ */ new Error("Code Mode pass is closing"));
1762
1731
  issuedHostCalls += 1;
1763
1732
  if (issuedHostCalls > request.limits.maxHostCalls) {
1764
- recordHostDispatchFailure({ _tag: "host-call-limit" });
1733
+ const error = CodeHostCallLimitError.make({
1734
+ implementation: dynamicWorkerImplementation,
1735
+ limit: request.limits.maxHostCalls,
1736
+ logs: []
1737
+ });
1738
+ failPass(error);
1739
+ Queue.offerUnsafe(queue, { _tag: "limit" });
1765
1740
  return Promise.reject(/* @__PURE__ */ new Error("host-call limit exceeded"));
1766
1741
  }
1767
1742
  const decoded = decodeHostCall(hostCall);
1768
1743
  if (Option.isNone(decoded)) return Promise.reject(/* @__PURE__ */ new TypeError("host calls must match the CodeHostCall schema"));
1769
1744
  return new Promise((resolve, reject) => {
1770
- queuedHostCalls.push({
1745
+ const queued = {
1771
1746
  call: decoded.value,
1772
1747
  resolve,
1773
1748
  reject
1749
+ };
1750
+ queuedHostCalls.push(queued);
1751
+ Queue.offerUnsafe(queue, {
1752
+ _tag: "call",
1753
+ queued
1774
1754
  });
1775
- startNextHostCall();
1776
1755
  });
1777
1756
  };
1778
- const closeHostDispatch = Effect.gen(function* () {
1757
+ const closeAdmission = Effect.sync(() => {
1779
1758
  passOpen = false;
1780
1759
  passRegistry.delete(passId);
1781
1760
  rejectQueuedHostCalls(/* @__PURE__ */ new Error("Code Mode pass is closing"));
1782
- const active = activeHostCall;
1783
- if (active !== void 0) {
1784
- yield* Fiber.interrupt(active.fiber);
1785
- yield* Effect.promise(() => active.settlement);
1786
- if (activeHostCall === active) activeHostCall = void 0;
1787
- }
1788
- return hostDispatchFailure;
1789
1761
  });
1790
- const stopHostDispatch = closeHostDispatch.pipe(Effect.flatMap((failure) => failure !== void 0 && propagatedHostDispatchFailure !== failure ? propagateHostDispatchFailure(failure) : Effect.void));
1791
- const releaseHostDispatch = closeHostDispatch.pipe(Effect.flatMap((failure) => {
1792
- if (failure?._tag !== "host-call-defect" || propagatedHostDispatchFailure === failure) return Effect.void;
1793
- propagatedHostDispatchFailure = failure;
1794
- return Effect.failCause(failure.cause);
1795
- }));
1796
1762
  yield* Effect.acquireRelease(Effect.sync(() => {
1797
1763
  passRegistry.set(passId, { dispatch });
1798
- }), () => releaseHostDispatch);
1764
+ }), () => closeAdmission.pipe(Effect.andThen(Fiber.interrupt(server))));
1799
1765
  const workerCode = {
1800
1766
  compatibilityDate: options.compatibilityDate ?? "2025-05-01",
1801
1767
  mainModule: "harness.js",
@@ -1849,7 +1815,7 @@ const makeExecute = (options) => Effect.fn("DynamicWorkerCodeExecutor.execute")(
1849
1815
  },
1850
1816
  catch: (cause) => classifyWorkerFailure(cause, request.limits.maxWallTime)
1851
1817
  });
1852
- const raw = yield* Effect.raceFirst(rpc.pipe(Effect.timeoutOrElse({
1818
+ const exit = yield* Effect.raceFirst(rpc.pipe(Effect.timeoutOrElse({
1853
1819
  duration: remainingPassWallTime(),
1854
1820
  orElse: () => CodeExecutionTimeoutError.make({
1855
1821
  implementation: dynamicWorkerImplementation,
@@ -1857,10 +1823,13 @@ const makeExecute = (options) => Effect.fn("DynamicWorkerCodeExecutor.execute")(
1857
1823
  maxWallTime: request.limits.maxWallTime,
1858
1824
  logs: []
1859
1825
  })
1860
- })), Effect.promise(() => hostDispatchFailureSignal).pipe(Effect.flatMap(propagateHostDispatchFailure)));
1861
- yield* stopHostDispatch;
1826
+ })), Fiber.join(server)).pipe(Effect.exit);
1827
+ yield* closeAdmission;
1828
+ yield* Fiber.interrupt(server);
1829
+ if (passFailure !== void 0) return yield* passFailure;
1830
+ if (Exit.isFailure(exit)) return yield* Effect.failCause(exit.cause);
1831
+ const raw = exit.value;
1862
1832
  const finishedAt = performance.now();
1863
- if (hostDispatchFailure !== void 0) return yield* propagateHostDispatchFailure(hostDispatchFailure);
1864
1833
  const outcome = decodeHarnessOutcome(raw);
1865
1834
  if (Option.isNone(outcome)) return yield* CodeExecutionProtocolError.make({
1866
1835
  implementation: dynamicWorkerImplementation,