effect-agent 0.1.0-beta.125 → 0.1.0-beta.126

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 (80) hide show
  1. package/dist/{Records-uGX4_EGf.d.mts → Admin-C34cVKlT.d.mts} +2908 -3941
  2. package/dist/{AgentRuntime-ov0LFEb-.d.mts → AgentRuntime-DEDvMkAR.d.mts} +2 -2
  3. package/dist/Digest-U69rDHuO.d.mts +22 -0
  4. package/dist/{DurableAgentRuntime-BvDGe7F9.mjs → DurableAgentRuntime-BydyN_n-.mjs} +88 -15
  5. package/dist/DurableAgentRuntime-BydyN_n-.mjs.map +1 -0
  6. package/dist/{EventSource-CNBoY8AA.d.mts → EventSource-Bac0SxKL.d.mts} +3 -3
  7. package/dist/{PreparedInputAdmission--_APJzWY.d.mts → PreparedInputAdmission-DcQGQ0Yp.d.mts} +4 -4
  8. package/dist/Records-B5GFWCpn.d.mts +1104 -0
  9. package/dist/{Schedule-C8ze8WTW.d.mts → Schedule-CtYREFnz.d.mts} +2 -2
  10. package/dist/{Subagent-CudP5BlT.mjs → Subagent-DJeZDrbD.mjs} +5 -2
  11. package/dist/Subagent-DJeZDrbD.mjs.map +1 -0
  12. package/dist/{Subagent-CCf7rY70.d.mts → Subagent-DRFyQxdb.d.mts} +13 -4
  13. package/dist/{SubagentHost-B0-cRCqs.d.mts → SubagentHost-DQjHFGqH.d.mts} +7 -2
  14. package/dist/{Subscription-CYb8ltMK.d.mts → Subscription-Bk2Smmqc.d.mts} +34 -3
  15. package/dist/{SubscriptionInput-C1XE9Vyi.d.mts → SubscriptionInput-ekbJz3pF.d.mts} +3 -3
  16. package/dist/capabilities/Subagent.d.mts +1 -1
  17. package/dist/capabilities/Subagent.mjs +1 -1
  18. package/dist/durable/ActivityStore.d.mts +1 -1
  19. package/dist/durable/Admin.d.mts +1 -1
  20. package/dist/durable/AgentRegistration.d.mts +1 -1
  21. package/dist/durable/Certification.d.mts +1 -1
  22. package/dist/durable/CommittedActivity.d.mts +3 -1
  23. package/dist/durable/Digest.d.mts +1 -1
  24. package/dist/durable/DurableAgentRuntime.d.mts +1 -1
  25. package/dist/durable/DurableAgentRuntime.mjs +1 -1
  26. package/dist/durable/EventSource.d.mts +1 -1
  27. package/dist/durable/GitHubWorkflowSource.d.mts +3 -3
  28. package/dist/durable/MessageDelivery.d.mts +44 -3
  29. package/dist/durable/MessageDeliveryStoreConformance.d.mts +61 -39
  30. package/dist/durable/PersistentHistory.d.mts +1 -1
  31. package/dist/durable/PreparedInputAdmission.d.mts +1 -1
  32. package/dist/durable/Records.d.mts +2 -2
  33. package/dist/durable/Records.mjs +12 -2
  34. package/dist/durable/Records.mjs.map +1 -1
  35. package/dist/durable/Recovery.d.mts +1 -1
  36. package/dist/durable/RunJournal.d.mts +1 -1
  37. package/dist/durable/Schedule.d.mts +1 -1
  38. package/dist/durable/ScheduleStoreConformance.d.mts +1 -1
  39. package/dist/durable/ScheduleTransition.d.mts +1 -1
  40. package/dist/durable/Scheduling.d.mts +3 -2
  41. package/dist/durable/SqlStorageV2Upgrade.d.mts +2 -2
  42. package/dist/durable/SqlSubscriptionStore.d.mts +2 -2
  43. package/dist/durable/SqlThreadNativeReads.d.mts +2 -1
  44. package/dist/durable/SqlThreadNativeReads.mjs +1 -1
  45. package/dist/durable/SqlThreadNativeReads.mjs.map +1 -1
  46. package/dist/durable/SubmissionLedger.d.mts +1 -1
  47. package/dist/durable/SubmissionLedgerConformance.d.mts +2 -1
  48. package/dist/durable/SubmissionStatus.d.mts +1 -1
  49. package/dist/durable/Subscription.d.mts +1 -1
  50. package/dist/durable/SubscriptionInput.d.mts +1 -1
  51. package/dist/durable/SubscriptionStoreConformance.d.mts +1 -1
  52. package/dist/durable/SubscriptionTools.d.mts +4 -3
  53. package/dist/durable/SubscriptionTransition.d.mts +1 -1
  54. package/dist/durable/Subscriptions.d.mts +6 -5
  55. package/dist/durable/ThreadContextHistory.d.mts +1 -1
  56. package/dist/durable/ThreadContextHistoryProjection.d.mts +1 -1
  57. package/dist/durable/ThreadInvariants.d.mts +2 -1
  58. package/dist/durable/ThreadProjection.d.mts +1 -1
  59. package/dist/durable/ThreadProjectionMaintenance.d.mts +1 -1
  60. package/dist/durable/ThreadStore.d.mts +1 -1
  61. package/dist/durable/ThreadStoreConformance.d.mts +1 -1
  62. package/dist/durable/ThreadStoreConformance.mjs +10 -1
  63. package/dist/durable/ThreadStoreConformance.mjs.map +1 -1
  64. package/dist/durable/WorkerHost.d.mts +9 -2
  65. package/dist/durable/WorkerHost.mjs.map +1 -1
  66. package/dist/engine/AgentRuntime.d.mts +1 -1
  67. package/dist/engine/SubagentHost.d.mts +1 -1
  68. package/dist/engine/SubagentHost.mjs.map +1 -1
  69. package/dist/index.d.mts +12 -10
  70. package/dist/index.mjs +2 -2
  71. package/package.json +1 -1
  72. package/src/capabilities/internal/subagent-background.ts +25 -3
  73. package/src/durable/Records.ts +13 -1
  74. package/src/durable/SqlThreadNativeReads.ts +1 -1
  75. package/src/durable/ThreadStoreConformance.ts +28 -0
  76. package/src/durable/WorkerHost.ts +14 -2
  77. package/src/durable/internal/worker-host.ts +282 -9
  78. package/src/engine/SubagentHost.ts +6 -0
  79. package/dist/DurableAgentRuntime-BvDGe7F9.mjs.map +0 -1
  80. package/dist/Subagent-CudP5BlT.mjs.map +0 -1
@@ -15,7 +15,7 @@ import { n as CompactionError } from "./ContextCompactor-WwSIG_Z2.mjs";
15
15
  import { t as DurableStep } from "./DurableStep-Cry_iol4.mjs";
16
16
  import { B as RunSubagentChildIdentity, H as RunSubagentEstablishRequest, M as RunOptions, S as RunContextPreparationError, W as RunSubagentJoinRequest, i as ChildEstablishStatus, l as ModelUsageAccounting, t as AgentUpdateAcceptance, x as RunContextPreparation } from "./RunOptions-CSBsSj0X.mjs";
17
17
  import { t as MessagingHost } from "./MessagingHost-CqzpxbGz.mjs";
18
- import { o as SubagentHost } from "./SubagentHost-B0-cRCqs.mjs";
18
+ import { o as SubagentHost } from "./SubagentHost-DQjHFGqH.mjs";
19
19
  import { t as RunEventSink } from "./RunEventSink-D5aVhISG.mjs";
20
20
  import { AiError, LanguageModel, Model, Prompt, Tool, Toolkit } from "effect/unstable/ai";
21
21
  import { Cause, Context, Effect, Layer, Option, Schema, Scope, Stream, Tracer } from "effect";
@@ -343,4 +343,4 @@ declare namespace AgentRuntime_d_exports {
343
343
  }
344
344
  //#endregion
345
345
  export { start as A, decodeFinalOutput as C, renderInputPrompt as D, projectCompletionOutput as E, withTerminalDefectEvent as F, stream as M, streamUnknown as N, run as O, streamWithUsageAccountingUnknown as P, ToolCallWaiting as S, projectCompletionFromToolOutput as T, SubagentDurability as _, AgentResultSchema as a, SubagentDurabilityError as b, AgentSpawner as c, DetachedRun as d, EngineProvidedToolServices as f, SpawnedChildRun as g, SpawnRunOptions as h, AgentResult as i, startUnknown as j, runUnknown as k, AgentSpawnerParent as l, SpawnDelegation as m, AgentChildPending as n, AgentRuntimeFailure as o, RuntimeBinding as p, AgentCompletionProjectionRequirements as r, AgentRuntimeRequirements as s, AgentRuntime_d_exports as t, AgentSpawnerService as u, SubagentDurabilityDurable as v, encodeRunDisposition as w, SubagentDurabilityService as x, SubagentDurabilityEphemeral as y };
346
- //# sourceMappingURL=AgentRuntime-ov0LFEb-.d.mts.map
346
+ //# sourceMappingURL=AgentRuntime-DEDvMkAR.d.mts.map
@@ -0,0 +1,22 @@
1
+ import { _ as Digest, h as DefinitionDigests, m as DefinitionDigestInput, s as CanonicalBatch } from "./Records-B5GFWCpn.mjs";
2
+ import { Crypto, Effect, Schema } from "effect";
3
+ declare namespace Digest_d_exports {
4
+ export { DigestError, EMPTY_TAIL_DIGEST, digestCanonicalBatch, digestDefinition, digestDefinitions, digestJson };
5
+ }
6
+ declare const DigestError_base: Schema.Class<DigestError, Schema.TaggedStruct<"DigestError", {
7
+ readonly message: Schema.String;
8
+ readonly cause: Schema.optionalKey<Schema.Defect>;
9
+ }>, import("effect/Cause").YieldableError>;
10
+ declare class DigestError extends DigestError_base {}
11
+ /** Digest a JSON value using a stable, locale-independent object-key ordering (UTF-16 code units, RFC 8785 style). */
12
+ declare const digestJson: (value: Schema.Json) => Effect.Effect<string & import("effect/Brand").Brand<"@effect-agent/thread/Digest">, DigestError, Crypto.Crypto>;
13
+ /** Digest a canonical batch together with the prior tail to form an append-only hash chain. */
14
+ declare const digestCanonicalBatch: (previousTailDigest: Digest, batch: CanonicalBatch) => Effect.Effect<Digest, DigestError, Crypto.Crypto>;
15
+ /** Digest one schema-encoded Agent, Model, or Toolkit definition. */
16
+ declare const digestDefinition: (definition: Schema.Json) => Effect.Effect<string & import("effect/Brand").Brand<"@effect-agent/thread/Digest">, DigestError, Crypto.Crypto>;
17
+ /** Digest all replay-relevant definitions without hiding which authority changed. */
18
+ declare const digestDefinitions: (definitions: DefinitionDigestInput) => Effect.Effect<DefinitionDigests, DigestError, Crypto.Crypto>;
19
+ declare const EMPTY_TAIL_DIGEST: string & import("effect/Brand").Brand<"@effect-agent/thread/Digest">;
20
+ //#endregion
21
+ export { digestDefinition as a, digestCanonicalBatch as i, Digest_d_exports as n, digestDefinitions as o, EMPTY_TAIL_DIGEST as r, digestJson as s, DigestError as t };
22
+ //# sourceMappingURL=Digest-U69rDHuO.d.mts.map
@@ -21,7 +21,7 @@ import { getToolExecutionClass } from "./engine/DurableStep.mjs";
21
21
  import { CompactionError, ContextCompactor } from "./engine/ContextCompactor.mjs";
22
22
  import { RunPolicyUsage } from "./core/RunPolicyUsage.mjs";
23
23
  import { AgentUpdateAcceptance, CurrentToolFailureObserver, ModelUsageAccounting, RunContextPreparation, RunContextPreparationPassthrough, RunToolAuthorization, RunToolScheduling } from "./engine/RunOptions.mjs";
24
- import { AbortRequested, AgentUpdateEmitted, BatchId, CanonicalBatch, CanonicalRecordEnvelope, CanonicalSequence, CompactionCreated, DefinitionDigests, Digest, ModelResponseInterrupted, PeerMessagePrepared, PersistedJson, ProducerEpoch, RecordEnvelope, RecordId, RepairAnnotated, RunDurationExhausted, RunPolicyUsageReserved, RunStartedRecord, SettlementFailureDiagnostic, SubagentJoined, SubagentLineageRecorded, SubagentRequested, SubagentStarted, SubmissionSettled, SubmissionSettledRecord, SubtreeBudgetReserved, ThreadCreated, ToolApprovalDecided, ToolApprovalRequested, ToolCallPrepared, ToolCallResolved, ToolCallSettled, ToolCallUnknown, ToolOperation, ToolStepSettled, ToolUnavailable, UserInputRecorded, WorkerAdmission, WorkerInputCompleted, WorkerInputRequested, WorkerOrigin, WorkerOriginRecorded, WorkerReportPrepared, WorkerReportRefused, WorkerReportingIntent, WorkerStopRequested } from "./durable/Records.mjs";
24
+ import { AbortRequested, AgentUpdateEmitted, BatchId, CanonicalBatch, CanonicalRecordEnvelope, CanonicalSequence, CompactionCreated, DefinitionDigests, Digest, ModelResponseInterrupted, PeerMessagePrepared, PersistedJson, ProducerEpoch, RecordEnvelope, RecordId, RepairAnnotated, RunDurationExhausted, RunPolicyUsageReserved, RunStartedRecord, SettlementFailureDiagnostic, SubagentJoined, SubagentLineageRecorded, SubagentRequested, SubagentStarted, SubmissionSettled, SubmissionSettledRecord, SubtreeBudgetReserved, ThreadCreated, ToolApprovalDecided, ToolApprovalRequested, ToolCallPrepared, ToolCallResolved, ToolCallSettled, ToolCallUnknown, ToolOperation, ToolStepSettled, ToolUnavailable, UserInputRecorded, WorkerAdmission, WorkerContinuation, WorkerInputCompleted, WorkerInputRequested, WorkerOrigin, WorkerOriginRecorded, WorkerReportPrepared, WorkerReportRefused, WorkerReportingIntent, WorkerStopRequested } from "./durable/Records.mjs";
25
25
  import { AbortCommand, AbortIntentRequest, AdmissionPolicyError, AdmissionRequest, ApprovalDecisionCommand, ApprovalPendingSuspension, AttachChildToReservationRequest, BeginChildBudgetReleaseRequest, ChildBudgetReservationRequest, ChildReservationId, ChildSettledNotification, ClaimJoiningRequest, ClaimRequest, LedgerError, MarkInputAppliedRequest, MarkJoinedRequest, MarkReadyRequest, MarkUnknownRequest, OwnershipToken, ParentLinkage, RecoverySnapshotRequest, ReleaseChildBudgetRequest, ReleaseOwnershipRequest, RenewOwnershipRequest, RevertJoiningRequest, Settlement, SettlementFinalization, SettlementReservation, SubmissionLedger, SubmissionLookupById, SubmissionLookupByKey, SuspendRequest, UnknownResolutionCommand, WaitingChild, WaitingForChildSuspension, WorkerLedgerState, submissionAbortBatchId, submissionAbortRecordId, submissionInputBatchId, submissionInputRecordId, submissionSettlementBatchId, submissionSettlementId, submissionSettlementRecordId } from "./durable/SubmissionLedger.mjs";
26
26
  import { DeclaredPendingBatchEvidence, OpenDelegationCallEvidence, OpenToolCallEvidence, PendingApprovalEvidence, RecoveryDecision, RecoveryEvidence, classifyRecovery } from "./durable/Recovery.mjs";
27
27
  import { ExplainedEvidence, ExplainedSubmission, ExplainedUnknownCall, IntegrityCheck, IntegrityReport, ObligationEntry, ObligationReport, RecoveryExplanation, RetryRefused, obligationSeverityOf, predictRecoveryDisposition, recoveryDecisionMeaning } from "./durable/Admin.mjs";
@@ -653,12 +653,14 @@ const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
653
653
  };
654
654
  const withCrypto = (effect) => Effect.provideService(effect, Crypto.Crypto, deps.crypto);
655
655
  const authorizeBudget = Effect.fn("WorkerHost.authorizeBudget")(function* (origin, principal) {
656
+ yield* verifyContinuation(origin);
656
657
  if (origin.budgetScope !== "worker-run") return;
657
658
  if (origin.depth !== 1) return yield* failure("start", "denied");
658
659
  yield* deps.budgetAuthorizer.authorize({
659
660
  source: origin.source,
660
661
  principal,
661
662
  worker: origin.worker,
663
+ ...origin.continuationOf === void 0 ? {} : { continuationOf: origin.continuationOf },
662
664
  policy: origin.policy,
663
665
  budget: origin.budget
664
666
  });
@@ -670,6 +672,59 @@ const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
670
672
  recordId
671
673
  }).pipe(Effect.provideService(ThreadStore, deps.store), Effect.mapError(storageFailure(operation)));
672
674
  });
675
+ const completedContinuation = Effect.fn("WorkerHost.completedContinuation")(function* (source, worker, targetAgentId, delegationId, expected) {
676
+ const selected = yield* decode(WorkerRef, worker, "start");
677
+ if (selected.targetAgentId !== targetAgentId || selected.delegationId !== delegationId || selected.threadId === source.threadId || deps.ledger.inspectWorker === void 0) return yield* failure("start", "worker-mismatch");
678
+ const sourceState = yield* readWorkerState$1(source.threadId, "start");
679
+ if (sourceState.records.some(({ record }) => record.payload._tag === "WorkerStopRequested" && record.payload.command.worker.threadId === selected.threadId)) return yield* failure("start", "denied");
680
+ const first = sourceState.records.find(({ record }) => record.recordId === firstWorkerInputRecordId(selected))?.record.payload;
681
+ const origin = first?._tag === "WorkerInputRequested" ? first.admission.origin : void 0;
682
+ if (origin === void 0 || origin.lifecycle !== "assignment" || !Schema.toEquivalence(WorkerRef)(origin.worker, selected) || origin.source.threadId !== source.threadId || origin.source.agentId !== source.agentId || first?._tag !== "WorkerInputRequested" || first.admission.messageId !== origin.firstMessageId) return yield* failure("start", "worker-mismatch");
683
+ const recorded = Option.getOrUndefined(yield* exactRecord(selected.threadId, workerOriginRecordId(selected.threadId), "start"))?.record.payload;
684
+ if (recorded?._tag !== "WorkerOriginRecorded" || !sameOrigin(recorded.origin, origin)) return yield* failure("start", "worker-mismatch");
685
+ const control = yield* deps.ledger.inspectWorker(selected.threadId).pipe(Effect.mapError(storageFailure("start")));
686
+ if (control.terminal !== "completed" || !control.stopped || control.active !== null) return yield* failure("start", "denied");
687
+ const tail = yield* deps.store.inspectTail(ThreadTailRequest.make({ threadId: selected.threadId })).pipe(Effect.mapError(storageFailure("start")));
688
+ const run = (yield* deps.store.read({
689
+ threadId: selected.threadId,
690
+ selection: {
691
+ _tag: "WorkerExecution",
692
+ expectedTailSequence: tail.tailSequence,
693
+ expectedTailDigest: tail.tailDigest
694
+ },
695
+ page: { limit: 2 }
696
+ }).pipe(Stream.runCollect, Effect.mapError(storageFailure("start")))).find(({ record }) => record.payload._tag === "RunStarted")?.record.payload;
697
+ if (run?._tag !== "RunStarted") return yield* failure("start", "corrupt");
698
+ const input = Option.getOrUndefined(yield* getRunInput({
699
+ threadId: selected.threadId,
700
+ runId: run.runId
701
+ }).pipe(Effect.provideService(ThreadStore, deps.store), Effect.mapError(storageFailure("start"))))?.record.payload;
702
+ if (input?._tag !== "UserInputRecorded" || input.submissionId === void 0) return yield* failure("start", "corrupt");
703
+ const found = yield* deps.ledger.lookup(SubmissionLookupById.make({ submissionId: input.submissionId })).pipe(Effect.mapError(storageFailure("start")));
704
+ const row = Option.getOrUndefined(found);
705
+ const settlement = Option.getOrUndefined(yield* exactRecord(selected.threadId, submissionSettlementRecordId(input.submissionId), "start"))?.record.payload;
706
+ if (row === void 0 || row.threadId !== selected.threadId || row.state !== "settled" || row.settledOutcome !== "completed" || row.workerAdmission === void 0 || !sameOrigin(row.workerAdmission.origin, origin) || settlement?._tag !== "SubmissionSettled" || settlement.outcome !== "completed" || settlement.runDisposition !== "completed" || settlement.finishReason !== void 0 || settlement.runId !== run.runId || settlement.submissionId !== row.submissionId || settlement.receiptId !== row.receiptId) return yield* failure("start", "denied");
707
+ const evidence = WorkerContinuation.make({
708
+ worker: selected,
709
+ receipt: Receipt.make({
710
+ threadId: row.threadId,
711
+ submissionId: row.submissionId,
712
+ receiptId: row.receiptId,
713
+ queueSequence: row.queueSequence
714
+ }),
715
+ settlementId: settlement.settlementId
716
+ });
717
+ if (expected !== void 0 && !Schema.toEquivalence(WorkerContinuation)(expected, evidence)) return yield* failure("start", "worker-mismatch");
718
+ return {
719
+ evidence,
720
+ origin
721
+ };
722
+ });
723
+ const verifyContinuation = Effect.fn("WorkerHost.verifyContinuation")(function* (origin) {
724
+ if (origin.continuationOf === void 0) return;
725
+ const previous = yield* completedContinuation(origin.source, origin.continuationOf.worker, origin.worker.targetAgentId, origin.worker.delegationId, origin.continuationOf);
726
+ if (origin.worker.threadId === previous.origin.worker.threadId || origin.lifecycle !== "assignment" || !samePolicy(origin.policy, previous.origin.policy) || !Schema.toEquivalence(WorkerOrigin.fields.budget)(origin.budget, previous.origin.budget) || !Schema.toEquivalence(SubagentGrant)(origin.grant, previous.origin.grant) || origin.budgetScope !== previous.origin.budgetScope || origin.depth !== previous.origin.depth || origin.toolCallAllowance !== previous.origin.toolCallAllowance || origin.expiresAtMillis > previous.origin.expiresAtMillis) return yield* failure("start", "denied");
727
+ });
673
728
  const readIdentity = Effect.fn("WorkerHost.readIdentity")(function* (threadId, operation) {
674
729
  const tail = yield* deps.store.inspectTail(ThreadTailRequest.make({ threadId })).pipe(Effect.mapError(storageFailure(operation)));
675
730
  const first = yield* deps.store.read(ThreadRead.make({
@@ -901,10 +956,12 @@ const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
901
956
  });
902
957
  const reservation = Effect.fn("WorkerHost.reserveInput")(function* (admission, inputDigest, input, principal, retainedFrameworkInput) {
903
958
  const origin = admission.origin;
959
+ yield* verifyContinuation(origin);
904
960
  const id = workerInputRecordId(admission.messageId);
905
961
  for (let attempt = 0; attempt < 16; attempt++) {
906
962
  const source = yield* sourceAuthority(origin.source.threadId, admission.sourceSubmissionId, true);
907
963
  const current = source.current;
964
+ if (origin.continuationOf !== void 0 && current.records.some(({ record }) => record.payload._tag === "WorkerStopRequested" && record.payload.command.worker.threadId === origin.continuationOf?.worker.threadId)) return yield* failure("start", "denied");
908
965
  const rows = requests(current.records);
909
966
  const existing = current.records.find(({ record }) => record.recordId === id)?.record.payload;
910
967
  if (existing !== void 0) {
@@ -931,6 +988,7 @@ const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
931
988
  const selected = yield* resolveTargetPolicy(admission.messageId === origin.firstMessageId ? {
932
989
  ...targetRequest,
933
990
  _tag: "InitialInput",
991
+ ...origin.continuationOf === void 0 ? {} : { continuationOf: origin.continuationOf },
934
992
  input,
935
993
  inputDigest,
936
994
  ...source.submission === void 0 ? {} : { sourceSubmission: source.submission }
@@ -963,6 +1021,7 @@ const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
963
1021
  const selectedConcurrency = yield* deps.concurrencyResolver.resolve({
964
1022
  source: origin.source,
965
1023
  worker: origin.worker,
1024
+ ...origin.continuationOf === void 0 ? {} : { continuationOf: origin.continuationOf },
966
1025
  principal,
967
1026
  ...source.submission === void 0 ? {} : { sourceSubmission: source.submission }
968
1027
  });
@@ -1009,13 +1068,15 @@ const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
1009
1068
  if (!Schema.is(WorkerUpdate)(options.messageAdmission)) return yield* failure("start", "denied");
1010
1069
  yield* validateCompletion(options.messageAdmission, options, agentId, inputDigest);
1011
1070
  }
1071
+ yield* verifyContinuation(admission.origin);
1012
1072
  yield* deps.authorizer.authorize({
1013
1073
  sourceThreadId: admission.origin.source.threadId,
1014
1074
  ...admission.sourceSubmissionId === void 0 ? {} : { sourceSubmissionId: admission.sourceSubmissionId },
1015
1075
  principal: options.principal,
1016
1076
  operation: "start",
1017
1077
  access: "send",
1018
- worker: admission.origin.worker
1078
+ worker: admission.origin.worker,
1079
+ ...admission.origin.continuationOf === void 0 ? {} : { continuationOf: admission.origin.continuationOf }
1019
1080
  });
1020
1081
  yield* authorizeBudget(admission.origin, options.principal);
1021
1082
  if (admission.origin.worker.threadId !== options.threadId || admission.origin.worker.targetAgentId !== agentId || !definitionDigestsEqual(admission.origin.targetDigests, options.definitions) || options.idempotencyKey !== admission.messageId || admission.deliveryPrincipal !== void 0 && admission.deliveryPrincipal !== options.principal) return yield* failure("start", "worker-mismatch");
@@ -1159,11 +1220,12 @@ const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
1159
1220
  budgetExhausted: host.finishReason === "budget-exhausted"
1160
1221
  }
1161
1222
  };
1162
- const projection = yield* Effect.suspend(() => descriptor.prepare(report)).pipe(Effect.timeout(Math.min(deps.limits.reportPreparationTimeoutMillis ?? 5e3, deadlineAtMillis - now)), Effect.map((value) => ({
1223
+ const projection = yield* Effect.suspend(() => descriptor.reportCompletion?.(report) === false ? Effect.succeed(void 0) : descriptor.prepare(report)).pipe(Effect.timeout(Math.min(deps.limits.reportPreparationTimeoutMillis ?? 5e3, deadlineAtMillis - now)), Effect.map((value) => ({
1163
1224
  _tag: "Prepared",
1164
1225
  value
1165
1226
  })), Effect.catchTag("WorkerReportPreparationFailure", (error) => Effect.succeed(refused(error.stage))), Effect.catchTag("TimeoutError", () => Effect.succeed(refused("timeout"))), Effect.catchCauseIf((cause) => !Cause.hasInterrupts(cause), () => Effect.succeed(refused("defect"))));
1166
1227
  if (projection._tag === "WorkerReportRefused") return projection;
1228
+ if (projection.value === void 0) return refused("filtered");
1167
1229
  const message = projection.value.message;
1168
1230
  if (!Schema.is(WorkerCompletion)(message)) return refused("input");
1169
1231
  if (!Schema.toEquivalence(WorkerRef)(message.report.worker, origin.worker) || !Schema.toEquivalence(Receipt)(message.report.receipt, report.observation.receipt) || message.report.runId !== runId || message.report.settlementId !== host.settlementId || message.report.outcome !== host.outcome || message.budgetExhausted !== report.observation.budgetExhausted) return refused("input");
@@ -1284,17 +1346,18 @@ const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
1284
1346
  return yield* failure("inspect", "storage");
1285
1347
  });
1286
1348
  const facet = (context, principal, sourceSubmissionId) => {
1287
- const authorize = (operation, access, worker) => deps.authorizer.authorize({
1349
+ const authorize = (operation, access, worker, continuationOf) => deps.authorizer.authorize({
1288
1350
  sourceThreadId: context.source.threadId,
1289
1351
  ...sourceSubmissionId === void 0 ? {} : { sourceSubmissionId },
1290
1352
  principal,
1291
1353
  operation,
1292
1354
  access,
1293
- ...worker === void 0 ? {} : { worker }
1355
+ ...worker === void 0 ? {} : { worker },
1356
+ ...continuationOf === void 0 ? {} : { continuationOf }
1294
1357
  });
1295
1358
  const binding = (target, operation) => resolveDefinitionBinding(deps.bindings, target).pipe(Effect.mapError((cause) => failure(operation, "declaration-unavailable", cause)));
1296
1359
  const deliveryStatus = (row, operation) => messageStatus(row).pipe(Effect.mapError((cause) => failure(operation, "corrupt", cause)));
1297
- const preparedTarget = Effect.fn("WorkerHost.preparedTarget")(function* (target, encodedInput) {
1360
+ const preparedTarget = Effect.fn("WorkerHost.preparedTarget")(function* (target, encodedInput, continuationOf) {
1298
1361
  const resolved = yield* binding(target, "start");
1299
1362
  yield* Schema.decodeUnknownEffect(Schema.toEncoded(target.input))(encodedInput).pipe(Effect.mapError((cause) => failure("start", "corrupt", cause)));
1300
1363
  const input = yield* decode(PersistedJson, encodedInput, "start");
@@ -1305,6 +1368,7 @@ const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
1305
1368
  source,
1306
1369
  policy: yield* resolveTargetPolicy({
1307
1370
  _tag: "InitialInput",
1371
+ ...continuationOf === void 0 ? {} : { continuationOf },
1308
1372
  definition: resolved.definition,
1309
1373
  definitions: resolved.digests,
1310
1374
  source: context.source,
@@ -1539,11 +1603,13 @@ const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
1539
1603
  };
1540
1604
  }),
1541
1605
  resolveTargetPolicy: Effect.fn("WorkerHost.resolvePreparedTargetPolicy")(function* (request) {
1542
- yield* authorize("start", "send");
1543
- return (yield* preparedTarget(request.target, request.encodedInput)).policy;
1606
+ const previous = request.continuationOf === void 0 ? void 0 : yield* completedContinuation(context.source, request.continuationOf, request.target.id, request.continuationOf.delegationId);
1607
+ yield* authorize("start", "send", void 0, previous?.evidence);
1608
+ return (yield* preparedTarget(request.target, request.encodedInput, previous?.evidence)).policy;
1544
1609
  }),
1545
1610
  start: Effect.fn("WorkerHost.start")(function* (command) {
1546
- const principal = yield* authorize("start", "send");
1611
+ const previous = command.continuationOf === void 0 ? void 0 : yield* completedContinuation(context.source, command.continuationOf, command.target.id, command.delegationId);
1612
+ const principal = yield* authorize("start", "send", void 0, previous?.evidence);
1547
1613
  if (context.depth !== 0 && sourceSubmissionId === void 0) return yield* failure("start", "denied");
1548
1614
  const grant = yield* Schema.decodeUnknownEffect(SubagentGrant)(command.encodedGrant).pipe(Effect.mapError((cause) => failure("start", "corrupt", cause)));
1549
1615
  const parameters = yield* decode(PersistedJson, command.encodedParameters, "start");
@@ -1559,12 +1625,14 @@ const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
1559
1625
  messageId
1560
1626
  }).pipe(Effect.mapError(storageFailure("start")));
1561
1627
  const replay = (saved) => Effect.gen(function* () {
1562
- const replayPrincipal = yield* authorize("start", "send");
1628
+ const currentPrevious = command.continuationOf === void 0 ? void 0 : yield* completedContinuation(context.source, command.continuationOf, command.target.id, command.delegationId, previous?.evidence);
1629
+ const replayPrincipal = yield* authorize("start", "send", void 0, currentPrevious?.evidence);
1563
1630
  yield* binding(command.target, "start");
1564
1631
  const metadata = saved.envelope.workerAdmission;
1565
1632
  if (metadata === void 0) return yield* failure("start", "idempotency-conflict");
1566
1633
  const origin = metadata.origin;
1567
- if (origin.firstMessageId !== messageId || metadata.messageId !== messageId || origin.source.threadId !== context.source.threadId || origin.worker.delegationId !== command.delegationId || origin.worker.targetAgentId !== command.target.id || !sameJson(metadata.parameters, parameters) || !Schema.toEquivalence(SubagentGrant)(origin.grant, grant) || origin.budgetScope !== command.budgetScope || origin.depth !== context.depth + 1 || !("prepare" in command) && (!samePolicy(origin.policy, command.policy) || !Schema.toEquivalence(WorkerOrigin.fields.budget)(origin.budget, command.budget) || origin.toolCallAllowance !== command.toolCallAllowance)) return yield* failure("start", "idempotency-conflict");
1634
+ if (!Schema.toEquivalence(Schema.UndefinedOr(WorkerContinuation))(origin.continuationOf, currentPrevious?.evidence) || origin.firstMessageId !== messageId || metadata.messageId !== messageId || origin.source.threadId !== context.source.threadId || origin.worker.delegationId !== command.delegationId || origin.worker.targetAgentId !== command.target.id || !sameJson(metadata.parameters, parameters) || !Schema.toEquivalence(SubagentGrant)(origin.grant, grant) || origin.budgetScope !== command.budgetScope || origin.depth !== context.depth + 1 || !("prepare" in command) && (!samePolicy(origin.policy, command.policy) || !Schema.toEquivalence(WorkerOrigin.fields.budget)(origin.budget, command.budget) || origin.toolCallAllowance !== command.toolCallAllowance)) return yield* failure("start", "idempotency-conflict");
1635
+ yield* verifyContinuation(origin);
1568
1636
  return {
1569
1637
  worker: origin.worker,
1570
1638
  delivery: yield* send(origin, messageId, "prepare" in command ? saved.envelope.input : command.encodedInput, parameters, replayPrincipal, "start")
@@ -1577,7 +1645,11 @@ const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
1577
1645
  ...yield* command.prepare,
1578
1646
  ...command
1579
1647
  } : command;
1580
- const prepared = yield* preparedTarget(request.target, request.encodedInput);
1648
+ const currentPrevious = command.continuationOf === void 0 ? void 0 : yield* completedContinuation(context.source, command.continuationOf, command.target.id, command.delegationId, previous?.evidence);
1649
+ if (currentPrevious !== void 0) {
1650
+ if ((yield* authorize("start", "send", void 0, currentPrevious.evidence)) !== principal) return yield* failure("start", "denied");
1651
+ }
1652
+ const prepared = yield* preparedTarget(request.target, request.encodedInput, currentPrevious?.evidence);
1581
1653
  const resolved = prepared.resolved;
1582
1654
  const sourcePolicy = Option.getOrElse(prepared.source.policyOverride, () => context.policy);
1583
1655
  const now = yield* Clock.currentTimeMillis;
@@ -1593,6 +1665,7 @@ const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
1593
1665
  threadId: Schema.decodeSync(ThreadId)(messageId)
1594
1666
  },
1595
1667
  source: context.source,
1668
+ ...currentPrevious === void 0 ? {} : { continuationOf: currentPrevious.evidence },
1596
1669
  ...resolved.definition.runDisposition?.workerLifecycle === "assignment" ? { lifecycle: "assignment" } : {},
1597
1670
  targetDigests: resolved.digests,
1598
1671
  policy: request.policy,
@@ -1602,7 +1675,7 @@ const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
1602
1675
  depth: context.depth + 1,
1603
1676
  firstMessageId: messageId,
1604
1677
  createdAtMillis: now,
1605
- expiresAtMillis: now + deps.limits.lifetimeMillis,
1678
+ expiresAtMillis: Math.min(now + deps.limits.lifetimeMillis, currentPrevious?.origin.expiresAtMillis ?? Infinity),
1606
1679
  ...reporting === void 0 ? {} : { reporting },
1607
1680
  ...request.toolCallAllowance === void 0 ? {} : { toolCallAllowance: request.toolCallAllowance }
1608
1681
  }, "start");
@@ -1816,7 +1889,7 @@ const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
1816
1889
  ...sourceSubmissionId === void 0 ? {} : { sourceSubmissionId },
1817
1890
  principal: options.principal,
1818
1891
  operation: "followUp",
1819
- access: "send",
1892
+ access: "report",
1820
1893
  worker: receiving?.origin.worker ?? origin.worker
1821
1894
  })) !== options.principal) return yield* failure("followUp", "denied");
1822
1895
  return message;
@@ -7059,4 +7132,4 @@ var DurableAgentRuntime = class DurableAgentRuntime extends Context.Service()("@
7059
7132
  //#endregion
7060
7133
  export { DurableApprovalSuspension as a, RecoveryFailure as c, childReservationIdFor as d, isolateRecovery as f, threadCreatedRecordId as g, threadCreatedBatchId as h, DurableApprovalResolver as i, RecoveryReport as l, recoveryRepairRecordId as m, DurableAgentRuntime as n, DurableRuntimeConfig as o, recoveryRepairBatchId as p, DurableAgentRuntime_exports as r, RecoveryBlocked as s, ApprovalSuspensionError as t, RecoverySweepResult as u };
7061
7134
 
7062
- //# sourceMappingURL=DurableAgentRuntime-BvDGe7F9.mjs.map
7135
+ //# sourceMappingURL=DurableAgentRuntime-BydyN_n-.mjs.map