@effect-agent/platform-cloudflare 0.1.0-beta.11 → 0.1.0-beta.13
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.d.mts +80 -78
- package/dist/index.mjs +159 -79
- package/dist/index.mjs.map +1 -1
- package/package.json +10 -7
- package/src/code-mode-executor.ts +243 -100
package/dist/index.d.mts
CHANGED
|
@@ -594,6 +594,50 @@ declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorded | Hos
|
|
|
594
594
|
readonly createdAt: string;
|
|
595
595
|
readonly deploymentId: string;
|
|
596
596
|
readonly payload: {
|
|
597
|
+
readonly _tag: "ToolCallPrepared";
|
|
598
|
+
readonly runId: string;
|
|
599
|
+
readonly turnId: string;
|
|
600
|
+
readonly turn: number;
|
|
601
|
+
readonly toolCallId: string;
|
|
602
|
+
readonly toolName: string;
|
|
603
|
+
readonly parameters: Schema.Json;
|
|
604
|
+
readonly parametersDigest: string;
|
|
605
|
+
} | {
|
|
606
|
+
readonly _tag: "ToolCallUnknown";
|
|
607
|
+
readonly runId: string;
|
|
608
|
+
readonly turn: number;
|
|
609
|
+
readonly toolCallId: string;
|
|
610
|
+
readonly toolName: string;
|
|
611
|
+
readonly reason: string;
|
|
612
|
+
} | {
|
|
613
|
+
readonly _tag: "ToolApprovalDecided";
|
|
614
|
+
readonly runId: string;
|
|
615
|
+
readonly turn: number;
|
|
616
|
+
readonly toolCallId: string;
|
|
617
|
+
readonly decision: "approved" | "denied";
|
|
618
|
+
readonly resolver: string;
|
|
619
|
+
readonly reason: string;
|
|
620
|
+
} | {
|
|
621
|
+
readonly _tag: "ToolCallResolved";
|
|
622
|
+
readonly runId: string;
|
|
623
|
+
readonly toolCallId: string;
|
|
624
|
+
readonly resolution: "completed-with-result" | "failed-with-error" | "never-started" | "safe-retry";
|
|
625
|
+
readonly author: string;
|
|
626
|
+
readonly reason: string;
|
|
627
|
+
} | {
|
|
628
|
+
readonly _tag: "AbortRequested";
|
|
629
|
+
readonly submissionId: string;
|
|
630
|
+
readonly author: string;
|
|
631
|
+
readonly reason: string;
|
|
632
|
+
} | {
|
|
633
|
+
readonly _tag: "SubagentStarted";
|
|
634
|
+
readonly runId: string;
|
|
635
|
+
readonly toolCallId: string;
|
|
636
|
+
readonly childConversationId: string;
|
|
637
|
+
readonly childSubmissionId: string;
|
|
638
|
+
readonly childReceiptId: string;
|
|
639
|
+
readonly childRunId: string;
|
|
640
|
+
} | {
|
|
597
641
|
readonly _tag: "ConversationCreated";
|
|
598
642
|
readonly agentId: string;
|
|
599
643
|
readonly definitions: {
|
|
@@ -621,15 +665,6 @@ declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorded | Hos
|
|
|
621
665
|
readonly inputTokens?: number | undefined;
|
|
622
666
|
readonly outputTokens?: number | undefined;
|
|
623
667
|
readonly costMicrousd?: number | undefined;
|
|
624
|
-
} | {
|
|
625
|
-
readonly _tag: "ToolCallPrepared";
|
|
626
|
-
readonly runId: string;
|
|
627
|
-
readonly turnId: string;
|
|
628
|
-
readonly turn: number;
|
|
629
|
-
readonly toolCallId: string;
|
|
630
|
-
readonly toolName: string;
|
|
631
|
-
readonly parameters: Schema.Json;
|
|
632
|
-
readonly parametersDigest: string;
|
|
633
668
|
} | {
|
|
634
669
|
readonly _tag: "ToolCallSettled";
|
|
635
670
|
readonly runId: string;
|
|
@@ -637,20 +672,6 @@ declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorded | Hos
|
|
|
637
672
|
readonly toolName: string;
|
|
638
673
|
readonly result: Schema.Json;
|
|
639
674
|
readonly isFailure: boolean;
|
|
640
|
-
} | {
|
|
641
|
-
readonly _tag: "ToolCallUnknown";
|
|
642
|
-
readonly runId: string;
|
|
643
|
-
readonly turn: number;
|
|
644
|
-
readonly toolCallId: string;
|
|
645
|
-
readonly toolName: string;
|
|
646
|
-
readonly reason: string;
|
|
647
|
-
} | {
|
|
648
|
-
readonly _tag: "ToolCallResolved";
|
|
649
|
-
readonly runId: string;
|
|
650
|
-
readonly toolCallId: string;
|
|
651
|
-
readonly resolution: "completed-with-result" | "failed-with-error" | "never-started" | "safe-retry";
|
|
652
|
-
readonly author: string;
|
|
653
|
-
readonly reason: string;
|
|
654
675
|
} | {
|
|
655
676
|
readonly _tag: "ToolStepSettled";
|
|
656
677
|
readonly runId: string;
|
|
@@ -666,14 +687,6 @@ declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorded | Hos
|
|
|
666
687
|
readonly toolCallId: string;
|
|
667
688
|
readonly toolName: string;
|
|
668
689
|
readonly parametersDigest: string;
|
|
669
|
-
} | {
|
|
670
|
-
readonly _tag: "ToolApprovalDecided";
|
|
671
|
-
readonly runId: string;
|
|
672
|
-
readonly turn: number;
|
|
673
|
-
readonly toolCallId: string;
|
|
674
|
-
readonly decision: "approved" | "denied";
|
|
675
|
-
readonly resolver: string;
|
|
676
|
-
readonly reason: string;
|
|
677
690
|
} | {
|
|
678
691
|
readonly _tag: "ModelResponseInterrupted";
|
|
679
692
|
readonly runId: string;
|
|
@@ -695,11 +708,6 @@ declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorded | Hos
|
|
|
695
708
|
readonly _tag: "RunCompleted";
|
|
696
709
|
readonly runId: string;
|
|
697
710
|
readonly output: Schema.Json;
|
|
698
|
-
} | {
|
|
699
|
-
readonly _tag: "AbortRequested";
|
|
700
|
-
readonly submissionId: string;
|
|
701
|
-
readonly author: string;
|
|
702
|
-
readonly reason: string;
|
|
703
711
|
} | {
|
|
704
712
|
readonly _tag: "SubmissionSettled";
|
|
705
713
|
readonly submissionId: string;
|
|
@@ -709,6 +717,8 @@ declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorded | Hos
|
|
|
709
717
|
readonly runId?: string | undefined;
|
|
710
718
|
readonly result?: Schema.Json | undefined;
|
|
711
719
|
readonly finishReason?: "budget-exhausted" | undefined;
|
|
720
|
+
readonly exhausted?: "tokens" | "tool-calls" | "turns" | undefined;
|
|
721
|
+
readonly policyLimit?: "cost" | "duration" | "repeated-failures" | "tokens" | "tool-calls" | "turns" | "usage" | undefined;
|
|
712
722
|
} | {
|
|
713
723
|
readonly _tag: "SubagentRequested";
|
|
714
724
|
readonly runId: string;
|
|
@@ -730,14 +740,6 @@ declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorded | Hos
|
|
|
730
740
|
readonly childConversationId: string;
|
|
731
741
|
readonly childPrincipal: string;
|
|
732
742
|
readonly childIdempotencyKey: string;
|
|
733
|
-
} | {
|
|
734
|
-
readonly _tag: "SubagentStarted";
|
|
735
|
-
readonly runId: string;
|
|
736
|
-
readonly toolCallId: string;
|
|
737
|
-
readonly childConversationId: string;
|
|
738
|
-
readonly childSubmissionId: string;
|
|
739
|
-
readonly childReceiptId: string;
|
|
740
|
-
readonly childRunId: string;
|
|
741
743
|
} | {
|
|
742
744
|
readonly _tag: "SubagentJoined";
|
|
743
745
|
readonly runId: string;
|
|
@@ -819,44 +821,18 @@ declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorded | Hos
|
|
|
819
821
|
} | {
|
|
820
822
|
readonly _tag: "HostFailed";
|
|
821
823
|
readonly failure: {
|
|
822
|
-
readonly _tag: "
|
|
823
|
-
readonly
|
|
824
|
-
} | {
|
|
825
|
-
readonly _tag: "AgentInputError";
|
|
824
|
+
readonly _tag: "LedgerError";
|
|
825
|
+
readonly operation: string;
|
|
826
826
|
readonly message: string;
|
|
827
|
+
readonly cause?: Schema.Json | undefined;
|
|
827
828
|
} | {
|
|
828
829
|
readonly _tag: "DigestError";
|
|
829
830
|
readonly message: string;
|
|
830
831
|
readonly cause?: Schema.Json | undefined;
|
|
831
|
-
} | {
|
|
832
|
-
readonly _tag: "AdmissionConflict";
|
|
833
|
-
readonly conversationId: string;
|
|
834
|
-
readonly principal: string;
|
|
835
|
-
readonly idempotencyKey: string;
|
|
836
|
-
readonly existingInputDigest: string;
|
|
837
|
-
readonly attemptedInputDigest: string;
|
|
838
832
|
} | {
|
|
839
833
|
readonly _tag: "SettlementConflict";
|
|
840
834
|
readonly submissionId: string;
|
|
841
835
|
readonly existingOutcome: "aborted" | "completed" | "failed";
|
|
842
|
-
} | {
|
|
843
|
-
readonly _tag: "ApprovalConflict";
|
|
844
|
-
readonly submissionId: string;
|
|
845
|
-
readonly toolCallId: string;
|
|
846
|
-
readonly existingDecision: "approved" | "denied";
|
|
847
|
-
} | {
|
|
848
|
-
readonly _tag: "UnknownResolutionConflict";
|
|
849
|
-
readonly submissionId: string;
|
|
850
|
-
readonly toolCallId: string;
|
|
851
|
-
} | {
|
|
852
|
-
readonly _tag: "JoinedToHost";
|
|
853
|
-
readonly submissionId: string;
|
|
854
|
-
readonly hostSubmissionId: string;
|
|
855
|
-
} | {
|
|
856
|
-
readonly _tag: "LedgerError";
|
|
857
|
-
readonly operation: string;
|
|
858
|
-
readonly message: string;
|
|
859
|
-
readonly cause?: Schema.Json | undefined;
|
|
860
836
|
} | {
|
|
861
837
|
readonly _tag: "ConversationStoreError";
|
|
862
838
|
readonly operation: string;
|
|
@@ -880,16 +856,42 @@ declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorded | Hos
|
|
|
880
856
|
} | {
|
|
881
857
|
readonly _tag: "DurableRuntimeFailpointError";
|
|
882
858
|
readonly location: "abort:after-intent" | "approval:after-request-append" | "approval:after-suspend" | "claim:after-claim" | "compaction:after-canonical-append" | "input:after-canonical-append" | "join:after-canonical-append" | "join:after-claim" | "resolve:after-intent" | "step:after-step-append" | "subagent:after-admit" | "subagent:after-child-abort-intent" | "subagent:after-child-ready" | "subagent:after-join-append" | "subagent:after-release" | "subagent:after-release-pending" | "subagent:after-request-append" | "subagent:after-reserve" | "subagent:after-sibling-settle" | "subagent:after-start-append" | "subagent:after-suspend" | "submit:after-admit" | "submit:after-materialize" | "terminalize:after-canonical-append" | "terminalize:after-reserve" | "tools:after-prepared-append" | "turn:after-canonical-append" | "turn:after-response-append" | "turn:after-results-append";
|
|
883
|
-
} | {
|
|
884
|
-
readonly _tag: "AdmissionLimitExceeded";
|
|
885
|
-
readonly limit: "database-bytes" | "input-bytes" | "queue-depth";
|
|
886
|
-
readonly actual: number;
|
|
887
|
-
readonly maximum: number;
|
|
888
859
|
} | {
|
|
889
860
|
readonly _tag: "DurableAlarmError";
|
|
890
861
|
readonly operation: string;
|
|
891
862
|
readonly message: string;
|
|
892
863
|
readonly cause?: Schema.Json | undefined;
|
|
864
|
+
} | {
|
|
865
|
+
readonly _tag: "HostProtocolError";
|
|
866
|
+
readonly message: string;
|
|
867
|
+
} | {
|
|
868
|
+
readonly _tag: "AgentInputError";
|
|
869
|
+
readonly message: string;
|
|
870
|
+
} | {
|
|
871
|
+
readonly _tag: "AdmissionConflict";
|
|
872
|
+
readonly conversationId: string;
|
|
873
|
+
readonly principal: string;
|
|
874
|
+
readonly idempotencyKey: string;
|
|
875
|
+
readonly existingInputDigest: string;
|
|
876
|
+
readonly attemptedInputDigest: string;
|
|
877
|
+
} | {
|
|
878
|
+
readonly _tag: "ApprovalConflict";
|
|
879
|
+
readonly submissionId: string;
|
|
880
|
+
readonly toolCallId: string;
|
|
881
|
+
readonly existingDecision: "approved" | "denied";
|
|
882
|
+
} | {
|
|
883
|
+
readonly _tag: "UnknownResolutionConflict";
|
|
884
|
+
readonly submissionId: string;
|
|
885
|
+
readonly toolCallId: string;
|
|
886
|
+
} | {
|
|
887
|
+
readonly _tag: "JoinedToHost";
|
|
888
|
+
readonly submissionId: string;
|
|
889
|
+
readonly hostSubmissionId: string;
|
|
890
|
+
} | {
|
|
891
|
+
readonly _tag: "AdmissionLimitExceeded";
|
|
892
|
+
readonly limit: "database-bytes" | "input-bytes" | "queue-depth";
|
|
893
|
+
readonly actual: number;
|
|
894
|
+
readonly maximum: number;
|
|
893
895
|
};
|
|
894
896
|
}, Schema.SchemaError, never>;
|
|
895
897
|
declare const decodeHostResponse: (input: unknown, options?: import("effect/SchemaAST").ParseOptions) => Effect.Effect<AbortRecorded | ApprovalRecorded | HostFailed | ObservedPage | SettlementReached | SubmitSucceeded | UnknownResolutionRecorded, Schema.SchemaError, never>;
|
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { Clock, Context, Duration, Effect, Fiber, Layer, Option, PubSub, Random, Ref, Schema, Stream } from "effect";
|
|
1
|
+
import { Cause, Clock, Context, Duration, Effect, Exit, Fiber, Layer, Option, PubSub, Random, Ref, Schema, 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 } 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";
|
|
5
5
|
import { BrowserCrypto } from "@effect/platform-browser";
|
|
6
6
|
import { SqliteClient } from "@effect/sql-sqlite-do";
|
|
7
7
|
import { DurableObject, DurableObjectState, WorkerEnvironment } from "effect-cf";
|
|
8
|
-
import { CodeExecutionHost, CodeExecutionProtocolError, CodeExecutionResourceUse, CodeExecutionResult, CodeExecutionTimeoutError, CodeExecutor, CodeExecutorStartError, CodeExecutorTerminatedError, CodeExecutorUnsupportedError, CodeHostCall, CodeHostCallLimitError, CodeOutputLimitError, CodeProgramFailedError, CodeSourceError, SandboxImplementation } from "@effect-agent/sandbox";
|
|
8
|
+
import { CodeExecutionHost, CodeExecutionProtocolError, CodeExecutionResourceUse, CodeExecutionResult, CodeExecutionTimeoutError, CodeExecutor, CodeExecutorStartError, CodeExecutorTerminatedError, CodeExecutorUnsupportedError, CodeHostCall, CodeHostCallLimitError, CodeHostCallResult, CodeOutputLimitError, CodeProgramFailedError, CodeSourceError, SandboxImplementation } from "@effect-agent/sandbox";
|
|
9
9
|
import { WorkerEntrypoint } from "cloudflare:workers";
|
|
10
10
|
//#region src/bindings.ts
|
|
11
11
|
/**
|
|
@@ -1348,19 +1348,25 @@ const decodeHostCall = (value) => {
|
|
|
1348
1348
|
return Option.none();
|
|
1349
1349
|
}
|
|
1350
1350
|
};
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
const
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1351
|
+
const decodeHostCallResult = (value) => {
|
|
1352
|
+
try {
|
|
1353
|
+
return Schema.decodeUnknownOption(CodeHostCallResult)(value);
|
|
1354
|
+
} catch {
|
|
1355
|
+
return Option.none();
|
|
1356
|
+
}
|
|
1357
|
+
};
|
|
1358
|
+
const encodeHostResultPayload = (outcome) => {
|
|
1359
|
+
try {
|
|
1360
|
+
const payload = outcome._tag === "CodeHostCallSuccess" ? outcome.value : outcome.error;
|
|
1361
|
+
const encodedPayload = JSON.stringify(payload);
|
|
1362
|
+
if (encodedPayload === void 0) return void 0;
|
|
1363
|
+
return {
|
|
1364
|
+
encodedPayload,
|
|
1365
|
+
resultBytes: utf8ByteLength(encodedPayload)
|
|
1366
|
+
};
|
|
1367
|
+
} catch {
|
|
1368
|
+
return;
|
|
1369
|
+
}
|
|
1364
1370
|
};
|
|
1365
1371
|
const utf8ByteLength = (value) => {
|
|
1366
1372
|
let total = 0;
|
|
@@ -1370,14 +1376,6 @@ const utf8ByteLength = (value) => {
|
|
|
1370
1376
|
}
|
|
1371
1377
|
return total;
|
|
1372
1378
|
};
|
|
1373
|
-
const encodedJsonByteLength = (value) => {
|
|
1374
|
-
try {
|
|
1375
|
-
const encoded = JSON.stringify(value);
|
|
1376
|
-
return encoded === void 0 ? void 0 : utf8ByteLength(encoded);
|
|
1377
|
-
} catch {
|
|
1378
|
-
return;
|
|
1379
|
-
}
|
|
1380
|
-
};
|
|
1381
1379
|
/** Reserved global names the harness owns inside the dynamic worker. */
|
|
1382
1380
|
const reservedHarnessGlobals = /* @__PURE__ */ new Set(["console"]);
|
|
1383
1381
|
const passCounterState = { next: 0 };
|
|
@@ -1401,67 +1399,149 @@ const makeExecute = (options) => Effect.fn("DynamicWorkerCodeExecutor.execute")(
|
|
|
1401
1399
|
const host = yield* CodeExecutionHost;
|
|
1402
1400
|
passCounterState.next += 1;
|
|
1403
1401
|
const passId = `code-mode-pass-${passCounterState.next}-${crypto.randomUUID()}`;
|
|
1404
|
-
const
|
|
1405
|
-
|
|
1402
|
+
const startedAt = performance.now();
|
|
1403
|
+
const passDeadline = startedAt + Duration.toMillis(request.limits.maxWallTime);
|
|
1404
|
+
const remainingPassWallTime = () => Duration.millis(Math.max(0, passDeadline - performance.now()));
|
|
1406
1405
|
let issuedHostCalls = 0;
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
resolve,
|
|
1416
|
-
reject
|
|
1417
|
-
});
|
|
1418
|
-
wake?.();
|
|
1419
|
-
});
|
|
1420
|
-
yield* Effect.acquireRelease(Effect.sync(() => {
|
|
1421
|
-
passRegistry.set(passId, { dispatch });
|
|
1422
|
-
}), () => Effect.sync(() => {
|
|
1423
|
-
passRegistry.delete(passId);
|
|
1424
|
-
}));
|
|
1425
|
-
const nextPending = Effect.suspend(() => {
|
|
1426
|
-
const item = pending.shift();
|
|
1427
|
-
if (item !== void 0) return Effect.succeed(item);
|
|
1428
|
-
return Effect.callback((resume) => {
|
|
1429
|
-
wake = () => {
|
|
1430
|
-
wake = void 0;
|
|
1431
|
-
const next = pending.shift();
|
|
1432
|
-
if (next !== void 0) resume(Effect.succeed(next));
|
|
1433
|
-
};
|
|
1434
|
-
});
|
|
1406
|
+
let passOpen = true;
|
|
1407
|
+
const queuedHostCalls = [];
|
|
1408
|
+
let activeHostCall;
|
|
1409
|
+
let hostDispatchFailure;
|
|
1410
|
+
let propagatedHostDispatchFailure;
|
|
1411
|
+
let signalHostDispatchFailure = (_failure) => void 0;
|
|
1412
|
+
const hostDispatchFailureSignal = new Promise((resolve) => {
|
|
1413
|
+
signalHostDispatchFailure = resolve;
|
|
1435
1414
|
});
|
|
1436
|
-
const
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1415
|
+
const rejectQueuedHostCalls = (reason) => {
|
|
1416
|
+
for (const queued of queuedHostCalls.splice(0)) queued.reject(reason);
|
|
1417
|
+
};
|
|
1418
|
+
const recordHostDispatchFailure = (failure) => {
|
|
1419
|
+
if (hostDispatchFailure !== void 0) return;
|
|
1420
|
+
hostDispatchFailure = failure;
|
|
1421
|
+
signalHostDispatchFailure(failure);
|
|
1422
|
+
rejectQueuedHostCalls(/* @__PURE__ */ new Error("Code Mode pass failed"));
|
|
1423
|
+
};
|
|
1424
|
+
const failHostDispatch = (failure) => {
|
|
1425
|
+
switch (failure._tag) {
|
|
1426
|
+
case "host-call-limit": return Effect.fail(CodeHostCallLimitError.make({
|
|
1442
1427
|
implementation: dynamicWorkerImplementation,
|
|
1443
1428
|
limit: request.limits.maxHostCalls,
|
|
1444
1429
|
logs: []
|
|
1445
|
-
});
|
|
1446
|
-
|
|
1430
|
+
}));
|
|
1431
|
+
case "host-call-result-limit": return Effect.fail(CodeOutputLimitError.make({
|
|
1432
|
+
implementation: dynamicWorkerImplementation,
|
|
1433
|
+
surface: "host-call-result",
|
|
1434
|
+
limit: request.limits.maxHostCallResultBytes,
|
|
1435
|
+
observed: failure.observed,
|
|
1436
|
+
logs: []
|
|
1437
|
+
}));
|
|
1438
|
+
case "host-call-protocol": return Effect.fail(CodeExecutionProtocolError.make({
|
|
1439
|
+
implementation: dynamicWorkerImplementation,
|
|
1440
|
+
message: "The execution host returned a value outside the CodeHostCallResult schema"
|
|
1441
|
+
}));
|
|
1442
|
+
case "wall-clock-timeout": return Effect.fail(CodeExecutionTimeoutError.make({
|
|
1443
|
+
implementation: dynamicWorkerImplementation,
|
|
1444
|
+
kind: "wall-clock",
|
|
1445
|
+
maxWallTime: request.limits.maxWallTime,
|
|
1446
|
+
logs: []
|
|
1447
|
+
}));
|
|
1448
|
+
case "host-call-defect": return Effect.failCause(failure.cause);
|
|
1449
|
+
}
|
|
1450
|
+
};
|
|
1451
|
+
const propagateHostDispatchFailure = (failure) => Effect.gen(function* () {
|
|
1452
|
+
propagatedHostDispatchFailure = failure;
|
|
1453
|
+
return yield* failHostDispatch(failure);
|
|
1454
|
+
});
|
|
1455
|
+
const startNextHostCall = () => {
|
|
1456
|
+
if (!passOpen || hostDispatchFailure !== void 0 || activeHostCall !== void 0) return;
|
|
1457
|
+
const queued = queuedHostCalls.shift();
|
|
1458
|
+
if (queued === void 0) return;
|
|
1459
|
+
const fiber = Effect.runFork(Effect.yieldNow.pipe(Effect.andThen(host.call(queued.call)), Effect.timeoutOrElse({
|
|
1460
|
+
duration: remainingPassWallTime(),
|
|
1461
|
+
orElse: () => Effect.sync(() => {
|
|
1462
|
+
recordHostDispatchFailure({ _tag: "wall-clock-timeout" });
|
|
1463
|
+
throw new Error("code-mode host call exceeded the pass wall-clock limit");
|
|
1464
|
+
})
|
|
1465
|
+
}), Effect.map((outcome) => {
|
|
1466
|
+
const decoded = decodeHostCallResult(outcome);
|
|
1447
1467
|
if (Option.isNone(decoded)) {
|
|
1448
|
-
|
|
1449
|
-
|
|
1468
|
+
recordHostDispatchFailure({ _tag: "host-call-protocol" });
|
|
1469
|
+
throw new Error("host-call protocol violation");
|
|
1450
1470
|
}
|
|
1451
|
-
const
|
|
1452
|
-
if (
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
surface: "host-call-result",
|
|
1457
|
-
limit: request.limits.maxHostCallResultBytes,
|
|
1458
|
-
observed: bytes ?? 0,
|
|
1459
|
-
logs: []
|
|
1471
|
+
const encoded = encodeHostResultPayload(decoded.value);
|
|
1472
|
+
if (encoded === void 0 || encoded.resultBytes > request.limits.maxHostCallResultBytes) {
|
|
1473
|
+
recordHostDispatchFailure({
|
|
1474
|
+
_tag: "host-call-result-limit",
|
|
1475
|
+
observed: encoded?.resultBytes ?? 0
|
|
1460
1476
|
});
|
|
1477
|
+
throw new Error("host-call result limit exceeded");
|
|
1461
1478
|
}
|
|
1462
|
-
|
|
1479
|
+
const normalizedPayload = JSON.parse(encoded.encodedPayload);
|
|
1480
|
+
return decoded.value._tag === "CodeHostCallSuccess" ? {
|
|
1481
|
+
_tag: "CodeHostCallSuccess",
|
|
1482
|
+
value: normalizedPayload
|
|
1483
|
+
} : {
|
|
1484
|
+
_tag: "CodeHostCallFailure",
|
|
1485
|
+
error: normalizedPayload
|
|
1486
|
+
};
|
|
1487
|
+
})));
|
|
1488
|
+
activeHostCall = {
|
|
1489
|
+
fiber,
|
|
1490
|
+
settlement: Effect.runPromise(Fiber.await(fiber)).then((exit) => {
|
|
1491
|
+
if (Exit.isSuccess(exit)) {
|
|
1492
|
+
queued.resolve(exit.value);
|
|
1493
|
+
return;
|
|
1494
|
+
}
|
|
1495
|
+
if (!Cause.hasInterruptsOnly(exit.cause)) recordHostDispatchFailure({
|
|
1496
|
+
_tag: "host-call-defect",
|
|
1497
|
+
cause: exit.cause
|
|
1498
|
+
});
|
|
1499
|
+
queued.reject(/* @__PURE__ */ new Error("Code Mode host call failed"));
|
|
1500
|
+
}).finally(() => {
|
|
1501
|
+
if (activeHostCall?.fiber === fiber) activeHostCall = void 0;
|
|
1502
|
+
startNextHostCall();
|
|
1503
|
+
})
|
|
1504
|
+
};
|
|
1505
|
+
};
|
|
1506
|
+
const dispatch = (hostCall) => {
|
|
1507
|
+
if (!passOpen) return Promise.reject(/* @__PURE__ */ new Error("Code Mode pass is closing"));
|
|
1508
|
+
issuedHostCalls += 1;
|
|
1509
|
+
if (issuedHostCalls > request.limits.maxHostCalls) {
|
|
1510
|
+
recordHostDispatchFailure({ _tag: "host-call-limit" });
|
|
1511
|
+
return Promise.reject(/* @__PURE__ */ new Error("host-call limit exceeded"));
|
|
1512
|
+
}
|
|
1513
|
+
const decoded = decodeHostCall(hostCall);
|
|
1514
|
+
if (Option.isNone(decoded)) return Promise.reject(/* @__PURE__ */ new TypeError("host calls must match the CodeHostCall schema"));
|
|
1515
|
+
return new Promise((resolve, reject) => {
|
|
1516
|
+
queuedHostCalls.push({
|
|
1517
|
+
call: decoded.value,
|
|
1518
|
+
resolve,
|
|
1519
|
+
reject
|
|
1520
|
+
});
|
|
1521
|
+
startNextHostCall();
|
|
1522
|
+
});
|
|
1523
|
+
};
|
|
1524
|
+
const closeHostDispatch = Effect.gen(function* () {
|
|
1525
|
+
passOpen = false;
|
|
1526
|
+
passRegistry.delete(passId);
|
|
1527
|
+
rejectQueuedHostCalls(/* @__PURE__ */ new Error("Code Mode pass is closing"));
|
|
1528
|
+
const active = activeHostCall;
|
|
1529
|
+
if (active !== void 0) {
|
|
1530
|
+
yield* Fiber.interrupt(active.fiber);
|
|
1531
|
+
yield* Effect.promise(() => active.settlement);
|
|
1532
|
+
if (activeHostCall === active) activeHostCall = void 0;
|
|
1463
1533
|
}
|
|
1534
|
+
return hostDispatchFailure;
|
|
1464
1535
|
});
|
|
1536
|
+
const stopHostDispatch = closeHostDispatch.pipe(Effect.flatMap((failure) => failure !== void 0 && propagatedHostDispatchFailure !== failure ? propagateHostDispatchFailure(failure) : Effect.void));
|
|
1537
|
+
const releaseHostDispatch = closeHostDispatch.pipe(Effect.flatMap((failure) => {
|
|
1538
|
+
if (failure?._tag !== "host-call-defect" || propagatedHostDispatchFailure === failure) return Effect.void;
|
|
1539
|
+
propagatedHostDispatchFailure = failure;
|
|
1540
|
+
return Effect.failCause(failure.cause);
|
|
1541
|
+
}));
|
|
1542
|
+
yield* Effect.acquireRelease(Effect.sync(() => {
|
|
1543
|
+
passRegistry.set(passId, { dispatch });
|
|
1544
|
+
}), () => releaseHostDispatch);
|
|
1465
1545
|
const workerCode = {
|
|
1466
1546
|
compatibilityDate: options.compatibilityDate ?? "2025-05-01",
|
|
1467
1547
|
allowExperimental: true,
|
|
@@ -1492,7 +1572,6 @@ const makeExecute = (options) => Effect.fn("DynamicWorkerCodeExecutor.execute")(
|
|
|
1492
1572
|
subRequests: request.limits.maxHostCalls + 8
|
|
1493
1573
|
} }
|
|
1494
1574
|
};
|
|
1495
|
-
const startedAt = yield* Clock.currentTimeMillis;
|
|
1496
1575
|
const worker = yield* Effect.acquireRelease(Effect.try({
|
|
1497
1576
|
try: () => options.loader.load(workerCode),
|
|
1498
1577
|
catch: (cause) => {
|
|
@@ -1511,23 +1590,24 @@ const makeExecute = (options) => Effect.fn("DynamicWorkerCodeExecutor.execute")(
|
|
|
1511
1590
|
}), (stub) => Effect.sync(() => {
|
|
1512
1591
|
stub[Symbol.dispose]?.();
|
|
1513
1592
|
}));
|
|
1514
|
-
const server = yield* serveHostCalls.pipe(Effect.forkScoped);
|
|
1515
1593
|
const rpc = Effect.tryPromise({
|
|
1516
1594
|
try: async () => {
|
|
1517
1595
|
return await worker.getEntrypoint().run();
|
|
1518
1596
|
},
|
|
1519
1597
|
catch: (cause) => classifyWorkerFailure(cause, request.limits.maxWallTime)
|
|
1520
1598
|
});
|
|
1521
|
-
const raw = yield* Effect.raceFirst(rpc
|
|
1522
|
-
duration:
|
|
1599
|
+
const raw = yield* Effect.raceFirst(rpc.pipe(Effect.timeoutOrElse({
|
|
1600
|
+
duration: remainingPassWallTime(),
|
|
1523
1601
|
orElse: () => CodeExecutionTimeoutError.make({
|
|
1524
1602
|
implementation: dynamicWorkerImplementation,
|
|
1525
1603
|
kind: "wall-clock",
|
|
1526
1604
|
maxWallTime: request.limits.maxWallTime,
|
|
1527
1605
|
logs: []
|
|
1528
1606
|
})
|
|
1529
|
-
}), Effect.
|
|
1530
|
-
|
|
1607
|
+
})), Effect.promise(() => hostDispatchFailureSignal).pipe(Effect.flatMap(propagateHostDispatchFailure)));
|
|
1608
|
+
yield* stopHostDispatch;
|
|
1609
|
+
const finishedAt = performance.now();
|
|
1610
|
+
if (hostDispatchFailure !== void 0) return yield* propagateHostDispatchFailure(hostDispatchFailure);
|
|
1531
1611
|
const outcome = decodeHarnessOutcome(raw);
|
|
1532
1612
|
if (Option.isNone(outcome)) return yield* CodeExecutionProtocolError.make({
|
|
1533
1613
|
implementation: dynamicWorkerImplementation,
|