@noopolis/daimon 0.1.1 → 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.
- package/README.md +307 -45
- package/dist/contracts/attentionContract.d.ts +117 -0
- package/dist/contracts/attentionContract.d.ts.map +1 -0
- package/dist/contracts/attentionContract.js +14 -0
- package/dist/contracts/canonicalJson.d.ts +3 -0
- package/dist/contracts/canonicalJson.d.ts.map +1 -0
- package/dist/contracts/canonicalJson.js +54 -0
- package/dist/contracts/grokWorkerContract.d.ts +74 -0
- package/dist/contracts/grokWorkerContract.d.ts.map +1 -0
- package/dist/contracts/grokWorkerContract.js +88 -0
- package/dist/contracts/organizationRuntimeContract.d.ts +765 -0
- package/dist/contracts/organizationRuntimeContract.d.ts.map +1 -0
- package/dist/contracts/organizationRuntimeContract.js +121 -0
- package/dist/contracts/runtimeContractManifest.d.ts +1615 -0
- package/dist/contracts/runtimeContractManifest.d.ts.map +1 -0
- package/dist/contracts/runtimeContractManifest.js +181 -0
- package/dist/core/credentialRedaction.d.ts +4 -0
- package/dist/core/credentialRedaction.d.ts.map +1 -0
- package/dist/core/credentialRedaction.js +28 -0
- package/dist/core/siblingBuildFreshness.d.ts +21 -0
- package/dist/core/siblingBuildFreshness.d.ts.map +1 -0
- package/dist/core/siblingBuildFreshness.js +25 -0
- package/dist/core/types.d.ts +10 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/examples/exampleCausalId.d.ts +3 -0
- package/dist/examples/exampleCausalId.d.ts.map +1 -0
- package/dist/examples/exampleCausalId.js +8 -0
- package/dist/examples/jungian-play-org.js +3 -2
- package/dist/examples/jungian-triad-org.js +3 -2
- package/dist/examples/jungianPlayAgent.d.ts +1 -1
- package/dist/examples/jungianPlayAgent.d.ts.map +1 -1
- package/dist/examples/jungianPlayAgent.js +1 -1
- package/dist/examples/jungianProfiles.d.ts +1 -1
- package/dist/examples/jungianProfiles.d.ts.map +1 -1
- package/dist/examples/jungianTriadProfiles.d.ts +1 -1
- package/dist/examples/jungianTriadProfiles.d.ts.map +1 -1
- package/dist/examples/pi-agent.js +3 -2
- package/dist/examples/pi-memory-org.js +6 -5
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/mcp/toolServer.d.ts +31 -0
- package/dist/mcp/toolServer.d.ts.map +1 -0
- package/dist/mcp/toolServer.js +145 -0
- package/dist/observability/causalEvents.d.ts +118 -0
- package/dist/observability/causalEvents.d.ts.map +1 -0
- package/dist/observability/causalEvents.js +223 -0
- package/dist/observability/controlCausal.d.ts +117 -0
- package/dist/observability/controlCausal.d.ts.map +1 -0
- package/dist/observability/controlCausal.js +107 -0
- package/dist/observability/emitCausalFixture.d.ts +25 -0
- package/dist/observability/emitCausalFixture.d.ts.map +1 -0
- package/dist/observability/emitCausalFixture.js +98 -0
- package/dist/observability/index.d.ts +2 -0
- package/dist/observability/index.d.ts.map +1 -1
- package/dist/observability/index.js +2 -0
- package/dist/observability/orgObserver.d.ts.map +1 -1
- package/dist/observability/orgObserver.js +3 -3
- package/dist/pi/agyHeadlessResult.d.ts +60 -0
- package/dist/pi/agyHeadlessResult.d.ts.map +1 -0
- package/dist/pi/agyHeadlessResult.js +95 -0
- package/dist/pi/cliChildOutput.d.ts +67 -0
- package/dist/pi/cliChildOutput.d.ts.map +1 -0
- package/dist/pi/cliChildOutput.js +269 -0
- package/dist/pi/cliEngineRun.d.ts +16 -0
- package/dist/pi/cliEngineRun.d.ts.map +1 -0
- package/dist/pi/cliEngineRun.js +27 -0
- package/dist/pi/cliEngineSpawn.d.ts +55 -0
- package/dist/pi/cliEngineSpawn.d.ts.map +1 -0
- package/dist/pi/cliEngineSpawn.js +164 -0
- package/dist/pi/cliEnvironment.d.ts +12 -0
- package/dist/pi/cliEnvironment.d.ts.map +1 -0
- package/dist/pi/cliEnvironment.js +32 -0
- package/dist/pi/cliMcpRegistration.d.ts +61 -0
- package/dist/pi/cliMcpRegistration.d.ts.map +1 -0
- package/dist/pi/cliMcpRegistration.js +75 -0
- package/dist/pi/cliProcess.d.ts +7 -0
- package/dist/pi/cliProcess.d.ts.map +1 -0
- package/dist/pi/cliProcess.js +132 -0
- package/dist/pi/cliSession.d.ts +106 -0
- package/dist/pi/cliSession.d.ts.map +1 -0
- package/dist/pi/cliSession.js +379 -0
- package/dist/pi/cliTurnMetering.d.ts +60 -0
- package/dist/pi/cliTurnMetering.d.ts.map +1 -0
- package/dist/pi/cliTurnMetering.js +60 -0
- package/dist/pi/codexFilesystemRules.d.ts +3 -0
- package/dist/pi/codexFilesystemRules.d.ts.map +1 -0
- package/dist/pi/codexFilesystemRules.js +28 -0
- package/dist/pi/codexHeadlessResult.d.ts +68 -0
- package/dist/pi/codexHeadlessResult.d.ts.map +1 -0
- package/dist/pi/codexHeadlessResult.js +122 -0
- package/dist/pi/codexRolloutUsage.d.ts +95 -0
- package/dist/pi/codexRolloutUsage.d.ts.map +1 -0
- package/dist/pi/codexRolloutUsage.js +221 -0
- package/dist/pi/engineWakeLimits.d.ts +39 -0
- package/dist/pi/engineWakeLimits.d.ts.map +1 -0
- package/dist/pi/engineWakeLimits.js +55 -0
- package/dist/pi/grokHeadlessResult.d.ts +36 -0
- package/dist/pi/grokHeadlessResult.d.ts.map +1 -0
- package/dist/pi/grokHeadlessResult.js +118 -0
- package/dist/pi/grokHomeMcpRegistration.d.ts +21 -0
- package/dist/pi/grokHomeMcpRegistration.d.ts.map +1 -0
- package/dist/pi/grokHomeMcpRegistration.js +57 -0
- package/dist/pi/grokSandbox.d.ts +11 -0
- package/dist/pi/grokSandbox.d.ts.map +1 -0
- package/dist/pi/grokSandbox.js +216 -0
- package/dist/pi/grokStreamUsage.d.ts +31 -0
- package/dist/pi/grokStreamUsage.d.ts.map +1 -0
- package/dist/pi/grokStreamUsage.js +51 -0
- package/dist/pi/index.d.ts +5 -0
- package/dist/pi/index.d.ts.map +1 -1
- package/dist/pi/index.js +5 -0
- package/dist/pi/memoryTools.d.ts +55 -1
- package/dist/pi/memoryTools.d.ts.map +1 -1
- package/dist/pi/memoryTools.js +144 -24
- package/dist/pi/modelRegistry.d.ts +13 -0
- package/dist/pi/modelRegistry.d.ts.map +1 -0
- package/dist/pi/modelRegistry.js +19 -0
- package/dist/pi/piAgentHandle.d.ts +46 -0
- package/dist/pi/piAgentHandle.d.ts.map +1 -0
- package/dist/pi/piAgentHandle.js +351 -0
- package/dist/pi/piAgentWakeSupport.d.ts +103 -0
- package/dist/pi/piAgentWakeSupport.d.ts.map +1 -0
- package/dist/pi/piAgentWakeSupport.js +151 -0
- package/dist/pi/piHarness.d.ts +40 -5
- package/dist/pi/piHarness.d.ts.map +1 -1
- package/dist/pi/piHarness.js +151 -256
- package/dist/pi/prompts.d.ts +10 -0
- package/dist/pi/prompts.d.ts.map +1 -0
- package/dist/pi/prompts.js +63 -0
- package/dist/pi/rawTrainingCapture.d.ts +59 -0
- package/dist/pi/rawTrainingCapture.d.ts.map +1 -0
- package/dist/pi/rawTrainingCapture.js +175 -0
- package/dist/pi/turnCausal.d.ts +73 -0
- package/dist/pi/turnCausal.d.ts.map +1 -0
- package/dist/pi/turnCausal.js +75 -0
- package/dist/pi/turnTrace.d.ts +128 -0
- package/dist/pi/turnTrace.d.ts.map +1 -0
- package/dist/pi/turnTrace.js +138 -0
- package/dist/pi/wakeAcceptance.d.ts +49 -0
- package/dist/pi/wakeAcceptance.d.ts.map +1 -0
- package/dist/pi/wakeAcceptance.js +281 -0
- package/dist/pi/wakeAcceptanceFs.d.ts +44 -0
- package/dist/pi/wakeAcceptanceFs.d.ts.map +1 -0
- package/dist/pi/wakeAcceptanceFs.js +318 -0
- package/dist/pi/wakeAcceptanceSchema.d.ts +75 -0
- package/dist/pi/wakeAcceptanceSchema.d.ts.map +1 -0
- package/dist/pi/wakeAcceptanceSchema.js +265 -0
- package/dist/pi/wakeModes.d.ts +9 -0
- package/dist/pi/wakeModes.d.ts.map +1 -0
- package/dist/pi/wakeModes.js +19 -0
- package/dist/pi/worldNudge.d.ts +22 -0
- package/dist/pi/worldNudge.d.ts.map +1 -0
- package/dist/pi/worldNudge.js +62 -0
- package/dist/pi/worldToolProtocol.d.ts +13 -0
- package/dist/pi/worldToolProtocol.d.ts.map +1 -0
- package/dist/pi/worldToolProtocol.js +49 -0
- package/dist/pi/worldTools.d.ts +32 -0
- package/dist/pi/worldTools.d.ts.map +1 -0
- package/dist/pi/worldTools.js +373 -0
- package/dist/pi/worldTrajectory.d.ts +52 -0
- package/dist/pi/worldTrajectory.d.ts.map +1 -0
- package/dist/pi/worldTrajectory.js +131 -0
- package/dist/runtime/agySubscriptionBootstrap.d.ts +16 -0
- package/dist/runtime/agySubscriptionBootstrap.d.ts.map +1 -0
- package/dist/runtime/agySubscriptionBootstrap.js +80 -0
- package/dist/runtime/agySubscriptionRealm.d.ts +38 -0
- package/dist/runtime/agySubscriptionRealm.d.ts.map +1 -0
- package/dist/runtime/agySubscriptionRealm.js +242 -0
- package/dist/runtime/attention.d.ts +21 -0
- package/dist/runtime/attention.d.ts.map +1 -0
- package/dist/runtime/attention.js +36 -0
- package/dist/runtime/attentionDispatcher.d.ts +66 -0
- package/dist/runtime/attentionDispatcher.d.ts.map +1 -0
- package/dist/runtime/attentionDispatcher.js +271 -0
- package/dist/runtime/cli.d.ts +7 -0
- package/dist/runtime/cli.d.ts.map +1 -0
- package/dist/runtime/cli.js +251 -0
- package/dist/runtime/codexSandboxProjection.d.ts +17 -0
- package/dist/runtime/codexSandboxProjection.d.ts.map +1 -0
- package/dist/runtime/codexSandboxProjection.js +40 -0
- package/dist/runtime/contract-manifest.json +1 -0
- package/dist/runtime/contract-manifest.sha256 +1 -0
- package/dist/runtime/contractManifest.d.ts +8 -0
- package/dist/runtime/contractManifest.d.ts.map +1 -0
- package/dist/runtime/contractManifest.js +4 -0
- package/dist/runtime/engineBrokerCapabilities.d.ts +30 -0
- package/dist/runtime/engineBrokerCapabilities.d.ts.map +1 -0
- package/dist/runtime/engineBrokerCapabilities.js +59 -0
- package/dist/runtime/engineBrokerControlClient.d.ts +44 -0
- package/dist/runtime/engineBrokerControlClient.d.ts.map +1 -0
- package/dist/runtime/engineBrokerControlClient.js +132 -0
- package/dist/runtime/engineBrokerCredentialJournal.d.ts +10 -0
- package/dist/runtime/engineBrokerCredentialJournal.d.ts.map +1 -0
- package/dist/runtime/engineBrokerCredentialJournal.js +17 -0
- package/dist/runtime/engineBrokerInferenceProtocol.d.ts +52 -0
- package/dist/runtime/engineBrokerInferenceProtocol.d.ts.map +1 -0
- package/dist/runtime/engineBrokerInferenceProtocol.js +65 -0
- package/dist/runtime/engineBrokerMcpCallLog.d.ts +160 -0
- package/dist/runtime/engineBrokerMcpCallLog.d.ts.map +1 -0
- package/dist/runtime/engineBrokerMcpCallLog.js +219 -0
- package/dist/runtime/engineBrokerMcpFacade.d.ts +56 -0
- package/dist/runtime/engineBrokerMcpFacade.d.ts.map +1 -0
- package/dist/runtime/engineBrokerMcpFacade.js +343 -0
- package/dist/runtime/engineBrokerNativeClient.d.ts +52 -0
- package/dist/runtime/engineBrokerNativeClient.d.ts.map +1 -0
- package/dist/runtime/engineBrokerNativeClient.js +151 -0
- package/dist/runtime/engineBrokerProtocol.d.ts +135 -0
- package/dist/runtime/engineBrokerProtocol.d.ts.map +1 -0
- package/dist/runtime/engineBrokerProtocol.js +274 -0
- package/dist/runtime/engineBrokerSealLedger.d.ts +70 -0
- package/dist/runtime/engineBrokerSealLedger.d.ts.map +1 -0
- package/dist/runtime/engineBrokerSealLedger.js +123 -0
- package/dist/runtime/engineBrokerService.d.ts +37 -0
- package/dist/runtime/engineBrokerService.d.ts.map +1 -0
- package/dist/runtime/engineBrokerService.js +138 -0
- package/dist/runtime/engineBrokerServiceCli.d.ts +5 -0
- package/dist/runtime/engineBrokerServiceCli.d.ts.map +1 -0
- package/dist/runtime/engineBrokerServiceCli.js +32 -0
- package/dist/runtime/engineBrokerServiceConfig.d.ts +50 -0
- package/dist/runtime/engineBrokerServiceConfig.d.ts.map +1 -0
- package/dist/runtime/engineBrokerServiceConfig.js +92 -0
- package/dist/runtime/engineBrokerSingleflight.d.ts +13 -0
- package/dist/runtime/engineBrokerSingleflight.d.ts.map +1 -0
- package/dist/runtime/engineBrokerSingleflight.js +24 -0
- package/dist/runtime/engineBrokerTurnAccounting.d.ts +76 -0
- package/dist/runtime/engineBrokerTurnAccounting.d.ts.map +1 -0
- package/dist/runtime/engineBrokerTurnAccounting.js +108 -0
- package/dist/runtime/engineBrokerTurnRegistry.d.ts +57 -0
- package/dist/runtime/engineBrokerTurnRegistry.d.ts.map +1 -0
- package/dist/runtime/engineBrokerTurnRegistry.js +158 -0
- package/dist/runtime/engineDispatcher.d.ts +36 -0
- package/dist/runtime/engineDispatcher.d.ts.map +1 -0
- package/dist/runtime/engineDispatcher.js +216 -0
- package/dist/runtime/engineReadiness.d.ts +23 -0
- package/dist/runtime/engineReadiness.d.ts.map +1 -0
- package/dist/runtime/engineReadiness.js +222 -0
- package/dist/runtime/grokAuthenticationError.d.ts +8 -0
- package/dist/runtime/grokAuthenticationError.d.ts.map +1 -0
- package/dist/runtime/grokAuthenticationError.js +20 -0
- package/dist/runtime/grokBrokerCredentialAuthority.d.ts +22 -0
- package/dist/runtime/grokBrokerCredentialAuthority.d.ts.map +1 -0
- package/dist/runtime/grokBrokerCredentialAuthority.js +124 -0
- package/dist/runtime/grokBrokerCredentialReader.d.ts +5 -0
- package/dist/runtime/grokBrokerCredentialReader.d.ts.map +1 -0
- package/dist/runtime/grokBrokerCredentialReader.js +37 -0
- package/dist/runtime/grokBrokerModelPolicy.d.ts +23 -0
- package/dist/runtime/grokBrokerModelPolicy.d.ts.map +1 -0
- package/dist/runtime/grokBrokerModelPolicy.js +28 -0
- package/dist/runtime/grokBrokerProjection.d.ts +106 -0
- package/dist/runtime/grokBrokerProjection.d.ts.map +1 -0
- package/dist/runtime/grokBrokerProjection.js +94 -0
- package/dist/runtime/grokBrokerProxy.d.ts +55 -0
- package/dist/runtime/grokBrokerProxy.d.ts.map +1 -0
- package/dist/runtime/grokBrokerProxy.js +262 -0
- package/dist/runtime/grokBrokerProxyRequest.d.ts +30 -0
- package/dist/runtime/grokBrokerProxyRequest.d.ts.map +1 -0
- package/dist/runtime/grokBrokerProxyRequest.js +74 -0
- package/dist/runtime/grokBrokerRealmLease.d.ts +4 -0
- package/dist/runtime/grokBrokerRealmLease.d.ts.map +1 -0
- package/dist/runtime/grokBrokerRealmLease.js +33 -0
- package/dist/runtime/grokBrokerRefresh.d.ts +2 -0
- package/dist/runtime/grokBrokerRefresh.d.ts.map +1 -0
- package/dist/runtime/grokBrokerRefresh.js +15 -0
- package/dist/runtime/grokBrokerTurnMeter.d.ts +128 -0
- package/dist/runtime/grokBrokerTurnMeter.d.ts.map +1 -0
- package/dist/runtime/grokBrokerTurnMeter.js +251 -0
- package/dist/runtime/grokBrokerWorkerConfig.d.ts +86 -0
- package/dist/runtime/grokBrokerWorkerConfig.d.ts.map +1 -0
- package/dist/runtime/grokBrokerWorkerConfig.js +135 -0
- package/dist/runtime/grokEngineBroker.d.ts +48 -0
- package/dist/runtime/grokEngineBroker.d.ts.map +1 -0
- package/dist/runtime/grokEngineBroker.js +114 -0
- package/dist/runtime/grokEngineBrokerLedger.d.ts +52 -0
- package/dist/runtime/grokEngineBrokerLedger.d.ts.map +1 -0
- package/dist/runtime/grokEngineBrokerLedger.js +114 -0
- package/dist/runtime/grokEngineBrokerMetering.d.ts +51 -0
- package/dist/runtime/grokEngineBrokerMetering.d.ts.map +1 -0
- package/dist/runtime/grokEngineBrokerMetering.js +34 -0
- package/dist/runtime/grokEngineBrokerTurn.d.ts +58 -0
- package/dist/runtime/grokEngineBrokerTurn.d.ts.map +1 -0
- package/dist/runtime/grokEngineBrokerTurn.js +165 -0
- package/dist/runtime/grokInferenceClientConfig.d.ts +41 -0
- package/dist/runtime/grokInferenceClientConfig.d.ts.map +1 -0
- package/dist/runtime/grokInferenceClientConfig.js +62 -0
- package/dist/runtime/grokInferenceGrants.d.ts +77 -0
- package/dist/runtime/grokInferenceGrants.d.ts.map +1 -0
- package/dist/runtime/grokInferenceGrants.js +116 -0
- package/dist/runtime/grokInferenceProxy.d.ts +29 -0
- package/dist/runtime/grokInferenceProxy.d.ts.map +1 -0
- package/dist/runtime/grokInferenceProxy.js +82 -0
- package/dist/runtime/grokInferenceProxyRequest.d.ts +23 -0
- package/dist/runtime/grokInferenceProxyRequest.d.ts.map +1 -0
- package/dist/runtime/grokInferenceProxyRequest.js +63 -0
- package/dist/runtime/grokSlotPreflightReceipt.d.ts +70 -0
- package/dist/runtime/grokSlotPreflightReceipt.d.ts.map +1 -0
- package/dist/runtime/grokSlotPreflightReceipt.js +101 -0
- package/dist/runtime/grokSubscriptionRealm.d.ts +4 -0
- package/dist/runtime/grokSubscriptionRealm.d.ts.map +1 -0
- package/dist/runtime/grokSubscriptionRealm.js +435 -0
- package/dist/runtime/grokSubscriptionRealmTypes.d.ts +26 -0
- package/dist/runtime/grokSubscriptionRealmTypes.d.ts.map +1 -0
- package/dist/runtime/grokSubscriptionRealmTypes.js +1 -0
- package/dist/runtime/grokWorkerAttestation.d.ts +170 -0
- package/dist/runtime/grokWorkerAttestation.d.ts.map +1 -0
- package/dist/runtime/grokWorkerAttestation.js +266 -0
- package/dist/runtime/grokWorkerDenyPlacement.d.ts +80 -0
- package/dist/runtime/grokWorkerDenyPlacement.d.ts.map +1 -0
- package/dist/runtime/grokWorkerDenyPlacement.js +128 -0
- package/dist/runtime/grokWorkerHomeAttestation.d.ts +30 -0
- package/dist/runtime/grokWorkerHomeAttestation.d.ts.map +1 -0
- package/dist/runtime/grokWorkerHomeAttestation.js +69 -0
- package/dist/runtime/grokWorkerSandboxProfile.d.ts +27 -0
- package/dist/runtime/grokWorkerSandboxProfile.d.ts.map +1 -0
- package/dist/runtime/grokWorkerSandboxProfile.js +44 -0
- package/dist/runtime/grokWorkerTmpAttestation.d.ts +55 -0
- package/dist/runtime/grokWorkerTmpAttestation.d.ts.map +1 -0
- package/dist/runtime/grokWorkerTmpAttestation.js +63 -0
- package/dist/runtime/index.d.ts +26 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +23 -0
- package/dist/runtime/inferenceUsageLedger.d.ts +38 -0
- package/dist/runtime/inferenceUsageLedger.d.ts.map +1 -0
- package/dist/runtime/inferenceUsageLedger.js +53 -0
- package/dist/runtime/mcpToolResult.d.ts +127 -0
- package/dist/runtime/mcpToolResult.d.ts.map +1 -0
- package/dist/runtime/mcpToolResult.js +214 -0
- package/dist/runtime/moltnetMachineRead.d.ts +97 -0
- package/dist/runtime/moltnetMachineRead.d.ts.map +1 -0
- package/dist/runtime/moltnetMachineRead.js +183 -0
- package/dist/runtime/native/daimon-engine-broker +0 -0
- package/dist/runtime/organizationRuntime.d.ts +165 -0
- package/dist/runtime/organizationRuntime.d.ts.map +1 -0
- package/dist/runtime/organizationRuntime.js +3 -0
- package/dist/runtime/organizationRuntimeControl.d.ts +42 -0
- package/dist/runtime/organizationRuntimeControl.d.ts.map +1 -0
- package/dist/runtime/organizationRuntimeControl.js +235 -0
- package/dist/runtime/organizationRuntimeHost.d.ts +19 -0
- package/dist/runtime/organizationRuntimeHost.d.ts.map +1 -0
- package/dist/runtime/organizationRuntimeHost.js +359 -0
- package/dist/runtime/organizationRuntimeParsing.d.ts +6 -0
- package/dist/runtime/organizationRuntimeParsing.d.ts.map +1 -0
- package/dist/runtime/organizationRuntimeParsing.js +370 -0
- package/dist/runtime/organizationRuntimeReadiness.d.ts +12 -0
- package/dist/runtime/organizationRuntimeReadiness.d.ts.map +1 -0
- package/dist/runtime/organizationRuntimeReadiness.js +59 -0
- package/dist/runtime/physicalReadiness.d.ts +47 -0
- package/dist/runtime/physicalReadiness.d.ts.map +1 -0
- package/dist/runtime/physicalReadiness.js +142 -0
- package/dist/runtime/portableCredentialAuth.d.ts +6 -0
- package/dist/runtime/portableCredentialAuth.d.ts.map +1 -0
- package/dist/runtime/portableCredentialAuth.js +70 -0
- package/dist/runtime/portableCredentialMaterial.d.ts +8 -0
- package/dist/runtime/portableCredentialMaterial.d.ts.map +1 -0
- package/dist/runtime/portableCredentialMaterial.js +169 -0
- package/dist/runtime/productionAgentTools.d.ts +5 -0
- package/dist/runtime/productionAgentTools.d.ts.map +1 -0
- package/dist/runtime/productionAgentTools.js +328 -0
- package/dist/runtime/runtimeHomeLayout.d.ts +48 -0
- package/dist/runtime/runtimeHomeLayout.d.ts.map +1 -0
- package/dist/runtime/runtimeHomeLayout.js +84 -0
- package/dist/runtime/schedule.d.ts +40 -0
- package/dist/runtime/schedule.d.ts.map +1 -0
- package/dist/runtime/schedule.js +371 -0
- package/dist/runtime/storeCoordination.d.ts +23 -0
- package/dist/runtime/storeCoordination.d.ts.map +1 -0
- package/dist/runtime/storeCoordination.js +94 -0
- package/dist/runtime/toolResultSpill.d.ts +152 -0
- package/dist/runtime/toolResultSpill.d.ts.map +1 -0
- package/dist/runtime/toolResultSpill.js +351 -0
- package/dist/runtime/turnRequestLedger.d.ts +160 -0
- package/dist/runtime/turnRequestLedger.d.ts.map +1 -0
- package/dist/runtime/turnRequestLedger.js +249 -0
- package/dist/runtime/turnUsageLedger.d.ts +143 -0
- package/dist/runtime/turnUsageLedger.d.ts.map +1 -0
- package/dist/runtime/turnUsageLedger.js +203 -0
- package/dist/runtime/wakeAcceptanceProcessIdentity.d.ts +17 -0
- package/dist/runtime/wakeAcceptanceProcessIdentity.d.ts.map +1 -0
- package/dist/runtime/wakeAcceptanceProcessIdentity.js +50 -0
- package/dist/runtime/wakeAcceptanceReconciliation.d.ts +211 -0
- package/dist/runtime/wakeAcceptanceReconciliation.d.ts.map +1 -0
- package/dist/runtime/wakeAcceptanceReconciliation.js +289 -0
- package/dist/runtime/wakeAcceptanceRecord.d.ts +23 -0
- package/dist/runtime/wakeAcceptanceRecord.d.ts.map +1 -0
- package/dist/runtime/wakeAcceptanceRecord.js +56 -0
- package/dist/runtime/wakeAcceptanceRetention.d.ts +12 -0
- package/dist/runtime/wakeAcceptanceRetention.d.ts.map +1 -0
- package/dist/runtime/wakeAcceptanceRetention.js +12 -0
- package/dist/runtime/wakeAcceptanceStore.d.ts +113 -0
- package/dist/runtime/wakeAcceptanceStore.d.ts.map +1 -0
- package/dist/runtime/wakeAcceptanceStore.js +558 -0
- package/dist/runtime/wakeAcceptanceTypes.d.ts +179 -0
- package/dist/runtime/wakeAcceptanceTypes.d.ts.map +1 -0
- package/dist/runtime/wakeAcceptanceTypes.js +95 -0
- package/dist/runtime/wakeFuse.d.ts +69 -0
- package/dist/runtime/wakeFuse.d.ts.map +1 -0
- package/dist/runtime/wakeFuse.js +367 -0
- package/package.json +25 -17
- package/dist/examples/mixed-engine-org.d.ts +0 -2
- package/dist/examples/mixed-engine-org.d.ts.map +0 -1
- package/dist/examples/mixed-engine-org.js +0 -351
- package/dist/examples/mixedEngineCli.d.ts +0 -15
- package/dist/examples/mixedEngineCli.d.ts.map +0 -1
- package/dist/examples/mixedEngineCli.js +0 -174
|
@@ -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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
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 const DEFAULT_CODEX_WAKE_TIMEOUT_MS = 240_000;
|
|
23
|
+
export const DEFAULT_CODEX_WAKE_TOKEN_CEILING = 300_000;
|
|
24
|
+
export const DAIMON_ENGINE_WAKE_TIMEOUT_MS_ENV = "DAIMON_ENGINE_WAKE_TIMEOUT_MS";
|
|
25
|
+
export const DAIMON_ENGINE_WAKE_TOKEN_CEILING_ENV = "DAIMON_ENGINE_WAKE_TOKEN_CEILING";
|
|
26
|
+
export const DAIMON_CODEX_WAKE_TIMEOUT_MS_ENV = "DAIMON_CODEX_WAKE_TIMEOUT_MS";
|
|
27
|
+
export const DAIMON_CODEX_WAKE_TOKEN_CEILING_ENV = "DAIMON_CODEX_WAKE_TOKEN_CEILING";
|
|
28
|
+
const positiveInteger = (value, name) => {
|
|
29
|
+
const parsed = Number(value);
|
|
30
|
+
if (!Number.isSafeInteger(parsed) || parsed <= 0)
|
|
31
|
+
throw new Error(`${name} must be a positive integer`);
|
|
32
|
+
return parsed;
|
|
33
|
+
};
|
|
34
|
+
const declared = (environment, neutral, alias) => {
|
|
35
|
+
const primary = environment[neutral], legacy = environment[alias];
|
|
36
|
+
const value = primary === undefined ? undefined : positiveInteger(primary, neutral);
|
|
37
|
+
const aliased = legacy === undefined ? undefined : positiveInteger(legacy, alias);
|
|
38
|
+
if (value !== undefined && aliased !== undefined && value !== aliased)
|
|
39
|
+
throw new Error(`${neutral} and ${alias} disagree; set one`);
|
|
40
|
+
return value ?? aliased;
|
|
41
|
+
};
|
|
42
|
+
export const resolveCodexWakeTimeoutMs = (environment = process.env) => declared(environment, DAIMON_ENGINE_WAKE_TIMEOUT_MS_ENV, DAIMON_CODEX_WAKE_TIMEOUT_MS_ENV) ?? DEFAULT_CODEX_WAKE_TIMEOUT_MS;
|
|
43
|
+
export const resolveCodexWakeTokenCeiling = (environment = process.env) => declared(environment, DAIMON_ENGINE_WAKE_TOKEN_CEILING_ENV, DAIMON_CODEX_WAKE_TOKEN_CEILING_ENV) ?? DEFAULT_CODEX_WAKE_TOKEN_CEILING;
|
|
44
|
+
/**
|
|
45
|
+
* The limits a wake asks a broker to lower to: only the bounds the operator
|
|
46
|
+
* actually set, never the Codex defaults (a broker registration's declared
|
|
47
|
+
* limits already are the defaults there).
|
|
48
|
+
*/
|
|
49
|
+
export const resolveEngineWakeLimitOverrides = (environment = process.env) => {
|
|
50
|
+
const timeoutMs = declared(environment, DAIMON_ENGINE_WAKE_TIMEOUT_MS_ENV, DAIMON_CODEX_WAKE_TIMEOUT_MS_ENV);
|
|
51
|
+
const maxTokens = declared(environment, DAIMON_ENGINE_WAKE_TOKEN_CEILING_ENV, DAIMON_CODEX_WAKE_TOKEN_CEILING_ENV);
|
|
52
|
+
if (timeoutMs === undefined && maxTokens === undefined)
|
|
53
|
+
return undefined;
|
|
54
|
+
return { ...(timeoutMs === undefined ? {} : { timeoutMs }), ...(maxTokens === undefined ? {} : { maxTokens }) };
|
|
55
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token accounting for one turn, as the engine itself reported it.
|
|
3
|
+
*
|
|
4
|
+
* These are subscription-backed CLIs, so nothing here is billed: the counts are
|
|
5
|
+
* real quota consumption and `notionalUsd` is what the same turn would have cost
|
|
6
|
+
* at metered API rates. Kept away from anything named `cost` so a later reader
|
|
7
|
+
* cannot mistake it for a charge.
|
|
8
|
+
*
|
|
9
|
+
* Field provenance is the `streaming-messages-json` terminal `result` frame,
|
|
10
|
+
* which production hardcodes (`grokBrokerWorkerConfig.ts`). Its `result.usage`
|
|
11
|
+
* is the Messages API `message.usage` shape with three *disjoint* prompt-side
|
|
12
|
+
* buckets, so the full turn cost is
|
|
13
|
+
* `input_tokens + cache_read_input_tokens + cache_creation_input_tokens + output_tokens`.
|
|
14
|
+
*/
|
|
15
|
+
export type GrokTurnUsage = Readonly<{
|
|
16
|
+
input: number;
|
|
17
|
+
output: number;
|
|
18
|
+
cacheRead: number;
|
|
19
|
+
cacheWrite: number;
|
|
20
|
+
total: number;
|
|
21
|
+
calls: number;
|
|
22
|
+
notionalUsd: number;
|
|
23
|
+
complete: boolean;
|
|
24
|
+
}>;
|
|
25
|
+
export type GrokHeadlessTurn = Readonly<{
|
|
26
|
+
text: string;
|
|
27
|
+
usage?: GrokTurnUsage;
|
|
28
|
+
}>;
|
|
29
|
+
/**
|
|
30
|
+
* Decode Grok's terminal message stream without treating progress messages as a
|
|
31
|
+
* reply, and extract the turn's own token accounting from the same frame.
|
|
32
|
+
*/
|
|
33
|
+
export declare const decodeGrokHeadlessTurn: (output: string) => GrokHeadlessTurn;
|
|
34
|
+
/** Text-only view of {@link decodeGrokHeadlessTurn}, for callers that do not meter. */
|
|
35
|
+
export declare const decodeGrokHeadlessResult: (output: string) => string;
|
|
36
|
+
//# sourceMappingURL=grokHeadlessResult.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grokHeadlessResult.d.ts","sourceRoot":"","sources":["../../src/pi/grokHeadlessResult.ts"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC;IACnC,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,gBAAgB,GAAG,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,aAAa,CAAA;CAAE,CAAC,CAAC;AA8DjF;;;GAGG;AACH,eAAO,MAAM,sBAAsB,GAAI,QAAQ,MAAM,KAAG,gBA+BvD,CAAC;AAEF,uFAAuF;AACvF,eAAO,MAAM,wBAAwB,GAAI,QAAQ,MAAM,KAAG,MAA6C,CAAC"}
|