effect-agent 0.1.0-beta.95 → 0.1.0-beta.97

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 (124) hide show
  1. package/dist/{AgentRuntime-CufqQ4JM.d.mts → AgentRuntime-B64362Id.d.mts} +2 -2
  2. package/dist/AgentRuntime-Cdvqw7l_.mjs.map +1 -1
  3. package/dist/{DurableAgentRuntime-BaGsWDHO.mjs → DurableAgentRuntime-DbUvZHDZ.mjs} +82 -66
  4. package/dist/DurableAgentRuntime-DbUvZHDZ.mjs.map +1 -0
  5. package/dist/DurableFailpoint-DQJet828.d.mts +41 -0
  6. package/dist/{EventSource-DVfX1GRH.d.mts → EventSource-D6PAAEyK.d.mts} +3 -3
  7. package/dist/{PreparedInputAdmission-DoWaMC2R.d.mts → PreparedInputAdmission-omMbwd--.d.mts} +4 -4
  8. package/dist/{Records-CsEsSW2o.mjs → Records-BAutSSnJ.mjs} +18 -5
  9. package/dist/Records-BAutSSnJ.mjs.map +1 -0
  10. package/dist/{Records-B84j3Jq_.d.mts → Records-CV49DgQK.d.mts} +90 -16
  11. package/dist/{RunJournal-yYpUlTOE.mjs → RunJournal-DRRRZmG7.mjs} +8 -3
  12. package/dist/RunJournal-DRRRZmG7.mjs.map +1 -0
  13. package/dist/{RunOptions-CE-G3niT.d.mts → RunOptions-Clj8cLsp.d.mts} +4 -4
  14. package/dist/{Schedule-DCYBfhgT.d.mts → Schedule-DePbGfgd.d.mts} +2 -2
  15. package/dist/{Scheduling-CUuYc3-D.mjs → Scheduling-C3QpYn0W.mjs} +2 -2
  16. package/dist/{Scheduling-CUuYc3-D.mjs.map → Scheduling-C3QpYn0W.mjs.map} +1 -1
  17. package/dist/{Subagent-DscbtbNY.d.mts → Subagent-Bm1dRecN.d.mts} +3 -3
  18. package/dist/{Subscription-C8IHdmFk.d.mts → Subscription-BR_8Cxh3.d.mts} +3 -3
  19. package/dist/{SubscriptionInput-DhM3jUW2.d.mts → SubscriptionInput-B95sQbuk.d.mts} +3 -3
  20. package/dist/agent-registration-CXGDwvJH.mjs +379 -0
  21. package/dist/agent-registration-CXGDwvJH.mjs.map +1 -0
  22. package/dist/capabilities/Commands.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/durable/ActivityStore.d.mts +1 -1
  26. package/dist/durable/ActivityStore.mjs +1 -1
  27. package/dist/durable/Admin.d.mts +1 -1
  28. package/dist/durable/Admin.mjs +1 -1
  29. package/dist/durable/AgentRegistration.d.mts +2 -2
  30. package/dist/durable/AgentRegistration.mjs +7 -3
  31. package/dist/durable/AgentRegistration.mjs.map +1 -1
  32. package/dist/durable/Certification.d.mts +2 -2
  33. package/dist/durable/CommittedActivity.d.mts +1 -1
  34. package/dist/durable/CommittedActivity.mjs +1 -1
  35. package/dist/durable/Digest.d.mts +1 -1
  36. package/dist/durable/Digest.mjs +1 -1
  37. package/dist/durable/DurableAgentRuntime.d.mts +1 -1
  38. package/dist/durable/DurableAgentRuntime.mjs +1 -1
  39. package/dist/durable/DurableFailpoint.d.mts +1 -1
  40. package/dist/durable/DurableFailpoint.mjs +2 -0
  41. package/dist/durable/DurableFailpoint.mjs.map +1 -1
  42. package/dist/durable/DurableFailpointTestControl.d.mts +1 -1
  43. package/dist/durable/EventSource.d.mts +1 -1
  44. package/dist/durable/EventSource.mjs +1 -1
  45. package/dist/durable/GitHubWorkflowSource.d.mts +3 -3
  46. package/dist/durable/GitHubWorkflowSource.mjs +1 -1
  47. package/dist/durable/MessageDelivery.d.mts +3 -3
  48. package/dist/durable/MessageDelivery.mjs +1 -1
  49. package/dist/durable/MessageDeliveryStoreConformance.d.mts +39 -39
  50. package/dist/durable/MessageDeliveryStoreConformance.mjs +1 -1
  51. package/dist/durable/PersistentHistory.d.mts +1 -1
  52. package/dist/durable/PersistentHistory.mjs +2 -2
  53. package/dist/durable/PreparedInputAdmission.d.mts +1 -1
  54. package/dist/durable/Records.d.mts +2 -2
  55. package/dist/durable/Records.mjs +2 -2
  56. package/dist/durable/Recovery.d.mts +1 -1
  57. package/dist/durable/Recovery.mjs +1 -1
  58. package/dist/durable/RunJournal.d.mts +2 -2
  59. package/dist/durable/RunJournal.mjs +2 -2
  60. package/dist/durable/Schedule.d.mts +1 -1
  61. package/dist/durable/Schedule.mjs +1 -1
  62. package/dist/durable/ScheduleStoreConformance.d.mts +1 -1
  63. package/dist/durable/ScheduleStoreConformance.mjs +1 -1
  64. package/dist/durable/ScheduleTransition.d.mts +1 -1
  65. package/dist/durable/ScheduleTransition.mjs +1 -1
  66. package/dist/durable/Scheduling.d.mts +2 -2
  67. package/dist/durable/Scheduling.mjs +1 -1
  68. package/dist/durable/SqlStorageV2Upgrade.d.mts +2 -2
  69. package/dist/durable/SqlStorageV2Upgrade.mjs +1 -1
  70. package/dist/durable/SqlSubscriptionStore.d.mts +2 -2
  71. package/dist/durable/SqlSubscriptionStore.mjs +1 -1
  72. package/dist/durable/SubmissionLedger.d.mts +1 -1
  73. package/dist/durable/SubmissionLedger.mjs +1 -1
  74. package/dist/durable/SubmissionLedgerConformance.d.mts +1 -1
  75. package/dist/durable/SubmissionLedgerConformance.mjs +1 -1
  76. package/dist/durable/SubmissionStatus.d.mts +1 -1
  77. package/dist/durable/Subscription.d.mts +1 -1
  78. package/dist/durable/Subscription.mjs +1 -1
  79. package/dist/durable/SubscriptionInput.d.mts +1 -1
  80. package/dist/durable/SubscriptionInput.mjs +2 -2
  81. package/dist/durable/SubscriptionStoreConformance.d.mts +1 -1
  82. package/dist/durable/SubscriptionStoreConformance.mjs +1 -1
  83. package/dist/durable/SubscriptionTools.d.mts +3 -3
  84. package/dist/durable/SubscriptionTransition.d.mts +1 -1
  85. package/dist/durable/SubscriptionTransition.mjs +1 -1
  86. package/dist/durable/Subscriptions.d.mts +5 -5
  87. package/dist/durable/Subscriptions.mjs +1 -1
  88. package/dist/durable/ThreadContextHistory.d.mts +1 -1
  89. package/dist/durable/ThreadContextHistory.mjs +1 -1
  90. package/dist/durable/ThreadContextHistoryProjection.d.mts +1 -1
  91. package/dist/durable/ThreadContextHistoryProjection.mjs +1 -1
  92. package/dist/durable/ThreadInvariants.d.mts +1 -1
  93. package/dist/durable/ThreadInvariants.mjs +1 -1
  94. package/dist/durable/ThreadProjection.d.mts +1 -1
  95. package/dist/durable/ThreadProjection.mjs +1 -1
  96. package/dist/durable/ThreadProjectionMaintenance.d.mts +1 -1
  97. package/dist/durable/ThreadStore.d.mts +1 -1
  98. package/dist/durable/ThreadStore.mjs +1 -1
  99. package/dist/durable/ThreadStoreConformance.d.mts +1 -1
  100. package/dist/durable/ThreadStoreConformance.mjs +1 -1
  101. package/dist/durable/ToolReconciler.mjs +1 -1
  102. package/dist/durable/WorkerHost.d.mts +1 -1
  103. package/dist/engine/AgentRuntime.d.mts +1 -1
  104. package/dist/engine/RunOptions.d.mts +1 -1
  105. package/dist/engine/RunOptions.mjs.map +1 -1
  106. package/dist/index.d.mts +10 -10
  107. package/dist/index.mjs +4 -4
  108. package/package.json +1 -1
  109. package/src/durable/AgentRegistration.ts +5 -0
  110. package/src/durable/DurableAgentRuntime.ts +155 -84
  111. package/src/durable/DurableFailpoint.ts +2 -0
  112. package/src/durable/Records.ts +19 -2
  113. package/src/durable/RunJournal.ts +6 -0
  114. package/src/durable/internal/agent-registration.ts +427 -14
  115. package/src/durable/internal/messaging-host.ts +3 -6
  116. package/src/durable/internal/worker-host.ts +114 -88
  117. package/src/engine/RunOptions.ts +3 -3
  118. package/src/engine/internal/agent-runtime.ts +3 -4
  119. package/dist/DurableAgentRuntime-BaGsWDHO.mjs.map +0 -1
  120. package/dist/DurableFailpoint-Oinuuedm.d.mts +0 -41
  121. package/dist/Records-CsEsSW2o.mjs.map +0 -1
  122. package/dist/RunJournal-yYpUlTOE.mjs.map +0 -1
  123. package/dist/agent-registration-CWDMOAZA.mjs +0 -172
  124. package/dist/agent-registration-CWDMOAZA.mjs.map +0 -1
@@ -105,6 +105,7 @@ import {
105
105
  } from "../WorkerHost.ts";
106
106
  import {
107
107
  definitionDigestsEqual,
108
+ bindingSupports,
108
109
  resolveDefinitionBinding,
109
110
  type ResolvedBinding,
110
111
  } from "./agent-registration.ts";
@@ -380,6 +381,13 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
380
381
  };
381
382
  });
382
383
 
384
+ const firstThreadInput = (history: Effect.Success<ReturnType<typeof read>>) => {
385
+ const first = history.records.find(({ record }) => record.payload._tag === "UserInputRecorded")
386
+ ?.record.payload;
387
+
388
+ return first?._tag === "UserInputRecorded" ? first.input : undefined;
389
+ };
390
+
383
391
  const sourceAuthority = Effect.fn("WorkerHost.sourceAuthority")(function* (
384
392
  threadId: ThreadId,
385
393
  submissionId?: SubmissionId,
@@ -392,7 +400,7 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
392
400
  const binding = deps.bindings.find(
393
401
  (entry) =>
394
402
  entry.agentId === created.agentId &&
395
- definitionDigestsEqual(entry.digests, created.definitions),
403
+ bindingSupports(entry, created.definitions, undefined, firstThreadInput(current)),
396
404
  );
397
405
 
398
406
  const worker = current.records.find(
@@ -435,10 +443,26 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
435
443
  return yield* failure("start", "denied");
436
444
  }
437
445
 
446
+ const ownerBinding =
447
+ ownerSubmission === undefined
448
+ ? undefined
449
+ : deps.bindings.find(
450
+ (entry) =>
451
+ entry.agentId === ownerSubmission.agentId &&
452
+ bindingSupports(
453
+ entry,
454
+ ownerSubmission.agentDigests,
455
+ undefined,
456
+ ownerSubmission.inputPayload,
457
+ ),
458
+ );
459
+
460
+ const selectedBinding = ownerBinding ?? binding;
461
+
438
462
  if (worker?._tag === "WorkerOriginRecorded")
439
463
  return {
440
464
  current,
441
- binding,
465
+ binding: selectedBinding,
442
466
  submission: ownerSubmission,
443
467
  policyOverride: Option.none<AgentPolicy>(),
444
468
  policy: worker.origin.policy,
@@ -457,7 +481,7 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
457
481
 
458
482
  return {
459
483
  current,
460
- binding,
484
+ binding: selectedBinding,
461
485
  submission: ownerSubmission,
462
486
  policyOverride: Option.none<AgentPolicy>(),
463
487
  policy: attached.policy,
@@ -468,17 +492,6 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
468
492
  };
469
493
  }
470
494
 
471
- const ownerBinding =
472
- ownerSubmission === undefined
473
- ? undefined
474
- : deps.bindings.find(
475
- (entry) =>
476
- entry.agentId === ownerSubmission.agentId &&
477
- definitionDigestsEqual(entry.digests, ownerSubmission.agentDigests),
478
- );
479
-
480
- const selectedBinding = ownerBinding ?? binding;
481
-
482
495
  const changedRootAgent =
483
496
  ownerSubmission !== undefined && ownerSubmission.agentId !== created.agentId;
484
497
 
@@ -498,7 +511,9 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
498
511
  return yield* failure("start", "declaration-unavailable");
499
512
 
500
513
  const effectiveBinding =
501
- Option.isSome(selected) || changedRootAgent ? selectedBinding : binding;
514
+ Option.isSome(selected) || changedRootAgent || binding === undefined
515
+ ? selectedBinding
516
+ : binding;
502
517
 
503
518
  if (effectiveBinding === undefined) return yield* failure("start", "declaration-unavailable");
504
519
 
@@ -767,7 +782,7 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
767
782
  const targetBinding = deps.bindings.find(
768
783
  (entry) =>
769
784
  entry.agentId === origin.worker.targetAgentId &&
770
- definitionDigestsEqual(entry.digests, origin.targetDigests),
785
+ bindingSupports(entry, origin.targetDigests, undefined, input),
771
786
  );
772
787
 
773
788
  if (sourceBinding === undefined || targetBinding === undefined)
@@ -1039,16 +1054,42 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
1039
1054
  if (update.threadId !== submission.threadId || update.agentId !== origin.worker.targetAgentId)
1040
1055
  return yield* failure("followUp", "worker-mismatch");
1041
1056
 
1057
+ const sourceHistory = yield* read(origin.source.threadId, "followUp");
1058
+
1059
+ const first = requests(sourceHistory.records).find(
1060
+ (row) => row.admission.messageId === origin.firstMessageId,
1061
+ );
1062
+
1063
+ if (first === undefined || !sameOrigin(first.admission.origin, origin))
1064
+ return yield* failure("followUp", "corrupt");
1065
+
1066
+ const source = yield* sourceAuthority(
1067
+ origin.source.threadId,
1068
+ first.admission.sourceSubmissionId,
1069
+ );
1070
+
1071
+ if (
1072
+ source.binding === undefined ||
1073
+ source.submission === undefined ||
1074
+ !bindingSupports(
1075
+ source.binding,
1076
+ intent.sourceDigests,
1077
+ undefined,
1078
+ source.submission?.inputPayload,
1079
+ )
1080
+ )
1081
+ return yield* failure("followUp", "declaration-unavailable");
1082
+
1042
1083
  const sourceBinding = deps.bindings.find(
1043
1084
  (entry) =>
1044
1085
  entry.agentId === origin.source.agentId &&
1045
- definitionDigestsEqual(entry.digests, intent.sourceDigests),
1086
+ bindingSupports(entry, intent.sourceDigests, undefined, source.submission?.inputPayload),
1046
1087
  );
1047
1088
 
1048
1089
  const targetBinding = deps.bindings.find(
1049
1090
  (entry) =>
1050
1091
  entry.agentId === origin.worker.targetAgentId &&
1051
- definitionDigestsEqual(entry.digests, origin.targetDigests),
1092
+ bindingSupports(entry, origin.targetDigests, undefined, submission.inputPayload),
1052
1093
  );
1053
1094
 
1054
1095
  const reports =
@@ -1065,26 +1106,6 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
1065
1106
  !definitionDigestsEqual(submission.agentDigests, origin.targetDigests)
1066
1107
  )
1067
1108
  return yield* failure("followUp", "declaration-unavailable");
1068
- const sourceHistory = yield* read(origin.source.threadId, "followUp");
1069
-
1070
- const first = requests(sourceHistory.records).find(
1071
- (row) => row.admission.messageId === origin.firstMessageId,
1072
- );
1073
-
1074
- if (first === undefined || !sameOrigin(first.admission.origin, origin))
1075
- return yield* failure("followUp", "corrupt");
1076
-
1077
- const source = yield* sourceAuthority(
1078
- origin.source.threadId,
1079
- first.admission.sourceSubmissionId,
1080
- );
1081
-
1082
- if (
1083
- source.binding === undefined ||
1084
- source.submission === undefined ||
1085
- !definitionDigestsEqual(source.binding.digests, intent.sourceDigests)
1086
- )
1087
- return yield* failure("followUp", "declaration-unavailable");
1088
1109
 
1089
1110
  const recorded = source.current.records.find(
1090
1111
  ({ record }) => record.payload._tag === "WorkerOriginRecorded",
@@ -1231,40 +1252,6 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
1231
1252
  const refused = (reason: WorkerReportRefused["reason"]) =>
1232
1253
  WorkerReportRefused.make({ runId, messageId, reason });
1233
1254
 
1234
- const sourceBinding = deps.bindings.find(
1235
- (entry) =>
1236
- entry.agentId === origin.source.agentId &&
1237
- definitionDigestsEqual(entry.digests, intent.sourceDigests),
1238
- );
1239
-
1240
- const targetBinding = deps.bindings.find(
1241
- (entry) =>
1242
- entry.agentId === origin.worker.targetAgentId &&
1243
- definitionDigestsEqual(entry.digests, origin.targetDigests),
1244
- );
1245
-
1246
- const reports =
1247
- sourceBinding?.reporting?.filter(
1248
- (entry) => entry.delegationId === origin.worker.delegationId,
1249
- ) ?? [];
1250
-
1251
- const descriptor = reports[0];
1252
-
1253
- if (
1254
- sourceBinding === undefined ||
1255
- targetBinding === undefined ||
1256
- descriptor === undefined ||
1257
- reports.length !== 1 ||
1258
- !Object.is(descriptor.target, targetBinding.definition) ||
1259
- (descriptor.mode !== "standard" &&
1260
- !Object.is(descriptor.input, sourceBinding.definition.input)) ||
1261
- descriptor.mode !== intent.mode ||
1262
- descriptor.destination?.delegationId !== intent.destinationDelegationId ||
1263
- (descriptor.destination !== undefined &&
1264
- !Object.is(descriptor.destination.target, sourceBinding.definition))
1265
- )
1266
- return refused("declaration-unavailable");
1267
-
1268
1255
  const selected = yield* deps.ledger
1269
1256
  .lookup(SubmissionLookupById.make({ submissionId: host.submissionId }))
1270
1257
  .pipe(Effect.mapError(storageFailure("inspect")));
@@ -1298,7 +1285,46 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
1298
1285
 
1299
1286
  if (
1300
1287
  source.binding === undefined ||
1301
- !definitionDigestsEqual(source.binding.digests, intent.sourceDigests)
1288
+ !bindingSupports(
1289
+ source.binding,
1290
+ intent.sourceDigests,
1291
+ undefined,
1292
+ source.submission?.inputPayload,
1293
+ )
1294
+ )
1295
+ return refused("declaration-unavailable");
1296
+
1297
+ const sourceBinding = deps.bindings.find(
1298
+ (entry) =>
1299
+ entry.agentId === origin.source.agentId &&
1300
+ bindingSupports(entry, intent.sourceDigests, undefined, source.submission?.inputPayload),
1301
+ );
1302
+
1303
+ const targetBinding = deps.bindings.find(
1304
+ (entry) =>
1305
+ entry.agentId === origin.worker.targetAgentId &&
1306
+ bindingSupports(entry, origin.targetDigests, undefined, hostSubmission.inputPayload),
1307
+ );
1308
+
1309
+ const reports =
1310
+ sourceBinding?.reporting?.filter(
1311
+ (entry) => entry.delegationId === origin.worker.delegationId,
1312
+ ) ?? [];
1313
+
1314
+ const descriptor = reports[0];
1315
+
1316
+ if (
1317
+ sourceBinding === undefined ||
1318
+ targetBinding === undefined ||
1319
+ descriptor === undefined ||
1320
+ reports.length !== 1 ||
1321
+ !Object.is(descriptor.target, targetBinding.definition) ||
1322
+ (descriptor.mode !== "standard" &&
1323
+ !Object.is(descriptor.input, sourceBinding.definition.input)) ||
1324
+ descriptor.mode !== intent.mode ||
1325
+ descriptor.destination?.delegationId !== intent.destinationDelegationId ||
1326
+ (descriptor.destination !== undefined &&
1327
+ !Object.is(descriptor.destination.target, sourceBinding.definition))
1302
1328
  )
1303
1329
  return refused("declaration-unavailable");
1304
1330
 
@@ -1686,7 +1712,7 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
1686
1712
  target: Agent.AnyDefinition,
1687
1713
  operation: WorkerError["operation"],
1688
1714
  ) {
1689
- const resolved = yield* binding(target, operation);
1715
+ yield* binding(target, operation);
1690
1716
 
1691
1717
  if (worker.targetAgentId !== target.id) return yield* failure(operation, "worker-mismatch");
1692
1718
  const source = yield* read(context.source.threadId, operation);
@@ -1696,10 +1722,7 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
1696
1722
  )?.admission.origin;
1697
1723
 
1698
1724
  if (origin === undefined) return yield* failure(operation, "not-found");
1699
- if (
1700
- origin.worker.delegationId !== worker.delegationId ||
1701
- !definitionDigestsEqual(origin.targetDigests, resolved.digests)
1702
- )
1725
+ if (origin.worker.delegationId !== worker.delegationId)
1703
1726
  return yield* failure(operation, "worker-mismatch");
1704
1727
 
1705
1728
  return origin;
@@ -2404,11 +2427,19 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
2404
2427
 
2405
2428
  if (created?._tag !== "ThreadCreated") return yield* failure("context", "not-found");
2406
2429
 
2407
- const resolved = deps.bindings.find(
2408
- (entry) =>
2409
- entry.agentId === created.agentId &&
2410
- definitionDigestsEqual(entry.digests, created.definitions),
2411
- );
2430
+ const selected =
2431
+ request.sourceSubmissionId === undefined
2432
+ ? undefined
2433
+ : yield* sourceAuthority(sourceThreadId, request.sourceSubmissionId);
2434
+
2435
+ const resolved =
2436
+ selected === undefined
2437
+ ? deps.bindings.find(
2438
+ (entry) =>
2439
+ entry.agentId === created.agentId &&
2440
+ bindingSupports(entry, created.definitions, undefined, firstThreadInput(current)),
2441
+ )
2442
+ : selected.binding;
2412
2443
 
2413
2444
  if (resolved === undefined) return yield* failure("context", "declaration-unavailable");
2414
2445
 
@@ -2427,11 +2458,6 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
2427
2458
  ? attached
2428
2459
  : undefined;
2429
2460
 
2430
- const selected =
2431
- request.sourceSubmissionId === undefined
2432
- ? undefined
2433
- : yield* sourceAuthority(sourceThreadId, request.sourceSubmissionId);
2434
-
2435
2461
  return facet(
2436
2462
  {
2437
2463
  source: {
@@ -1005,9 +1005,9 @@ export interface RunOptions<HookError = never, HookRequirements = never> {
1005
1005
  * Optional absolute deadline for the Run's `maxDuration` rail. The engine
1006
1006
  * uses the earlier of this value and the fresh policy deadline, so callers
1007
1007
  * may preserve or tighten an existing Run allowance but can never widen it.
1008
- * Durable coordinators derive this value from the canonical `RunStarted`
1009
- * record timestamp and stored duration so replacement Attempts share one
1010
- * wall-clock allowance (RUN-030).
1008
+ * Durable coordinators reuse the canonical per-Attempt duration allowance;
1009
+ * deployment downtime does not consume it. An immutable worker grant can
1010
+ * impose an earlier absolute expiry. Turn, Tool and cost budgets remain Run-wide.
1011
1011
  */
1012
1012
  readonly durationDeadline?: DateTime.Utc | undefined;
1013
1013
  /**
@@ -532,7 +532,7 @@ interface RunContext {
532
532
  readonly pendingFollowUps: Array<Prompt.RawInput>;
533
533
  /** Wall-clock Run start, the base of the run-status elapsed rendering (RUN-024). */
534
534
  readonly startedAtMillis: number;
535
- /** Absolute `maxDuration` rail shared by every durable Attempt (RUN-030). */
535
+ /** Absolute `maxDuration` rail for this Attempt, optionally tightened by its coordinator. */
536
536
  readonly durationDeadlineMillis: number;
537
537
  history: Prompt.Prompt;
538
538
  modelCalls: number;
@@ -7921,9 +7921,8 @@ function streamWithCompletion<
7921
7921
  const maxDurationMillis = Duration.toMillis(agent.definition.policy.maxDuration);
7922
7922
  const attemptDeadlineMillis = attemptStartedAtMillis + maxDurationMillis;
7923
7923
 
7924
- // RUN-030: a durable coordinator supplies the logical Run deadline from
7925
- // canonical Run-start evidence. Taking the earlier deadline keeps this
7926
- // public option tightening-only for every other caller.
7924
+ // A coordinator can impose an earlier deadline (for example a worker grant).
7925
+ // This option can only tighten the fresh execution allowance.
7927
7926
  const durationDeadlineMillis =
7928
7927
  options.durationDeadline === undefined
7929
7928
  ? attemptDeadlineMillis