@effect-agent/platform-cloudflare 0.1.0-beta.22 → 0.1.0-beta.23
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 +77 -108
- package/dist/index.mjs.map +1 -1
- package/package.json +8 -8
- package/src/code-mode-executor.ts +108 -163
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
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
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
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
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
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
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
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:
|
|
1686
|
+
observed: encoded?.resultBytes ?? 0,
|
|
1690
1687
|
logs: []
|
|
1691
|
-
})
|
|
1692
|
-
|
|
1693
|
-
|
|
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
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
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
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
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
|
-
|
|
1710
|
+
failPass(error);
|
|
1711
|
+
return yield* error;
|
|
1732
1712
|
}
|
|
1733
|
-
const
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
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
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
}), () =>
|
|
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
|
|
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
|
-
})),
|
|
1861
|
-
yield*
|
|
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,
|