@zq-silk/yui 0.15.7 → 0.15.8

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 (281) hide show
  1. package/ARCHITECTURE.md +192 -399
  2. package/README.md +127 -1149
  3. package/dist/agent/adapterCatalog.js +15 -2
  4. package/dist/agent/agent.js +23 -3
  5. package/dist/agent/argumentPolicy.js +7 -1
  6. package/dist/agent/connectionPlan.js +62 -0
  7. package/dist/agent/executionComponents.js +158 -0
  8. package/dist/agent/launchEnvironment.js +31 -3
  9. package/dist/agent/managedRuntimeEnvironment.js +3 -5
  10. package/dist/{turn/turn.js → agentRun/agentRun.js} +166 -109
  11. package/dist/{turn/turnIdentity.js → agentRun/runIdentity.js} +4 -4
  12. package/dist/brief/taskBrief.js +12 -0
  13. package/dist/cli/agentConfigurationPicker.js +13 -0
  14. package/dist/cli/commandCatalog.js +157 -70
  15. package/dist/cli/interactionCandidates.js +5 -5
  16. package/dist/cli/interactionPolicy.js +38 -8
  17. package/dist/cli/invocationRouter.js +1 -1
  18. package/dist/cli/managedDiagnostics.js +28 -0
  19. package/dist/cli/operatorWizard.js +1 -7
  20. package/dist/cli/roleOptionOrder.js +27 -0
  21. package/dist/cli/roleWizard.js +50 -14
  22. package/dist/cli/updateOrchestrator.js +1 -1
  23. package/dist/cli/updatePorts.js +3 -4
  24. package/dist/cli.js +178 -95
  25. package/dist/commands/agentCommands.js +72 -14
  26. package/dist/commands/capabilityCommands.js +9 -6
  27. package/dist/commands/configCommands.js +20 -20
  28. package/dist/commands/deliveryGuardPreflight.js +2 -2
  29. package/dist/commands/executionAuditCommands.js +24 -24
  30. package/dist/commands/globalRoleCommands.js +1 -1
  31. package/dist/commands/grantCommands.js +4 -4
  32. package/dist/commands/operatorCommands.js +1 -7
  33. package/dist/commands/projectCommands.js +4 -4
  34. package/dist/commands/resourcesCommands.js +2 -2
  35. package/dist/commands/roleConfiguration.js +25 -5
  36. package/dist/commands/roleRuntimeGuard.js +4 -5
  37. package/dist/commands/sessionCommands.js +3 -7
  38. package/dist/commands/taskActivationCommands.js +259 -0
  39. package/dist/commands/taskActor.js +28 -49
  40. package/dist/commands/taskCommands.js +1188 -710
  41. package/dist/commands/taskContextCommand.js +39 -583
  42. package/dist/commands/taskExecutionCommands.js +32 -32
  43. package/dist/commands/taskInputCommands.js +40 -104
  44. package/dist/commands/taskIntegrationCommands.js +3 -2
  45. package/dist/commands/taskIntegrationQueueCommands.js +1 -1
  46. package/dist/commands/taskNextActionCommand.js +8 -8
  47. package/dist/commands/taskOverviewCommand.js +33 -45
  48. package/dist/commands/taskRemoteDeliveryCommand.js +2 -2
  49. package/dist/commands/taskRoleRuntimeStatus.js +133 -102
  50. package/dist/commands/telemetryCommands.js +36 -38
  51. package/dist/config/configCatalog.js +4 -4
  52. package/dist/config/yuiConfig.js +8 -8
  53. package/dist/context/contextSnapshot.js +10 -10
  54. package/dist/context/dispatchContext.js +11 -11
  55. package/dist/context/roleSessionContext.js +6 -3
  56. package/dist/context/{turnContextPack.js → runContextPack.js} +146 -81
  57. package/dist/context/{turnInputContract.js → runInputContract.js} +73 -60
  58. package/dist/context/sessionBootstrapManifest.js +21 -2
  59. package/dist/context/sourceRunContext.js +30 -0
  60. package/dist/context/taskContext.js +458 -0
  61. package/dist/context/wakeNotification.js +27 -27
  62. package/dist/controller/agentRuntimeObserver.js +21 -24
  63. package/dist/controller/capabilityBridge.js +17 -6
  64. package/dist/controller/clientRuntime.js +65 -92
  65. package/dist/controller/controller.js +114 -188
  66. package/dist/controller/fileSchedulerStoreAdapter.js +787 -887
  67. package/dist/controller/jobControl.js +54 -85
  68. package/dist/controller/resourceInventory.js +8 -27
  69. package/dist/controller/resourceInventoryLinux.js +12 -13
  70. package/dist/controller/runtime.js +529 -479
  71. package/dist/controller/runtimeEventInbox.js +55 -25
  72. package/dist/controller/runtimeEventProcessor.js +22 -31
  73. package/dist/controller/{runtimeHookTurnFence.js → runtimeHookRunFence.js} +91 -115
  74. package/dist/controller/runtimeLaunchCoordinator.js +80 -426
  75. package/dist/controller/runtimeObservationHook.js +14 -18
  76. package/dist/controller/sessionNotify.js +16 -24
  77. package/dist/controller/sessionOwnerReconciliation.js +168 -50
  78. package/dist/controller/structuredProviderObservation.js +138 -99
  79. package/dist/coordination/workMailbox.js +3 -3
  80. package/dist/coordination/workMailboxQueue.js +36 -33
  81. package/dist/core/boundedRpc.js +8 -1
  82. package/dist/core/controllerClient.js +20 -1
  83. package/dist/core/controllerServer.js +4 -4
  84. package/dist/doctor/doctor.js +13 -2
  85. package/dist/domain/agentResultTransport.js +9 -9
  86. package/dist/execution/codexThreadNaming.js +2 -8
  87. package/dist/execution/executionHealth.js +51 -63
  88. package/dist/execution/reviewMainRun.js +137 -0
  89. package/dist/execution/workItemExecution.js +28 -29
  90. package/dist/execution/workItemExecutionProjection.js +99 -107
  91. package/dist/execution/workItemMainRun.js +141 -0
  92. package/dist/executor/agentAdapter.js +227 -20
  93. package/dist/executor/agentConfigurationCatalog.js +126 -4
  94. package/dist/executor/agentConfigurationProbe.js +162 -4
  95. package/dist/executor/agentExecutor.js +79 -78
  96. package/dist/executor/effectiveLaunch.js +105 -18
  97. package/dist/executor/executorRegistry.js +29 -44
  98. package/dist/executor/fileRoleLaunchPlanner.js +229 -154
  99. package/dist/executor/workspacePreflightClassification.js +16 -16
  100. package/dist/grant/capabilityGrant.js +6 -3
  101. package/dist/input/inputRequest.js +12 -10
  102. package/dist/integration/gitIntegrationService.js +4 -11
  103. package/dist/integration/integrationQueueService.js +4 -4
  104. package/dist/interaction/operatorPresentation.js +1 -1
  105. package/dist/kernel/builtinCapabilities.js +247 -12
  106. package/dist/kernel/capabilityRegistry.js +64 -18
  107. package/dist/kernel/instanceHost.js +12 -1
  108. package/dist/kernel/kernelPorts.js +2 -2
  109. package/dist/lifecycle/canonicalLifecycleEvent.js +44 -49
  110. package/dist/lifecycle/exactRunTerminalization.js +449 -0
  111. package/dist/message/message.js +62 -6
  112. package/dist/message/messageContinuation.js +204 -0
  113. package/dist/observability/executionAudit.js +70 -72
  114. package/dist/observability/faultClassification.js +2 -2
  115. package/dist/observability/orchestrationMetrics.js +8 -8
  116. package/dist/operator/operatorSessionHistory.js +1 -7
  117. package/dist/output/agentConfigurationPresentation.js +8 -3
  118. package/dist/output/agentRunConfigurationPresentation.js +128 -0
  119. package/dist/output/rolePresentation.js +54 -3
  120. package/dist/plugins/pluginChild.js +104 -0
  121. package/dist/plugins/pluginIntent.js +26 -0
  122. package/dist/plugins/pluginInterpreter.js +43 -0
  123. package/dist/plugins/pluginPackage.js +101 -0
  124. package/dist/plugins/pluginProcess.js +112 -0
  125. package/dist/plugins/pluginService.js +380 -0
  126. package/dist/profile/agentProfile.js +1 -1
  127. package/dist/repository/gitWorkspace.js +26 -4
  128. package/dist/repository/project.js +19 -4
  129. package/dist/repository/taskBaseFreshness.js +13 -13
  130. package/dist/repository/taskWorkspaceCoordinator.js +20 -27
  131. package/dist/repository/taskWorkspacePreparer.js +344 -83
  132. package/dist/resources/autoResourceGc.js +3 -3
  133. package/dist/resources/liveReferences.js +3 -3
  134. package/dist/resources/projectResource.js +123 -0
  135. package/dist/resources/projectResourceService.js +421 -0
  136. package/dist/resources/resourceDiscovery.js +6 -6
  137. package/dist/resources/resourceGc.js +1 -1
  138. package/dist/resources/resourceRegistrar.js +1 -1
  139. package/dist/resources/resourceTypes.js +1 -1
  140. package/dist/review/deltaRecheck.js +3 -3
  141. package/dist/review/reviewAcceptance.js +16 -16
  142. package/dist/review/reviewDecision.js +7 -7
  143. package/dist/review/reviewRound.js +21 -20
  144. package/dist/review/reviewerAvailability.js +2 -2
  145. package/dist/role/role.js +51 -7
  146. package/dist/role/taskRoleUpdate.js +30 -0
  147. package/dist/runtime/acpProtocol.js +425 -0
  148. package/dist/runtime/acpSession.js +731 -0
  149. package/dist/runtime/acpSessionConfiguration.js +260 -0
  150. package/dist/runtime/agentDriver.js +30 -11
  151. package/dist/runtime/agentEndpoint.js +278 -0
  152. package/dist/runtime/agentEndpointIdentity.js +86 -0
  153. package/dist/runtime/agentEndpointOwnership.js +239 -0
  154. package/dist/runtime/agentError.js +2 -10
  155. package/dist/runtime/agentHost.js +565 -314
  156. package/dist/runtime/agentRunConfiguration.js +258 -0
  157. package/dist/runtime/builtinAgentDrivers.js +134 -18
  158. package/dist/runtime/builtinAgentErrorMappers.js +55 -3
  159. package/dist/runtime/builtinTranscriptUsage.js +1 -1
  160. package/dist/runtime/claude-process-owner +0 -0
  161. package/dist/runtime/codexAppServerRuntime.js +38 -30
  162. package/dist/runtime/codexInteractiveHost.js +41 -6
  163. package/dist/runtime/continuationManager.js +2 -6
  164. package/dist/runtime/executionEnvironment.js +30 -0
  165. package/dist/runtime/firstProgressAdvisory.js +11 -11
  166. package/dist/runtime/index.js +4 -3
  167. package/dist/runtime/jsonLineChannel.js +109 -0
  168. package/dist/runtime/launchBroker.js +91 -16
  169. package/dist/runtime/launchDiagnostics.js +2 -2
  170. package/dist/runtime/lifecycleReservation.js +10 -18
  171. package/dist/runtime/managedCaller.js +61 -17
  172. package/dist/runtime/nativeSessionControl.js +102 -0
  173. package/dist/runtime/ports.js +6 -21
  174. package/dist/runtime/processExitObservation.js +8 -7
  175. package/dist/runtime/promptEnvelope.js +17 -6
  176. package/dist/runtime/providerContinuation.js +3 -9
  177. package/dist/runtime/providerContinuationReconciliationService.js +4 -13
  178. package/dist/runtime/providerControl.js +2 -7
  179. package/dist/runtime/providerRuntimeIdentity.js +110 -222
  180. package/dist/runtime/providerRuntimeReconciler.js +5 -9
  181. package/dist/runtime/runtimeBinding.js +0 -1
  182. package/dist/runtime/runtimeContinuationProjection.js +4 -7
  183. package/dist/runtime/runtimeDeadlines.js +9 -0
  184. package/dist/runtime/runtimeHealthPolicy.js +1 -1
  185. package/dist/runtime/runtimeObservation.js +29 -65
  186. package/dist/runtime/runtimeProjection.js +43 -51
  187. package/dist/runtime/runtimeSessionCandidate.js +1 -3
  188. package/dist/runtime/sessionLaunchRequest.js +3 -7
  189. package/dist/runtime/sessionOwnerIdentity.js +7 -54
  190. package/dist/runtime/sessionOwnerRegistry.js +22 -17
  191. package/dist/runtime/sessionReconciliation.js +4 -8
  192. package/dist/runtime/sessionTerminationGuard.js +70 -259
  193. package/dist/runtime/sessionTokenMetrics.js +5 -16
  194. package/dist/runtime/structuredProviderHost.js +237 -117
  195. package/dist/runtime/taskRuntimeIsolation.js +39 -122
  196. package/dist/runtime/tmuxAdapters.js +39 -86
  197. package/dist/scheduler/activeRoleRunDelivery.js +354 -0
  198. package/dist/scheduler/leaderWakeupProcessor.js +75 -266
  199. package/dist/scheduler/operatorInputNotificationProcessor.js +1 -1
  200. package/dist/scheduler/ports.js +80 -9
  201. package/dist/scheduler/{roleTurnLiveness.js → roleRunLiveness.js} +26 -30
  202. package/dist/scheduler/{roleTurnStall.js → roleRunStall.js} +128 -139
  203. package/dist/scheduler/taskExecutionProjection.js +120 -124
  204. package/dist/scheduler/taskObservabilityProjection.js +29 -29
  205. package/dist/scheduler/taskWake.js +11 -4
  206. package/dist/scheduler/wakeReason.js +9 -1
  207. package/dist/setup/setupCommand.js +1 -0
  208. package/dist/storage/migrations/agentRunContract.js +159 -0
  209. package/dist/storage/migrations/removeRuntimeGeneration.js +207 -0
  210. package/dist/storage/sqliteSchema.js +431 -5
  211. package/dist/storage/sqliteStore.js +375 -220
  212. package/dist/storage/storageVersions.js +1 -1
  213. package/dist/storage/storeRpc.js +10 -5
  214. package/dist/storage/taskStore.js +13 -11
  215. package/dist/storage/upgrade/upgradeOrchestrator.js +5 -7
  216. package/dist/surface/surfaceContributions.js +102 -0
  217. package/dist/task/completionReadiness.js +32 -6
  218. package/dist/task/deliveryGuard.js +16 -16
  219. package/dist/task/draftPlan.js +72 -12
  220. package/dist/task/nextAction.js +144 -128
  221. package/dist/task/remoteDelivery.js +6 -6
  222. package/dist/task/task.js +184 -18
  223. package/dist/task/taskActivation.js +301 -0
  224. package/dist/task/taskActivationService.js +392 -0
  225. package/dist/task/taskRecordReference.js +5 -4
  226. package/dist/task/taskRecordRetirement.js +1 -1
  227. package/dist/telemetry/sqliteTelemetryStore.js +55 -68
  228. package/dist/telemetry/telemetryConfig.js +14 -14
  229. package/dist/telemetry/telemetryWiring.js +2 -2
  230. package/dist/web/assets/assetManifest.js +2 -0
  231. package/dist/web/assets/client/app.js +120 -20
  232. package/dist/web/assets/client/components.js +87 -54
  233. package/dist/web/assets/client/i18n.js +83 -41
  234. package/dist/web/assets/client/markdown.js +1 -1
  235. package/dist/web/assets/client/taskSurface.js +353 -0
  236. package/dist/web/assets/client/view.js +49 -44
  237. package/dist/web/assets/shell.js +1 -1
  238. package/dist/web/assets/styles/cards.js +22 -4
  239. package/dist/web/controllerWeb.js +60 -0
  240. package/dist/web/webMutation.js +28 -0
  241. package/dist/web/webServer.js +118 -8
  242. package/dist/web/webSnapshot.js +81 -74
  243. package/dist/web/webTaskSurface.js +64 -0
  244. package/dist/workItem/dependencyGate.js +1 -1
  245. package/dist/workItem/workItem.js +80 -48
  246. package/dist/workspace/workItemChangeSetManager.js +16 -9
  247. package/docs/agent-result-consumption.md +94 -0
  248. package/docs/agent-runtime-drivers.md +91 -0
  249. package/docs/architecture/README.md +38 -0
  250. package/docs/architecture/capabilities-and-resources.md +79 -0
  251. package/docs/managed-turn-and-session-runtime.md +222 -0
  252. package/docs/observability/README.md +81 -0
  253. package/docs/plugin-sdk.md +290 -0
  254. package/docs/provider-runtime.md +163 -0
  255. package/docs/release-workflow.md +303 -0
  256. package/docs/roles-and-configuration.md +113 -0
  257. package/docs/sqlite-control-plane-design.md +76 -0
  258. package/docs/task-dag-semantics.md +57 -0
  259. package/docs/task-delivery.md +103 -0
  260. package/docs/task-local-identity.md +6 -6
  261. package/docs/testing/verification-levels.md +86 -0
  262. package/i18n/README.zh-CN.md +98 -739
  263. package/package.json +2 -2
  264. package/skills/yui-leader/SKILL.md +130 -103
  265. package/skills/yui-leader/references/integration.md +39 -0
  266. package/skills/yui-leader/references/replicated-execution.md +42 -0
  267. package/skills/yui-leader/references/task-plugins.md +33 -0
  268. package/skills/yui-operator/SKILL.md +30 -59
  269. package/skills/yui-reviewer/SKILL.md +35 -36
  270. package/skills/yui-runtime/SKILL.md +88 -24
  271. package/skills/yui-runtime/references/publication.md +22 -0
  272. package/skills/yui-runtime/references/recovery.md +64 -0
  273. package/skills/yui-worker/SKILL.md +37 -39
  274. package/dist/cli/roleOptionCatalog.js +0 -68
  275. package/dist/context/sourceTurnContext.js +0 -30
  276. package/dist/execution/reviewMainTurn.js +0 -161
  277. package/dist/execution/workItemMainTurn.js +0 -164
  278. package/dist/lifecycle/exactTurnTerminalization.js +0 -407
  279. package/dist/runtime/preallocatedNativeSession.js +0 -13
  280. package/dist/runtime/runtimeStopReceipt.js +0 -42
  281. package/dist/scheduler/activeRoleTurnDelivery.js +0 -315
@@ -1,5 +1,5 @@
1
1
  export function createProviderRuntimeBinding(input) {
2
- const startedAt = timestamp(input.startedAt, "Provider Activation startedAt");
2
+ const startedAt = timestamp(input.startedAt, "Provider Conversation startedAt");
3
3
  return validateProviderRuntimeBinding({
4
4
  schemaVersion: 5,
5
5
  providerNamespace: identity(input.providerNamespace, "Provider namespace"),
@@ -12,20 +12,13 @@ export function createProviderRuntimeBinding(input) {
12
12
  recoverability: "unknown",
13
13
  createdAt: startedAt
14
14
  }],
15
- activations: [{
16
- activationId: identity(input.activationId, "Provider Activation id"),
17
- conversationId: input.conversationId,
18
- generation: 1,
19
- status: "active",
20
- startedAt
21
- }],
22
15
  authority: {
23
16
  epoch: 1,
24
17
  owner: "controller",
25
- holderId: input.activationId,
18
+ holderId: "controller",
26
19
  changedAt: startedAt
27
20
  },
28
- turn: null,
21
+ run: null,
29
22
  goal: null
30
23
  });
31
24
  }
@@ -51,72 +44,6 @@ export function currentProviderConversation(binding) {
51
44
  validateProviderRuntimeBinding(binding);
52
45
  return binding.conversations.find((entry) => (entry.epoch === binding.currentConversationEpoch && entry.status === "current"));
53
46
  }
54
- export function currentProviderActivation(binding) {
55
- const conversation = currentProviderConversation(binding);
56
- return [...binding.activations].reverse().find((entry) => (entry.conversationId === conversation.conversationId && entry.status === "active")) ?? null;
57
- }
58
- export function startProviderActivation(raw, input) {
59
- const binding = validateProviderRuntimeBinding(raw);
60
- if (currentProviderActivation(binding) !== null) {
61
- throw new Error("Provider Conversation already has a live writer Activation.");
62
- }
63
- if (binding.authority.owner !== "none") {
64
- throw new Error("Provider Conversation authority must be unowned before a new Activation starts.");
65
- }
66
- const conversation = currentProviderConversation(binding);
67
- const generation = binding.activations
68
- .filter((entry) => entry.conversationId === conversation.conversationId)
69
- .reduce((maximum, entry) => Math.max(maximum, entry.generation), 0) + 1;
70
- const startedAt = timestamp(input.startedAt, "Provider Activation startedAt");
71
- const activationId = identity(input.activationId, "Provider Activation id");
72
- return validateProviderRuntimeBinding({
73
- ...binding,
74
- activations: [...binding.activations, {
75
- activationId,
76
- conversationId: conversation.conversationId,
77
- generation,
78
- status: "active",
79
- startedAt
80
- }],
81
- authority: {
82
- epoch: binding.authority.epoch + 1,
83
- owner: "controller",
84
- holderId: activationId,
85
- changedAt: startedAt
86
- }
87
- });
88
- }
89
- export function endProviderActivation(raw, activationId, input) {
90
- const binding = validateProviderRuntimeBinding(raw);
91
- const id = identity(activationId, "Provider Activation id");
92
- const target = binding.activations.find((entry) => entry.activationId === id);
93
- if (target === undefined)
94
- throw new Error(`Provider Activation is not recorded: ${id}.`);
95
- if (target.status !== "active")
96
- return binding;
97
- const endedAt = timestamp(input.endedAt, "Provider Activation endedAt");
98
- if (Date.parse(endedAt) < Date.parse(target.startedAt)) {
99
- throw new Error("Provider Activation endedAt is earlier than startedAt.");
100
- }
101
- return validateProviderRuntimeBinding({
102
- ...binding,
103
- activations: binding.activations.map((entry) => entry.activationId === id
104
- ? {
105
- ...entry,
106
- status: input.status,
107
- endedAt,
108
- ...(input.reason === undefined
109
- ? {}
110
- : { terminalReason: identity(input.reason, "Provider Activation terminal reason") })
111
- }
112
- : entry),
113
- authority: {
114
- epoch: binding.authority.epoch + 1,
115
- owner: "none",
116
- changedAt: endedAt
117
- }
118
- });
119
- }
120
47
  /**
121
48
  * Compare-and-swap the only Provider writer. A stale Controller or detached
122
49
  * terminal cannot regain authority with an older epoch.
@@ -127,10 +54,9 @@ export function transferProviderAuthority(raw, input) {
127
54
  || binding.authority.owner !== input.expectedOwner) {
128
55
  throw new Error("Provider authority fence is stale.");
129
56
  }
130
- if (providerTurnIsActive(binding.turn)) {
131
- throw new Error("Provider authority cannot transfer while a Turn is unsettled.");
57
+ if (providerTurnIsActive(binding.run)) {
58
+ throw new Error("Provider authority cannot transfer while a AgentRun is unsettled.");
132
59
  }
133
- const active = currentProviderActivation(binding);
134
60
  const changedAt = timestamp(input.changedAt, "Provider authority changedAt");
135
61
  if (Date.parse(changedAt) < Date.parse(binding.authority.changedAt)) {
136
62
  throw new Error("Provider authority changedAt moved backwards.");
@@ -142,12 +68,9 @@ export function transferProviderAuthority(raw, input) {
142
68
  }
143
69
  }
144
70
  else {
145
- if (active === null) {
146
- throw new Error("Provider authority requires a live Activation.");
147
- }
148
71
  holderId = identity(input.holderId, "Provider authority holder id");
149
- if (input.owner === "controller" && holderId !== active.activationId) {
150
- throw new Error("Controller authority must be held by the live Activation.");
72
+ if (input.owner === "controller" && holderId !== "controller") {
73
+ throw new Error("Controller authority must name the Controller.");
151
74
  }
152
75
  }
153
76
  return validateProviderRuntimeBinding({
@@ -163,13 +86,13 @@ export function transferProviderAuthority(raw, input) {
163
86
  export function beginProviderTurn(raw, input) {
164
87
  const binding = validateProviderRuntimeBinding(raw);
165
88
  const attemptId = identity(input.attemptId, "Provider input attempt id");
166
- const turnId = input.turnId === undefined ? undefined : identity(input.turnId, "Turn id");
167
- const currentTurn = binding.turn;
168
- if (currentTurn !== null
169
- && currentTurn.turnId === turnId
170
- && currentTurn.attemptId === attemptId
171
- && currentTurn.authorityEpoch === input.authorityEpoch
172
- && currentTurn.status === "submitting") {
89
+ const runId = input.runId === undefined ? undefined : identity(input.runId, "AgentRun id");
90
+ const currentRun = binding.run;
91
+ if (currentRun !== null
92
+ && currentRun.runId === runId
93
+ && currentRun.attemptId === attemptId
94
+ && currentRun.authorityEpoch === input.authorityEpoch
95
+ && currentRun.status === "submitting") {
173
96
  return binding;
174
97
  }
175
98
  if (binding.authority.epoch !== input.authorityEpoch
@@ -177,16 +100,15 @@ export function beginProviderTurn(raw, input) {
177
100
  || binding.authority.owner === "unknown") {
178
101
  throw new Error("Provider Turn authority fence is stale.");
179
102
  }
180
- if (providerTurnIsActive(binding.turn)) {
181
- throw new Error("Provider Conversation already has an unsettled Turn.");
103
+ if (providerTurnIsActive(binding.run)) {
104
+ throw new Error("Provider Conversation already has an unsettled AgentRun.");
182
105
  }
183
106
  const submittedAt = timestamp(input.submittedAt, "Provider Turn submittedAt");
184
107
  return validateProviderRuntimeBinding({
185
108
  ...binding,
186
- turn: {
187
- ...(turnId === undefined ? {} : { turnId }),
109
+ run: {
110
+ ...(runId === undefined ? {} : { runId }),
188
111
  attemptId,
189
- activationId: currentProviderActivation(binding).activationId,
190
112
  authorityEpoch: input.authorityEpoch,
191
113
  status: "submitting",
192
114
  submittedAt,
@@ -197,16 +119,16 @@ export function beginProviderTurn(raw, input) {
197
119
  export function acceptProviderTurn(raw, input) {
198
120
  const binding = validateProviderRuntimeBinding(raw);
199
121
  const attemptId = identity(input.attemptId, "Provider input attempt id");
200
- const turn = binding.turn;
201
- if (turn === null || turn.attemptId !== attemptId
202
- || (turn.status !== "submitting" && turn.status !== "delivery-unknown")) {
122
+ const run = binding.run;
123
+ if (run === null || run.attemptId !== attemptId
124
+ || (run.status !== "submitting" && run.status !== "delivery-unknown")) {
203
125
  throw new Error("Provider Turn does not match an acceptable delivery state.");
204
126
  }
205
- const acceptedAt = orderedTurnTimestamp(turn, input.acceptedAt, "Provider Turn acceptedAt");
127
+ const acceptedAt = orderedRunTimestamp(run, input.acceptedAt, "Provider Turn acceptedAt");
206
128
  return validateProviderRuntimeBinding({
207
129
  ...binding,
208
- turn: {
209
- ...turn,
130
+ run: {
131
+ ...run,
210
132
  status: "accepted",
211
133
  ...(input.nativeTurnId === undefined
212
134
  ? {}
@@ -217,12 +139,12 @@ export function acceptProviderTurn(raw, input) {
217
139
  }
218
140
  export function markProviderTurnDeliveryUnknown(raw, input) {
219
141
  const binding = validateProviderRuntimeBinding(raw);
220
- const turn = requireProviderTurn(binding, input.attemptId, "submitting");
221
- const observedAt = orderedTurnTimestamp(turn, input.observedAt, "Provider Turn unknownAt");
142
+ const run = requireProviderTurn(binding, input.attemptId, "submitting");
143
+ const observedAt = orderedRunTimestamp(run, input.observedAt, "Provider Turn unknownAt");
222
144
  return validateProviderRuntimeBinding({
223
145
  ...binding,
224
- turn: {
225
- ...turn,
146
+ run: {
147
+ ...run,
226
148
  status: "delivery-unknown",
227
149
  terminalReason: identity(input.reason, "Provider Turn unknown reason"),
228
150
  updatedAt: observedAt
@@ -232,16 +154,16 @@ export function markProviderTurnDeliveryUnknown(raw, input) {
232
154
  /** Exact negative acknowledgement before a Provider Turn identity existed. */
233
155
  export function rejectProviderTurn(raw, input) {
234
156
  const binding = validateProviderRuntimeBinding(raw);
235
- const turn = binding.turn;
236
- if (turn === null || turn.attemptId !== identity(input.attemptId, "Provider input attempt id")
237
- || (turn.status !== "submitting" && turn.status !== "delivery-unknown")) {
157
+ const run = binding.run;
158
+ if (run === null || run.attemptId !== identity(input.attemptId, "Provider input attempt id")
159
+ || (run.status !== "submitting" && run.status !== "delivery-unknown")) {
238
160
  throw new Error("Provider Turn does not match a rejectable delivery state.");
239
161
  }
240
- const rejectedAt = orderedTurnTimestamp(turn, input.rejectedAt, "Provider Turn rejectedAt");
162
+ const rejectedAt = orderedRunTimestamp(run, input.rejectedAt, "Provider Turn rejectedAt");
241
163
  return validateProviderRuntimeBinding({
242
164
  ...binding,
243
- turn: {
244
- ...turn,
165
+ run: {
166
+ ...run,
245
167
  status: "rejected",
246
168
  terminalReason: identity(input.reason, "Provider Turn rejection reason"),
247
169
  updatedAt: rejectedAt
@@ -252,15 +174,26 @@ export function rejectProviderTurn(raw, input) {
252
174
  export function settleProviderTurnSubmission(raw, input) {
253
175
  const binding = validateProviderRuntimeBinding(raw);
254
176
  const attemptId = identity(input.attemptId, "Provider input attempt id");
255
- if (binding.turn?.attemptId !== attemptId) {
177
+ if (binding.run?.attemptId !== attemptId) {
256
178
  throw new Error("Provider Turn does not match a resolvable delivery state.");
257
179
  }
258
- if (binding.turn.status === input.status)
180
+ if (binding.run.status === input.status)
259
181
  return binding;
260
- if (binding.turn.status !== "submitting"
261
- && !(binding.turn.status === "delivery-unknown" && input.status === "rejected")) {
182
+ if (binding.run.status !== "submitting"
183
+ && !(binding.run.status === "delivery-unknown" && input.status === "rejected")) {
262
184
  throw new Error("Provider Turn does not match a resolvable delivery state.");
263
185
  }
186
+ if (input.status === "deferred") {
187
+ return validateProviderRuntimeBinding({
188
+ ...binding,
189
+ run: {
190
+ ...binding.run,
191
+ status: "deferred",
192
+ terminalReason: identity(input.reason, "Provider admission deferral reason"),
193
+ updatedAt: orderedRunTimestamp(binding.run, input.resolvedAt, "Provider deferredAt")
194
+ }
195
+ });
196
+ }
264
197
  return input.status === "delivery-unknown"
265
198
  ? markProviderTurnDeliveryUnknown(binding, {
266
199
  attemptId,
@@ -275,23 +208,23 @@ export function settleProviderTurnSubmission(raw, input) {
275
208
  }
276
209
  export function settleProviderTurn(raw, input) {
277
210
  const binding = validateProviderRuntimeBinding(raw);
278
- const turn = binding.turn;
211
+ const run = binding.run;
279
212
  const nativeTurnId = input.nativeTurnId === undefined
280
213
  ? undefined : identity(input.nativeTurnId, "Provider native Turn id");
281
- if (turn === null
214
+ if (run === null
282
215
  || (input.attemptId === undefined
283
- ? nativeTurnId === undefined || turn.nativeTurnId !== nativeTurnId
284
- : turn.attemptId !== input.attemptId)
285
- || (turn.nativeTurnId !== undefined && nativeTurnId !== undefined
286
- && turn.nativeTurnId !== nativeTurnId)
287
- || turn.status !== "accepted") {
288
- throw new Error("Provider Turn settlement does not match the current Turn.");
289
- }
290
- const settledAt = orderedTurnTimestamp(turn, input.settledAt, "Provider Turn settledAt");
216
+ ? nativeTurnId === undefined || run.nativeTurnId !== nativeTurnId
217
+ : run.attemptId !== input.attemptId)
218
+ || (run.nativeTurnId !== undefined && nativeTurnId !== undefined
219
+ && run.nativeTurnId !== nativeTurnId)
220
+ || run.status !== "accepted") {
221
+ throw new Error("Provider Turn settlement does not match the current AgentRun.");
222
+ }
223
+ const settledAt = orderedRunTimestamp(run, input.settledAt, "Provider Turn settledAt");
291
224
  return validateProviderRuntimeBinding({
292
225
  ...binding,
293
- turn: {
294
- ...turn,
226
+ run: {
227
+ ...run,
295
228
  ...(nativeTurnId === undefined ? {} : { nativeTurnId }),
296
229
  status: input.status,
297
230
  updatedAt: settledAt,
@@ -301,6 +234,21 @@ export function settleProviderTurn(raw, input) {
301
234
  }
302
235
  });
303
236
  }
237
+ /** Explicitly abandon an engineering input only after its execution resources
238
+ * are quiescent. This does not invent native acceptance, a Turn id or success. */
239
+ export function cancelQuiescentProviderInput(raw, input) {
240
+ const binding = validateProviderRuntimeBinding(raw);
241
+ if (binding.run?.attemptId !== input.attemptId)
242
+ throw new Error("Provider input identity changed during stop.");
243
+ if (!providerTurnIsActive(binding.run))
244
+ return binding;
245
+ return validateProviderRuntimeBinding({
246
+ ...binding,
247
+ run: { ...binding.run, status: "cancelled",
248
+ updatedAt: orderedRunTimestamp(binding.run, input.cancelledAt, "Provider input cancelledAt"),
249
+ terminalReason: input.reason }
250
+ });
251
+ }
304
252
  export function updateProviderConversationRecoverability(raw, recoverability) {
305
253
  const binding = validateProviderRuntimeBinding(raw);
306
254
  const current = currentProviderConversation(binding);
@@ -314,11 +262,8 @@ export function updateProviderConversationRecoverability(raw, recoverability) {
314
262
  /** Shared pre-start and commit guard for explicit native Conversation replacement. */
315
263
  export function assertProviderConversationReplaceable(raw) {
316
264
  const binding = validateProviderRuntimeBinding(raw);
317
- if (currentProviderActivation(binding) !== null || binding.authority.owner !== "none") {
318
- throw new Error("Provider Conversation replacement requires its prior Activation to be ended and unowned.");
319
- }
320
- if (providerTurnIsActive(binding.turn)) {
321
- throw new Error(`Provider Conversation replacement cannot discard unsettled input attempt ${binding.turn.attemptId} (${binding.turn.status}). Resolve its actual outcome before selecting a new Conversation.`);
265
+ if (providerTurnIsActive(binding.run)) {
266
+ throw new Error(`Provider Conversation replacement cannot discard unsettled input attempt ${binding.run.attemptId} (${binding.run.status}). Resolve its actual outcome before selecting a new Conversation.`);
322
267
  }
323
268
  }
324
269
  export function supersedeProviderConversation(raw, input) {
@@ -345,17 +290,10 @@ export function supersedeProviderConversation(raw, input) {
345
290
  createdAt: switchedAt
346
291
  }
347
292
  ],
348
- activations: [...binding.activations, {
349
- activationId: identity(input.activationId, "Provider Activation id"),
350
- conversationId: input.conversationId,
351
- generation: 1,
352
- status: "active",
353
- startedAt: switchedAt
354
- }],
355
293
  authority: {
356
294
  epoch: binding.authority.epoch + 1,
357
295
  owner: "controller",
358
- holderId: input.activationId,
296
+ holderId: "controller",
359
297
  changedAt: switchedAt
360
298
  },
361
299
  goal: null
@@ -406,70 +344,24 @@ export function validateProviderRuntimeBinding(value) {
406
344
  }
407
345
  if (currentCount !== 1)
408
346
  throw new Error("Provider Runtime Binding requires one current Conversation.");
409
- const activationIds = new Set();
410
- const activeByConversation = new Set();
411
- const generations = new Set();
412
- for (const activation of value.activations) {
413
- identity(activation.activationId, "Provider Activation id");
414
- if (activationIds.has(activation.activationId)) {
415
- throw new Error("Provider Runtime Binding contains duplicate Activation identity.");
416
- }
417
- activationIds.add(activation.activationId);
418
- if (!conversationIds.has(activation.conversationId)) {
419
- throw new Error("Provider Activation references an unknown Conversation.");
420
- }
421
- integer(activation.generation, 1, "Provider Activation generation");
422
- const generationKey = `${activation.conversationId}\u0000${activation.generation}`;
423
- if (generations.has(generationKey)) {
424
- throw new Error("Provider Runtime Binding contains duplicate Activation generation.");
425
- }
426
- generations.add(generationKey);
427
- if (!["active", "ended", "failed"].includes(activation.status)) {
428
- throw new Error("Provider Activation status is invalid.");
429
- }
430
- timestamp(activation.startedAt, "Provider Activation startedAt");
431
- if (activation.status === "active") {
432
- if (activation.endedAt !== undefined) {
433
- throw new Error("Active Provider Activation cannot have endedAt.");
434
- }
435
- if (activeByConversation.has(activation.conversationId)) {
436
- throw new Error("Provider Conversation has multiple live writer Activations.");
437
- }
438
- activeByConversation.add(activation.conversationId);
439
- }
440
- else {
441
- if (activation.endedAt === undefined)
442
- throw new Error("Terminal Provider Activation requires endedAt.");
443
- timestamp(activation.endedAt, "Provider Activation endedAt");
444
- }
445
- }
446
347
  integer(value.authority.epoch, 1, "Provider authority epoch");
447
348
  timestamp(value.authority.changedAt, "Provider authority changedAt");
448
349
  if (!["controller", "human", "none", "unknown"].includes(value.authority.owner)) {
449
350
  throw new Error("Provider authority owner is invalid.");
450
351
  }
451
- const active = currentActivationUnchecked(value);
452
352
  if (value.authority.owner === "controller" || value.authority.owner === "human") {
453
353
  const holderId = identity(value.authority.holderId, "Provider authority holder id");
454
- if (active === null)
455
- throw new Error("Owned Provider authority requires a live Activation.");
456
- if (value.authority.owner === "controller" && holderId !== active.activationId) {
457
- throw new Error("Controller authority must be held by the live Activation.");
354
+ if (value.authority.owner === "controller" && holderId !== "controller") {
355
+ throw new Error("Controller authority must name the Controller.");
458
356
  }
459
357
  }
460
358
  else if (value.authority.holderId !== undefined) {
461
359
  throw new Error("Unowned or unknown Provider authority cannot name a holder.");
462
360
  }
463
- if (active !== null && (value.authority.owner === "none" || value.authority.owner === "unknown")) {
464
- throw new Error("A live Provider Activation requires an exact writer authority.");
465
- }
466
- if (!Object.hasOwn(value, "turn"))
467
- throw new Error("Provider Runtime Binding requires Turn state.");
468
- if (value.turn !== null) {
469
- validateProviderTurn(value.turn, value.authority.epoch);
470
- if (value.turn.activationId !== undefined && !activationIds.has(value.turn.activationId)) {
471
- throw new Error("Provider Turn references an unknown original Activation.");
472
- }
361
+ if (!Object.hasOwn(value, "run"))
362
+ throw new Error("Provider Runtime Binding requires AgentRun state.");
363
+ if (value.run !== null) {
364
+ validateProviderTurn(value.run, value.authority.epoch);
473
365
  }
474
366
  if (!Object.hasOwn(value, "goal"))
475
367
  throw new Error("Provider Runtime Binding requires Goal state.");
@@ -501,56 +393,52 @@ function validateProviderGoal(goal) {
501
393
  };
502
394
  return Object.freeze(normalized);
503
395
  }
504
- function validateProviderTurn(turn, currentAuthorityEpoch) {
505
- if (turn.turnId !== undefined)
506
- identity(turn.turnId, "Turn id");
507
- identity(turn.attemptId, "Provider input attempt id");
508
- integer(turn.authorityEpoch, 1, "Provider Turn authority epoch");
509
- if (turn.authorityEpoch > currentAuthorityEpoch) {
396
+ function validateProviderTurn(run, currentAuthorityEpoch) {
397
+ if (run.runId !== undefined)
398
+ identity(run.runId, "AgentRun id");
399
+ identity(run.attemptId, "Provider input attempt id");
400
+ integer(run.authorityEpoch, 1, "Provider Turn authority epoch");
401
+ if (run.authorityEpoch > currentAuthorityEpoch) {
510
402
  throw new Error("Provider Turn authority epoch is ahead of current authority.");
511
403
  }
512
- if (!["submitting", "accepted", "completed", "failed", "cancelled", "rejected", "delivery-unknown"]
513
- .includes(turn.status)) {
404
+ if (!["submitting", "accepted", "completed", "failed", "cancelled", "rejected", "deferred", "delivery-unknown"]
405
+ .includes(run.status)) {
514
406
  throw new Error("Provider Turn status is invalid.");
515
407
  }
516
- timestamp(turn.submittedAt, "Provider Turn submittedAt");
517
- timestamp(turn.updatedAt, "Provider Turn updatedAt");
518
- if (Date.parse(turn.updatedAt) < Date.parse(turn.submittedAt)) {
408
+ timestamp(run.submittedAt, "Provider Turn submittedAt");
409
+ timestamp(run.updatedAt, "Provider Turn updatedAt");
410
+ if (Date.parse(run.updatedAt) < Date.parse(run.submittedAt)) {
519
411
  throw new Error("Provider Turn updatedAt is earlier than submittedAt.");
520
412
  }
521
- const hasAcceptedIdentity = turn.status === "accepted"
522
- || turn.status === "completed" || turn.status === "failed" || turn.status === "cancelled";
523
- if (hasAcceptedIdentity && turn.nativeTurnId !== undefined) {
524
- identity(turn.nativeTurnId, "Provider native Turn id");
413
+ const hasAcceptedIdentity = run.status === "accepted"
414
+ || run.status === "completed" || run.status === "failed" || run.status === "cancelled";
415
+ if (hasAcceptedIdentity && run.nativeTurnId !== undefined) {
416
+ identity(run.nativeTurnId, "Provider native Turn id");
525
417
  }
526
- else if (!hasAcceptedIdentity && turn.nativeTurnId !== undefined) {
418
+ else if (!hasAcceptedIdentity && run.nativeTurnId !== undefined) {
527
419
  throw new Error("Unaccepted Provider Turn cannot have a native Turn id.");
528
420
  }
529
421
  }
530
- export function managedProviderTurnId(turn) {
531
- return turn?.turnId ?? null;
422
+ export function managedProviderTurnId(run) {
423
+ return run?.runId ?? null;
532
424
  }
533
425
  function requireProviderTurn(binding, attemptId, status) {
534
426
  const id = identity(attemptId, "Provider input attempt id");
535
- if (binding.turn === null || binding.turn.attemptId !== id || binding.turn.status !== status) {
427
+ if (binding.run === null || binding.run.attemptId !== id || binding.run.status !== status) {
536
428
  throw new Error("Provider Turn does not match the expected delivery state.");
537
429
  }
538
- return binding.turn;
430
+ return binding.run;
539
431
  }
540
- function orderedTurnTimestamp(turn, value, label) {
432
+ function orderedRunTimestamp(run, value, label) {
541
433
  const normalized = timestamp(value, label);
542
- if (Date.parse(normalized) < Date.parse(turn.updatedAt)) {
434
+ if (Date.parse(normalized) < Date.parse(run.updatedAt)) {
543
435
  throw new Error(`${label} moved backwards.`);
544
436
  }
545
437
  return normalized;
546
438
  }
547
- function providerTurnIsActive(turn) {
548
- return turn !== null && ["submitting", "accepted", "delivery-unknown"]
549
- .includes(turn.status);
550
- }
551
- function currentActivationUnchecked(binding) {
552
- const current = binding.conversations.find((entry) => (entry.epoch === binding.currentConversationEpoch && entry.status === "current"));
553
- return current === undefined ? null : [...binding.activations].reverse().find((entry) => (entry.conversationId === current.conversationId && entry.status === "active")) ?? null;
439
+ function providerTurnIsActive(run) {
440
+ return run !== null && ["submitting", "accepted", "delivery-unknown"]
441
+ .includes(run.status);
554
442
  }
555
443
  function identity(value, label) {
556
444
  if (typeof value !== "string" || value.trim().length === 0)
@@ -4,8 +4,8 @@ const MAX_RECONCILE_MS = 5 * 60_000;
4
4
  const CIRCUIT_ERROR_LIMIT = 5;
5
5
  const QUERY_TIMEOUT_MS = 5_000;
6
6
  /**
7
- * Reconciles only already-known children, grouped under one Conversation and
8
- * Activation generation. Missing entries settle ownership only for an exact
7
+ * Reconciles only already-known children, grouped under one Conversation.
8
+ * Missing entries settle ownership only for an exact
9
9
  * snapshot; partial/unavailable absence is never terminal evidence.
10
10
  */
11
11
  export async function reconcileKnownDetachedContinuations(input) {
@@ -17,16 +17,14 @@ export async function reconcileKnownDetachedContinuations(input) {
17
17
  const groupKey = [
18
18
  first.identity.providerNamespace,
19
19
  first.identity.accountScope,
20
- first.identity.conversationId,
21
- first.identity.activationId
20
+ first.identity.conversationId
22
21
  ].join("\u0000");
23
22
  if (candidates.some((entry) => [
24
23
  entry.identity.providerNamespace,
25
24
  entry.identity.accountScope,
26
- entry.identity.conversationId,
27
- entry.identity.activationId
25
+ entry.identity.conversationId
28
26
  ].join("\u0000") !== groupKey)) {
29
- throw new Error("Provider reconcile input must contain one Conversation/Activation group.");
27
+ throw new Error("Provider reconcile input must contain one Conversation group.");
30
28
  }
31
29
  const nowMs = input.now.getTime();
32
30
  if (input.previous?.circuitOpenUntil !== undefined
@@ -44,10 +42,8 @@ export async function reconcileKnownDetachedContinuations(input) {
44
42
  providerNamespace: first.identity.providerNamespace,
45
43
  accountScope: first.identity.accountScope,
46
44
  conversationId: first.identity.conversationId,
47
- activationId: first.identity.activationId,
48
45
  continuations: Object.freeze(candidates.map((entry) => Object.freeze({
49
46
  continuationId: entry.identity.continuationId,
50
- generation: entry.identity.generation
51
47
  })))
52
48
  }), QUERY_TIMEOUT_MS);
53
49
  result = validateQueryResult(raw, new Set(candidates.map((entry) => (providerContinuationKey(entry.identity)))));
@@ -7,7 +7,6 @@ export function createRuntimeBinding(input) {
7
7
  : requireBoolean(input.hostCreated, "Runtime host-created flag");
8
8
  return {
9
9
  id: requireSafeIdentity(input.id, "Runtime binding id"),
10
- runtimeGenerationId: requireSafeIdentity(input.runtimeGenerationId, "Runtime generation id"),
11
10
  owner: normalizeRuntimeOwner(input.owner),
12
11
  agentId: requireSafeIdentity(input.agentId, "Agent id"),
13
12
  adapterId: requireSafeIdentity(input.adapterId, "Agent adapter id"),
@@ -12,17 +12,14 @@ export function projectProviderContinuations(events) {
12
12
  // Provider sequence and must not be moved before the Provider start fact.
13
13
  for (const observation of observations) {
14
14
  const fence = observation.fence;
15
- if (fence.conversationId === undefined || fence.activationId === undefined
16
- || fence.continuationId === undefined || fence.continuationGeneration === undefined) {
15
+ if (fence.conversationId === undefined || fence.continuationId === undefined) {
17
16
  continue;
18
17
  }
19
18
  const key = [
20
19
  fence.driverId,
21
20
  fence.agentId,
22
21
  fence.conversationId,
23
- fence.activationId,
24
- fence.continuationId,
25
- fence.continuationGeneration
22
+ fence.continuationId
26
23
  ].join("\u0000");
27
24
  const result = foldContinuationObservation(projected.get(key) ?? null, observation);
28
25
  projected.set(providerContinuationKey(result.continuation.identity), result.continuation);
@@ -32,10 +29,10 @@ export function projectProviderContinuations(events) {
32
29
  export function blockingProviderContinuations(events) {
33
30
  return projectProviderContinuations(events).filter((entry) => (continuationOwnsWriterUmbrella(entry) || entry.identityConflict));
34
31
  }
35
- /** Exact Turn-scoped writer fence shared by terminalization and retry paths. */
32
+ /** Exact AgentRun-scoped writer fence shared by terminalization and retry paths. */
36
33
  export function runOwnsBlockingProviderContinuation(events, owner) {
37
34
  return blockingProviderContinuations(events).some((continuation) => (continuation.taskId === owner.taskId
38
35
  && continuation.roleName === owner.roleName
39
- && continuation.turnId === owner.turnId
36
+ && continuation.runId === owner.runId
40
37
  && continuation.identity.accountScope === owner.agentId));
41
38
  }
@@ -12,3 +12,12 @@ export const LIFECYCLE_REQUEST_TIMEOUT_MS = AGENT_HOST_CONTROL_TIMEOUT_MS + RUNT
12
12
  export const CONTROLLER_SHUTDOWN_TIMEOUT_MS = LIFECYCLE_REQUEST_TIMEOUT_MS + RUNTIME_ENVELOPE_MARGIN_MS;
13
13
  export const RELEASE_HANDOVER_OLD_OWNER_GRACE_MS = CONTROLLER_SHUTDOWN_TIMEOUT_MS + RUNTIME_ENVELOPE_MARGIN_MS;
14
14
  export const RELEASE_HANDOVER_PROMOTION_TIMEOUT_MS = RELEASE_HANDOVER_OLD_OWNER_GRACE_MS + RUNTIME_ENVELOPE_MARGIN_MS;
15
+ /** Grace for an owned Provider client to exit after the Host asks it to stop. */
16
+ export const AGENT_HOST_CLIENT_EXIT_GRACE_MS = 10_000;
17
+ /**
18
+ * Bounded wait for Endpoint implementation references to drain during shutdown.
19
+ * Strictly inside the owned client's exit grace, so reporting the remaining
20
+ * references never delays the Host past the point where it stops waiting for
21
+ * that client. Expiry reports what is still in use; it never kills anything.
22
+ */
23
+ export const ENDPOINT_DRAIN_TIMEOUT_MS = AGENT_HOST_CLIENT_EXIT_GRACE_MS / 2;
@@ -5,7 +5,7 @@
5
5
  * The layers are deliberately time-based and conservative: short silence is
6
6
  * normal for high-reasoning-effort turns, large reviews, and tool waits.
7
7
  * Time-based layers authorize display hints and coalesced read-only diagnosis
8
- * only. They never reset a Turn or replace a Provider Session.
8
+ * only. They never reset a AgentRun or replace a Provider Session.
9
9
  */
10
10
  /** Runtime silence after which a live turn is surfaced as "quiet" (hint only). */
11
11
  export const RUNTIME_QUIET_AFTER_MS = 5 * 60_000;