@noopolis/daimon 0.1.2 → 0.2.0

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 (330) hide show
  1. package/README.md +269 -51
  2. package/dist/contracts/attentionContract.d.ts +117 -0
  3. package/dist/contracts/attentionContract.d.ts.map +1 -0
  4. package/dist/contracts/attentionContract.js +14 -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/grokWorkerContract.d.ts +74 -0
  9. package/dist/contracts/grokWorkerContract.d.ts.map +1 -0
  10. package/dist/contracts/grokWorkerContract.js +88 -0
  11. package/dist/contracts/organizationRuntimeContract.d.ts +765 -0
  12. package/dist/contracts/organizationRuntimeContract.d.ts.map +1 -0
  13. package/dist/contracts/organizationRuntimeContract.js +121 -0
  14. package/dist/contracts/runtimeContractManifest.d.ts +1615 -0
  15. package/dist/contracts/runtimeContractManifest.d.ts.map +1 -0
  16. package/dist/contracts/runtimeContractManifest.js +181 -0
  17. package/dist/core/credentialRedaction.d.ts +4 -0
  18. package/dist/core/credentialRedaction.d.ts.map +1 -0
  19. package/dist/core/credentialRedaction.js +28 -0
  20. package/dist/mcp/toolServer.d.ts +19 -2
  21. package/dist/mcp/toolServer.d.ts.map +1 -1
  22. package/dist/mcp/toolServer.js +57 -17
  23. package/dist/observability/causalEvents.d.ts +3 -3
  24. package/dist/observability/causalEvents.d.ts.map +1 -1
  25. package/dist/observability/causalEvents.js +103 -15
  26. package/dist/observability/orgObserver.d.ts.map +1 -1
  27. package/dist/observability/orgObserver.js +3 -3
  28. package/dist/pi/agyHeadlessResult.d.ts +60 -0
  29. package/dist/pi/agyHeadlessResult.d.ts.map +1 -0
  30. package/dist/pi/agyHeadlessResult.js +95 -0
  31. package/dist/pi/cliChildOutput.d.ts +67 -0
  32. package/dist/pi/cliChildOutput.d.ts.map +1 -0
  33. package/dist/pi/cliChildOutput.js +269 -0
  34. package/dist/pi/cliEngineRun.d.ts +16 -0
  35. package/dist/pi/cliEngineRun.d.ts.map +1 -0
  36. package/dist/pi/cliEngineRun.js +27 -0
  37. package/dist/pi/cliEngineSpawn.d.ts +55 -0
  38. package/dist/pi/cliEngineSpawn.d.ts.map +1 -0
  39. package/dist/pi/cliEngineSpawn.js +164 -0
  40. package/dist/pi/cliEnvironment.d.ts +12 -0
  41. package/dist/pi/cliEnvironment.d.ts.map +1 -0
  42. package/dist/pi/cliEnvironment.js +32 -0
  43. package/dist/pi/cliMcpRegistration.d.ts +61 -0
  44. package/dist/pi/cliMcpRegistration.d.ts.map +1 -0
  45. package/dist/pi/cliMcpRegistration.js +75 -0
  46. package/dist/pi/cliProcess.d.ts +7 -0
  47. package/dist/pi/cliProcess.d.ts.map +1 -0
  48. package/dist/pi/cliProcess.js +132 -0
  49. package/dist/pi/cliSession.d.ts +84 -24
  50. package/dist/pi/cliSession.d.ts.map +1 -1
  51. package/dist/pi/cliSession.js +313 -158
  52. package/dist/pi/cliTurnMetering.d.ts +60 -0
  53. package/dist/pi/cliTurnMetering.d.ts.map +1 -0
  54. package/dist/pi/cliTurnMetering.js +60 -0
  55. package/dist/pi/codexFilesystemRules.d.ts +3 -0
  56. package/dist/pi/codexFilesystemRules.d.ts.map +1 -0
  57. package/dist/pi/codexFilesystemRules.js +28 -0
  58. package/dist/pi/codexHeadlessResult.d.ts +68 -0
  59. package/dist/pi/codexHeadlessResult.d.ts.map +1 -0
  60. package/dist/pi/codexHeadlessResult.js +122 -0
  61. package/dist/pi/codexRolloutUsage.d.ts +95 -0
  62. package/dist/pi/codexRolloutUsage.d.ts.map +1 -0
  63. package/dist/pi/codexRolloutUsage.js +221 -0
  64. package/dist/pi/engineWakeLimits.d.ts +39 -0
  65. package/dist/pi/engineWakeLimits.d.ts.map +1 -0
  66. package/dist/pi/engineWakeLimits.js +55 -0
  67. package/dist/pi/grokHeadlessResult.d.ts +36 -0
  68. package/dist/pi/grokHeadlessResult.d.ts.map +1 -0
  69. package/dist/pi/grokHeadlessResult.js +118 -0
  70. package/dist/pi/grokHomeMcpRegistration.d.ts +21 -0
  71. package/dist/pi/grokHomeMcpRegistration.d.ts.map +1 -0
  72. package/dist/pi/grokHomeMcpRegistration.js +57 -0
  73. package/dist/pi/grokSandbox.d.ts +11 -0
  74. package/dist/pi/grokSandbox.d.ts.map +1 -0
  75. package/dist/pi/grokSandbox.js +216 -0
  76. package/dist/pi/grokStreamUsage.d.ts +31 -0
  77. package/dist/pi/grokStreamUsage.d.ts.map +1 -0
  78. package/dist/pi/grokStreamUsage.js +51 -0
  79. package/dist/pi/piAgentHandle.d.ts +4 -3
  80. package/dist/pi/piAgentHandle.d.ts.map +1 -1
  81. package/dist/pi/piAgentHandle.js +37 -10
  82. package/dist/pi/piAgentWakeSupport.d.ts +35 -0
  83. package/dist/pi/piAgentWakeSupport.d.ts.map +1 -1
  84. package/dist/pi/piAgentWakeSupport.js +4 -0
  85. package/dist/pi/piHarness.d.ts +10 -1
  86. package/dist/pi/piHarness.d.ts.map +1 -1
  87. package/dist/pi/piHarness.js +61 -8
  88. package/dist/pi/prompts.d.ts +1 -0
  89. package/dist/pi/prompts.d.ts.map +1 -1
  90. package/dist/pi/prompts.js +24 -0
  91. package/dist/pi/turnTrace.d.ts.map +1 -1
  92. package/dist/pi/turnTrace.js +5 -8
  93. package/dist/pi/worldTrajectory.d.ts +1 -1
  94. package/dist/pi/worldTrajectory.d.ts.map +1 -1
  95. package/dist/pi/worldTrajectory.js +3 -3
  96. package/dist/runtime/agySubscriptionBootstrap.d.ts +16 -0
  97. package/dist/runtime/agySubscriptionBootstrap.d.ts.map +1 -0
  98. package/dist/runtime/agySubscriptionBootstrap.js +80 -0
  99. package/dist/runtime/agySubscriptionRealm.d.ts +38 -0
  100. package/dist/runtime/agySubscriptionRealm.d.ts.map +1 -0
  101. package/dist/runtime/agySubscriptionRealm.js +242 -0
  102. package/dist/runtime/attention.d.ts +21 -0
  103. package/dist/runtime/attention.d.ts.map +1 -0
  104. package/dist/runtime/attention.js +36 -0
  105. package/dist/runtime/attentionDispatcher.d.ts +66 -0
  106. package/dist/runtime/attentionDispatcher.d.ts.map +1 -0
  107. package/dist/runtime/attentionDispatcher.js +271 -0
  108. package/dist/runtime/cli.d.ts +7 -0
  109. package/dist/runtime/cli.d.ts.map +1 -0
  110. package/dist/runtime/cli.js +251 -0
  111. package/dist/runtime/codexSandboxProjection.d.ts +17 -0
  112. package/dist/runtime/codexSandboxProjection.d.ts.map +1 -0
  113. package/dist/runtime/codexSandboxProjection.js +40 -0
  114. package/dist/runtime/contract-manifest.json +1 -0
  115. package/dist/runtime/contract-manifest.sha256 +1 -0
  116. package/dist/runtime/contractManifest.d.ts +8 -0
  117. package/dist/runtime/contractManifest.d.ts.map +1 -0
  118. package/dist/runtime/contractManifest.js +4 -0
  119. package/dist/runtime/engineBrokerCapabilities.d.ts +30 -0
  120. package/dist/runtime/engineBrokerCapabilities.d.ts.map +1 -0
  121. package/dist/runtime/engineBrokerCapabilities.js +59 -0
  122. package/dist/runtime/engineBrokerControlClient.d.ts +44 -0
  123. package/dist/runtime/engineBrokerControlClient.d.ts.map +1 -0
  124. package/dist/runtime/engineBrokerControlClient.js +132 -0
  125. package/dist/runtime/engineBrokerCredentialJournal.d.ts +10 -0
  126. package/dist/runtime/engineBrokerCredentialJournal.d.ts.map +1 -0
  127. package/dist/runtime/engineBrokerCredentialJournal.js +17 -0
  128. package/dist/runtime/engineBrokerInferenceProtocol.d.ts +52 -0
  129. package/dist/runtime/engineBrokerInferenceProtocol.d.ts.map +1 -0
  130. package/dist/runtime/engineBrokerInferenceProtocol.js +65 -0
  131. package/dist/runtime/engineBrokerMcpCallLog.d.ts +160 -0
  132. package/dist/runtime/engineBrokerMcpCallLog.d.ts.map +1 -0
  133. package/dist/runtime/engineBrokerMcpCallLog.js +219 -0
  134. package/dist/runtime/engineBrokerMcpFacade.d.ts +56 -0
  135. package/dist/runtime/engineBrokerMcpFacade.d.ts.map +1 -0
  136. package/dist/runtime/engineBrokerMcpFacade.js +343 -0
  137. package/dist/runtime/engineBrokerNativeClient.d.ts +52 -0
  138. package/dist/runtime/engineBrokerNativeClient.d.ts.map +1 -0
  139. package/dist/runtime/engineBrokerNativeClient.js +151 -0
  140. package/dist/runtime/engineBrokerProtocol.d.ts +135 -0
  141. package/dist/runtime/engineBrokerProtocol.d.ts.map +1 -0
  142. package/dist/runtime/engineBrokerProtocol.js +274 -0
  143. package/dist/runtime/engineBrokerSealLedger.d.ts +70 -0
  144. package/dist/runtime/engineBrokerSealLedger.d.ts.map +1 -0
  145. package/dist/runtime/engineBrokerSealLedger.js +123 -0
  146. package/dist/runtime/engineBrokerService.d.ts +37 -0
  147. package/dist/runtime/engineBrokerService.d.ts.map +1 -0
  148. package/dist/runtime/engineBrokerService.js +138 -0
  149. package/dist/runtime/engineBrokerServiceCli.d.ts +5 -0
  150. package/dist/runtime/engineBrokerServiceCli.d.ts.map +1 -0
  151. package/dist/runtime/engineBrokerServiceCli.js +32 -0
  152. package/dist/runtime/engineBrokerServiceConfig.d.ts +50 -0
  153. package/dist/runtime/engineBrokerServiceConfig.d.ts.map +1 -0
  154. package/dist/runtime/engineBrokerServiceConfig.js +92 -0
  155. package/dist/runtime/engineBrokerSingleflight.d.ts +13 -0
  156. package/dist/runtime/engineBrokerSingleflight.d.ts.map +1 -0
  157. package/dist/runtime/engineBrokerSingleflight.js +24 -0
  158. package/dist/runtime/engineBrokerTurnAccounting.d.ts +76 -0
  159. package/dist/runtime/engineBrokerTurnAccounting.d.ts.map +1 -0
  160. package/dist/runtime/engineBrokerTurnAccounting.js +108 -0
  161. package/dist/runtime/engineBrokerTurnRegistry.d.ts +57 -0
  162. package/dist/runtime/engineBrokerTurnRegistry.d.ts.map +1 -0
  163. package/dist/runtime/engineBrokerTurnRegistry.js +158 -0
  164. package/dist/runtime/engineDispatcher.d.ts +36 -0
  165. package/dist/runtime/engineDispatcher.d.ts.map +1 -0
  166. package/dist/runtime/engineDispatcher.js +216 -0
  167. package/dist/runtime/engineReadiness.d.ts +23 -0
  168. package/dist/runtime/engineReadiness.d.ts.map +1 -0
  169. package/dist/runtime/engineReadiness.js +222 -0
  170. package/dist/runtime/grokAuthenticationError.d.ts +8 -0
  171. package/dist/runtime/grokAuthenticationError.d.ts.map +1 -0
  172. package/dist/runtime/grokAuthenticationError.js +20 -0
  173. package/dist/runtime/grokBrokerCredentialAuthority.d.ts +22 -0
  174. package/dist/runtime/grokBrokerCredentialAuthority.d.ts.map +1 -0
  175. package/dist/runtime/grokBrokerCredentialAuthority.js +124 -0
  176. package/dist/runtime/grokBrokerCredentialReader.d.ts +5 -0
  177. package/dist/runtime/grokBrokerCredentialReader.d.ts.map +1 -0
  178. package/dist/runtime/grokBrokerCredentialReader.js +37 -0
  179. package/dist/runtime/grokBrokerModelPolicy.d.ts +23 -0
  180. package/dist/runtime/grokBrokerModelPolicy.d.ts.map +1 -0
  181. package/dist/runtime/grokBrokerModelPolicy.js +28 -0
  182. package/dist/runtime/grokBrokerProjection.d.ts +106 -0
  183. package/dist/runtime/grokBrokerProjection.d.ts.map +1 -0
  184. package/dist/runtime/grokBrokerProjection.js +94 -0
  185. package/dist/runtime/grokBrokerProxy.d.ts +55 -0
  186. package/dist/runtime/grokBrokerProxy.d.ts.map +1 -0
  187. package/dist/runtime/grokBrokerProxy.js +262 -0
  188. package/dist/runtime/grokBrokerProxyRequest.d.ts +30 -0
  189. package/dist/runtime/grokBrokerProxyRequest.d.ts.map +1 -0
  190. package/dist/runtime/grokBrokerProxyRequest.js +74 -0
  191. package/dist/runtime/grokBrokerRealmLease.d.ts +4 -0
  192. package/dist/runtime/grokBrokerRealmLease.d.ts.map +1 -0
  193. package/dist/runtime/grokBrokerRealmLease.js +33 -0
  194. package/dist/runtime/grokBrokerRefresh.d.ts +2 -0
  195. package/dist/runtime/grokBrokerRefresh.d.ts.map +1 -0
  196. package/dist/runtime/grokBrokerRefresh.js +15 -0
  197. package/dist/runtime/grokBrokerTurnMeter.d.ts +128 -0
  198. package/dist/runtime/grokBrokerTurnMeter.d.ts.map +1 -0
  199. package/dist/runtime/grokBrokerTurnMeter.js +251 -0
  200. package/dist/runtime/grokBrokerWorkerConfig.d.ts +86 -0
  201. package/dist/runtime/grokBrokerWorkerConfig.d.ts.map +1 -0
  202. package/dist/runtime/grokBrokerWorkerConfig.js +135 -0
  203. package/dist/runtime/grokEngineBroker.d.ts +48 -0
  204. package/dist/runtime/grokEngineBroker.d.ts.map +1 -0
  205. package/dist/runtime/grokEngineBroker.js +114 -0
  206. package/dist/runtime/grokEngineBrokerLedger.d.ts +52 -0
  207. package/dist/runtime/grokEngineBrokerLedger.d.ts.map +1 -0
  208. package/dist/runtime/grokEngineBrokerLedger.js +114 -0
  209. package/dist/runtime/grokEngineBrokerMetering.d.ts +51 -0
  210. package/dist/runtime/grokEngineBrokerMetering.d.ts.map +1 -0
  211. package/dist/runtime/grokEngineBrokerMetering.js +34 -0
  212. package/dist/runtime/grokEngineBrokerTurn.d.ts +58 -0
  213. package/dist/runtime/grokEngineBrokerTurn.d.ts.map +1 -0
  214. package/dist/runtime/grokEngineBrokerTurn.js +165 -0
  215. package/dist/runtime/grokInferenceClientConfig.d.ts +41 -0
  216. package/dist/runtime/grokInferenceClientConfig.d.ts.map +1 -0
  217. package/dist/runtime/grokInferenceClientConfig.js +62 -0
  218. package/dist/runtime/grokInferenceGrants.d.ts +77 -0
  219. package/dist/runtime/grokInferenceGrants.d.ts.map +1 -0
  220. package/dist/runtime/grokInferenceGrants.js +116 -0
  221. package/dist/runtime/grokInferenceProxy.d.ts +29 -0
  222. package/dist/runtime/grokInferenceProxy.d.ts.map +1 -0
  223. package/dist/runtime/grokInferenceProxy.js +82 -0
  224. package/dist/runtime/grokInferenceProxyRequest.d.ts +23 -0
  225. package/dist/runtime/grokInferenceProxyRequest.d.ts.map +1 -0
  226. package/dist/runtime/grokInferenceProxyRequest.js +63 -0
  227. package/dist/runtime/grokSlotPreflightReceipt.d.ts +70 -0
  228. package/dist/runtime/grokSlotPreflightReceipt.d.ts.map +1 -0
  229. package/dist/runtime/grokSlotPreflightReceipt.js +101 -0
  230. package/dist/runtime/grokSubscriptionRealm.d.ts +4 -0
  231. package/dist/runtime/grokSubscriptionRealm.d.ts.map +1 -0
  232. package/dist/runtime/grokSubscriptionRealm.js +435 -0
  233. package/dist/runtime/grokSubscriptionRealmTypes.d.ts +26 -0
  234. package/dist/runtime/grokSubscriptionRealmTypes.d.ts.map +1 -0
  235. package/dist/runtime/grokSubscriptionRealmTypes.js +1 -0
  236. package/dist/runtime/grokWorkerAttestation.d.ts +170 -0
  237. package/dist/runtime/grokWorkerAttestation.d.ts.map +1 -0
  238. package/dist/runtime/grokWorkerAttestation.js +266 -0
  239. package/dist/runtime/grokWorkerDenyPlacement.d.ts +80 -0
  240. package/dist/runtime/grokWorkerDenyPlacement.d.ts.map +1 -0
  241. package/dist/runtime/grokWorkerDenyPlacement.js +128 -0
  242. package/dist/runtime/grokWorkerHomeAttestation.d.ts +30 -0
  243. package/dist/runtime/grokWorkerHomeAttestation.d.ts.map +1 -0
  244. package/dist/runtime/grokWorkerHomeAttestation.js +69 -0
  245. package/dist/runtime/grokWorkerSandboxProfile.d.ts +27 -0
  246. package/dist/runtime/grokWorkerSandboxProfile.d.ts.map +1 -0
  247. package/dist/runtime/grokWorkerSandboxProfile.js +44 -0
  248. package/dist/runtime/grokWorkerTmpAttestation.d.ts +55 -0
  249. package/dist/runtime/grokWorkerTmpAttestation.d.ts.map +1 -0
  250. package/dist/runtime/grokWorkerTmpAttestation.js +63 -0
  251. package/dist/runtime/index.d.ts +26 -0
  252. package/dist/runtime/index.d.ts.map +1 -0
  253. package/dist/runtime/index.js +23 -0
  254. package/dist/runtime/inferenceUsageLedger.d.ts +38 -0
  255. package/dist/runtime/inferenceUsageLedger.d.ts.map +1 -0
  256. package/dist/runtime/inferenceUsageLedger.js +53 -0
  257. package/dist/runtime/mcpToolResult.d.ts +127 -0
  258. package/dist/runtime/mcpToolResult.d.ts.map +1 -0
  259. package/dist/runtime/mcpToolResult.js +214 -0
  260. package/dist/runtime/moltnetMachineRead.d.ts +97 -0
  261. package/dist/runtime/moltnetMachineRead.d.ts.map +1 -0
  262. package/dist/runtime/moltnetMachineRead.js +183 -0
  263. package/dist/runtime/native/daimon-engine-broker +0 -0
  264. package/dist/runtime/organizationRuntime.d.ts +165 -0
  265. package/dist/runtime/organizationRuntime.d.ts.map +1 -0
  266. package/dist/runtime/organizationRuntime.js +3 -0
  267. package/dist/runtime/organizationRuntimeControl.d.ts +42 -0
  268. package/dist/runtime/organizationRuntimeControl.d.ts.map +1 -0
  269. package/dist/runtime/organizationRuntimeControl.js +235 -0
  270. package/dist/runtime/organizationRuntimeHost.d.ts +19 -0
  271. package/dist/runtime/organizationRuntimeHost.d.ts.map +1 -0
  272. package/dist/runtime/organizationRuntimeHost.js +359 -0
  273. package/dist/runtime/organizationRuntimeParsing.d.ts +6 -0
  274. package/dist/runtime/organizationRuntimeParsing.d.ts.map +1 -0
  275. package/dist/runtime/organizationRuntimeParsing.js +370 -0
  276. package/dist/runtime/organizationRuntimeReadiness.d.ts +12 -0
  277. package/dist/runtime/organizationRuntimeReadiness.d.ts.map +1 -0
  278. package/dist/runtime/organizationRuntimeReadiness.js +59 -0
  279. package/dist/runtime/physicalReadiness.d.ts +47 -0
  280. package/dist/runtime/physicalReadiness.d.ts.map +1 -0
  281. package/dist/runtime/physicalReadiness.js +142 -0
  282. package/dist/runtime/portableCredentialAuth.d.ts +6 -0
  283. package/dist/runtime/portableCredentialAuth.d.ts.map +1 -0
  284. package/dist/runtime/portableCredentialAuth.js +70 -0
  285. package/dist/runtime/portableCredentialMaterial.d.ts +8 -0
  286. package/dist/runtime/portableCredentialMaterial.d.ts.map +1 -0
  287. package/dist/runtime/portableCredentialMaterial.js +169 -0
  288. package/dist/runtime/productionAgentTools.d.ts +5 -0
  289. package/dist/runtime/productionAgentTools.d.ts.map +1 -0
  290. package/dist/runtime/productionAgentTools.js +328 -0
  291. package/dist/runtime/runtimeHomeLayout.d.ts +48 -0
  292. package/dist/runtime/runtimeHomeLayout.d.ts.map +1 -0
  293. package/dist/runtime/runtimeHomeLayout.js +84 -0
  294. package/dist/runtime/schedule.d.ts +40 -0
  295. package/dist/runtime/schedule.d.ts.map +1 -0
  296. package/dist/runtime/schedule.js +371 -0
  297. package/dist/runtime/storeCoordination.d.ts +23 -0
  298. package/dist/runtime/storeCoordination.d.ts.map +1 -0
  299. package/dist/runtime/storeCoordination.js +94 -0
  300. package/dist/runtime/toolResultSpill.d.ts +152 -0
  301. package/dist/runtime/toolResultSpill.d.ts.map +1 -0
  302. package/dist/runtime/toolResultSpill.js +351 -0
  303. package/dist/runtime/turnRequestLedger.d.ts +160 -0
  304. package/dist/runtime/turnRequestLedger.d.ts.map +1 -0
  305. package/dist/runtime/turnRequestLedger.js +249 -0
  306. package/dist/runtime/turnUsageLedger.d.ts +143 -0
  307. package/dist/runtime/turnUsageLedger.d.ts.map +1 -0
  308. package/dist/runtime/turnUsageLedger.js +203 -0
  309. package/dist/runtime/wakeAcceptanceProcessIdentity.d.ts +17 -0
  310. package/dist/runtime/wakeAcceptanceProcessIdentity.d.ts.map +1 -0
  311. package/dist/runtime/wakeAcceptanceProcessIdentity.js +50 -0
  312. package/dist/runtime/wakeAcceptanceReconciliation.d.ts +211 -0
  313. package/dist/runtime/wakeAcceptanceReconciliation.d.ts.map +1 -0
  314. package/dist/runtime/wakeAcceptanceReconciliation.js +289 -0
  315. package/dist/runtime/wakeAcceptanceRecord.d.ts +23 -0
  316. package/dist/runtime/wakeAcceptanceRecord.d.ts.map +1 -0
  317. package/dist/runtime/wakeAcceptanceRecord.js +56 -0
  318. package/dist/runtime/wakeAcceptanceRetention.d.ts +12 -0
  319. package/dist/runtime/wakeAcceptanceRetention.d.ts.map +1 -0
  320. package/dist/runtime/wakeAcceptanceRetention.js +12 -0
  321. package/dist/runtime/wakeAcceptanceStore.d.ts +113 -0
  322. package/dist/runtime/wakeAcceptanceStore.d.ts.map +1 -0
  323. package/dist/runtime/wakeAcceptanceStore.js +558 -0
  324. package/dist/runtime/wakeAcceptanceTypes.d.ts +179 -0
  325. package/dist/runtime/wakeAcceptanceTypes.d.ts.map +1 -0
  326. package/dist/runtime/wakeAcceptanceTypes.js +95 -0
  327. package/dist/runtime/wakeFuse.d.ts +69 -0
  328. package/dist/runtime/wakeFuse.d.ts.map +1 -0
  329. package/dist/runtime/wakeFuse.js +367 -0
  330. package/package.json +20 -9
@@ -0,0 +1,60 @@
1
+ import { cliChildFailureReason, tagCliChildFailure } from "./cliChildOutput.js";
2
+ import { decodeCodexHeadlessTurn } from "./codexHeadlessResult.js";
3
+ export const createCliTurnMeter = () => {
4
+ let usage;
5
+ let completions = 0;
6
+ return {
7
+ observeCodexTurnCompleted: (reported) => {
8
+ completions += 1;
9
+ if (reported !== undefined)
10
+ usage = reported;
11
+ },
12
+ reported: () => (completions === 1 ? usage : undefined)
13
+ };
14
+ };
15
+ /**
16
+ * A turn Codex reported usage for but that the decoder refuses to publish is
17
+ * still a turn that spent tokens. Tagging the rejection is what lets the
18
+ * ledger row name why the wake failed instead of matching on message prose.
19
+ */
20
+ export const decodeCodexTurn = (output) => {
21
+ try {
22
+ return decodeCodexHeadlessTurn(output);
23
+ }
24
+ catch (error) {
25
+ throw tagCliChildFailure(error, "turn_rejected");
26
+ }
27
+ };
28
+ /** The failed row's marker, named by the bound that actually fired. */
29
+ export const failedTurnOutcome = (failure) => ({ status: "failed", reason: cliChildFailureReason(failure) ?? "unknown" });
30
+ /**
31
+ * Advisory: metering never fails, delays, or rewrites the wake it describes —
32
+ * the same ordering rule the Grok engine broker states in
33
+ * `finishBrokerTurnWithUsage`.
34
+ */
35
+ export const publishTurnUsage = async (sink, usage, outcome) => {
36
+ if (usage === undefined)
37
+ return;
38
+ try {
39
+ await sink?.(usage, outcome).catch(() => undefined);
40
+ }
41
+ catch { /* advisory */ }
42
+ };
43
+ /**
44
+ * Advisory per-request instrumentation, under the same ordering rule as
45
+ * {@link publishTurnUsage}: it never fails, delays, or rewrites the wake it
46
+ * describes.
47
+ *
48
+ * No thread id means Codex never announced one — an engine that is not Codex,
49
+ * a child killed before its first frame, or a future stream that renamed the
50
+ * event. Nothing is written in that case, because the alternative is guessing
51
+ * which rollout on disk belongs to this wake.
52
+ */
53
+ export const publishTurnRequests = async (sink, threadId) => {
54
+ if (threadId === undefined)
55
+ return;
56
+ try {
57
+ await sink?.(threadId).catch(() => undefined);
58
+ }
59
+ catch { /* advisory */ }
60
+ };
@@ -0,0 +1,3 @@
1
+ /** Codex mounts deny roots read-only; a second deny below one cannot create parents. */
2
+ export declare function codexFilesystemRules(protectedPaths: readonly string[], readablePaths: readonly string[], workspacePath?: string): Record<string, "read" | "deny">;
3
+ //# sourceMappingURL=codexFilesystemRules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codexFilesystemRules.d.ts","sourceRoot":"","sources":["../../src/pi/codexFilesystemRules.ts"],"names":[],"mappings":"AAIA,wFAAwF;AACxF,wBAAgB,oBAAoB,CAClC,cAAc,EAAE,SAAS,MAAM,EAAE,EAAE,aAAa,EAAE,SAAS,MAAM,EAAE,EAAE,aAAa,CAAC,EAAE,MAAM,GAC1F,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAqBjC"}
@@ -0,0 +1,28 @@
1
+ import path from "node:path";
2
+ /** Codex mounts deny roots read-only; a second deny below one cannot create parents. */
3
+ export function codexFilesystemRules(protectedPaths, readablePaths, workspacePath) {
4
+ const explicit = new Map();
5
+ // Agent roots are canonical, but shared acceptance paths may contain `..`
6
+ // or trailing separators. Compare the same absolute locations Codex uses.
7
+ for (const readablePath of readablePaths)
8
+ explicit.set(path.resolve(readablePath), "read");
9
+ for (const protectedPath of protectedPaths)
10
+ explicit.set(path.resolve(protectedPath), "deny");
11
+ const effective = new Map([
12
+ ...(workspacePath === undefined ? [] : [[path.resolve(workspacePath), "write"]]),
13
+ ...explicit
14
+ ]);
15
+ return Object.fromEntries([...explicit].filter(([target, permission]) => {
16
+ if (permission !== "deny")
17
+ return true;
18
+ let ancestor = path.dirname(target);
19
+ while (ancestor !== target) {
20
+ const inherited = effective.get(ancestor);
21
+ if (inherited !== undefined)
22
+ return inherited !== "deny";
23
+ target = ancestor;
24
+ ancestor = path.dirname(target);
25
+ }
26
+ return true;
27
+ }));
28
+ }
@@ -0,0 +1,68 @@
1
+ type JsonRecord = Readonly<Record<string, unknown>>;
2
+ /**
3
+ * Token accounting for one Codex turn, from the terminal frame emitted by
4
+ * `codex exec --json`:
5
+ *
6
+ * {"type":"turn.completed","usage":{"input_tokens":…,
7
+ * "cached_input_tokens":…,"cache_write_input_tokens":…,
8
+ * "output_tokens":…,"reasoning_output_tokens":…}}
9
+ *
10
+ * Codex's reconciled session total proves `cached_input_tokens` is a subset of
11
+ * `input_tokens`: total is `input + output`, unlike AGY's disjoint cache-read
12
+ * bucket. Adding cacheRead would over-count every cached turn. Likewise,
13
+ * `reasoning_output_tokens` is a subset of `output_tokens`; it is read only to
14
+ * validate that relationship, never added. Codex reports cache writes, but no
15
+ * cost, so `cacheWrite` is measured while `notionalUsd: 0` means absent, not
16
+ * free. `calls` counts completed command/MCP tools; Codex exposes no AGY-like
17
+ * model-step count, so this is explicitly a tool-call count.
18
+ */
19
+ export type CodexTurnUsage = Readonly<{
20
+ input: number;
21
+ output: number;
22
+ cacheRead: number;
23
+ cacheWrite: number;
24
+ total: number;
25
+ calls: number;
26
+ notionalUsd: number;
27
+ complete: boolean;
28
+ }>;
29
+ export type CodexHeadlessTurn = Readonly<{
30
+ text: string;
31
+ usage?: CodexTurnUsage;
32
+ }>;
33
+ /**
34
+ * Advisory usage decoding: an absent or malformed block is `undefined`, never
35
+ * a failed published turn and never a zero-filled record. Every field must be
36
+ * a non-negative safe integer because a substituted zero is byte-identical to
37
+ * a real zero. `complete` requires a non-zero derived total and valid subset
38
+ * relationships. As with AGY, every emitted count remains a lower bound.
39
+ */
40
+ export declare const decodeCodexTurnUsage: (frame: JsonRecord, calls: number) => CodexTurnUsage | undefined;
41
+ /**
42
+ * Decode Codex's NDJSON stream without mistaking tool/progress items for the
43
+ * reply. Unknown envelopes and item types are skipped because Codex owns the
44
+ * vocabulary and a future frame must not fail a turn that published.
45
+ * A Codex turn that spent subscription money and produced a reply must reach
46
+ * the organization: uncertainty about accounting degrades to `usage:
47
+ * undefined` and never discards publishable text. Unlike AGY's stricter
48
+ * envelope, Codex may omit, repeat, or follow `turn.completed` with another
49
+ * frame, so only exactly one completion frame supplies trustworthy usage.
50
+ *
51
+ * Success is decided from the terminal frame, not from whether a reply was
52
+ * published: `engineDispatcher.ts`'s runtime envelope tells every agent its
53
+ * terminal response is a private note to the runtime, not an outward
54
+ * message, and that it may "leave it empty". A `turn.completed` with no
55
+ * `agent_message` is therefore a sanctioned silent success — `text: ""`,
56
+ * never a thrown failure — and its usage still reaches the ledger exactly as
57
+ * a spoken turn's would; do not reinstate throwing on empty text, it would
58
+ * both misreport a clean turn as failed and drop its usage from the ledger
59
+ * silently. Only `turn.failed` with no reply already published, or a stream
60
+ * with neither terminal frame at all (a truncated or killed child), reject
61
+ * the turn; the latter gets its own detail string so a genuinely truncated
62
+ * stream is never confused with a legitimately silent one.
63
+ */
64
+ export declare const decodeCodexHeadlessTurn: (output: string) => CodexHeadlessTurn;
65
+ /** Text-only view of {@link decodeCodexHeadlessTurn}, for callers that do not meter. */
66
+ export declare const decodeCodexHeadlessResult: (output: string) => string;
67
+ export {};
68
+ //# sourceMappingURL=codexHeadlessResult.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codexHeadlessResult.d.ts","sourceRoot":"","sources":["../../src/pi/codexHeadlessResult.ts"],"names":[],"mappings":"AAAA,KAAK,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAQpD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,cAAc,CAAA;CAAE,CAAC,CAAC;AA0BnF;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAAI,OAAO,UAAU,EAAE,OAAO,MAAM,KAAG,cAAc,GAAG,SAmBxF,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,uBAAuB,GAAI,QAAQ,MAAM,KAAG,iBAiCxD,CAAC;AAEF,wFAAwF;AACxF,eAAO,MAAM,yBAAyB,GAAI,QAAQ,MAAM,KAAG,MAA8C,CAAC"}
@@ -0,0 +1,122 @@
1
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
2
+ const invalidResult = (detail) => new Error(`Codex CLI returned no publishable terminal response: ${detail}`);
3
+ /**
4
+ * Every field Codex actually emits on `turn.completed.usage`.
5
+ *
6
+ * `cache_write_input_tokens` is NOT in this list: Codex 0.142.3 and 0.151.0
7
+ * both emit exactly `{input_tokens, cached_input_tokens, output_tokens,
8
+ * reasoning_output_tokens}`, verified against a live turn inside the runtime
9
+ * image and against `token_count` in a session rollout. Requiring the cache
10
+ * write field made `decodeCodexTurnUsage` return `undefined` for *every* real
11
+ * turn, so the codex half of the usage ledger recorded nothing at all while
12
+ * every test passed against a fixture that invented the field.
13
+ */
14
+ const USAGE_TOKEN_FIELDS = [
15
+ "input_tokens",
16
+ "cached_input_tokens",
17
+ "output_tokens",
18
+ "reasoning_output_tokens"
19
+ ];
20
+ /** Absent means zero; present-but-malformed still degrades the whole block. */
21
+ const CACHE_WRITE_FIELD = "cache_write_input_tokens";
22
+ const tokenCount = (value) => typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : undefined;
23
+ /**
24
+ * Advisory usage decoding: an absent or malformed block is `undefined`, never
25
+ * a failed published turn and never a zero-filled record. Every field must be
26
+ * a non-negative safe integer because a substituted zero is byte-identical to
27
+ * a real zero. `complete` requires a non-zero derived total and valid subset
28
+ * relationships. As with AGY, every emitted count remains a lower bound.
29
+ */
30
+ export const decodeCodexTurnUsage = (frame, calls) => {
31
+ if (!isRecord(frame.usage))
32
+ return undefined;
33
+ const usage = frame.usage;
34
+ const counts = USAGE_TOKEN_FIELDS.map((field) => tokenCount(usage[field]));
35
+ if (counts.some((count) => count === undefined))
36
+ return undefined;
37
+ const cacheWrite = usage[CACHE_WRITE_FIELD] === undefined ? 0 : tokenCount(usage[CACHE_WRITE_FIELD]);
38
+ if (cacheWrite === undefined)
39
+ return undefined;
40
+ const [input, cacheRead, output, reasoningOutput] = counts;
41
+ const total = input + output;
42
+ return {
43
+ input,
44
+ output,
45
+ cacheRead,
46
+ cacheWrite,
47
+ total,
48
+ calls,
49
+ notionalUsd: 0,
50
+ complete: total > 0 && cacheRead <= input && reasoningOutput <= output
51
+ };
52
+ };
53
+ /**
54
+ * Decode Codex's NDJSON stream without mistaking tool/progress items for the
55
+ * reply. Unknown envelopes and item types are skipped because Codex owns the
56
+ * vocabulary and a future frame must not fail a turn that published.
57
+ * A Codex turn that spent subscription money and produced a reply must reach
58
+ * the organization: uncertainty about accounting degrades to `usage:
59
+ * undefined` and never discards publishable text. Unlike AGY's stricter
60
+ * envelope, Codex may omit, repeat, or follow `turn.completed` with another
61
+ * frame, so only exactly one completion frame supplies trustworthy usage.
62
+ *
63
+ * Success is decided from the terminal frame, not from whether a reply was
64
+ * published: `engineDispatcher.ts`'s runtime envelope tells every agent its
65
+ * terminal response is a private note to the runtime, not an outward
66
+ * message, and that it may "leave it empty". A `turn.completed` with no
67
+ * `agent_message` is therefore a sanctioned silent success — `text: ""`,
68
+ * never a thrown failure — and its usage still reaches the ledger exactly as
69
+ * a spoken turn's would; do not reinstate throwing on empty text, it would
70
+ * both misreport a clean turn as failed and drop its usage from the ledger
71
+ * silently. Only `turn.failed` with no reply already published, or a stream
72
+ * with neither terminal frame at all (a truncated or killed child), reject
73
+ * the turn; the latter gets its own detail string so a genuinely truncated
74
+ * stream is never confused with a legitimately silent one.
75
+ */
76
+ export const decodeCodexHeadlessTurn = (output) => {
77
+ const lines = output.split(/\r?\n/).filter((line) => line.trim().length > 0);
78
+ if (lines.length === 0)
79
+ throw invalidResult("empty stream");
80
+ let text;
81
+ const completed = [];
82
+ let failed = false;
83
+ let calls = 0;
84
+ for (const line of lines) {
85
+ let frame;
86
+ try {
87
+ frame = JSON.parse(line);
88
+ }
89
+ catch {
90
+ throw invalidResult("invalid JSON");
91
+ }
92
+ if (!isRecord(frame) || typeof frame.type !== "string")
93
+ throw invalidResult("invalid event");
94
+ if (frame.type === "turn.failed") {
95
+ failed = true;
96
+ continue;
97
+ }
98
+ if (frame.type === "turn.completed") {
99
+ completed.push(frame);
100
+ continue;
101
+ }
102
+ if (frame.type !== "item.completed" || !isRecord(frame.item) || typeof frame.item.type !== "string")
103
+ continue;
104
+ if (frame.item.type === "command_execution" || frame.item.type === "mcp_tool_call")
105
+ calls += 1;
106
+ if (frame.item.type === "agent_message" && typeof frame.item.text === "string" && frame.item.text.trim().length > 0) {
107
+ text = frame.item.text;
108
+ }
109
+ }
110
+ if (typeof text !== "string") {
111
+ if (failed)
112
+ throw invalidResult("failed turn");
113
+ // No reply, but a completion frame arrived: a sanctioned silent success.
114
+ if (completed.length === 0)
115
+ throw invalidResult("no terminal frame");
116
+ text = "";
117
+ }
118
+ const usage = !failed && completed.length === 1 ? decodeCodexTurnUsage(completed[0], calls) : undefined;
119
+ return usage === undefined ? { text: text.trim() } : { text: text.trim(), usage };
120
+ };
121
+ /** Text-only view of {@link decodeCodexHeadlessTurn}, for callers that do not meter. */
122
+ export const decodeCodexHeadlessResult = (output) => decodeCodexHeadlessTurn(output).text;
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Per-model-request token accounting, recovered from the rollout file Codex
3
+ * already writes for every non-`--ephemeral` thread.
4
+ *
5
+ * Daimon's usage ledger records exactly one row per wake, decoded from the
6
+ * single `turn.completed` frame on the `--json` stream. That row is a sum: it
7
+ * cannot say whether a wake's fresh input is one cold miss on a shared prefix
8
+ * that is then replayed cheaply, or a context that grows with every tool call.
9
+ * Those two shapes call for opposite optimisations, and the aggregate row is
10
+ * blind to the difference. It also drops `reasoning_output_tokens` entirely.
11
+ *
12
+ * Codex writes the missing detail to
13
+ * `$CODEX_HOME/sessions/<yyyy>/<mm>/<dd>/rollout-<ts>-<thread-id>.jsonl`, one
14
+ * usage frame per model request. Two frame shapes carry it, and both were read
15
+ * off real rollouts written by codex-cli 0.153.4:
16
+ *
17
+ * {"type":"token_usage_record","payload":{"thread_id":…,"turn_id":…,
18
+ * "usage":{"input_tokens":22119,"cached_input_tokens":21888,
19
+ * "cache_write_input_tokens":0,"output_tokens":358,
20
+ * "reasoning_output_tokens":169,"total_tokens":22477}, …}}
21
+ *
22
+ * {"type":"event_msg","payload":{"type":"token_count","info":{
23
+ * "last_token_usage":{…same fields…},"total_token_usage":{…}}}}
24
+ *
25
+ * `token_usage_record` is preferred because it names its thread and turn. The
26
+ * `token_count` shape is the fallback for a Codex version that predates it —
27
+ * the pinned runtime image's version was not available to check. The two are
28
+ * emitted in pairs, so they are never both counted.
29
+ *
30
+ * Reading is strictly advisory and strictly read-only: Codex owns these files,
31
+ * Daimon never writes, moves, or prunes them.
32
+ */
33
+ /** One model request's own token usage, exactly as Codex reported it. */
34
+ export type CodexRequestUsage = Readonly<{
35
+ /** 0-based position of this request within the rollout. */
36
+ index: number;
37
+ input: number;
38
+ cachedInput: number;
39
+ cacheWrite: number;
40
+ output: number;
41
+ reasoning: number;
42
+ total: number;
43
+ /**
44
+ * When the request began and ended, from the rollout's own frame
45
+ * `timestamp`s. `endedAt` is the usage frame's timestamp (Codex appends it at
46
+ * `response.completed`); `startedAt` is the first non-usage frame after the
47
+ * previous request's usage frame — the tool output or turn context that
48
+ * triggers the next request — falling back to the previous request's end.
49
+ * Either is absent when the frames carry no valid timestamp: a wake-end stamp
50
+ * substituted here would be indistinguishable from a measured one.
51
+ */
52
+ startedAt?: string;
53
+ endedAt?: string;
54
+ }>;
55
+ export declare const isCodexThreadId: (value: unknown) => value is string;
56
+ /** Rollouts are model transcripts; refuse to buffer an implausible one. */
57
+ export declare const CODEX_ROLLOUT_MAX_BYTES: number;
58
+ /**
59
+ * Locate the rollout belonging to *this* turn, by thread id.
60
+ *
61
+ * The thread id comes from the `thread.started` frame Codex emits as the very
62
+ * first line of its own `--json` stream (verified live against codex-cli
63
+ * 0.153.4: `{"type":"thread.started","thread_id":"01a076d3-…"}`), and the
64
+ * rollout filename ends with `-<thread-id>.jsonl`. Nothing here globs for "the
65
+ * newest file": with concurrent agents in one container, newest-file matching
66
+ * would attribute one agent's requests to another's wake.
67
+ */
68
+ export declare const findCodexRolloutPath: (codexHome: string, threadId: string) => Promise<string | undefined>;
69
+ /**
70
+ * Every model request in one rollout, in stream order — or an empty list.
71
+ *
72
+ * "Or an empty list" is the whole contract. A rollout that yields no usage
73
+ * frame, or that contains a usage frame Daimon cannot decode, produces nothing:
74
+ * a partial or invented row here would be indistinguishable from a real
75
+ * measurement, and the entire point of this file is to be trusted about which
76
+ * of two cost shapes production actually has.
77
+ *
78
+ * Individual unparseable *lines* are skipped rather than fatal. Codex appends
79
+ * to this file while the turn runs, so a torn final line is an ordinary
80
+ * artefact of reading it, not evidence that the accounting is wrong. A usage
81
+ * frame that parses but whose usage block does not decode is fatal, because
82
+ * that is a genuine disagreement about the shape of the number.
83
+ *
84
+ * Daimon spawns one `codex exec` per wake and never resumes a thread, so one
85
+ * rollout is one wake. If that ever changes, this needs a turn-id filter.
86
+ */
87
+ export declare const parseCodexRolloutRequests: (text: string, threadId: string) => readonly CodexRequestUsage[];
88
+ /**
89
+ * Read one turn's per-request usage. Never throws.
90
+ *
91
+ * Absent, unreadable, oversized, or undecodable all answer the same way: an
92
+ * empty list, which the caller writes nothing for.
93
+ */
94
+ export declare const readCodexRolloutRequests: (codexHome: string, threadId: string) => Promise<readonly CodexRequestUsage[]>;
95
+ //# sourceMappingURL=codexRolloutUsage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codexRolloutUsage.d.ts","sourceRoot":"","sources":["../../src/pi/codexRolloutUsage.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,yEAAyE;AACzE,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACvC,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC,CAAC;AAUH,eAAO,MAAM,eAAe,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,MACD,CAAC;AAc1D,2EAA2E;AAC3E,eAAO,MAAM,uBAAuB,QAAmB,CAAC;AAExD;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB,GAAU,WAAW,MAAM,EAAE,UAAU,MAAM,KAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAoB1G,CAAC;AAqDF;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,yBAAyB,GAAI,MAAM,MAAM,EAAE,UAAU,MAAM,KAAG,SAAS,iBAAiB,EAqCpG,CAAC;AAkBF;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,GACnC,WAAW,MAAM,EACjB,UAAU,MAAM,KACf,OAAO,CAAC,SAAS,iBAAiB,EAAE,CAUtC,CAAC"}
@@ -0,0 +1,221 @@
1
+ import { readdir, readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ /**
4
+ * A thread id is interpolated into a filename suffix, so it is constrained to
5
+ * the shape Codex actually emits (a UUID) before it can reach the filesystem.
6
+ * A value carrying `/` or `..` would otherwise steer the search out of
7
+ * `$CODEX_HOME`.
8
+ */
9
+ const SAFE_THREAD_ID = /^[A-Za-z0-9][A-Za-z0-9-]{0,63}$/u;
10
+ export const isCodexThreadId = (value) => typeof value === "string" && SAFE_THREAD_ID.test(value);
11
+ /**
12
+ * Codex lays rollouts out as `sessions/<yyyy>/<mm>/<dd>/rollout-*.jsonl`, so
13
+ * three directory levels below `sessions` is the whole tree. Directory entries
14
+ * are walked newest-name-first, which for zero-padded date components is
15
+ * newest-day-first — the wake that just finished is in the first day directory
16
+ * examined, so the search normally reads one directory per level.
17
+ */
18
+ const ROLLOUT_MAX_DEPTH = 3;
19
+ /** A budget so a pathological sessions tree cannot turn instrumentation into a stall. */
20
+ const ROLLOUT_MAX_ENTRIES = 20_000;
21
+ /** Rollouts are model transcripts; refuse to buffer an implausible one. */
22
+ export const CODEX_ROLLOUT_MAX_BYTES = 64 * 1024 * 1024;
23
+ /**
24
+ * Locate the rollout belonging to *this* turn, by thread id.
25
+ *
26
+ * The thread id comes from the `thread.started` frame Codex emits as the very
27
+ * first line of its own `--json` stream (verified live against codex-cli
28
+ * 0.153.4: `{"type":"thread.started","thread_id":"01a076d3-…"}`), and the
29
+ * rollout filename ends with `-<thread-id>.jsonl`. Nothing here globs for "the
30
+ * newest file": with concurrent agents in one container, newest-file matching
31
+ * would attribute one agent's requests to another's wake.
32
+ */
33
+ export const findCodexRolloutPath = async (codexHome, threadId) => {
34
+ if (!isCodexThreadId(threadId))
35
+ return undefined;
36
+ const suffix = `-${threadId}.jsonl`;
37
+ let budget = ROLLOUT_MAX_ENTRIES;
38
+ const walk = async (directory, depth) => {
39
+ let entries;
40
+ try {
41
+ entries = await readdir(directory, { withFileTypes: true });
42
+ }
43
+ catch {
44
+ return undefined;
45
+ }
46
+ budget -= entries.length;
47
+ if (budget < 0)
48
+ return undefined;
49
+ const match = entries.find((entry) => entry.isFile() && entry.name.startsWith("rollout-") && entry.name.endsWith(suffix));
50
+ if (match !== undefined)
51
+ return path.join(directory, match.name);
52
+ if (depth >= ROLLOUT_MAX_DEPTH)
53
+ return undefined;
54
+ const directories = entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort().reverse();
55
+ for (const name of directories) {
56
+ const found = await walk(path.join(directory, name), depth + 1);
57
+ if (found !== undefined)
58
+ return found;
59
+ }
60
+ return undefined;
61
+ };
62
+ return walk(path.join(codexHome, "sessions"), 0);
63
+ };
64
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
65
+ const tokenCount = (value) => typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : undefined;
66
+ /**
67
+ * Decode one usage block, or `undefined` when any part of it is not a
68
+ * non-negative safe integer.
69
+ *
70
+ * The rule `turnUsageLedger.ts` and `codexHeadlessResult.ts` already hold to
71
+ * applies here unchanged: a substituted zero is byte-identical to a real zero,
72
+ * so a number is never invented. `cache_write_input_tokens` and `total_tokens`
73
+ * may be absent (older Codex versions omit them); absent means zero and a
74
+ * derived total respectively, but present-and-malformed still rejects the
75
+ * block. The subset relationships Codex's own totals imply — cached input
76
+ * inside input, reasoning output inside output — are checked rather than
77
+ * assumed, because a block that violates them is not describing the request
78
+ * this row claims to describe.
79
+ */
80
+ const decodeRequestUsage = (usage, index) => {
81
+ if (!isRecord(usage))
82
+ return undefined;
83
+ const input = tokenCount(usage.input_tokens);
84
+ const cachedInput = tokenCount(usage.cached_input_tokens);
85
+ const output = tokenCount(usage.output_tokens);
86
+ const reasoning = tokenCount(usage.reasoning_output_tokens);
87
+ if (input === undefined || cachedInput === undefined || output === undefined || reasoning === undefined)
88
+ return undefined;
89
+ const cacheWrite = usage.cache_write_input_tokens === undefined ? 0 : tokenCount(usage.cache_write_input_tokens);
90
+ const total = usage.total_tokens === undefined ? input + output : tokenCount(usage.total_tokens);
91
+ if (cacheWrite === undefined || total === undefined)
92
+ return undefined;
93
+ if (cachedInput > input || reasoning > output)
94
+ return undefined;
95
+ return { index, input, cachedInput, cacheWrite, output, reasoning, total };
96
+ };
97
+ const usageBlock = (frame, threadId) => {
98
+ const payload = isRecord(frame.payload) ? frame.payload : undefined;
99
+ if (payload === undefined)
100
+ return undefined;
101
+ if (frame.type === "token_usage_record") {
102
+ // The file is already thread-scoped by its name; the field is checked anyway
103
+ // so a forked or sub-thread record can never be billed to this wake.
104
+ if (typeof payload.thread_id === "string" && payload.thread_id !== threadId)
105
+ return undefined;
106
+ return { usage: payload.usage };
107
+ }
108
+ if (frame.type === "event_msg" && payload.type === "token_count" && isRecord(payload.info)) {
109
+ return { usage: payload.info.last_token_usage };
110
+ }
111
+ return undefined;
112
+ };
113
+ /**
114
+ * Every model request in one rollout, in stream order — or an empty list.
115
+ *
116
+ * "Or an empty list" is the whole contract. A rollout that yields no usage
117
+ * frame, or that contains a usage frame Daimon cannot decode, produces nothing:
118
+ * a partial or invented row here would be indistinguishable from a real
119
+ * measurement, and the entire point of this file is to be trusted about which
120
+ * of two cost shapes production actually has.
121
+ *
122
+ * Individual unparseable *lines* are skipped rather than fatal. Codex appends
123
+ * to this file while the turn runs, so a torn final line is an ordinary
124
+ * artefact of reading it, not evidence that the accounting is wrong. A usage
125
+ * frame that parses but whose usage block does not decode is fatal, because
126
+ * that is a genuine disagreement about the shape of the number.
127
+ *
128
+ * Daimon spawns one `codex exec` per wake and never resumes a thread, so one
129
+ * rollout is one wake. If that ever changes, this needs a turn-id filter.
130
+ */
131
+ export const parseCodexRolloutRequests = (text, threadId) => {
132
+ const requests = [];
133
+ const fallback = [];
134
+ let previousFallback = "";
135
+ const clocks = { record: requestClock(), fallback: requestClock() };
136
+ for (const line of text.split("\n")) {
137
+ if (line.trim().length === 0)
138
+ continue;
139
+ let frame;
140
+ try {
141
+ frame = JSON.parse(line);
142
+ }
143
+ catch {
144
+ continue;
145
+ }
146
+ if (!isRecord(frame))
147
+ continue;
148
+ const block = usageBlock(frame, threadId);
149
+ const usageFrame = frame.type === "token_usage_record" || (frame.type === "event_msg" && isRecord(frame.payload) && frame.payload.type === "token_count");
150
+ if (!usageFrame) {
151
+ if (frame.type !== "session_meta") {
152
+ clocks.record.observe(frame.timestamp);
153
+ clocks.fallback.observe(frame.timestamp);
154
+ }
155
+ continue;
156
+ }
157
+ if (block === undefined)
158
+ continue;
159
+ if (frame.type === "token_usage_record") {
160
+ const decoded = decodeRequestUsage(block.usage, requests.length);
161
+ if (decoded === undefined)
162
+ return [];
163
+ requests.push({ ...decoded, ...clocks.record.close(frame.timestamp) });
164
+ continue;
165
+ }
166
+ // `token_count` is NOT one frame per request: the captured fixture carries
167
+ // six of them for four requests, three of which repeat one earlier
168
+ // `last_token_usage` verbatim because the event is re-emitted whenever the
169
+ // rate-limit block refreshes. Counting them would inflate the request count
170
+ // — the single number this whole stream exists to establish. Only a block
171
+ // that differs from the one before it is a new request.
172
+ const serialized = JSON.stringify(block.usage);
173
+ if (serialized === previousFallback)
174
+ continue;
175
+ previousFallback = serialized;
176
+ const decoded = decodeRequestUsage(block.usage, fallback.length);
177
+ if (decoded === undefined)
178
+ return [];
179
+ fallback.push({ ...decoded, ...clocks.fallback.close(frame.timestamp) });
180
+ }
181
+ // A Codex version that emits both shapes emits `token_usage_record` once per
182
+ // request, so the richer one wins outright rather than being merged into a
183
+ // double count. The fallback exists only for a version that has neither.
184
+ return requests.length > 0 ? requests : fallback;
185
+ };
186
+ const timestampOf = (value) => typeof value === "string" && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,9})?Z$/u.test(value) && !Number.isNaN(Date.parse(value)) ? value : undefined;
187
+ /** Tracks one request stream's start/end stamps; see {@link CodexRequestUsage.startedAt}. */
188
+ const requestClock = () => {
189
+ let start, previousEnd;
190
+ return {
191
+ observe(value) { start ??= timestampOf(value); },
192
+ close(value) {
193
+ const endedAt = timestampOf(value), startedAt = start ?? previousEnd;
194
+ start = undefined;
195
+ previousEnd = endedAt;
196
+ return { ...(startedAt === undefined ? {} : { startedAt }), ...(endedAt === undefined ? {} : { endedAt }) };
197
+ }
198
+ };
199
+ };
200
+ /**
201
+ * Read one turn's per-request usage. Never throws.
202
+ *
203
+ * Absent, unreadable, oversized, or undecodable all answer the same way: an
204
+ * empty list, which the caller writes nothing for.
205
+ */
206
+ export const readCodexRolloutRequests = async (codexHome, threadId) => {
207
+ const file = await findCodexRolloutPath(codexHome, threadId);
208
+ if (file === undefined)
209
+ return [];
210
+ let text;
211
+ try {
212
+ const bytes = await readFile(file);
213
+ if (bytes.byteLength > CODEX_ROLLOUT_MAX_BYTES)
214
+ return [];
215
+ text = bytes.toString("utf8");
216
+ }
217
+ catch {
218
+ return [];
219
+ }
220
+ return parseCodexRolloutRequests(text, threadId);
221
+ };
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Per-wake engine bounds, and the one place they are decided.
3
+ *
4
+ * `maxToolTurns` mediates only daimon-MCP tool calls; Codex's own shell
5
+ * (`exec_command`) is never routed through that gate, so a single Codex turn
6
+ * previously had no ceiling at all — one production wake ran 23:32→23:42
7
+ * (unbounded wall clock) making 51 shell calls. Codex's `--json` stream
8
+ * reports token usage exactly once, on `turn.completed` — there is no
9
+ * incremental total to watch mid-turn (verified against a live multi-tool-call
10
+ * turn: `item.completed` fires once per tool call, but usage is reported only
11
+ * on the single terminal `turn.completed`) — so the token ceiling is the best
12
+ * bound obtainable from that wire shape: it converts an over-budget turn into
13
+ * an explicit, killed, named failure instead of a silent success, and the
14
+ * wall-clock timeout is what actually interrupts a runaway turn in progress.
15
+ *
16
+ * The names are engine-neutral: `DAIMON_ENGINE_WAKE_TIMEOUT_MS` and
17
+ * `DAIMON_ENGINE_WAKE_TOKEN_CEILING` bound Codex locally and are passed to the
18
+ * Grok broker as the wake's *lowering* limits (the broker refuses a value above
19
+ * its registration). The `DAIMON_CODEX_*` names remain aliases; setting both
20
+ * names of one bound to different values is refused rather than guessed.
21
+ */
22
+ export declare const DEFAULT_CODEX_WAKE_TIMEOUT_MS = 240000;
23
+ export declare const DEFAULT_CODEX_WAKE_TOKEN_CEILING = 300000;
24
+ export declare const DAIMON_ENGINE_WAKE_TIMEOUT_MS_ENV = "DAIMON_ENGINE_WAKE_TIMEOUT_MS";
25
+ export declare const DAIMON_ENGINE_WAKE_TOKEN_CEILING_ENV = "DAIMON_ENGINE_WAKE_TOKEN_CEILING";
26
+ export declare const DAIMON_CODEX_WAKE_TIMEOUT_MS_ENV = "DAIMON_CODEX_WAKE_TIMEOUT_MS";
27
+ export declare const DAIMON_CODEX_WAKE_TOKEN_CEILING_ENV = "DAIMON_CODEX_WAKE_TOKEN_CEILING";
28
+ export declare const resolveCodexWakeTimeoutMs: (environment?: NodeJS.ProcessEnv) => number;
29
+ export declare const resolveCodexWakeTokenCeiling: (environment?: NodeJS.ProcessEnv) => number;
30
+ /**
31
+ * The limits a wake asks a broker to lower to: only the bounds the operator
32
+ * actually set, never the Codex defaults (a broker registration's declared
33
+ * limits already are the defaults there).
34
+ */
35
+ export declare const resolveEngineWakeLimitOverrides: (environment?: NodeJS.ProcessEnv) => Readonly<{
36
+ timeoutMs?: number;
37
+ maxTokens?: number;
38
+ }> | undefined;
39
+ //# sourceMappingURL=engineWakeLimits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engineWakeLimits.d.ts","sourceRoot":"","sources":["../../src/pi/engineWakeLimits.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,6BAA6B,SAAU,CAAC;AACrD,eAAO,MAAM,gCAAgC,SAAU,CAAC;AACxD,eAAO,MAAM,iCAAiC,kCAAkC,CAAC;AACjF,eAAO,MAAM,oCAAoC,qCAAqC,CAAC;AACvF,eAAO,MAAM,gCAAgC,iCAAiC,CAAC;AAC/E,eAAO,MAAM,mCAAmC,oCAAoC,CAAC;AAgBrF,eAAO,MAAM,yBAAyB,GAAI,cAAa,MAAM,CAAC,UAAwB,KAAG,MACoC,CAAC;AAC9H,eAAO,MAAM,4BAA4B,GAAI,cAAa,MAAM,CAAC,UAAwB,KAAG,MAC0C,CAAC;AAEvI;;;;GAIG;AACH,eAAO,MAAM,+BAA+B,GAAI,cAAa,MAAM,CAAC,UAAwB,KAAG,QAAQ,CAAC;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,SAKrJ,CAAC"}