@noopolis/daimon 0.1.2 → 0.2.1

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 (422) hide show
  1. package/README.md +275 -51
  2. package/dist/contracts/attentionContract.d.ts +142 -0
  3. package/dist/contracts/attentionContract.d.ts.map +1 -0
  4. package/dist/contracts/attentionContract.js +21 -0
  5. package/dist/contracts/canonicalJson.d.ts +3 -0
  6. package/dist/contracts/canonicalJson.d.ts.map +1 -0
  7. package/dist/contracts/canonicalJson.js +54 -0
  8. package/dist/contracts/grokBrokerTaskClock.d.ts +18 -0
  9. package/dist/contracts/grokBrokerTaskClock.d.ts.map +1 -0
  10. package/dist/contracts/grokBrokerTaskClock.js +16 -0
  11. package/dist/contracts/grokWorkerContract.d.ts +74 -0
  12. package/dist/contracts/grokWorkerContract.d.ts.map +1 -0
  13. package/dist/contracts/grokWorkerContract.js +88 -0
  14. package/dist/contracts/organizationRuntimeContract.d.ts +841 -0
  15. package/dist/contracts/organizationRuntimeContract.d.ts.map +1 -0
  16. package/dist/contracts/organizationRuntimeContract.js +123 -0
  17. package/dist/contracts/runtimeContractManifest.d.ts +1822 -0
  18. package/dist/contracts/runtimeContractManifest.d.ts.map +1 -0
  19. package/dist/contracts/runtimeContractManifest.js +206 -0
  20. package/dist/contracts/shellEnvironmentPolicy.d.ts +3 -0
  21. package/dist/contracts/shellEnvironmentPolicy.d.ts.map +1 -0
  22. package/dist/contracts/shellEnvironmentPolicy.js +5 -0
  23. package/dist/contracts/wakeMomentContract.d.ts +61 -0
  24. package/dist/contracts/wakeMomentContract.d.ts.map +1 -0
  25. package/dist/contracts/wakeMomentContract.js +27 -0
  26. package/dist/core/credentialRedaction.d.ts +4 -0
  27. package/dist/core/credentialRedaction.d.ts.map +1 -0
  28. package/dist/core/credentialRedaction.js +28 -0
  29. package/dist/core/types.d.ts +2 -0
  30. package/dist/core/types.d.ts.map +1 -1
  31. package/dist/examples/jungianPlayAgent.d.ts +1 -0
  32. package/dist/examples/jungianPlayAgent.d.ts.map +1 -1
  33. package/dist/examples/jungianPlayAgent.js +6 -2
  34. package/dist/mcp/toolServer.d.ts +19 -2
  35. package/dist/mcp/toolServer.d.ts.map +1 -1
  36. package/dist/mcp/toolServer.js +57 -17
  37. package/dist/observability/causalEvents.d.ts +6 -6
  38. package/dist/observability/causalEvents.d.ts.map +1 -1
  39. package/dist/observability/causalEvents.js +107 -19
  40. package/dist/observability/orgObserver.d.ts.map +1 -1
  41. package/dist/observability/orgObserver.js +3 -3
  42. package/dist/pi/agyHeadlessResult.d.ts +60 -0
  43. package/dist/pi/agyHeadlessResult.d.ts.map +1 -0
  44. package/dist/pi/agyHeadlessResult.js +95 -0
  45. package/dist/pi/cliChildOutput.d.ts +67 -0
  46. package/dist/pi/cliChildOutput.d.ts.map +1 -0
  47. package/dist/pi/cliChildOutput.js +269 -0
  48. package/dist/pi/cliEngineRun.d.ts +16 -0
  49. package/dist/pi/cliEngineRun.d.ts.map +1 -0
  50. package/dist/pi/cliEngineRun.js +27 -0
  51. package/dist/pi/cliEngineSpawn.d.ts +55 -0
  52. package/dist/pi/cliEngineSpawn.d.ts.map +1 -0
  53. package/dist/pi/cliEngineSpawn.js +169 -0
  54. package/dist/pi/cliEnvironment.d.ts +12 -0
  55. package/dist/pi/cliEnvironment.d.ts.map +1 -0
  56. package/dist/pi/cliEnvironment.js +34 -0
  57. package/dist/pi/cliMcpRegistration.d.ts +61 -0
  58. package/dist/pi/cliMcpRegistration.d.ts.map +1 -0
  59. package/dist/pi/cliMcpRegistration.js +75 -0
  60. package/dist/pi/cliProcess.d.ts +7 -0
  61. package/dist/pi/cliProcess.d.ts.map +1 -0
  62. package/dist/pi/cliProcess.js +132 -0
  63. package/dist/pi/cliSession.d.ts +86 -24
  64. package/dist/pi/cliSession.d.ts.map +1 -1
  65. package/dist/pi/cliSession.js +251 -173
  66. package/dist/pi/cliSessionMcp.d.ts +9 -0
  67. package/dist/pi/cliSessionMcp.d.ts.map +1 -0
  68. package/dist/pi/cliSessionMcp.js +80 -0
  69. package/dist/pi/cliTurnMetering.d.ts +60 -0
  70. package/dist/pi/cliTurnMetering.d.ts.map +1 -0
  71. package/dist/pi/cliTurnMetering.js +60 -0
  72. package/dist/pi/codexFilesystemRules.d.ts +3 -0
  73. package/dist/pi/codexFilesystemRules.d.ts.map +1 -0
  74. package/dist/pi/codexFilesystemRules.js +28 -0
  75. package/dist/pi/codexHeadlessResult.d.ts +68 -0
  76. package/dist/pi/codexHeadlessResult.d.ts.map +1 -0
  77. package/dist/pi/codexHeadlessResult.js +122 -0
  78. package/dist/pi/codexRolloutUsage.d.ts +95 -0
  79. package/dist/pi/codexRolloutUsage.d.ts.map +1 -0
  80. package/dist/pi/codexRolloutUsage.js +221 -0
  81. package/dist/pi/engineTaskClock.d.ts +9 -0
  82. package/dist/pi/engineTaskClock.d.ts.map +1 -0
  83. package/dist/pi/engineTaskClock.js +28 -0
  84. package/dist/pi/engineWakeLimits.d.ts +39 -0
  85. package/dist/pi/engineWakeLimits.d.ts.map +1 -0
  86. package/dist/pi/engineWakeLimits.js +55 -0
  87. package/dist/pi/grokHeadlessResult.d.ts +36 -0
  88. package/dist/pi/grokHeadlessResult.d.ts.map +1 -0
  89. package/dist/pi/grokHeadlessResult.js +118 -0
  90. package/dist/pi/grokHomeMcpRegistration.d.ts +21 -0
  91. package/dist/pi/grokHomeMcpRegistration.d.ts.map +1 -0
  92. package/dist/pi/grokHomeMcpRegistration.js +58 -0
  93. package/dist/pi/grokSandbox.d.ts +11 -0
  94. package/dist/pi/grokSandbox.d.ts.map +1 -0
  95. package/dist/pi/grokSandbox.js +216 -0
  96. package/dist/pi/grokStreamUsage.d.ts +31 -0
  97. package/dist/pi/grokStreamUsage.d.ts.map +1 -0
  98. package/dist/pi/grokStreamUsage.js +51 -0
  99. package/dist/pi/memoryClock.d.ts +25 -0
  100. package/dist/pi/memoryClock.d.ts.map +1 -0
  101. package/dist/pi/memoryClock.js +18 -0
  102. package/dist/pi/piAgentHandle.d.ts +6 -3
  103. package/dist/pi/piAgentHandle.d.ts.map +1 -1
  104. package/dist/pi/piAgentHandle.js +42 -12
  105. package/dist/pi/piAgentWakeSupport.d.ts +35 -0
  106. package/dist/pi/piAgentWakeSupport.d.ts.map +1 -1
  107. package/dist/pi/piAgentWakeSupport.js +4 -0
  108. package/dist/pi/piHarness.d.ts +18 -3
  109. package/dist/pi/piHarness.d.ts.map +1 -1
  110. package/dist/pi/piHarness.js +83 -14
  111. package/dist/pi/prompts.d.ts +1 -0
  112. package/dist/pi/prompts.d.ts.map +1 -1
  113. package/dist/pi/prompts.js +24 -0
  114. package/dist/pi/taskClockProcess.d.ts +6 -0
  115. package/dist/pi/taskClockProcess.d.ts.map +1 -0
  116. package/dist/pi/taskClockProcess.js +8 -0
  117. package/dist/pi/turnCausal.d.ts +4 -2
  118. package/dist/pi/turnCausal.d.ts.map +1 -1
  119. package/dist/pi/turnCausal.js +4 -4
  120. package/dist/pi/turnTrace.d.ts.map +1 -1
  121. package/dist/pi/turnTrace.js +5 -8
  122. package/dist/pi/wakeAcceptance.d.ts +1 -1
  123. package/dist/pi/wakeAcceptance.d.ts.map +1 -1
  124. package/dist/pi/wakeAcceptance.js +2 -2
  125. package/dist/pi/worldTrajectory.d.ts +1 -1
  126. package/dist/pi/worldTrajectory.d.ts.map +1 -1
  127. package/dist/pi/worldTrajectory.js +3 -3
  128. package/dist/runtime/agySubscriptionBootstrap.d.ts +16 -0
  129. package/dist/runtime/agySubscriptionBootstrap.d.ts.map +1 -0
  130. package/dist/runtime/agySubscriptionBootstrap.js +80 -0
  131. package/dist/runtime/agySubscriptionRealm.d.ts +38 -0
  132. package/dist/runtime/agySubscriptionRealm.d.ts.map +1 -0
  133. package/dist/runtime/agySubscriptionRealm.js +242 -0
  134. package/dist/runtime/attention.d.ts +26 -0
  135. package/dist/runtime/attention.d.ts.map +1 -0
  136. package/dist/runtime/attention.js +49 -0
  137. package/dist/runtime/attentionDispatcher.d.ts +78 -0
  138. package/dist/runtime/attentionDispatcher.d.ts.map +1 -0
  139. package/dist/runtime/attentionDispatcher.js +365 -0
  140. package/dist/runtime/cli.d.ts +7 -0
  141. package/dist/runtime/cli.d.ts.map +1 -0
  142. package/dist/runtime/cli.js +256 -0
  143. package/dist/runtime/codexSandboxProjection.d.ts +17 -0
  144. package/dist/runtime/codexSandboxProjection.d.ts.map +1 -0
  145. package/dist/runtime/codexSandboxProjection.js +40 -0
  146. package/dist/runtime/contract-manifest.json +1 -0
  147. package/dist/runtime/contract-manifest.sha256 +1 -0
  148. package/dist/runtime/contractManifest.d.ts +8 -0
  149. package/dist/runtime/contractManifest.d.ts.map +1 -0
  150. package/dist/runtime/contractManifest.js +4 -0
  151. package/dist/runtime/engineBrokerCapabilities.d.ts +40 -0
  152. package/dist/runtime/engineBrokerCapabilities.d.ts.map +1 -0
  153. package/dist/runtime/engineBrokerCapabilities.js +69 -0
  154. package/dist/runtime/engineBrokerControlClient.d.ts +55 -0
  155. package/dist/runtime/engineBrokerControlClient.d.ts.map +1 -0
  156. package/dist/runtime/engineBrokerControlClient.js +228 -0
  157. package/dist/runtime/engineBrokerCredentialJournal.d.ts +12 -0
  158. package/dist/runtime/engineBrokerCredentialJournal.d.ts.map +1 -0
  159. package/dist/runtime/engineBrokerCredentialJournal.js +26 -0
  160. package/dist/runtime/engineBrokerInferenceProtocol.d.ts +53 -0
  161. package/dist/runtime/engineBrokerInferenceProtocol.d.ts.map +1 -0
  162. package/dist/runtime/engineBrokerInferenceProtocol.js +65 -0
  163. package/dist/runtime/engineBrokerMcpCallLog.d.ts +171 -0
  164. package/dist/runtime/engineBrokerMcpCallLog.d.ts.map +1 -0
  165. package/dist/runtime/engineBrokerMcpCallLog.js +231 -0
  166. package/dist/runtime/engineBrokerMcpFacade.d.ts +59 -0
  167. package/dist/runtime/engineBrokerMcpFacade.d.ts.map +1 -0
  168. package/dist/runtime/engineBrokerMcpFacade.js +346 -0
  169. package/dist/runtime/engineBrokerNativeClient.d.ts +52 -0
  170. package/dist/runtime/engineBrokerNativeClient.d.ts.map +1 -0
  171. package/dist/runtime/engineBrokerNativeClient.js +151 -0
  172. package/dist/runtime/engineBrokerProtocol.d.ts +167 -0
  173. package/dist/runtime/engineBrokerProtocol.d.ts.map +1 -0
  174. package/dist/runtime/engineBrokerProtocol.js +357 -0
  175. package/dist/runtime/engineBrokerSealLedger.d.ts +70 -0
  176. package/dist/runtime/engineBrokerSealLedger.d.ts.map +1 -0
  177. package/dist/runtime/engineBrokerSealLedger.js +132 -0
  178. package/dist/runtime/engineBrokerService.d.ts +43 -0
  179. package/dist/runtime/engineBrokerService.d.ts.map +1 -0
  180. package/dist/runtime/engineBrokerService.js +196 -0
  181. package/dist/runtime/engineBrokerServiceCli.d.ts +5 -0
  182. package/dist/runtime/engineBrokerServiceCli.d.ts.map +1 -0
  183. package/dist/runtime/engineBrokerServiceCli.js +32 -0
  184. package/dist/runtime/engineBrokerServiceConfig.d.ts +55 -0
  185. package/dist/runtime/engineBrokerServiceConfig.d.ts.map +1 -0
  186. package/dist/runtime/engineBrokerServiceConfig.js +130 -0
  187. package/dist/runtime/engineBrokerSingleflight.d.ts +13 -0
  188. package/dist/runtime/engineBrokerSingleflight.d.ts.map +1 -0
  189. package/dist/runtime/engineBrokerSingleflight.js +24 -0
  190. package/dist/runtime/engineBrokerTurnAccounting.d.ts +76 -0
  191. package/dist/runtime/engineBrokerTurnAccounting.d.ts.map +1 -0
  192. package/dist/runtime/engineBrokerTurnAccounting.js +108 -0
  193. package/dist/runtime/engineBrokerTurnRegistry.d.ts +57 -0
  194. package/dist/runtime/engineBrokerTurnRegistry.d.ts.map +1 -0
  195. package/dist/runtime/engineBrokerTurnRegistry.js +159 -0
  196. package/dist/runtime/engineDispatcher.d.ts +38 -0
  197. package/dist/runtime/engineDispatcher.d.ts.map +1 -0
  198. package/dist/runtime/engineDispatcher.js +228 -0
  199. package/dist/runtime/engineReadiness.d.ts +23 -0
  200. package/dist/runtime/engineReadiness.d.ts.map +1 -0
  201. package/dist/runtime/engineReadiness.js +222 -0
  202. package/dist/runtime/grokAuthenticationError.d.ts +8 -0
  203. package/dist/runtime/grokAuthenticationError.d.ts.map +1 -0
  204. package/dist/runtime/grokAuthenticationError.js +20 -0
  205. package/dist/runtime/grokBrokerCredentialAuthority.d.ts +23 -0
  206. package/dist/runtime/grokBrokerCredentialAuthority.d.ts.map +1 -0
  207. package/dist/runtime/grokBrokerCredentialAuthority.js +150 -0
  208. package/dist/runtime/grokBrokerCredentialReader.d.ts +6 -0
  209. package/dist/runtime/grokBrokerCredentialReader.d.ts.map +1 -0
  210. package/dist/runtime/grokBrokerCredentialReader.js +38 -0
  211. package/dist/runtime/grokBrokerModelPolicy.d.ts +23 -0
  212. package/dist/runtime/grokBrokerModelPolicy.d.ts.map +1 -0
  213. package/dist/runtime/grokBrokerModelPolicy.js +28 -0
  214. package/dist/runtime/grokBrokerProjection.d.ts +114 -0
  215. package/dist/runtime/grokBrokerProjection.d.ts.map +1 -0
  216. package/dist/runtime/grokBrokerProjection.js +101 -0
  217. package/dist/runtime/grokBrokerProviderClock.d.ts +26 -0
  218. package/dist/runtime/grokBrokerProviderClock.d.ts.map +1 -0
  219. package/dist/runtime/grokBrokerProviderClock.js +133 -0
  220. package/dist/runtime/grokBrokerProxy.d.ts +69 -0
  221. package/dist/runtime/grokBrokerProxy.d.ts.map +1 -0
  222. package/dist/runtime/grokBrokerProxy.js +326 -0
  223. package/dist/runtime/grokBrokerProxyJson.d.ts +10 -0
  224. package/dist/runtime/grokBrokerProxyJson.d.ts.map +1 -0
  225. package/dist/runtime/grokBrokerProxyJson.js +31 -0
  226. package/dist/runtime/grokBrokerProxyRequest.d.ts +30 -0
  227. package/dist/runtime/grokBrokerProxyRequest.d.ts.map +1 -0
  228. package/dist/runtime/grokBrokerProxyRequest.js +85 -0
  229. package/dist/runtime/grokBrokerRealmLease.d.ts +4 -0
  230. package/dist/runtime/grokBrokerRealmLease.d.ts.map +1 -0
  231. package/dist/runtime/grokBrokerRealmLease.js +33 -0
  232. package/dist/runtime/grokBrokerRefresh.d.ts +2 -0
  233. package/dist/runtime/grokBrokerRefresh.d.ts.map +1 -0
  234. package/dist/runtime/grokBrokerRefresh.js +15 -0
  235. package/dist/runtime/grokBrokerRunBudget.d.ts +20 -0
  236. package/dist/runtime/grokBrokerRunBudget.d.ts.map +1 -0
  237. package/dist/runtime/grokBrokerRunBudget.js +85 -0
  238. package/dist/runtime/grokBrokerSlot.d.ts +6 -0
  239. package/dist/runtime/grokBrokerSlot.d.ts.map +1 -0
  240. package/dist/runtime/grokBrokerSlot.js +21 -0
  241. package/dist/runtime/grokBrokerTaskClock.d.ts +32 -0
  242. package/dist/runtime/grokBrokerTaskClock.d.ts.map +1 -0
  243. package/dist/runtime/grokBrokerTaskClock.js +120 -0
  244. package/dist/runtime/grokBrokerTurnMeter.d.ts +180 -0
  245. package/dist/runtime/grokBrokerTurnMeter.d.ts.map +1 -0
  246. package/dist/runtime/grokBrokerTurnMeter.js +337 -0
  247. package/dist/runtime/grokBrokerWorkerConfig.d.ts +89 -0
  248. package/dist/runtime/grokBrokerWorkerConfig.d.ts.map +1 -0
  249. package/dist/runtime/grokBrokerWorkerConfig.js +154 -0
  250. package/dist/runtime/grokEngineBroker.d.ts +88 -0
  251. package/dist/runtime/grokEngineBroker.d.ts.map +1 -0
  252. package/dist/runtime/grokEngineBroker.js +202 -0
  253. package/dist/runtime/grokEngineBrokerLedger.d.ts +52 -0
  254. package/dist/runtime/grokEngineBrokerLedger.d.ts.map +1 -0
  255. package/dist/runtime/grokEngineBrokerLedger.js +114 -0
  256. package/dist/runtime/grokEngineBrokerMetering.d.ts +51 -0
  257. package/dist/runtime/grokEngineBrokerMetering.d.ts.map +1 -0
  258. package/dist/runtime/grokEngineBrokerMetering.js +34 -0
  259. package/dist/runtime/grokEngineBrokerTurn.d.ts +82 -0
  260. package/dist/runtime/grokEngineBrokerTurn.d.ts.map +1 -0
  261. package/dist/runtime/grokEngineBrokerTurn.js +348 -0
  262. package/dist/runtime/grokEngineBrokerTurnEnd.d.ts +88 -0
  263. package/dist/runtime/grokEngineBrokerTurnEnd.d.ts.map +1 -0
  264. package/dist/runtime/grokEngineBrokerTurnEnd.js +148 -0
  265. package/dist/runtime/grokInferenceClientConfig.d.ts +41 -0
  266. package/dist/runtime/grokInferenceClientConfig.d.ts.map +1 -0
  267. package/dist/runtime/grokInferenceClientConfig.js +62 -0
  268. package/dist/runtime/grokInferenceGrants.d.ts +77 -0
  269. package/dist/runtime/grokInferenceGrants.d.ts.map +1 -0
  270. package/dist/runtime/grokInferenceGrants.js +116 -0
  271. package/dist/runtime/grokInferenceProxy.d.ts +29 -0
  272. package/dist/runtime/grokInferenceProxy.d.ts.map +1 -0
  273. package/dist/runtime/grokInferenceProxy.js +85 -0
  274. package/dist/runtime/grokInferenceProxyRequest.d.ts +23 -0
  275. package/dist/runtime/grokInferenceProxyRequest.d.ts.map +1 -0
  276. package/dist/runtime/grokInferenceProxyRequest.js +63 -0
  277. package/dist/runtime/grokSlotPreflightReceipt.d.ts +70 -0
  278. package/dist/runtime/grokSlotPreflightReceipt.d.ts.map +1 -0
  279. package/dist/runtime/grokSlotPreflightReceipt.js +101 -0
  280. package/dist/runtime/grokSubscriptionRealm.d.ts +4 -0
  281. package/dist/runtime/grokSubscriptionRealm.d.ts.map +1 -0
  282. package/dist/runtime/grokSubscriptionRealm.js +435 -0
  283. package/dist/runtime/grokSubscriptionRealmTypes.d.ts +26 -0
  284. package/dist/runtime/grokSubscriptionRealmTypes.d.ts.map +1 -0
  285. package/dist/runtime/grokSubscriptionRealmTypes.js +1 -0
  286. package/dist/runtime/grokWorkerAttestation.d.ts +175 -0
  287. package/dist/runtime/grokWorkerAttestation.d.ts.map +1 -0
  288. package/dist/runtime/grokWorkerAttestation.js +266 -0
  289. package/dist/runtime/grokWorkerDenyPlacement.d.ts +80 -0
  290. package/dist/runtime/grokWorkerDenyPlacement.d.ts.map +1 -0
  291. package/dist/runtime/grokWorkerDenyPlacement.js +128 -0
  292. package/dist/runtime/grokWorkerHomeAttestation.d.ts +32 -0
  293. package/dist/runtime/grokWorkerHomeAttestation.d.ts.map +1 -0
  294. package/dist/runtime/grokWorkerHomeAttestation.js +75 -0
  295. package/dist/runtime/grokWorkerSandboxProfile.d.ts +27 -0
  296. package/dist/runtime/grokWorkerSandboxProfile.d.ts.map +1 -0
  297. package/dist/runtime/grokWorkerSandboxProfile.js +44 -0
  298. package/dist/runtime/grokWorkerTmpAttestation.d.ts +55 -0
  299. package/dist/runtime/grokWorkerTmpAttestation.d.ts.map +1 -0
  300. package/dist/runtime/grokWorkerTmpAttestation.js +63 -0
  301. package/dist/runtime/index.d.ts +31 -0
  302. package/dist/runtime/index.d.ts.map +1 -0
  303. package/dist/runtime/index.js +27 -0
  304. package/dist/runtime/inferenceUsageLedger.d.ts +38 -0
  305. package/dist/runtime/inferenceUsageLedger.d.ts.map +1 -0
  306. package/dist/runtime/inferenceUsageLedger.js +53 -0
  307. package/dist/runtime/mcpToolResult.d.ts +127 -0
  308. package/dist/runtime/mcpToolResult.d.ts.map +1 -0
  309. package/dist/runtime/mcpToolResult.js +214 -0
  310. package/dist/runtime/moltnetMachineRead.d.ts +97 -0
  311. package/dist/runtime/moltnetMachineRead.d.ts.map +1 -0
  312. package/dist/runtime/moltnetMachineRead.js +183 -0
  313. package/dist/runtime/native/daimon-engine-broker +0 -0
  314. package/dist/runtime/organizationRuntime.d.ts +168 -0
  315. package/dist/runtime/organizationRuntime.d.ts.map +1 -0
  316. package/dist/runtime/organizationRuntime.js +3 -0
  317. package/dist/runtime/organizationRuntimeAdmission.d.ts +6 -0
  318. package/dist/runtime/organizationRuntimeAdmission.d.ts.map +1 -0
  319. package/dist/runtime/organizationRuntimeAdmission.js +22 -0
  320. package/dist/runtime/organizationRuntimeControl.d.ts +51 -0
  321. package/dist/runtime/organizationRuntimeControl.d.ts.map +1 -0
  322. package/dist/runtime/organizationRuntimeControl.js +283 -0
  323. package/dist/runtime/organizationRuntimeHost.d.ts +19 -0
  324. package/dist/runtime/organizationRuntimeHost.d.ts.map +1 -0
  325. package/dist/runtime/organizationRuntimeHost.js +368 -0
  326. package/dist/runtime/organizationRuntimeParsing.d.ts +6 -0
  327. package/dist/runtime/organizationRuntimeParsing.d.ts.map +1 -0
  328. package/dist/runtime/organizationRuntimeParsing.js +373 -0
  329. package/dist/runtime/organizationRuntimeReadiness.d.ts +12 -0
  330. package/dist/runtime/organizationRuntimeReadiness.d.ts.map +1 -0
  331. package/dist/runtime/organizationRuntimeReadiness.js +67 -0
  332. package/dist/runtime/organizationRuntimeRecording.d.ts +7 -0
  333. package/dist/runtime/organizationRuntimeRecording.d.ts.map +1 -0
  334. package/dist/runtime/organizationRuntimeRecording.js +58 -0
  335. package/dist/runtime/physicalReadiness.d.ts +59 -0
  336. package/dist/runtime/physicalReadiness.d.ts.map +1 -0
  337. package/dist/runtime/physicalReadiness.js +176 -0
  338. package/dist/runtime/portableCredentialAuth.d.ts +6 -0
  339. package/dist/runtime/portableCredentialAuth.d.ts.map +1 -0
  340. package/dist/runtime/portableCredentialAuth.js +70 -0
  341. package/dist/runtime/portableCredentialMaterial.d.ts +8 -0
  342. package/dist/runtime/portableCredentialMaterial.d.ts.map +1 -0
  343. package/dist/runtime/portableCredentialMaterial.js +169 -0
  344. package/dist/runtime/productionAgentTools.d.ts +5 -0
  345. package/dist/runtime/productionAgentTools.d.ts.map +1 -0
  346. package/dist/runtime/productionAgentTools.js +336 -0
  347. package/dist/runtime/relocateRuntimeConfig.d.ts +14 -0
  348. package/dist/runtime/relocateRuntimeConfig.d.ts.map +1 -0
  349. package/dist/runtime/relocateRuntimeConfig.js +38 -0
  350. package/dist/runtime/runtimeHomeLayout.d.ts +48 -0
  351. package/dist/runtime/runtimeHomeLayout.d.ts.map +1 -0
  352. package/dist/runtime/runtimeHomeLayout.js +84 -0
  353. package/dist/runtime/schedule.d.ts +40 -0
  354. package/dist/runtime/schedule.d.ts.map +1 -0
  355. package/dist/runtime/schedule.js +376 -0
  356. package/dist/runtime/storeCoordination.d.ts +33 -0
  357. package/dist/runtime/storeCoordination.d.ts.map +1 -0
  358. package/dist/runtime/storeCoordination.js +117 -0
  359. package/dist/runtime/taskClock.d.ts +42 -0
  360. package/dist/runtime/taskClock.d.ts.map +1 -0
  361. package/dist/runtime/taskClock.js +102 -0
  362. package/dist/runtime/taskClockProcess.d.ts +17 -0
  363. package/dist/runtime/taskClockProcess.d.ts.map +1 -0
  364. package/dist/runtime/taskClockProcess.js +58 -0
  365. package/dist/runtime/toolResultSpill.d.ts +152 -0
  366. package/dist/runtime/toolResultSpill.d.ts.map +1 -0
  367. package/dist/runtime/toolResultSpill.js +351 -0
  368. package/dist/runtime/turnRequestLedger.d.ts +155 -0
  369. package/dist/runtime/turnRequestLedger.d.ts.map +1 -0
  370. package/dist/runtime/turnRequestLedger.js +251 -0
  371. package/dist/runtime/turnUsageLedger.d.ts +143 -0
  372. package/dist/runtime/turnUsageLedger.d.ts.map +1 -0
  373. package/dist/runtime/turnUsageLedger.js +203 -0
  374. package/dist/runtime/wakeAcceptanceClaimDiagnostics.d.ts +34 -0
  375. package/dist/runtime/wakeAcceptanceClaimDiagnostics.d.ts.map +1 -0
  376. package/dist/runtime/wakeAcceptanceClaimDiagnostics.js +79 -0
  377. package/dist/runtime/wakeAcceptanceIndex.d.ts +55 -0
  378. package/dist/runtime/wakeAcceptanceIndex.d.ts.map +1 -0
  379. package/dist/runtime/wakeAcceptanceIndex.js +158 -0
  380. package/dist/runtime/wakeAcceptanceProcessIdentity.d.ts +25 -0
  381. package/dist/runtime/wakeAcceptanceProcessIdentity.d.ts.map +1 -0
  382. package/dist/runtime/wakeAcceptanceProcessIdentity.js +54 -0
  383. package/dist/runtime/wakeAcceptanceReconciliation.d.ts +211 -0
  384. package/dist/runtime/wakeAcceptanceReconciliation.d.ts.map +1 -0
  385. package/dist/runtime/wakeAcceptanceReconciliation.js +289 -0
  386. package/dist/runtime/wakeAcceptanceRecord.d.ts +25 -0
  387. package/dist/runtime/wakeAcceptanceRecord.d.ts.map +1 -0
  388. package/dist/runtime/wakeAcceptanceRecord.js +58 -0
  389. package/dist/runtime/wakeAcceptanceRetention.d.ts +36 -0
  390. package/dist/runtime/wakeAcceptanceRetention.d.ts.map +1 -0
  391. package/dist/runtime/wakeAcceptanceRetention.js +38 -0
  392. package/dist/runtime/wakeAcceptanceStore.d.ts +113 -0
  393. package/dist/runtime/wakeAcceptanceStore.d.ts.map +1 -0
  394. package/dist/runtime/wakeAcceptanceStore.js +561 -0
  395. package/dist/runtime/wakeAcceptanceTypes.d.ts +179 -0
  396. package/dist/runtime/wakeAcceptanceTypes.d.ts.map +1 -0
  397. package/dist/runtime/wakeAcceptanceTypes.js +95 -0
  398. package/dist/runtime/wakeFuse.d.ts +124 -0
  399. package/dist/runtime/wakeFuse.d.ts.map +1 -0
  400. package/dist/runtime/wakeFuse.js +466 -0
  401. package/dist/runtime/wakeMomentFs.d.ts +27 -0
  402. package/dist/runtime/wakeMomentFs.d.ts.map +1 -0
  403. package/dist/runtime/wakeMomentFs.js +223 -0
  404. package/dist/runtime/wakeMomentHistory.d.ts +26 -0
  405. package/dist/runtime/wakeMomentHistory.d.ts.map +1 -0
  406. package/dist/runtime/wakeMomentHistory.js +109 -0
  407. package/dist/runtime/wakeMomentIo.d.ts +22 -0
  408. package/dist/runtime/wakeMomentIo.d.ts.map +1 -0
  409. package/dist/runtime/wakeMomentIo.js +114 -0
  410. package/dist/runtime/wakeMomentRecorder.d.ts +33 -0
  411. package/dist/runtime/wakeMomentRecorder.d.ts.map +1 -0
  412. package/dist/runtime/wakeMomentRecorder.js +81 -0
  413. package/dist/runtime/wakeMomentRetention.d.ts +7 -0
  414. package/dist/runtime/wakeMomentRetention.d.ts.map +1 -0
  415. package/dist/runtime/wakeMomentRetention.js +143 -0
  416. package/dist/runtime/wakeMomentRows.d.ts +8 -0
  417. package/dist/runtime/wakeMomentRows.d.ts.map +1 -0
  418. package/dist/runtime/wakeMomentRows.js +66 -0
  419. package/dist/runtime/wakeMomentSnapshot.d.ts +56 -0
  420. package/dist/runtime/wakeMomentSnapshot.d.ts.map +1 -0
  421. package/dist/runtime/wakeMomentSnapshot.js +248 -0
  422. package/package.json +22 -11
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grokEngineBrokerTurn.d.ts","sourceRoot":"","sources":["../../src/runtime/grokEngineBrokerTurn.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,348 @@
1
+ import { brokerTaskClockFileFor } from "./grokBrokerSlot.js";
2
+ import { brokerClockObservation, parseBrokerProcessClock, prepareBrokerTaskClock, writeBrokerTaskClock } from "./grokBrokerTaskClock.js";
3
+ import { GrokBrokerProviderClock } from "./grokBrokerProviderClock.js";
4
+ import { createHash, randomUUID } from "node:crypto";
5
+ import { engineBrokerCapabilityTtlMs } from "./engineBrokerCapabilities.js";
6
+ import { decodeGrokHeadlessTurn } from "../pi/grokHeadlessResult.js";
7
+ import { decodeGrokStreamUsage } from "../pi/grokStreamUsage.js";
8
+ import { ENGINE_BROKER_VERSION, ENGINE_BROKER_TASK_CLOCK_RESET_FAILED } from "./engineBrokerProtocol.js";
9
+ import { lowerEngineBrokerTurnLimits, mapGrokReportedModel } from "./engineBrokerTurnAccounting.js";
10
+ import { NativeBrokerTurnFailure } from "./engineBrokerNativeClient.js";
11
+ import { engineBrokerRequestLedgerPathFor, engineBrokerSealLedgerPathFor } from "./engineBrokerServiceConfig.js";
12
+ import { ensureBrokerTurnLedgered } from "./grokEngineBrokerLedger.js";
13
+ import { finishBrokerTurnWithUsage } from "./grokEngineBrokerMetering.js";
14
+ import { GrokBrokerTurnMeter } from "./grokBrokerTurnMeter.js";
15
+ import { awaitGrokWorkerIdentityEmpty, findGrokWorkerProcess, GROK_WORKER_REAP_WAIT_MS, grokWorkerIdentityEmpty, watchGrokBrokerTurnEnd } from "./grokEngineBrokerTurnEnd.js";
16
+ import { GrokWorkerAttestationFailure } from "./grokWorkerAttestation.js";
17
+ export class EngineBrokerTurnFailure extends Error {
18
+ code;
19
+ diagnostic;
20
+ accounting;
21
+ mcpCalls;
22
+ shellClock;
23
+ providerClock;
24
+ cleanupDiagnostic;
25
+ constructor(code, diagnostic, accounting, mcpCalls, shellClock, providerClock, cleanupDiagnostic) {
26
+ super("engine broker turn failed");
27
+ this.code = code;
28
+ this.diagnostic = diagnostic;
29
+ this.accounting = accounting;
30
+ this.mcpCalls = mcpCalls;
31
+ this.shellClock = shellClock;
32
+ this.providerClock = providerClock;
33
+ this.cleanupDiagnostic = cleanupDiagnostic;
34
+ }
35
+ }
36
+ const limitReasonFor = { tokens: "token_ceiling", requests: "request_ceiling", timeout: "wake_timeout" };
37
+ const usageOf = (usage) => ({ input: usage.input, cacheRead: usage.cacheRead, cacheWrite: usage.cacheWrite, output: usage.output, total: usage.total });
38
+ /**
39
+ * One brokered Grok turn under its declared limits.
40
+ *
41
+ * The limits are the registration's, lowered (never raised) by the wake. The
42
+ * proxy meter refuses model requests past `maxRequests`, past the elapsed
43
+ * deadline, or once the upstream-reported running total reached `maxTokens`,
44
+ * and a tripped limit aborts the worker through the same cancel/kill path a
45
+ * client cancellation uses. A wall-clock timer trips `timeout` for a worker
46
+ * that is mid-request.
47
+ *
48
+ * Every terminal path — completed, failed, limit, cancelled — is sealed and
49
+ * metered through {@link finishBrokerTurnWithUsage}; a replayed turn returns its
50
+ * sealed accounting before any of this runs and never meters again.
51
+ */
52
+ export async function runGrokEngineBrokerTurn(deps, registration, wakeId, prompt, mcpEndpoint, signal, overrides, processClock) {
53
+ const { agentId } = registration, declared = registration.model.model;
54
+ const writeClock = deps.writeTaskClock ?? ((value) => writeBrokerTaskClock(value, brokerTaskClockFileFor(registration.slot)));
55
+ let limits;
56
+ try {
57
+ limits = lowerEngineBrokerTurnLimits(registration.limits, overrides);
58
+ if (processClock !== undefined)
59
+ parseBrokerProcessClock(processClock);
60
+ }
61
+ catch {
62
+ throw new EngineBrokerTurnFailure("invalid_request", undefined, { outcome: "failed", usage: null, model: declared, requests: 0, limitReason: "none" });
63
+ }
64
+ const turnId = createHash("sha256").update(`${registration.slot}\0${agentId}\0${wakeId}`).digest("hex");
65
+ const request = { version: ENGINE_BROKER_VERSION, kind: "start_turn", requestId: randomUUID(), turnId, slot: registration.slot, agentId, wakeId, prompt, mcpEndpoint, ...(overrides === undefined ? {} : { limits: overrides }), ...(processClock === undefined ? {} : { processClock }) };
66
+ const begun = await deps.turns.begin(request, declared);
67
+ const metering = { usageLedgerPath: registration.usageLedgerPath, requestLedgerPath: engineBrokerRequestLedgerPathFor(registration.usageLedgerPath), sealLedgerPath: engineBrokerSealLedgerPathFor(registration.usageLedgerPath), agentId, wakeId };
68
+ if (begun !== "start") {
69
+ await ensureBrokerTurnLedgered(begun.ledger, turnId, metering);
70
+ return replay(begun.replay);
71
+ }
72
+ const clock = processClock === undefined ? undefined : new GrokBrokerProviderClock(processClock);
73
+ const controller = new AbortController();
74
+ let worker;
75
+ const meter = new GrokBrokerTurnMeter(limits, () => controller.abort());
76
+ let cancelledByCaller = false;
77
+ const onAbort = () => { cancelledByCaller = true; controller.abort(); };
78
+ signal?.addEventListener("abort", onAbort, { once: true });
79
+ if (signal?.aborted) {
80
+ cancelledByCaller = true;
81
+ controller.abort();
82
+ }
83
+ const timer = setTimeout(() => meter.trip("timeout"), limits.timeoutMs);
84
+ timer.unref?.();
85
+ // What was in flight, and which worker held the final reply, at the instant the
86
+ // turn ended — read before killing the worker can close its calls or empty its
87
+ // identity. A final reply the 1 s watchdog poll never saw is caught here too.
88
+ let inFlightAtEnd = false;
89
+ controller.signal.addEventListener("abort", () => {
90
+ let mcp = 0;
91
+ try {
92
+ mcp = deps.mcp.activity?.(turnId)?.inFlight ?? 0;
93
+ }
94
+ catch {
95
+ mcp = 0;
96
+ }
97
+ inFlightAtEnd = mcp > 0 || meter.busy();
98
+ if (meter.finalReply() !== undefined)
99
+ worker ??= (deps.observeWorker ?? findGrokWorkerProcess)(registration.workerUid).catch(() => undefined);
100
+ }, { once: true });
101
+ let shellClock;
102
+ let resetClock = deps.clockedSlot === true;
103
+ let nativeStarted = false;
104
+ let workerReaped = false;
105
+ let sealedFailure;
106
+ let nativeDiagnostic, attested = false, output, rejected = false, sealed;
107
+ // Set when the broker itself ended the turn (`grokEngineBrokerTurnEnd.ts`); the worker seen at the final reply names the turn it ended.
108
+ let endedBy;
109
+ let watchdog, isolationGuard;
110
+ try {
111
+ const isolation = await deps.prepareIsolation(registration);
112
+ isolationGuard = isolation.guard;
113
+ // Publication may throw after rename. Claim cleanup before attempting it.
114
+ resetClock ||= isolation.configVariant === "clocked";
115
+ const coverage = await prepareBrokerTaskClock(isolation.configVariant, processClock, writeClock);
116
+ if (isolation.configVariant === "clocked" || processClock !== undefined)
117
+ shellClock = coverage;
118
+ deps.proxy.registerIsolationGuard(turnId, isolationGuard);
119
+ deps.proxy.registerTurn(turnId, { policy: registration.model, meter, clock });
120
+ const capabilityTtlMs = engineBrokerCapabilityTtlMs(limits.timeoutMs);
121
+ const providerCapability = deps.proxy.capabilities.issue(agentId, turnId, capabilityTtlMs), mcpCapability = deps.mcp.register(agentId, turnId, mcpEndpoint, capabilityTtlMs);
122
+ watchdog = watchGrokBrokerTurnEnd({
123
+ meter, activity: () => deps.mcp.activity?.(turnId), signal: controller.signal, ...(deps.turnEnd === undefined ? {} : { timing: deps.turnEnd }),
124
+ // The worker is read once, as soon as it has made a request — long before
125
+ // anything can end the turn and reap it — so a final reply is never left
126
+ // without the worker that gave it.
127
+ onPoll: () => { if (worker === undefined && meter.snapshot().requests > 0)
128
+ worker = (deps.observeWorker ?? findGrokWorkerProcess)(registration.workerUid).catch(() => undefined); },
129
+ onFinalReply: () => { worker ??= (deps.observeWorker ?? findGrokWorkerProcess)(registration.workerUid).catch(() => undefined); },
130
+ // An idle stall is a deadline of its own: it trips the meter as a timeout, so it seals like one.
131
+ onEnd: (reason) => { endedBy = reason; if (reason === "idle")
132
+ meter.trip("timeout");
133
+ else
134
+ controller.abort(); }
135
+ });
136
+ nativeStarted = true;
137
+ const result = await deps.runNative({ slot: registration.slot, requestId: request.requestId, turnId, agentId, wakeId, prompt, providerCapability, mcpCapability }, controller.signal);
138
+ nativeDiagnostic = result.diagnostic;
139
+ output = result.text;
140
+ if (result.workerUid !== registration.workerUid)
141
+ throw new Error("engine broker worker identity mismatch");
142
+ await isolationGuard();
143
+ attested = true;
144
+ rejected = true;
145
+ const decoded = decodeGrokHeadlessTurn(result.text), stream = decodeGrokStreamUsage(result.text);
146
+ if (stream.reportedModels.some((reported) => mapGrokReportedModel(reported, declared) === undefined))
147
+ throw new Error("engine broker reported an undeclared model");
148
+ rejected = false;
149
+ const snapshot = meter.snapshot();
150
+ if (snapshot.limitReason !== "none")
151
+ throw new Error("engine broker turn limit reached");
152
+ const usage = decoded.usage === undefined ? streamOrMeterUsage(stream, snapshot) : usageOf(decoded.usage);
153
+ const accounting = { outcome: "completed", usage, model: declared, requests: requestCount(stream, snapshot), limitReason: "none" };
154
+ const observation = brokerClockObservation(shellClock, clock?.snapshot());
155
+ const completed = {
156
+ version: request.version, kind: "completed", requestId: request.requestId, turnId,
157
+ text: decoded.text, workerPid: result.workerPid, workerUid: result.workerUid,
158
+ workerStartTime: result.startTicks.toString(), ...observation, ...accounting
159
+ };
160
+ const result_ = {
161
+ text: completed.text, workerPid: completed.workerPid, workerUid: completed.workerUid,
162
+ workerStartTime: completed.workerStartTime, ...observation, ...accounting
163
+ };
164
+ await finishBrokerTurnWithUsage(deps.turns, request, completed, metering, { notionalUsd: decoded.usage?.notionalUsd ?? 0, complete: decoded.usage?.complete ?? false, estimatedRequests: snapshot.estimatedRequests, requests: requestRows(stream, snapshot), ...(stream.sessionId === undefined ? {} : { session: stream.sessionId }) }, () => { sealed = result_; });
165
+ return result_;
166
+ }
167
+ catch (error) {
168
+ // Once the completed record is published it is the durable truth: anything
169
+ // failing after that (metering) must neither re-seal the turn as failed nor
170
+ // append a second row.
171
+ if (sealed !== undefined)
172
+ return sealed;
173
+ watchdog?.stop();
174
+ // A turn this broker aborted is sealed only once its worker identity is
175
+ // empty (bounded): the agent's next turn must not start a worker the
176
+ // previous launcher handler's identity-wide reap would kill.
177
+ if (controller.signal.aborted) {
178
+ workerReaped = await awaitGrokWorkerIdentityEmpty(registration.workerUid, deps.workerReapWaitMs ?? GROK_WORKER_REAP_WAIT_MS, deps.workerIdentityEmpty ?? ((uid) => grokWorkerIdentityEmpty(uid, undefined, resetClock)));
179
+ }
180
+ // Not aborted (an output-limit failure, say): nothing was killed, so the live view is the true one.
181
+ if (!controller.signal.aborted) {
182
+ let mcp = 0;
183
+ try {
184
+ mcp = deps.mcp.activity?.(turnId)?.inFlight ?? 0;
185
+ }
186
+ catch {
187
+ mcp = 0;
188
+ }
189
+ inFlightAtEnd = mcp > 0 || meter.busy();
190
+ }
191
+ const vetoed = cancelledByCaller || rejected || (output !== undefined && !attested) || inFlightAtEnd;
192
+ // Finished work is completed work. A worker that gave its final reply and was
193
+ // then ended by the broker, refused its stdout by the launcher's output bound,
194
+ // or left idle into the deadline did its job; only its exit went wrong.
195
+ const finished = vetoed ? undefined : await completedFromFinalReply(deps, registration, request, meter, error, endedBy, worker, isolationGuard, metering, (value) => { sealed = value; }, shellClock, clock).catch(() => undefined);
196
+ if (finished !== undefined)
197
+ return finished;
198
+ // Sealed completed but its ledger append failed: the published record is the truth, exactly as on the success path.
199
+ if (sealed !== undefined)
200
+ return sealed;
201
+ const snapshot = meter.snapshot();
202
+ const code = snapshot.limitReason !== "none" ? "limit_exceeded" : deps.credentialStale() ? "auth_stale" : controller.signal.aborted ? "cancelled" : "engine_failed";
203
+ const diagnostic = error instanceof NativeBrokerTurnFailure ? error.diagnostic : nativeDiagnostic && !attested ? { ...nativeDiagnostic, status: "worker_failed", stage: "attestation", failureClass: error instanceof GrokWorkerAttestationFailure ? error.failureClass : "profile_invalid", profileApplied: false } : undefined;
204
+ const stream = output === undefined ? undefined : decodeGrokStreamUsage(output);
205
+ const accounting = { outcome: "failed", usage: streamOrMeterUsage(stream, snapshot), model: declared, requests: requestCount(stream, snapshot), limitReason: snapshot.limitReason };
206
+ // Read before the `finally` revokes this turn's MCP registration, and
207
+ // swallowed like every other instrument here: it must never be the reason
208
+ // a turn reports something other than why it failed.
209
+ let mcpCalls;
210
+ try {
211
+ mcpCalls = deps.mcp.observe?.(turnId);
212
+ }
213
+ catch {
214
+ mcpCalls = undefined;
215
+ }
216
+ const observation = brokerClockObservation(shellClock, clock?.snapshot());
217
+ const failed = {
218
+ version: request.version, kind: "failed", requestId: request.requestId, turnId, code,
219
+ ...observation, ...(diagnostic ? { diagnostic } : {}),
220
+ ...(mcpCalls === undefined ? {} : { mcpCalls }), ...accounting
221
+ };
222
+ const reason = snapshot.limitReason !== "none" ? limitReasonFor[snapshot.limitReason] : rejected ? "turn_rejected" : "unknown";
223
+ const failure = new EngineBrokerTurnFailure(code, diagnostic, accounting, mcpCalls, shellClock, observation.providerClock);
224
+ await finishBrokerTurnWithUsage(deps.turns, request, failed, metering, {
225
+ notionalUsd: 0, complete: false, reason, estimatedRequests: snapshot.estimatedRequests,
226
+ requests: requestRows(stream, snapshot), ...(stream?.sessionId === undefined ? {} : { session: stream.sessionId })
227
+ }, () => { sealedFailure = failure; });
228
+ throw failure;
229
+ }
230
+ finally {
231
+ watchdog?.stop();
232
+ clearTimeout(timer);
233
+ signal?.removeEventListener("abort", onAbort);
234
+ meter.abortInFlight();
235
+ try {
236
+ deps.proxy.revokeTurn(turnId);
237
+ deps.proxy.revokeIsolationGuard(turnId);
238
+ deps.proxy.capabilities.revoke(turnId);
239
+ deps.mcp.revoke(turnId);
240
+ }
241
+ finally {
242
+ if (resetClock) {
243
+ try {
244
+ // A disconnected launcher client can settle before its worker is reaped.
245
+ // Never change the clock of a surviving shell, or release the slot as healthy.
246
+ if (nativeStarted && !workerReaped) {
247
+ workerReaped = await awaitGrokWorkerIdentityEmpty(registration.workerUid, deps.workerReapWaitMs ?? GROK_WORKER_REAP_WAIT_MS, deps.workerIdentityEmpty ?? ((uid) => grokWorkerIdentityEmpty(uid, undefined, true)));
248
+ if (!workerReaped)
249
+ throw new Error("Grok broker task clock worker did not terminate");
250
+ }
251
+ await writeClock(undefined);
252
+ }
253
+ catch (error) {
254
+ deps.taskClockFailed?.();
255
+ // Cleanup cannot replace a published outcome. Report the live fence
256
+ // on the wire without rewriting the seal or its accounting.
257
+ if (sealed !== undefined)
258
+ return { ...sealed, cleanupDiagnostic: ENGINE_BROKER_TASK_CLOCK_RESET_FAILED };
259
+ if (sealedFailure !== undefined)
260
+ throw new EngineBrokerTurnFailure(sealedFailure.code, sealedFailure.diagnostic, sealedFailure.accounting, sealedFailure.mcpCalls, sealedFailure.shellClock, sealedFailure.providerClock, ENGINE_BROKER_TASK_CLOCK_RESET_FAILED);
261
+ throw new Error("Grok broker task clock cleanup failed; restart required", { cause: error });
262
+ }
263
+ }
264
+ }
265
+ }
266
+ }
267
+ function replay(response) {
268
+ const accounting = { outcome: response.outcome, usage: response.usage, model: response.model, requests: response.requests, limitReason: response.limitReason };
269
+ if (response.kind === "completed")
270
+ return {
271
+ text: response.text, workerPid: response.workerPid, workerUid: response.workerUid,
272
+ workerStartTime: response.workerStartTime,
273
+ ...brokerClockObservation(response.shellClock, response.providerClock), ...accounting, outcome: "completed"
274
+ };
275
+ const code = response.code === "turn_conflict" || response.code === "unavailable" ? "engine_failed" : response.code;
276
+ throw new EngineBrokerTurnFailure(code, response.diagnostic, accounting, response.mcpCalls, response.shellClock, response.providerClock);
277
+ }
278
+ /**
279
+ * The completed seal for a turn whose model gave its final reply but whose
280
+ * worker never delivered stdout: the broker ended it (`final_reply`), the
281
+ * launcher's output bound refused its stream (`output_limit`, which publishes
282
+ * nothing), or it idled into the wall-clock deadline. The reply is the one the
283
+ * proxy saw, already bounded with a marker (`boundGrokFinalReply`), the usage is
284
+ * what the proxy metered, and the worker is the one the launcher reported or
285
+ * the broker observed while it was alive. `undefined` — and the ordinary
286
+ * failure seal — whenever any of that is missing, the isolation attestation
287
+ * fails, or the failure was anything else (a token or request limit, a client
288
+ * cancellation, an engine fault before the reply). The caller vetoes it outright
289
+ * for a caller cancellation, a rejected or unattested stdout, and a model
290
+ * request or MCP tool call still in flight.
291
+ */
292
+ async function completedFromFinalReply(deps, registration, request, meter, error, endedBy, worker, isolationGuard, metering, onSealed, shellClock, clock) {
293
+ const final = meter.finalReply(), snapshot = meter.snapshot();
294
+ if (final === undefined || isolationGuard === undefined || snapshot.usage === null)
295
+ return undefined;
296
+ // A token or request limit is never finished work, whatever else failed beside it.
297
+ if (snapshot.limitReason === "tokens" || snapshot.limitReason === "requests")
298
+ return undefined;
299
+ const outputLimited = error instanceof NativeBrokerTurnFailure && error.diagnostic.failureClass === "output_limit" && error.diagnostic.workerPid > 0;
300
+ if (!(endedBy === "final_reply" || outputLimited || (snapshot.limitReason === "timeout" && endedBy !== "idle")))
301
+ return undefined;
302
+ const identity = outputLimited ? { pid: error.diagnostic.workerPid, uid: error.diagnostic.workerUid, startTicks: error.diagnostic.startTicks } : await (async () => { const seen = (await worker) ?? await (deps.observeWorker ?? findGrokWorkerProcess)(registration.workerUid).catch(() => undefined); return seen === undefined ? undefined : { ...seen, uid: registration.workerUid }; })();
303
+ if (identity === undefined || identity.uid !== registration.workerUid)
304
+ return undefined;
305
+ await isolationGuard();
306
+ const accounting = { outcome: "completed", usage: snapshot.usage, model: registration.model.model, requests: snapshot.requests, limitReason: "none" };
307
+ const observation = brokerClockObservation(shellClock, clock?.snapshot());
308
+ const completed = {
309
+ version: request.version, kind: "completed", requestId: request.requestId, turnId: request.turnId,
310
+ text: final.text, workerPid: identity.pid, workerUid: identity.uid, workerStartTime: identity.startTicks,
311
+ ...observation, ...accounting
312
+ };
313
+ const result = {
314
+ text: completed.text, workerPid: completed.workerPid, workerUid: completed.workerUid,
315
+ workerStartTime: completed.workerStartTime, ...observation, ...accounting
316
+ };
317
+ await finishBrokerTurnWithUsage(deps.turns, request, completed, metering, { notionalUsd: 0, complete: false, estimatedRequests: snapshot.estimatedRequests, requests: requestRows(undefined, snapshot) }, () => onSealed(result));
318
+ return result;
319
+ }
320
+ /** The proxy saw every forwarded request; the stream is the fallback when no request crossed this proxy. */
321
+ const requestCount = (stream, snapshot) => snapshot.requests > 0 ? snapshot.requests : stream?.requests.length ?? 0;
322
+ /** Best partial usage: the worker's own per-request frames when any arrived, else what upstream reported to the proxy. */
323
+ function streamOrMeterUsage(stream, snapshot) {
324
+ if (stream !== undefined && stream.requests.length > 0) {
325
+ const sum = (pick) => stream.requests.reduce((total, value) => total + pick(value), 0);
326
+ return { input: sum((value) => value.input), cacheRead: sum((value) => value.cacheRead), cacheWrite: sum((value) => value.cacheWrite), output: sum((value) => value.output), total: sum((value) => value.total) };
327
+ }
328
+ return snapshot.usage;
329
+ }
330
+ /** Per-request rows: stream usage with the proxy's own observation when both describe the same requests, else the proxy's measured requests. */
331
+ function requestRows(stream, snapshot) {
332
+ if (stream !== undefined && stream.requests.length > 0) {
333
+ const timed = snapshot.timings.length === stream.requests.length;
334
+ return stream.requests.map((value, index) => ({ ...value, usageSource: "stream", ...(timed ? observed(snapshot.timings[index]) : {}) }));
335
+ }
336
+ return snapshot.timings.flatMap((timing, index) => timing.usage === undefined ? [] : [{ index, ...usageOf(timing.usage), usageSource: timing.estimated === true ? "estimated" : "upstream", ...observed(timing) }]);
337
+ }
338
+ /**
339
+ * What only the proxy saw of one request: its clock, and the tool-call names the
340
+ * response carried. Both are attached on the stream path only when the two
341
+ * descriptions are request-for-request aligned, because an unaligned index would
342
+ * credit one request's attempt to another.
343
+ */
344
+ const observed = (timing) => ({
345
+ startedAt: timing.startedAt,
346
+ ...(timing.endedAt === undefined ? {} : { endedAt: timing.endedAt }),
347
+ ...(timing.toolCalls === undefined ? {} : { toolCalls: timing.toolCalls })
348
+ });
@@ -0,0 +1,88 @@
1
+ import type { EngineBrokerMcpActivity } from "./engineBrokerMcpCallLog.js";
2
+ import type { GrokBrokerTurnMeter } from "./grokBrokerTurnMeter.js";
3
+ /**
4
+ * When a brokered turn is over, decided by the broker rather than by the
5
+ * worker's exit.
6
+ *
7
+ * Grok 1.0.34 answers, logs `handle_prompt.done ok:true`, ends its session
8
+ * `turn_ended completed` — and then does not exit. Production measured it: 61
9
+ * of 128 turns over two days sat 8–27 minutes after their last model request
10
+ * until the wall-clock limit killed them, and each was then sealed
11
+ * `failed/timeout` with its work already done. Every one still had its MCP GET
12
+ * tunnel open, but that is a symptom: against the real 1.0.34 binary the tunnel
13
+ * held open, closed, refused (405) or absent all exit ~55 ms after `result`,
14
+ * and Grok reopens a closed tunnel within milliseconds, so closing it cannot
15
+ * end a worker. The launcher only publishes a worker's output when the worker
16
+ * exits, so waiting for the exit made the deadline the only way a turn could
17
+ * end.
18
+ *
19
+ * The proxy sees every model answer, so the broker knows when the model has
20
+ * given its final reply: a successful response that called no tool and
21
+ * stopped. From that point:
22
+ *
23
+ * 1. `onFinalReply` runs once — the broker notes the worker it will end while
24
+ * that worker is certainly still alive.
25
+ * 2. After {@link GROK_BROKER_TURN_END}`.finalGraceMs` with no new model request
26
+ * and no tool call in flight, `onEnd("final_reply")` runs: the broker ends
27
+ * the worker and seals the turn completed with that reply.
28
+ *
29
+ * A new model request clears the final reply (the meter forgets it on admit),
30
+ * so a model that keeps going is never cut off. Independently, a turn with no
31
+ * model request and no tool call in flight and no activity of either kind for
32
+ * `idleMs` ends as `onEnd("idle")` — the backstop for a worker that stalls
33
+ * without ever answering. Shell tools Grok runs itself are invisible here, so
34
+ * the idle bound is minutes, not seconds.
35
+ */
36
+ export type GrokBrokerTurnEndTiming = Readonly<{
37
+ finalGraceMs: number;
38
+ idleMs: number;
39
+ pollMs: number;
40
+ }>;
41
+ export declare const GROK_BROKER_TURN_END: GrokBrokerTurnEndTiming;
42
+ /** How long a turn the broker aborted waits for its worker identity to empty before it is sealed. */
43
+ export declare const GROK_WORKER_REAP_WAIT_MS = 10000;
44
+ export type GrokBrokerTurnEndReason = "final_reply" | "idle";
45
+ export declare function watchGrokBrokerTurnEnd(input: Readonly<{
46
+ meter: Pick<GrokBrokerTurnMeter, "finalReply" | "busy" | "lastActivityAt">;
47
+ activity: () => EngineBrokerMcpActivity | undefined;
48
+ onFinalReply: () => void;
49
+ /** Every poll, before any decision: the broker records the worker while it is certainly alive. */
50
+ onPoll?: () => void;
51
+ onEnd: (reason: GrokBrokerTurnEndReason) => void;
52
+ timing?: GrokBrokerTurnEndTiming;
53
+ now?: () => number;
54
+ /** The turn's own abort: once anything else ended the turn, the watchdog never claims it. */
55
+ signal?: AbortSignal;
56
+ }>): Readonly<{
57
+ stop(): void;
58
+ }>;
59
+ /** The launcher-forked root of a worker identity's process tree: its pid and `/proc/<pid>/stat` start time, as the launcher itself reports them. */
60
+ export type GrokWorkerProcess = Readonly<{
61
+ pid: number;
62
+ startTicks: string;
63
+ }>;
64
+ /**
65
+ * Finds the worker the launcher started for `uid`, read-only from `/proc`.
66
+ *
67
+ * A turn the broker ends early never receives the launcher's result frame (a
68
+ * cancelled client is not written to), yet a completed response must name the
69
+ * worker it came from. One identity carries at most one turn at a time
70
+ * (`native/AGENTS.md`), so a process owned by `uid` whose parent is *not* owned
71
+ * by `uid` is a worker the launcher forked. A previous turn's worker can still
72
+ * be alive beside it — a hung worker is exactly what this module exists for, and
73
+ * its kill is the launcher's — so the newest such root (the latest start time)
74
+ * is this turn's: turns of one identity are sequential.
75
+ */
76
+ export declare function findGrokWorkerProcess(uid: number, procRoot?: string): Promise<GrokWorkerProcess | undefined>;
77
+ /** No process at all, zombies included, owned by `uid`. */
78
+ export declare function grokWorkerIdentityEmpty(uid: number, procRoot?: string, requireReadable?: boolean): Promise<boolean>;
79
+ /**
80
+ * Waits, bounded, for the worker identity to empty after the broker ended a
81
+ * turn. Ending a turn kills the launcher's client; the launcher handler then
82
+ * kills and reaps the identity on its own schedule. Sealing first would let
83
+ * the agent's next turn start a worker on the same identity that the previous
84
+ * handler's identity-wide reap then kills. The bound keeps a wedged launcher
85
+ * from holding the agent: past it the turn is sealed anyway, as before.
86
+ */
87
+ export declare function awaitGrokWorkerIdentityEmpty(uid: number, timeoutMs: number, empty?: (uid: number) => Promise<boolean>, pollMs?: number, stableMs?: number): Promise<boolean>;
88
+ //# sourceMappingURL=grokEngineBrokerTurnEnd.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grokEngineBrokerTurnEnd.d.ts","sourceRoot":"","sources":["../../src/runtime/grokEngineBrokerTurnEnd.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAC3E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAEpE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AACzG,eAAO,MAAM,oBAAoB,EAAE,uBAAqG,CAAC;AACzI,qGAAqG;AACrG,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAC/C,MAAM,MAAM,uBAAuB,GAAG,aAAa,GAAG,MAAM,CAAC;AAE7D,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,QAAQ,CAAC;IACrD,KAAK,EAAE,IAAI,CAAC,mBAAmB,EAAE,YAAY,GAAG,MAAM,GAAG,gBAAgB,CAAC,CAAC;IAC3E,QAAQ,EAAE,MAAM,uBAAuB,GAAG,SAAS,CAAC;IACpD,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,kGAAkG;IAClG,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,EAAE,CAAC,MAAM,EAAE,uBAAuB,KAAK,IAAI,CAAC;IACjD,MAAM,CAAC,EAAE,uBAAuB,CAAC;IACjC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,6FAA6F;IAC7F,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,CAAC,GAAG,QAAQ,CAAC;IAAE,IAAI,IAAI,IAAI,CAAA;CAAE,CAAC,CAyB9B;AAED,oJAAoJ;AACpJ,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE9E;;;;;;;;;;;GAWG;AACH,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,SAAU,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAqBnH;AAED,2DAA2D;AAC3D,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,MAAM,EAAE,QAAQ,SAAU,EAAE,eAAe,UAAQ,GACvD,OAAO,CAAC,OAAO,CAAC,CAgBlB;AAED;;;;;;;GAOG;AACH,wBAAsB,4BAA4B,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAA2B,EAAE,MAAM,SAAM,EAAE,QAAQ,SAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAarM"}
@@ -0,0 +1,148 @@
1
+ import { readdir, readFile } from "node:fs/promises";
2
+ import { performance } from "node:perf_hooks";
3
+ export const GROK_BROKER_TURN_END = Object.freeze({ finalGraceMs: 15_000, idleMs: 10 * 60_000, pollMs: 1_000 });
4
+ /** How long a turn the broker aborted waits for its worker identity to empty before it is sealed. */
5
+ export const GROK_WORKER_REAP_WAIT_MS = 10_000;
6
+ export function watchGrokBrokerTurnEnd(input) {
7
+ const timing = input.timing ?? GROK_BROKER_TURN_END, now = input.now ?? Date.now;
8
+ let notified, done = false;
9
+ const check = () => {
10
+ if (done)
11
+ return;
12
+ if (input.signal?.aborted === true) {
13
+ stop();
14
+ return;
15
+ }
16
+ try {
17
+ input.onPoll?.();
18
+ }
19
+ catch { /* observation only */ }
20
+ const final = input.meter.finalReply();
21
+ if (final !== undefined && notified !== final.index) {
22
+ notified = final.index;
23
+ try {
24
+ input.onFinalReply();
25
+ }
26
+ catch { /* closing streams is best effort; the grace below still ends the turn */ }
27
+ }
28
+ let activity;
29
+ try {
30
+ activity = input.activity();
31
+ }
32
+ catch {
33
+ activity = undefined;
34
+ }
35
+ if (input.meter.busy() || (activity?.inFlight ?? 0) > 0)
36
+ return;
37
+ const quietSince = Math.max(input.meter.lastActivityAt(), activity?.lastActivityAt ?? 0);
38
+ const reason = final !== undefined && now() - Math.max(final.at, quietSince) >= timing.finalGraceMs ? "final_reply"
39
+ : now() - quietSince >= timing.idleMs ? "idle" : undefined;
40
+ if (reason === undefined)
41
+ return;
42
+ stop();
43
+ input.onEnd(reason);
44
+ };
45
+ const timer = setInterval(check, timing.pollMs);
46
+ timer.unref?.();
47
+ const stop = () => { done = true; clearInterval(timer); };
48
+ return { stop };
49
+ }
50
+ /**
51
+ * Finds the worker the launcher started for `uid`, read-only from `/proc`.
52
+ *
53
+ * A turn the broker ends early never receives the launcher's result frame (a
54
+ * cancelled client is not written to), yet a completed response must name the
55
+ * worker it came from. One identity carries at most one turn at a time
56
+ * (`native/AGENTS.md`), so a process owned by `uid` whose parent is *not* owned
57
+ * by `uid` is a worker the launcher forked. A previous turn's worker can still
58
+ * be alive beside it — a hung worker is exactly what this module exists for, and
59
+ * its kill is the launcher's — so the newest such root (the latest start time)
60
+ * is this turn's: turns of one identity are sequential.
61
+ */
62
+ export async function findGrokWorkerProcess(uid, procRoot = "/proc") {
63
+ let entries;
64
+ try {
65
+ entries = await readdir(procRoot);
66
+ }
67
+ catch {
68
+ return undefined;
69
+ }
70
+ const owned = new Map();
71
+ for (const entry of entries) {
72
+ if (!/^\d+$/u.test(entry))
73
+ continue;
74
+ try {
75
+ const status = await readFile(`${procRoot}/${entry}/status`, "utf8");
76
+ const real = /^Uid:\s+(\d+)/mu.exec(status)?.[1];
77
+ if (real === undefined || Number(real) !== uid)
78
+ continue;
79
+ const stat = await readFile(`${procRoot}/${entry}/stat`, "utf8");
80
+ const fields = stat.slice(stat.lastIndexOf(")") + 1).trim().split(/\s+/u);
81
+ // After the command: state(0) ppid(1) … starttime is field 22 of stat, index 19 here.
82
+ const parent = Number(fields[1]), startTicks = fields[19];
83
+ if (fields[0] === "Z" || !Number.isSafeInteger(parent) || startTicks === undefined || !/^[1-9][0-9]*$/u.test(startTicks))
84
+ continue;
85
+ owned.set(Number(entry), { parent, startTicks });
86
+ }
87
+ catch { /* a process exiting mid-scan is not part of the answer */ }
88
+ }
89
+ const roots = [...owned].filter(([, value]) => !owned.has(value.parent)).sort(([, left], [, right]) => BigInt(right.startTicks) > BigInt(left.startTicks) ? 1 : BigInt(right.startTicks) < BigInt(left.startTicks) ? -1 : 0);
90
+ const newest = roots[0];
91
+ return newest === undefined ? undefined : { pid: newest[0], startTicks: newest[1].startTicks };
92
+ }
93
+ /** No process at all, zombies included, owned by `uid`. */
94
+ export async function grokWorkerIdentityEmpty(uid, procRoot = "/proc", requireReadable = false) {
95
+ let entries;
96
+ try {
97
+ entries = await readdir(procRoot);
98
+ }
99
+ catch {
100
+ return !requireReadable;
101
+ }
102
+ for (const entry of entries) {
103
+ if (!/^\d+$/u.test(entry))
104
+ continue;
105
+ try {
106
+ const status = await readFile(`${procRoot}/${entry}/status`, "utf8");
107
+ // Zombies count, exactly as the launcher's own reap counts them.
108
+ if (Number(/^Uid:\s+(\d+)/mu.exec(status)?.[1]) !== uid)
109
+ continue;
110
+ return false;
111
+ }
112
+ catch (error) {
113
+ // ENOENT is a process exiting mid-scan; an unreadable identity is not empty.
114
+ if (requireReadable && error.code !== "ENOENT")
115
+ return false;
116
+ }
117
+ }
118
+ return true;
119
+ }
120
+ /**
121
+ * Waits, bounded, for the worker identity to empty after the broker ended a
122
+ * turn. Ending a turn kills the launcher's client; the launcher handler then
123
+ * kills and reaps the identity on its own schedule. Sealing first would let
124
+ * the agent's next turn start a worker on the same identity that the previous
125
+ * handler's identity-wide reap then kills. The bound keeps a wedged launcher
126
+ * from holding the agent: past it the turn is sealed anyway, as before.
127
+ */
128
+ export async function awaitGrokWorkerIdentityEmpty(uid, timeoutMs, empty = grokWorkerIdentityEmpty, pollMs = 100, stableMs = 300) {
129
+ // Empty must hold across a window longer than the launcher's own reap pass
130
+ // (10 ms between scans): one empty glimpse can fall between its kill and its
131
+ // re-scan, and that re-scan would kill the agent's next worker.
132
+ // Cleanup must measure elapsed real time even if the wall clock changes.
133
+ const deadline = performance.now() + timeoutMs;
134
+ let emptySince;
135
+ for (;;) {
136
+ const now = performance.now();
137
+ if (await empty(uid).catch(() => false)) {
138
+ emptySince ??= now;
139
+ if (now - emptySince >= stableMs)
140
+ return true;
141
+ }
142
+ else
143
+ emptySince = undefined;
144
+ if (now >= deadline)
145
+ return false;
146
+ await new Promise((resolve) => setTimeout(resolve, pollMs));
147
+ }
148
+ }
@@ -0,0 +1,41 @@
1
+ import { type GrokBrokerModelPolicy } from "./grokBrokerModelPolicy.js";
2
+ /** The evaluator CLI's only model id: Paideia passes `--model daimon-inference-grok`, never a catalog id. */
3
+ export declare const GROK_INFERENCE_CLIENT_MODEL_ID: "daimon-inference-grok";
4
+ /** The environment variable the evaluator CLI reads its grant token from. */
5
+ export declare const GROK_INFERENCE_GRANT_ENV: "DAIMON_INFERENCE_GRANT";
6
+ export type GrokInferenceClientConfigInput = Readonly<{
7
+ baseUrl: string;
8
+ model: GrokBrokerModelPolicy["model"];
9
+ reasoningEffort: GrokBrokerModelPolicy["reasoningEffort"];
10
+ envKey: string;
11
+ }>;
12
+ /**
13
+ * `config.toml` bytes for an evaluator Grok CLI (Paideia judge or optimizer,
14
+ * uid 2000) that reaches the broker proxy through an inference grant.
15
+ *
16
+ * Paideia writes it into a private `GROK_HOME` (`0700`, uid 2000) and sets the
17
+ * grant token in `envKey`; the CLI never holds the broker credential. Grok
18
+ * 1.0.34 ignores `[auth_provider.*]` helpers for a custom model, so the token
19
+ * travels through `env_key` exactly as the worker's turn capability does.
20
+ *
21
+ * It mirrors the worker renderer's lean settings: every bundled skill
22
+ * disabled, workflows off, the per-call `session_title` request pointed at a
23
+ * hidden model with a placeholder key the proxy refuses before any credential
24
+ * read or upstream call, and the declared effort as the model's single
25
+ * effort. There is no MCP server. `max_retries = 0`: with the default, a
26
+ * refused request (HTTP 503) is retried with backoff past a 45 s bound
27
+ * (live stub capture), so a gate refusal would hang the judge until its own
28
+ * timeout; with it the CLI fails in ~0.35 s and the caller's routed retry
29
+ * policy decides. HTTP 401 is never retried either way. `baseUrl` is the `baseUrl` of the grant (the
30
+ * loopback provider proxy); the manifest pins the sha256 for the production
31
+ * proxy URL and {@link GROK_INFERENCE_GRANT_ENV}.
32
+ *
33
+ * Paideia must also accept the init frame this produces: `apiKeySource` is
34
+ * `"user"` (not `"oauth"`), with `tools: []` and `mcp_servers: []` (live
35
+ * stub capture with the Paideia judge argv).
36
+ */
37
+ export declare function renderGrokInferenceClientConfig(input: GrokInferenceClientConfigInput): string;
38
+ export declare const grokInferenceClientConfigSha256: (input: GrokInferenceClientConfigInput) => string;
39
+ /** The production bytes for a declared model/effort: the grant's proxy URL and the canonical env key. */
40
+ export declare const renderProductionGrokInferenceClientConfig: (policy: GrokBrokerModelPolicy) => string;
41
+ //# sourceMappingURL=grokInferenceClientConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grokInferenceClientConfig.d.ts","sourceRoot":"","sources":["../../src/runtime/grokInferenceClientConfig.ts"],"names":[],"mappings":"AAIA,OAAO,EAA8B,KAAK,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAIpG,6GAA6G;AAC7G,eAAO,MAAM,8BAA8B,yBAAe,CAAC;AAC3D,6EAA6E;AAC7E,eAAO,MAAM,wBAAwB,0BAAc,CAAC;AAEpD,MAAM,MAAM,8BAA8B,GAAG,QAAQ,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAAC,eAAe,EAAE,qBAAqB,CAAC,iBAAiB,CAAC,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE7L;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,8BAA8B,GAAG,MAAM,CAe7F;AAED,eAAO,MAAM,+BAA+B,GAAI,OAAO,8BAA8B,KAAG,MACL,CAAC;AAEpF,yGAAyG;AACzG,eAAO,MAAM,yCAAyC,GAAI,QAAQ,qBAAqB,KAAG,MACmF,CAAC"}