effect-agent 0.1.0-beta.144 → 0.1.0-beta.148

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 (81) hide show
  1. package/dist/{Admin-CQMppCcy.d.mts → Admin-BzPfXvzC.d.mts} +37 -22
  2. package/dist/Agent-1DMSO_Fl.mjs.map +1 -1
  3. package/dist/{Agent-BWhD4Dvu.d.mts → Agent-Cjd_ZveM.d.mts} +7 -3
  4. package/dist/{AgentRuntime-xeCUXutN.mjs → AgentRuntime-D8U9gl9Q.mjs} +23 -18
  5. package/dist/AgentRuntime-D8U9gl9Q.mjs.map +1 -0
  6. package/dist/{AgentRuntime-B4kIzmSF.d.mts → AgentRuntime-DZdgNcBk.d.mts} +5 -5
  7. package/dist/{DurableAgentRuntime-D8GI66mP.mjs → DurableAgentRuntime-N5Meflyt.mjs} +70 -42
  8. package/dist/DurableAgentRuntime-N5Meflyt.mjs.map +1 -0
  9. package/dist/{EventSource-w9PonN9X.d.mts → EventSource-DJW_1kPY.d.mts} +2 -2
  10. package/dist/{Messaging-Dnmk31yq.d.mts → Messaging-ccQURKCf.d.mts} +3 -3
  11. package/dist/{MessagingHost-CajpPDPG.d.mts → MessagingHost-D04wE-7W.d.mts} +2 -2
  12. package/dist/{Output-DhtWbBcw.d.mts → Output-CFD1CPfU.d.mts} +2 -2
  13. package/dist/{PreparedInputAdmission-BfcLy_k4.d.mts → PreparedInputAdmission-CNRSDoYu.d.mts} +3 -3
  14. package/dist/{RunOptions-IlEXLG5F.d.mts → RunOptions-Cy7CjrjS.d.mts} +2 -2
  15. package/dist/{Subagent-8RzJkqJ9.mjs → Subagent-hG9lJ7tJ.mjs} +2 -2
  16. package/dist/{Subagent-8RzJkqJ9.mjs.map → Subagent-hG9lJ7tJ.mjs.map} +1 -1
  17. package/dist/{Subagent-Cl8D1mFM.d.mts → Subagent-zS6prSK6.d.mts} +5 -5
  18. package/dist/{SubagentHost-B6f4PBC2.d.mts → SubagentHost-C-4A7tA2.d.mts} +2 -2
  19. package/dist/{Subscription-ClkC4_T0.d.mts → Subscription-C279AjM6.d.mts} +2 -2
  20. package/dist/{SubscriptionInput-CMjEKL1z.d.mts → SubscriptionInput-7R-Xrpxd.d.mts} +2 -2
  21. package/dist/capabilities/Commands.d.mts +1 -1
  22. package/dist/capabilities/Messaging.d.mts +1 -1
  23. package/dist/capabilities/RunHooks.d.mts +1 -1
  24. package/dist/capabilities/Subagent.d.mts +1 -1
  25. package/dist/capabilities/Subagent.mjs +1 -1
  26. package/dist/core/Agent.d.mts +1 -1
  27. package/dist/durable/Admin.d.mts +1 -1
  28. package/dist/durable/AgentRegistration.d.mts +1 -1
  29. package/dist/durable/Certification.d.mts +1 -1
  30. package/dist/durable/CommittedActivity.d.mts +1 -1
  31. package/dist/durable/DurableAgentRuntime.d.mts +1 -1
  32. package/dist/durable/DurableAgentRuntime.mjs +1 -1
  33. package/dist/durable/EventSource.d.mts +1 -1
  34. package/dist/durable/GitHubWorkflowSource.d.mts +3 -3
  35. package/dist/durable/LifecyclePublication.d.mts +2 -2
  36. package/dist/durable/LifecyclePublication.mjs +32 -12
  37. package/dist/durable/LifecyclePublication.mjs.map +1 -1
  38. package/dist/durable/MessageDelivery.d.mts +41 -41
  39. package/dist/durable/MessageDeliveryStoreConformance.d.mts +39 -39
  40. package/dist/durable/PersistentHistory.d.mts +1 -1
  41. package/dist/durable/PreparedInputAdmission.d.mts +1 -1
  42. package/dist/durable/Recovery.d.mts +1 -1
  43. package/dist/durable/RunJournal.d.mts +1 -1
  44. package/dist/durable/Scheduling.d.mts +1 -1
  45. package/dist/durable/SubmissionLedger.d.mts +1 -1
  46. package/dist/durable/SubmissionLedgerConformance.d.mts +1 -1
  47. package/dist/durable/SubmissionStatus.d.mts +1 -1
  48. package/dist/durable/Subscription.d.mts +1 -1
  49. package/dist/durable/SubscriptionInput.d.mts +1 -1
  50. package/dist/durable/SubscriptionStoreConformance.d.mts +1 -1
  51. package/dist/durable/SubscriptionTools.d.mts +2 -2
  52. package/dist/durable/SubscriptionTransition.d.mts +1 -1
  53. package/dist/durable/Subscriptions.d.mts +5 -5
  54. package/dist/durable/ThreadContextHistory.d.mts +1 -1
  55. package/dist/durable/ThreadInvariants.d.mts +1 -1
  56. package/dist/durable/ThreadProjectionMaintenance.d.mts +1 -1
  57. package/dist/durable/ThreadStore.d.mts +1 -1
  58. package/dist/durable/ThreadStoreConformance.d.mts +1 -1
  59. package/dist/durable/WorkerHost.d.mts +25 -5
  60. package/dist/durable/WorkerHost.mjs.map +1 -1
  61. package/dist/engine/AgentRuntime.d.mts +1 -1
  62. package/dist/engine/AgentRuntime.mjs +1 -1
  63. package/dist/engine/MessagingHost.d.mts +1 -1
  64. package/dist/engine/Output.d.mts +1 -1
  65. package/dist/engine/Output.mjs +1 -1
  66. package/dist/engine/RunOptions.d.mts +1 -1
  67. package/dist/engine/SubagentHost.d.mts +1 -1
  68. package/dist/index.d.mts +13 -13
  69. package/dist/index.mjs +3 -3
  70. package/dist/{output-contract-CANJJGA5.mjs → output-contract-DS-S8mTv.mjs} +46 -10
  71. package/dist/{output-contract-CANJJGA5.mjs.map → output-contract-DS-S8mTv.mjs.map} +1 -1
  72. package/package.json +1 -1
  73. package/src/core/Agent.ts +6 -2
  74. package/src/durable/DurableAgentRuntime.ts +50 -58
  75. package/src/durable/LifecyclePublication.ts +79 -25
  76. package/src/durable/WorkerHost.ts +23 -1
  77. package/src/durable/internal/worker-host.ts +169 -17
  78. package/src/engine/internal/agent-runtime.ts +80 -18
  79. package/src/engine/internal/output-contract.ts +67 -8
  80. package/dist/AgentRuntime-xeCUXutN.mjs.map +0 -1
  81. package/dist/DurableAgentRuntime-D8GI66mP.mjs.map +0 -1
@@ -8,14 +8,14 @@ import { n as CurrentToolCatalog } from "./ToolExposure-UCN12eCd.mjs";
8
8
  import { s as ToolBroker } from "./ToolBroker-DWs4tZra.mjs";
9
9
  import { a as AgentInputError, c as AgentPolicyError, d as AgentToolAuthorizationDenied, f as ContextBudgetError, m as ModelProtocolError, n as AgentApprovalPending, p as ContextOverflowError, s as AgentOutputError, t as AgentApprovalDenied, u as AgentToolAuthorizationCheckError } from "./AgentError-Bn1ytXRD.mjs";
10
10
  import { t as AgentPolicy } from "./AgentPolicy-BqDoSXO6.mjs";
11
- import { A as ToolUnion, C as OutputSchema, D as RunDispositionFailure, E as RunDispositionDeclaration, N as UpdatesSchema, O as RunDispositionSchema, S as Output, _ as InstructionSource, a as CompletionFromToolDeclaration, c as Definition, d as EncodedInput, f as Failure, m as InputPromptSource, n as Any, r as AnyDefinition, s as CompletionToolDeclaration, t as Agent_d_exports, w as Requirements } from "./Agent-BWhD4Dvu.mjs";
11
+ import { A as ToolUnion, C as OutputSchema, D as RunDispositionFailure, E as RunDispositionDeclaration, N as UpdatesSchema, O as RunDispositionSchema, S as Output, _ as InstructionSource, a as CompletionFromToolDeclaration, c as Definition, d as EncodedInput, f as Failure, m as InputPromptSource, n as Any, r as AnyDefinition, s as CompletionToolDeclaration, t as Agent_d_exports, w as Requirements } from "./Agent-Cjd_ZveM.mjs";
12
12
  import { a as WorkerBudgetScope } from "./Worker-fwWkBg12.mjs";
13
13
  import { a as ContextWindow } from "./ContextWindow-DRQ5Mbm2.mjs";
14
14
  import { n as CompactionError } from "./ContextCompactor-WwSIG_Z2.mjs";
15
15
  import { t as DurableStep } from "./DurableStep-Cry_iol4.mjs";
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-IlEXLG5F.mjs";
17
- import { t as MessagingHost } from "./MessagingHost-CajpPDPG.mjs";
18
- import { o as SubagentHost } from "./SubagentHost-B6f4PBC2.mjs";
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-Cy7CjrjS.mjs";
17
+ import { t as MessagingHost } from "./MessagingHost-D04wE-7W.mjs";
18
+ import { o as SubagentHost } from "./SubagentHost-C-4A7tA2.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-B4kIzmSF.d.mts.map
346
+ //# sourceMappingURL=AgentRuntime-DZdgNcBk.d.mts.map
@@ -15,7 +15,7 @@ import { a as PeerMessageCapacity, d as MessageAdmission, f as MessagingError, i
15
15
  import { SubagentHost } from "./engine/SubagentHost.mjs";
16
16
  import { ThreadHistory } from "./engine/ThreadHistory.mjs";
17
17
  import { n as RunToolVisibility } from "./ToolExposure-9uF_Yo0T.mjs";
18
- import { f as renderInputPrompt, n as AgentChildPending, y as streamWithUsageAccountingUnknown } from "./AgentRuntime-xeCUXutN.mjs";
18
+ import { f as renderInputPrompt, n as AgentChildPending, y as streamWithUsageAccountingUnknown } from "./AgentRuntime-D8U9gl9Q.mjs";
19
19
  import { ContextRolloverTool } from "./engine/ContextWindow.mjs";
20
20
  import { getToolExecutionClass } from "./engine/DurableStep.mjs";
21
21
  import { CompactionError, ContextCompactor } from "./engine/ContextCompactor.mjs";
@@ -634,6 +634,8 @@ const withinPolicy = (origin, source, target) => {
634
634
  };
635
635
  /** Admission and cancellation enter the owning runtime, never the raw ledger. */
636
636
  var WorkerInputControl = class extends Context.Service()("@effect-agent/thread/internal/WorkerInputControl") {};
637
+ const CurrentStartPreparation = Context.Reference("@effect-agent/thread/internal/CurrentStartPreparation", { defaultValue: () => void 0 });
638
+ const CurrentStartDelivery = Context.Reference("@effect-agent/thread/internal/CurrentStartDelivery", { defaultValue: () => void 0 });
637
639
  /** No in-memory ownership: every mutation is reserved in source canonical history with CAS. */
638
640
  const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
639
641
  const control = yield* WorkerInputControl;
@@ -654,11 +656,17 @@ const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
654
656
  status: Option.getOrUndefined(admission)?.submissionStatus ?? control.status
655
657
  };
656
658
  const withCrypto = (effect) => Effect.provideService(effect, Crypto.Crypto, deps.crypto);
657
- const authorizeBudget = Effect.fn("WorkerHost.authorizeBudget")(function* (origin, principal) {
659
+ const currentStart = Effect.fnUntraced(function* (admission, sourceThreadId, sourceSubmissionId, principal, targetAgentId, continuationOf) {
660
+ if (admission === void 0 || admission.sourceThreadId !== sourceThreadId || admission.sourceSubmissionId !== sourceSubmissionId || admission.principal !== principal && admission.requestedPrincipal !== principal || admission.targetAgentId !== targetAgentId || !Schema.toEquivalence(Schema.UndefinedOr(WorkerContinuation))(admission.continuationOf, continuationOf)) return void 0;
661
+ const tail = yield* deps.store.inspectTail(ThreadTailRequest.make({ threadId: sourceThreadId })).pipe(Effect.mapError(storageFailure("start")));
662
+ return tail.tailSequence === admission.tailSequence && tail.tailDigest === admission.tailDigest ? admission : void 0;
663
+ });
664
+ const authorizeBudget = Effect.fn("WorkerHost.authorizeBudget")(function* (origin, principal, admission) {
658
665
  yield* verifyContinuation(origin);
659
666
  if (origin.budgetScope !== "worker-run") return;
660
667
  if (origin.depth !== 1) return yield* failure("start", "denied");
661
668
  yield* deps.budgetAuthorizer.authorize({
669
+ ...admission === void 0 ? {} : { admission },
662
670
  source: origin.source,
663
671
  principal,
664
672
  worker: origin.worker,
@@ -946,7 +954,7 @@ const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
946
954
  }
947
955
  return yield* failure("start", "storage");
948
956
  });
949
- const reservation = Effect.fn("WorkerHost.reserveInput")(function* (admission, inputDigest, input, principal, retainedFrameworkInput) {
957
+ const reservation = Effect.fn("WorkerHost.reserveInput")(function* (admission, inputDigest, input, principal, retainedFrameworkInput, authorization) {
950
958
  const origin = admission.origin;
951
959
  yield* verifyContinuation(origin);
952
960
  const id = workerInputRecordId(admission.messageId);
@@ -980,6 +988,7 @@ const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
980
988
  const selected = yield* resolveTargetPolicy(admission.messageId === origin.firstMessageId ? {
981
989
  ...targetRequest,
982
990
  _tag: "InitialInput",
991
+ ...authorization === void 0 || authorization.tailSequence !== current.tailSequence || authorization.tailDigest !== current.tailDigest ? {} : { admission: authorization },
983
992
  ...origin.continuationOf === void 0 ? {} : { continuationOf: origin.continuationOf },
984
993
  input,
985
994
  inputDigest,
@@ -1061,7 +1070,10 @@ const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
1061
1070
  yield* validateCompletion(options.messageAdmission, options, agentId, inputDigest);
1062
1071
  }
1063
1072
  yield* verifyContinuation(admission.origin);
1073
+ const delivery = yield* CurrentStartDelivery;
1074
+ const authorization = delivery !== void 0 && sameAdmission(delivery.admission, admission) && delivery.inputDigest === inputDigest ? yield* currentStart(delivery.authorization, admission.origin.source.threadId, admission.sourceSubmissionId, options.principal, agentId, admission.origin.continuationOf) : void 0;
1064
1075
  yield* deps.authorizer.authorize({
1076
+ ...authorization === void 0 ? {} : { admission: authorization },
1065
1077
  sourceThreadId: admission.origin.source.threadId,
1066
1078
  ...admission.sourceSubmissionId === void 0 ? {} : { sourceSubmissionId: admission.sourceSubmissionId },
1067
1079
  principal: options.principal,
@@ -1070,11 +1082,11 @@ const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
1070
1082
  worker: admission.origin.worker,
1071
1083
  ...admission.origin.continuationOf === void 0 ? {} : { continuationOf: admission.origin.continuationOf }
1072
1084
  });
1073
- yield* authorizeBudget(admission.origin, options.principal);
1085
+ yield* authorizeBudget(admission.origin, options.principal, authorization);
1074
1086
  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");
1075
1087
  const retainedFrameworkInput = Schema.is(FrameworkMessage)(options.messageAdmission);
1076
1088
  if (retainedFrameworkInput && admission.reportKind !== "update") yield* validateCompletion(options.messageAdmission, options, agentId, inputDigest);
1077
- yield* reservation(admission, inputDigest, input, options.principal, retainedFrameworkInput);
1089
+ yield* reservation(admission, inputDigest, input, options.principal, retainedFrameworkInput, authorization);
1078
1090
  return admission;
1079
1091
  });
1080
1092
  const prepareUpdate = Effect.fn("WorkerHost.prepareUpdate")(function* (update, submission, messageId) {
@@ -1338,7 +1350,9 @@ const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
1338
1350
  return yield* failure("inspect", "storage");
1339
1351
  });
1340
1352
  const facet = (context, principal, sourceSubmissionId) => {
1341
- const authorize = (operation, access, worker, continuationOf) => deps.authorizer.authorize({
1353
+ const requestedPrincipal = principal;
1354
+ const authorize = (operation, access, worker, continuationOf, admission) => deps.authorizer.authorize({
1355
+ ...admission === void 0 ? {} : { admission },
1342
1356
  sourceThreadId: context.source.threadId,
1343
1357
  ...sourceSubmissionId === void 0 ? {} : { sourceSubmissionId },
1344
1358
  principal,
@@ -1349,17 +1363,19 @@ const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
1349
1363
  });
1350
1364
  const binding = (target, operation) => resolveDefinitionBinding(deps.bindings, target).pipe(Effect.mapError((cause) => failure(operation, "declaration-unavailable", cause)));
1351
1365
  const deliveryStatus = (row, operation) => messageStatus(row).pipe(Effect.mapError((cause) => failure(operation, "corrupt", cause)));
1352
- const preparedTarget = Effect.fn("WorkerHost.preparedTarget")(function* (target, encodedInput, continuationOf) {
1366
+ const preparedTarget = Effect.fn("WorkerHost.preparedTarget")(function* (target, encodedInput, continuationOf, authorization) {
1353
1367
  const resolved = yield* binding(target, "start");
1354
1368
  yield* Schema.decodeUnknownEffect(Schema.toEncoded(target.input))(encodedInput).pipe(Effect.mapError((cause) => failure("start", "corrupt", cause)));
1355
1369
  const input = yield* decode(PersistedJson, encodedInput, "start");
1356
1370
  const inputDigest = yield* withCrypto(digestJson(input)).pipe(Effect.mapError(storageFailure("start")));
1357
1371
  const source = yield* sourceAuthority(context.source.threadId, sourceSubmissionId);
1372
+ const admission = yield* currentStart(authorization, context.source.threadId, sourceSubmissionId, principal, target.id, continuationOf);
1358
1373
  return {
1359
1374
  resolved,
1360
1375
  source,
1361
1376
  policy: yield* resolveTargetPolicy({
1362
1377
  _tag: "InitialInput",
1378
+ ...admission === void 0 ? {} : { admission },
1363
1379
  ...continuationOf === void 0 ? {} : { continuationOf },
1364
1380
  definition: resolved.definition,
1365
1381
  definitions: resolved.digests,
@@ -1420,7 +1436,7 @@ const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
1420
1436
  budgetExhausted: result.finishReason === "budget-exhausted"
1421
1437
  };
1422
1438
  });
1423
- const send = Effect.fn("WorkerHost.send")(function* (origin, messageId, encodedInput, encodedParameters, principal, operation) {
1439
+ const send = Effect.fn("WorkerHost.send")(function* (origin, messageId, encodedInput, encodedParameters, principal, operation, authorization) {
1424
1440
  if (Option.isNone(deps.deliveries)) return yield* failure(operation, "unavailable");
1425
1441
  const deliveries = deps.deliveries.value;
1426
1442
  const input = yield* decode(PersistedJson, encodedInput, operation);
@@ -1472,7 +1488,11 @@ const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
1472
1488
  batchSize: 1,
1473
1489
  concurrency: 1
1474
1490
  })), Effect.provideService(MessageDeliveryStore, deliveries), Effect.provideService(PreparedInputAdmission, {
1475
- submit: (prepared) => deps.submit(prepared).pipe(Effect.mapError((error) => error._tag === "AdmissionConflict" || error._tag === "AgentInputError" ? ScheduledInputRefused.make({
1491
+ submit: (prepared) => deps.submit(prepared).pipe(Effect.provideService(CurrentStartDelivery, authorization !== void 0 && prepared.workerAdmission !== void 0 && prepared.admissionKey === messageId && prepared.inputDigest === inputDigest && sameOrigin(prepared.workerAdmission.origin, origin) ? {
1492
+ authorization,
1493
+ admission: prepared.workerAdmission,
1494
+ inputDigest
1495
+ } : void 0), Effect.mapError((error) => error._tag === "AdmissionConflict" || error._tag === "AgentInputError" ? ScheduledInputRefused.make({
1476
1496
  code: error._tag,
1477
1497
  cause: error
1478
1498
  }) : error._tag === "AdmissionPolicyError" && error.reason === "refused" ? ScheduledInputRefused.make({
@@ -1596,12 +1616,25 @@ const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
1596
1616
  }),
1597
1617
  resolveTargetPolicy: Effect.fn("WorkerHost.resolvePreparedTargetPolicy")(function* (request) {
1598
1618
  const previous = request.continuationOf === void 0 ? void 0 : yield* completedContinuation(context.source, request.continuationOf, request.target.id, request.continuationOf.delegationId);
1599
- yield* authorize("start", "send", void 0, previous?.evidence);
1600
- return (yield* preparedTarget(request.target, request.encodedInput, previous?.evidence)).policy;
1619
+ const admission = yield* currentStart(yield* CurrentStartPreparation, context.source.threadId, sourceSubmissionId, principal, request.target.id, previous?.evidence);
1620
+ yield* authorize("start", "send", void 0, previous?.evidence, admission);
1621
+ return (yield* preparedTarget(request.target, request.encodedInput, previous?.evidence, admission)).policy;
1601
1622
  }),
1602
1623
  start: Effect.fn("WorkerHost.start")(function* (command) {
1603
1624
  const previous = command.continuationOf === void 0 ? void 0 : yield* completedContinuation(context.source, command.continuationOf, command.target.id, command.delegationId);
1625
+ const tail = yield* deps.store.inspectTail(ThreadTailRequest.make({ threadId: context.source.threadId })).pipe(Effect.mapError(storageFailure("start")));
1604
1626
  const principal = yield* authorize("start", "send", void 0, previous?.evidence);
1627
+ const startAdmission = {
1628
+ sourceThreadId: context.source.threadId,
1629
+ ...sourceSubmissionId === void 0 ? {} : { sourceSubmissionId },
1630
+ requestedPrincipal,
1631
+ principal,
1632
+ targetAgentId: command.target.id,
1633
+ ...previous === void 0 ? {} : { continuationOf: previous.evidence },
1634
+ access: "send",
1635
+ tailSequence: tail.tailSequence,
1636
+ tailDigest: tail.tailDigest
1637
+ };
1605
1638
  if (context.depth !== 0 && sourceSubmissionId === void 0) return yield* failure("start", "denied");
1606
1639
  const grant = yield* Schema.decodeUnknownEffect(SubagentGrant)(command.encodedGrant).pipe(Effect.mapError((cause) => failure("start", "corrupt", cause)));
1607
1640
  const parameters = yield* decode(PersistedJson, command.encodedParameters, "start");
@@ -1634,14 +1667,14 @@ const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
1634
1667
  if (existing !== null) return yield* replay(existing);
1635
1668
  return yield* Effect.gen(function* () {
1636
1669
  const request = "prepare" in command ? {
1637
- ...yield* command.prepare,
1670
+ ...yield* command.prepare.pipe(Effect.provideService(CurrentStartPreparation, startAdmission)),
1638
1671
  ...command
1639
1672
  } : command;
1640
1673
  const currentPrevious = command.continuationOf === void 0 ? void 0 : yield* completedContinuation(context.source, command.continuationOf, command.target.id, command.delegationId, previous?.evidence);
1641
1674
  if (currentPrevious !== void 0) {
1642
1675
  if ((yield* authorize("start", "send", void 0, currentPrevious.evidence)) !== principal) return yield* failure("start", "denied");
1643
1676
  }
1644
- const prepared = yield* preparedTarget(request.target, request.encodedInput, currentPrevious?.evidence);
1677
+ const prepared = yield* preparedTarget(request.target, request.encodedInput, currentPrevious?.evidence, startAdmission);
1645
1678
  const resolved = prepared.resolved;
1646
1679
  const sourcePolicy = Option.getOrElse(prepared.source.policyOverride, () => context.policy);
1647
1680
  const now = yield* Clock.currentTimeMillis;
@@ -1671,10 +1704,10 @@ const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (options) {
1671
1704
  ...reporting === void 0 ? {} : { reporting },
1672
1705
  ...request.toolCallAllowance === void 0 ? {} : { toolCallAllowance: request.toolCallAllowance }
1673
1706
  }, "start");
1674
- yield* authorizeBudget(origin, principal);
1707
+ yield* authorizeBudget(origin, principal, yield* currentStart(startAdmission, context.source.threadId, sourceSubmissionId, principal, request.target.id, currentPrevious?.evidence));
1675
1708
  const targetPolicy = Option.isSome(prepared.policy) ? prepared.policy.value : origin.budgetScope === "worker-run" ? resolved.definition.policy : AgentPolicy.resolve(resolved.definition.policyOverrides ?? resolved.definition.policy, sourcePolicy);
1676
1709
  if (!withinPolicy(origin, origin.budgetScope === "worker-run" ? targetPolicy : sourcePolicy, targetPolicy)) return yield* failure("start", "capacity");
1677
- const delivery = yield* send(origin, messageId, request.encodedInput, request.encodedParameters, principal, "start");
1710
+ const delivery = yield* send(origin, messageId, request.encodedInput, request.encodedParameters, principal, "start", startAdmission);
1678
1711
  return {
1679
1712
  worker: origin.worker,
1680
1713
  delivery
@@ -2338,11 +2371,6 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (bindings) {
2338
2371
  const ledger = yield* SubmissionLedger;
2339
2372
  const submissionScheduling = yield* SubmissionScheduling;
2340
2373
  const store = yield* ThreadStore;
2341
- const publicationPending = (threadId) => store.lifecyclePublications === void 0 ? Effect.succeed(false) : store.lifecyclePublications.pendingDeadlineFor(threadId).pipe(Effect.map(Option.isSome), Effect.mapError((cause) => ThreadStoreError.make({
2342
- operation: "read lifecycle publication gate",
2343
- message: "Native lifecycle publication state is unavailable",
2344
- cause
2345
- })));
2346
2374
  const wake = yield* WakeScheduler;
2347
2375
  const failpoint = yield* DurableRuntimeFailpoint;
2348
2376
  const config = yield* DurableRuntimeConfig;
@@ -4103,7 +4131,6 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (bindings) {
4103
4131
  */
4104
4132
  const runModel = (agent, ctx, submission, tokenRef, records, canonical, canonicalThrough, journalSeed, journalMetadata, lineage, approvalDecisions, runTiming, yieldAfter) => Effect.gen(function* () {
4105
4133
  const submissionId = submission.submissionId;
4106
- if (yield* publicationPending(submission.threadId)) return { _tag: "yielded" };
4107
4134
  const runId = runIdForSubmission(submissionId);
4108
4135
  const boundaries = [];
4109
4136
  const journal = yield* projectRunJournalStream(canonical, runId, (boundary) => boundaries.push(boundary), journalSeed, journalMetadata);
@@ -4834,18 +4861,11 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (bindings) {
4834
4861
  const decodedInput = yield* Schema.decodeEffect(agent.definition.input)(encodedInput).pipe(Effect.mapError((cause) => AgentInputError.make({ message: cause.message })));
4835
4862
  return yield* renderInputPrompt(inputPrompt, decodedInput, encodedInput);
4836
4863
  });
4837
- const yieldForPublication = Effect.gen(function* () {
4838
- const pending = yield* Effect.exit(publicationPending(submission.threadId));
4839
- if (Exit.isSuccess(pending) && !pending.value) return;
4840
- yield* recordHalt(commitPendingTurn);
4841
- if (Exit.isFailure(pending)) return yield* recordHalt(Effect.failCause(pending.cause));
4842
- yield* Deferred.succeed(yieldSignal, void 0);
4843
- return yield* Effect.never;
4864
+ const preserveToolResults = Effect.gen(function* () {
4865
+ const state = yield* Ref.get(stateRef);
4866
+ if (state.pendingTurn !== void 0 && knownIds.has(modelResponseRecordId(runId, state.pendingTurn.turn))) yield* commitPendingTurn;
4844
4867
  });
4845
4868
  const input = { drain: (policy) => Effect.gen(function* () {
4846
- const state = yield* Ref.get(stateRef);
4847
- if (state.pendingTurn !== void 0 && knownIds.has(modelResponseRecordId(runId, state.pendingTurn.turn))) yield* recordHalt(commitPendingTurn);
4848
- yield* yieldForPublication;
4849
4869
  const joinedInputs = yield* recordHalt(Effect.gen(function* () {
4850
4870
  const limit = policy === "one" ? 1 : MAX_JOIN_DRAIN;
4851
4871
  const joinedInputs = [];
@@ -4870,6 +4890,7 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (bindings) {
4870
4890
  if (lastHostResponseSequence !== void 0 && lastHostResponseSequence > existing.sequence) continue;
4871
4891
  const payload = existing.record.payload;
4872
4892
  if (payload._tag !== "UserInputRecorded") continue;
4893
+ yield* preserveToolResults;
4873
4894
  joinedInputs.push(payload);
4874
4895
  }
4875
4896
  if (joinedInputs.length < limit) {
@@ -4887,6 +4908,16 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (bindings) {
4887
4908
  yield* ledger.revertJoining(RevertJoiningRequest.make({ submissionId: claim.submissionId }));
4888
4909
  continue;
4889
4910
  }
4911
+ const payload = {
4912
+ input: claim.inputPayload,
4913
+ ...claimSnapshot.submission.messageAdmission === void 0 ? {} : { messageAdmission: claimSnapshot.submission.messageAdmission }
4914
+ };
4915
+ const rendered = yield* Effect.result(renderJoinedInput(payload));
4916
+ if (Result.isFailure(rendered)) {
4917
+ for (const remaining of claims.slice(claims.indexOf(claim))) yield* ledger.revertJoining(RevertJoiningRequest.make({ submissionId: remaining.submissionId }));
4918
+ break;
4919
+ }
4920
+ yield* preserveToolResults;
4890
4921
  const recordId = submissionInputRecordId(claim.submissionId);
4891
4922
  let sequence;
4892
4923
  const existing = joinedInputEnvelopes.get(claim.submissionId);
@@ -4916,15 +4947,14 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (bindings) {
4916
4947
  }));
4917
4948
  deliveredJoinInputs.add(claim.submissionId);
4918
4949
  joinedInputs.push({
4919
- input: claim.inputPayload,
4920
- ...claimSnapshot.submission.messageAdmission === void 0 ? {} : { messageAdmission: claimSnapshot.submission.messageAdmission }
4950
+ ...payload,
4951
+ rendered: rendered.success
4921
4952
  });
4922
4953
  }
4923
4954
  }
4924
4955
  return joinedInputs;
4925
- }));
4926
- yield* yieldForPublication;
4927
- return yield* Effect.forEach(joinedInputs, (joinedInput) => renderJoinedInput(joinedInput).pipe(Effect.map((input) => ({
4956
+ }).pipe(Effect.onExit((exit) => Exit.isFailure(exit) ? preserveToolResults : Effect.void)));
4957
+ return yield* Effect.forEach(joinedInputs, (joinedInput) => (joinedInput.rendered === void 0 ? renderJoinedInput(joinedInput) : Effect.succeed(joinedInput.rendered)).pipe(Effect.map((input) => ({
4928
4958
  kind: "steering",
4929
4959
  input
4930
4960
  }))));
@@ -5216,7 +5246,7 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (bindings) {
5216
5246
  history: pending === void 0 ? journal.historyBefore : resumeProjection.historyBefore,
5217
5247
  onHistory,
5218
5248
  input,
5219
- commandDrainPolicy: submission.workerAdmission === void 0 ? "one" : "all",
5249
+ commandDrainPolicy: "all",
5220
5250
  ...journal.committedTurns > 0 || Schema.is(FrameworkMessage)(submission.messageAdmission) ? { retainedInput: submission.inputPayload } : {},
5221
5251
  ...Schema.is(FrameworkMessage)(submission.messageAdmission) ? { frameworkMessage: submission.messageAdmission } : {},
5222
5252
  approval,
@@ -5246,7 +5276,6 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (bindings) {
5246
5276
  ...preparedContext === void 0 ? {} : { context: preparedContext },
5247
5277
  beforeTurn: () => Effect.gen(function* () {
5248
5278
  yield* recordHalt(commitPendingTurn);
5249
- yield* yieldForPublication;
5250
5279
  if (yieldAfter !== void 0 && (yield* Clock.currentTimeMillis) >= DateTime.toEpochMillis(yieldAfter)) {
5251
5280
  yield* Deferred.succeed(yieldSignal, void 0);
5252
5281
  return yield* Effect.never;
@@ -5503,7 +5532,7 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (bindings) {
5503
5532
  const failure = yield* Ref.get(haltRef);
5504
5533
  if (failure !== void 0) return yield* Effect.fail(failure);
5505
5534
  yield* handleEvent(event);
5506
- }))).pipe(Effect.tapCause((cause) => Option.isSome(agentApprovalPendingOption(cause)) && cause.reasons.every(Cause.isFailReason) ? Effect.flatMap(DurableApprovalSuspension, (retain) => retain === void 0 ? Effect.void : halt(retain)) : Effect.void), Effect.as({ _tag: "run" }));
5535
+ }))).pipe(Effect.onExit((exit) => Exit.hasInterrupts(exit) ? preserveToolResults : Effect.void), Effect.tapCause((cause) => Option.isSome(agentApprovalPendingOption(cause)) && cause.reasons.every(Cause.isFailReason) ? Effect.flatMap(DurableApprovalSuspension, (retain) => retain === void 0 ? Effect.void : halt(retain)) : Effect.void), Effect.as({ _tag: "run" }));
5507
5536
  const abortWatcher = halt(Effect.gen(function* () {
5508
5537
  while (true) {
5509
5538
  yield* Effect.sleep(config.abortPollInterval);
@@ -5522,7 +5551,7 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (bindings) {
5522
5551
  yield* Ref.set(tokenRef, renewal.ownershipToken);
5523
5552
  }).pipe(Effect.uninterruptible), { schedule: Schedule.spaced(config.leaseRenewalInterval) }).pipe(Effect.andThen(Effect.never)));
5524
5553
  const execution = Effect.raceFirst(consume, Effect.raceFirst(abortWatcher, renewal));
5525
- const result = yield* (yieldAfter === void 0 && submissionScheduling.yieldTo === void 0 && store.lifecyclePublications === void 0 ? execution : Effect.raceFirst(execution, Deferred.await(yieldSignal).pipe(Effect.map((nextSubmissionId) => ({
5554
+ const result = yield* (yieldAfter === void 0 && submissionScheduling.yieldTo === void 0 ? execution : Effect.raceFirst(execution, Deferred.await(yieldSignal).pipe(Effect.map((nextSubmissionId) => ({
5526
5555
  _tag: "yielded",
5527
5556
  ...nextSubmissionId === void 0 ? {} : { nextSubmissionId }
5528
5557
  }))))).pipe(Effect.provideService(IdGenerator$1, idGenerator)).pipe(Effect.catchCauseFilter(Cause.findError, (error, cause) => {
@@ -5898,7 +5927,6 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (bindings) {
5898
5927
  let handoff;
5899
5928
  let nextHandoff;
5900
5929
  const attempt = Effect.scoped(Effect.gen(function* () {
5901
- if (yield* publicationPending(threadId)) return Option.none();
5902
5930
  const claimed = yield* acquireClaim(threadId, handoff);
5903
5931
  if (Option.isNone(claimed)) return Option.none();
5904
5932
  const { claim, tokenRef } = claimed.value;
@@ -7180,4 +7208,4 @@ var DurableAgentRuntime = class DurableAgentRuntime extends Context.Service()("@
7180
7208
  //#endregion
7181
7209
  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 };
7182
7210
 
7183
- //# sourceMappingURL=DurableAgentRuntime-D8GI66mP.mjs.map
7211
+ //# sourceMappingURL=DurableAgentRuntime-N5Meflyt.mjs.map