@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 @@
|
|
|
1
|
+
{"version":3,"file":"turnRequestLedger.d.ts","sourceRoot":"","sources":["../../src/runtime/turnRequestLedger.ts"],"names":[],"mappings":"AAGA,OAAO,EAA4B,KAAK,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC9F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAGlE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,2BAA2B,EAAG,kCAA2C,CAAC;AAEvF;;;GAGG;AACH,eAAO,MAAM,mBAAmB;;;;;;CAMtB,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,EAAG,kCAA2C,CAAC;AAExF,eAAO,MAAM,4BAA4B,GAAI,cAAa,MAAM,CAAC,UAAwB,KAAG,MAG3F,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACvC,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC,CAAC;AAIH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,GAAI,OAAO,gBAAgB,KAAG,MAqBhE,CAAC;AASF,0FAA0F;AAC1F;;;;GAIG;AACH;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,QAAQ,GAAG,UAAU,GAAG,WAAW,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC,CAAC;AACvQ;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,eAAe,CAAC;IAAC,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE/M;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,0BAA0B,GAAI,OAAO,oBAAoB,KAAG,MAuBxE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAU,MAAM,MAAM,EAAE,OAAO,MAAM,KAAG,OAAO,CAAC,OAAO,CAGpF,CAAC;AAEF,iGAAiG;AACjG,eAAO,MAAM,sBAAsB,GAAU,MAAM,MAAM,EAAE,OAAO,oBAAoB,KAAG,OAAO,CAAC,OAAO,CAGvG,CAAC;AA4BF;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,GAAU,MAAM,MAAM,EAAE,OAAO,gBAAgB,KAAG,OAAO,CAAC,OAAO,CAU/F,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB,GAAU,OAAO,QAAQ,CAAC;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC,KAAG,OAAO,CAAC,OAAO,CAiBnB,CAAC"}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { constants } from "node:fs";
|
|
2
|
+
import { open, rename, stat } from "node:fs/promises";
|
|
3
|
+
import { readCodexRolloutRequests } from "../pi/codexRolloutUsage.js";
|
|
4
|
+
import { TURN_USAGE_LEDGER, TURN_USAGE_MAX_IDENTIFIER_CHARS, TURN_USAGE_ROTATE_BYTES } from "./turnUsageLedger.js";
|
|
5
|
+
/**
|
|
6
|
+
* Per-model-request token accounting, written *beside* the per-wake usage
|
|
7
|
+
* ledger and never inside it.
|
|
8
|
+
*
|
|
9
|
+
* `turnUsageLedger.ts` records one aggregate row per wake. Production measured
|
|
10
|
+
* 55 wakes at 14,890,263 input tokens against 159,726 output — output is 1.06%
|
|
11
|
+
* of the spend — with context per model request flat at 23–32k regardless of
|
|
12
|
+
* how many requests a wake made. That is the signature of a fixed prefix
|
|
13
|
+
* replayed once per request rather than of a conversation that grows, but the
|
|
14
|
+
* aggregate row cannot tell the two apart, and every optimisation worth doing
|
|
15
|
+
* next depends on which one it is. This file is what tells them apart.
|
|
16
|
+
*
|
|
17
|
+
* It is a separate stream, not a wider row, for one specific reason. Spawnfile's
|
|
18
|
+
* reader (`spawnfile/src/runtime/usageLedger.ts`) rejects any line whose `v` is
|
|
19
|
+
* not `noopolis.daimon.turn-usage.v1` and returns `null` for the whole line, so
|
|
20
|
+
* a version bump on the existing ledger would make an unreleased Spawnfile drop
|
|
21
|
+
* every row it can read today. Nothing here changes the shape, version, path, or
|
|
22
|
+
* field list of that ledger; a reader that knows nothing about this file keeps
|
|
23
|
+
* working byte for byte.
|
|
24
|
+
*/
|
|
25
|
+
export const TURN_REQUEST_LEDGER_VERSION = "noopolis.daimon.turn-requests.v1";
|
|
26
|
+
/**
|
|
27
|
+
* Default location: the directory Spawnfile already provisions for the usage
|
|
28
|
+
* ledger, under its own filename. No new mount, no new provisioning step.
|
|
29
|
+
*/
|
|
30
|
+
export const TURN_REQUEST_LEDGER = {
|
|
31
|
+
version: TURN_REQUEST_LEDGER_VERSION,
|
|
32
|
+
directoryPath: TURN_USAGE_LEDGER.directoryPath,
|
|
33
|
+
filePath: `${TURN_USAGE_LEDGER.directoryPath}/requests.jsonl`,
|
|
34
|
+
rotatedFilePath: `${TURN_USAGE_LEDGER.directoryPath}/requests.jsonl.1`,
|
|
35
|
+
fileMode: TURN_USAGE_LEDGER.fileMode
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* `DAIMON_TURN_REQUESTS_LEDGER_PATH` relocates the stream, exactly as
|
|
39
|
+
* `DAIMON_TURN_USAGE_LEDGER_PATH` relocates the ledger it sits beside. A
|
|
40
|
+
* relative or empty value is ignored rather than honoured: a ledger written to
|
|
41
|
+
* a process-relative path is a ledger nobody can find again.
|
|
42
|
+
*/
|
|
43
|
+
export const TURN_REQUEST_LEDGER_PATH_ENV = "DAIMON_TURN_REQUESTS_LEDGER_PATH";
|
|
44
|
+
export const resolveTurnRequestLedgerPath = (environment = process.env) => {
|
|
45
|
+
const override = environment[TURN_REQUEST_LEDGER_PATH_ENV]?.trim();
|
|
46
|
+
return override !== undefined && override.startsWith("/") ? override : TURN_REQUEST_LEDGER.filePath;
|
|
47
|
+
};
|
|
48
|
+
const bounded = (value) => [...value].slice(0, TURN_USAGE_MAX_IDENTIFIER_CHARS).join("");
|
|
49
|
+
/**
|
|
50
|
+
* One line per model request.
|
|
51
|
+
*
|
|
52
|
+
* `fresh_input` is `input − cached_input`, the split the whole exercise exists
|
|
53
|
+
* to see. It is derived from exactly the relationship Daimon already validates
|
|
54
|
+
* (`cached_input_tokens` is a subset of `input_tokens`, asserted by Codex's own
|
|
55
|
+
* reconciled totals and re-checked when the block is decoded). `cache_write` is
|
|
56
|
+
* emitted raw and never subtracted, because whether Codex counts a cache write
|
|
57
|
+
* inside `input_tokens` has not been verified — a reader that needs that answer
|
|
58
|
+
* has the raw number to work from instead of a guess baked into the row.
|
|
59
|
+
*/
|
|
60
|
+
export const renderTurnRequestLines = (entry) => {
|
|
61
|
+
const at = entry.at ?? new Date().toISOString();
|
|
62
|
+
const requests = entry.requests.length;
|
|
63
|
+
return entry.requests.map((request) => `${JSON.stringify({
|
|
64
|
+
v: TURN_REQUEST_LEDGER_VERSION,
|
|
65
|
+
agent: bounded(entry.agent),
|
|
66
|
+
wake: bounded(entry.wake),
|
|
67
|
+
engine: "codex",
|
|
68
|
+
at,
|
|
69
|
+
thread: bounded(entry.thread),
|
|
70
|
+
request: request.index,
|
|
71
|
+
requests,
|
|
72
|
+
input: request.input,
|
|
73
|
+
cached_input: request.cachedInput,
|
|
74
|
+
fresh_input: request.input - request.cachedInput,
|
|
75
|
+
cache_write: request.cacheWrite,
|
|
76
|
+
output: request.output,
|
|
77
|
+
reasoning: request.reasoning,
|
|
78
|
+
total: request.total,
|
|
79
|
+
...requestClockFields(request)
|
|
80
|
+
})}\n`).join("");
|
|
81
|
+
};
|
|
82
|
+
const TIMESTAMP = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,9})?Z$/u;
|
|
83
|
+
/** Per-request `started_at`/`ended_at`, each only when it was measured; `at` stays the append time. */
|
|
84
|
+
const requestClockFields = (request) => ({
|
|
85
|
+
...(request.startedAt !== undefined && TIMESTAMP.test(request.startedAt) ? { started_at: request.startedAt } : {}),
|
|
86
|
+
...(request.endedAt !== undefined && TIMESTAMP.test(request.endedAt) ? { ended_at: request.endedAt } : {})
|
|
87
|
+
});
|
|
88
|
+
/**
|
|
89
|
+
* Grok rows share the Codex row's field meaning: `input` is the whole prompt
|
|
90
|
+
* side the request replayed (`input_tokens + cache_read`), `cached_input` the
|
|
91
|
+
* cache read, `fresh_input` the uncached remainder. Grok does not separate
|
|
92
|
+
* reasoning tokens, so `reasoning` is absent rather than zero. `turn` is the
|
|
93
|
+
* broker idempotency key and `thread` the Grok session id when the stream
|
|
94
|
+
* named one.
|
|
95
|
+
*
|
|
96
|
+
* `tool_calls` is what a turn's rows could not say before: whether the model
|
|
97
|
+
* ever *tried* to call anything. Two live turns ended with correctly mounted
|
|
98
|
+
* tools and no visible attempt, and the rows recorded timings and tokens only,
|
|
99
|
+
* so the question could not be answered after the fact. It is names only —
|
|
100
|
+
* never arguments, never message content, never a bearer — bounded, `[]` for a
|
|
101
|
+
* response that called nothing, and absent for a response that could not be
|
|
102
|
+
* decoded, because a fabricated empty list is byte-identical to a measured one.
|
|
103
|
+
*
|
|
104
|
+
* It is an additive field inside the unchanged
|
|
105
|
+
* `noopolis.daimon.turn-requests.v1` row, deliberately without a version bump:
|
|
106
|
+
* Spawnfile's usage reader (`spawnfile/src/runtime/usageLedger.ts`) drops every
|
|
107
|
+
* line whose `v` it does not recognise while ignoring fields it does not know,
|
|
108
|
+
* and Paideia only relocates this stream's path
|
|
109
|
+
* (`DAIMON_TURN_REQUESTS_LEDGER_PATH`). A bump is what would blind them; a new
|
|
110
|
+
* field is not.
|
|
111
|
+
*/
|
|
112
|
+
export const renderGrokTurnRequestLines = (entry) => {
|
|
113
|
+
const at = entry.at ?? new Date().toISOString();
|
|
114
|
+
return entry.requests.map((request) => `${JSON.stringify({
|
|
115
|
+
v: TURN_REQUEST_LEDGER_VERSION,
|
|
116
|
+
agent: bounded(entry.agent),
|
|
117
|
+
wake: bounded(entry.wake),
|
|
118
|
+
engine: "grok",
|
|
119
|
+
at,
|
|
120
|
+
turn: entry.turn,
|
|
121
|
+
...(entry.session === undefined ? {} : { thread: bounded(entry.session) }),
|
|
122
|
+
model: entry.model,
|
|
123
|
+
request: request.index,
|
|
124
|
+
requests: Math.max(entry.requests.length, entry.requestCount ?? 0),
|
|
125
|
+
input: request.input + request.cacheRead,
|
|
126
|
+
cached_input: request.cacheRead,
|
|
127
|
+
fresh_input: request.input,
|
|
128
|
+
cache_write: request.cacheWrite,
|
|
129
|
+
output: request.output,
|
|
130
|
+
total: request.total,
|
|
131
|
+
...(request.usageSource === undefined ? {} : { usage_source: request.usageSource }),
|
|
132
|
+
...(request.toolCalls === undefined ? {} : { tool_calls: request.toolCalls }),
|
|
133
|
+
...requestClockFields(request)
|
|
134
|
+
})}\n`).join("");
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* Append already-rendered, newline-terminated ledger lines in one write, with the
|
|
138
|
+
* same rotation and file mode as both ledgers. Advisory: never rejects. The
|
|
139
|
+
* broker uses it to append the exact bytes it sealed into a turn record.
|
|
140
|
+
*/
|
|
141
|
+
export const recordLedgerLines = async (file, lines) => {
|
|
142
|
+
if (lines.length === 0)
|
|
143
|
+
return false;
|
|
144
|
+
try {
|
|
145
|
+
await rotate(file);
|
|
146
|
+
await appendLines(file, lines);
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
/** Advisory and never rejects, like {@link recordTurnRequests}; an empty turn writes nothing. */
|
|
154
|
+
export const recordGrokTurnRequests = async (file, entry) => {
|
|
155
|
+
if (entry.requests.length === 0)
|
|
156
|
+
return false;
|
|
157
|
+
try {
|
|
158
|
+
await rotate(file);
|
|
159
|
+
await appendLines(file, renderGrokTurnRequestLines(entry));
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
const rotate = async (file) => {
|
|
167
|
+
let size;
|
|
168
|
+
try {
|
|
169
|
+
size = (await stat(file)).size;
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
if (size >= TURN_USAGE_ROTATE_BYTES)
|
|
175
|
+
await rename(file, `${file}.1`);
|
|
176
|
+
};
|
|
177
|
+
/**
|
|
178
|
+
* One `write(2)` for the whole wake's rows.
|
|
179
|
+
*
|
|
180
|
+
* Turns for different agents run concurrently inside the single broker process.
|
|
181
|
+
* `O_APPEND` makes a single sub-page write atomic against them, so a wake's rows
|
|
182
|
+
* are contiguous and never interleaved with another wake's — which matters more
|
|
183
|
+
* here than in the per-wake ledger, because a row only means something beside
|
|
184
|
+
* the other rows of its own thread. A wake with enough requests to exceed a page
|
|
185
|
+
* is still append-ordered per line; interleaving would cost grouping, not
|
|
186
|
+
* correctness, since every row carries its own thread id.
|
|
187
|
+
*/
|
|
188
|
+
const appendLines = async (file, lines) => {
|
|
189
|
+
const bytes = Buffer.from(lines, "utf8");
|
|
190
|
+
const handle = await open(file, constants.O_WRONLY | constants.O_APPEND | constants.O_CREAT | constants.O_NOFOLLOW, TURN_REQUEST_LEDGER.fileMode);
|
|
191
|
+
try {
|
|
192
|
+
const { bytesWritten } = await handle.write(bytes, 0, bytes.length);
|
|
193
|
+
if (bytesWritten !== bytes.length)
|
|
194
|
+
throw new Error("turn request ledger append was torn");
|
|
195
|
+
}
|
|
196
|
+
finally {
|
|
197
|
+
await handle.close();
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
/**
|
|
201
|
+
* Advisory. Never rejects, and never writes an empty wake.
|
|
202
|
+
*
|
|
203
|
+
* A wake whose rollout was absent, unreadable, or undecodable contributes no
|
|
204
|
+
* rows at all rather than a zero row — the same invariant the usage ledger
|
|
205
|
+
* holds, for the same reason: a fabricated zero is byte-identical to a measured
|
|
206
|
+
* one, and this stream exists to be believed.
|
|
207
|
+
*/
|
|
208
|
+
export const recordTurnRequests = async (file, entry) => {
|
|
209
|
+
if (entry.requests.length === 0)
|
|
210
|
+
return false;
|
|
211
|
+
try {
|
|
212
|
+
await rotate(file);
|
|
213
|
+
await appendLines(file, renderTurnRequestLines(entry));
|
|
214
|
+
return true;
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
/* advisory: instrumentation never fails a wake that published */
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
/**
|
|
222
|
+
* The whole instrumentation path for one Codex wake: find that thread's
|
|
223
|
+
* rollout, decode its per-request usage, append it. Never throws.
|
|
224
|
+
*
|
|
225
|
+
* A wake that produced no rows says so on stderr exactly once. Silence would
|
|
226
|
+
* make a permanently blind instrument indistinguishable from a working one —
|
|
227
|
+
* `--ephemeral`, a relocated `CODEX_HOME`, or a Codex version that renamed the
|
|
228
|
+
* usage frame all end here, and each is worth one line rather than a
|
|
229
|
+
* quietly-empty file nobody questions.
|
|
230
|
+
*/
|
|
231
|
+
export const recordCodexTurnRequests = async (input) => {
|
|
232
|
+
try {
|
|
233
|
+
const requests = await readCodexRolloutRequests(input.codexHome, input.threadId);
|
|
234
|
+
const written = await recordTurnRequests(input.file ?? resolveTurnRequestLedgerPath(), {
|
|
235
|
+
agent: input.agent,
|
|
236
|
+
wake: input.wake,
|
|
237
|
+
thread: input.threadId,
|
|
238
|
+
requests
|
|
239
|
+
});
|
|
240
|
+
if (!written) {
|
|
241
|
+
console.error(`daimon: no per-request usage recorded for codex thread ${input.threadId} (${requests.length === 0 ? "no decodable rollout usage" : "ledger append failed"})`);
|
|
242
|
+
}
|
|
243
|
+
return written;
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
console.error(`daimon: per-request usage instrumentation failed: ${error instanceof Error ? error.message : "unknown error"}`);
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
};
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { type EngineBrokerLimitReason } from "./engineBrokerTurnAccounting.js";
|
|
2
|
+
import type { GrokBrokerModel } from "./grokBrokerModelPolicy.js";
|
|
3
|
+
/**
|
|
4
|
+
* Append-only per-turn token accounting for one container.
|
|
5
|
+
*
|
|
6
|
+
* The record carries no organization: there is one ledger per container and one
|
|
7
|
+
* organization per container, so identity comes from which container was
|
|
8
|
+
* queried. Nothing engine-controlled and non-numeric is ever persisted.
|
|
9
|
+
*/
|
|
10
|
+
export declare const TURN_USAGE_LEDGER_VERSION: "noopolis.daimon.turn-usage.v1";
|
|
11
|
+
/**
|
|
12
|
+
* Where the broker writes, and what Spawnfile provisions.
|
|
13
|
+
*
|
|
14
|
+
* Deliberately *not* folded into `RUNTIME_CONTRACT_MANIFEST`. That manifest's
|
|
15
|
+
* canonical bytes are digest-pinned by Spawnfile
|
|
16
|
+
* (`DAIMON_CONTRACT_MANIFEST_SHA256`) and attested against the runtime image
|
|
17
|
+
* selected at compile time, so any new key there makes every pinned image fail
|
|
18
|
+
* to attest and blocks all Daimon compiles until an image is rebuilt and
|
|
19
|
+
* re-pinned. Nothing about metering needs digest attestation: this is a path
|
|
20
|
+
* both sides agree on, mirrored in `spawnfile/src/runtime/daimon/`. Registering
|
|
21
|
+
* the schema in the manifest is bookkeeping that belongs with the next image
|
|
22
|
+
* rebuild.
|
|
23
|
+
*/
|
|
24
|
+
export declare const TURN_USAGE_LEDGER: {
|
|
25
|
+
readonly version: "noopolis.daimon.turn-usage.v1";
|
|
26
|
+
readonly directoryPath: "/var/lib/spawnfile/daimon/usage";
|
|
27
|
+
readonly filePath: "/var/lib/spawnfile/daimon/usage/usage.jsonl";
|
|
28
|
+
readonly rotatedFilePath: "/var/lib/spawnfile/daimon/usage/usage.jsonl.1";
|
|
29
|
+
readonly directoryMode: 488;
|
|
30
|
+
readonly fileMode: 416;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* `agent` and `wake` are caller-supplied external text (`wake` is `event.id`
|
|
34
|
+
* from the wake request, schema-bounded to 4096 codepoints). They are truncated
|
|
35
|
+
* so one record cannot grow past a size where a single `write(2)` stops being
|
|
36
|
+
* atomic. JSON escaping already prevents line injection.
|
|
37
|
+
*/
|
|
38
|
+
export declare const TURN_USAGE_MAX_IDENTIFIER_CHARS = 128;
|
|
39
|
+
/** Rotate to a single `.1` sibling. ~2.5k lines/day observed, so this is months. */
|
|
40
|
+
export declare const TURN_USAGE_ROTATE_BYTES: number;
|
|
41
|
+
export type TurnUsageMeasurement = Readonly<{
|
|
42
|
+
input: number;
|
|
43
|
+
output: number;
|
|
44
|
+
cacheRead: number;
|
|
45
|
+
cacheWrite: number;
|
|
46
|
+
total: number;
|
|
47
|
+
calls: number;
|
|
48
|
+
notionalUsd: number;
|
|
49
|
+
complete: boolean;
|
|
50
|
+
}>;
|
|
51
|
+
/**
|
|
52
|
+
* Every engine whose headless stream reports its own token accounting.
|
|
53
|
+
*
|
|
54
|
+
* Codex, AGY, and Grok all publish decoded terminal-stream accounting here.
|
|
55
|
+
* Spawnfile's reader mirrors this list and is updated separately in packet
|
|
56
|
+
* A1b; until then, a reader that rejects `codex` will drop every Codex line.
|
|
57
|
+
*/
|
|
58
|
+
export declare const TURN_USAGE_ENGINES: readonly ["agy", "codex", "grok"];
|
|
59
|
+
/**
|
|
60
|
+
* Whether the wake that spent these tokens went on to succeed.
|
|
61
|
+
*
|
|
62
|
+
* Money is spent by a failed wake exactly as by a successful one, so a row is
|
|
63
|
+
* written whenever the engine actually reported usage — see
|
|
64
|
+
* `../pi/cliSession.ts`. Without this field every failed wake's spend was
|
|
65
|
+
* simply absent from the ledger, and an organization's cost total silently
|
|
66
|
+
* undercounted by however much its failures burned.
|
|
67
|
+
*
|
|
68
|
+
* `reason` is a closed vocabulary, never an engine- or error-supplied string:
|
|
69
|
+
* the record's rule that nothing engine-controlled and non-numeric is
|
|
70
|
+
* persisted still holds, and `renderTurnUsageLine` degrades anything outside
|
|
71
|
+
* the list to `unknown` rather than writing it through.
|
|
72
|
+
*/
|
|
73
|
+
export declare const TURN_USAGE_OUTCOMES: readonly ["completed", "failed"];
|
|
74
|
+
/**
|
|
75
|
+
* - `token_ceiling` — the turn's own reported usage crossed the per-wake ceiling.
|
|
76
|
+
* - `request_ceiling` — the broker refused a model request past the turn's request limit.
|
|
77
|
+
* - `wake_timeout` — the wall-clock bound fired before the child finished.
|
|
78
|
+
* - `output_limit` — the retained-output bound was exceeded.
|
|
79
|
+
* - `engine_exit` — the child exited non-zero (or died) after reporting usage.
|
|
80
|
+
* - `turn_rejected` — usage was reported but the decoded turn was not publishable.
|
|
81
|
+
* - `unknown` — any other failure (verification, cleanup, spawn).
|
|
82
|
+
*/
|
|
83
|
+
export declare const TURN_USAGE_FAILURE_REASONS: readonly ["token_ceiling", "request_ceiling", "wake_timeout", "output_limit", "engine_exit", "turn_rejected", "unknown"];
|
|
84
|
+
export type TurnUsageFailureReason = typeof TURN_USAGE_FAILURE_REASONS[number];
|
|
85
|
+
export type TurnUsageOutcome = Readonly<{
|
|
86
|
+
status: typeof TURN_USAGE_OUTCOMES[number];
|
|
87
|
+
reason?: TurnUsageFailureReason;
|
|
88
|
+
}>;
|
|
89
|
+
export type TurnUsageEntry = Readonly<{
|
|
90
|
+
agent: string;
|
|
91
|
+
wake: string;
|
|
92
|
+
engine: typeof TURN_USAGE_ENGINES[number];
|
|
93
|
+
usage: TurnUsageMeasurement;
|
|
94
|
+
at?: string;
|
|
95
|
+
outcome?: TurnUsageOutcome;
|
|
96
|
+
/**
|
|
97
|
+
* Broker rows only. `turn` is the idempotency key readers dedupe on (the
|
|
98
|
+
* broker turn id, a sha256 hex); `limitReason` and `model` come from the
|
|
99
|
+
* closed broker vocabularies and are dropped rather than written through
|
|
100
|
+
* when they are not members.
|
|
101
|
+
*/
|
|
102
|
+
turn?: string;
|
|
103
|
+
limitReason?: EngineBrokerLimitReason;
|
|
104
|
+
model?: GrokBrokerModel;
|
|
105
|
+
/** Broker rows only: how many of the turn's requests were charged an estimate because their response carried no valid usage. */
|
|
106
|
+
estimatedRequests?: number;
|
|
107
|
+
}>;
|
|
108
|
+
/**
|
|
109
|
+
* Where a metered turn is appended.
|
|
110
|
+
*
|
|
111
|
+
* Production is {@link TURN_USAGE_LEDGER}`.filePath`, which Spawnfile
|
|
112
|
+
* provisions as a non-run-scoped volume. `DAIMON_TURN_USAGE_LEDGER_PATH`
|
|
113
|
+
* redirects it to an absolute path elsewhere; it exists so the wiring between a
|
|
114
|
+
* live engine session and this ledger can be exercised end to end, and so an
|
|
115
|
+
* operator can relocate the ledger without a rebuild. A relative or empty value
|
|
116
|
+
* is ignored rather than honoured, because a ledger written to a
|
|
117
|
+
* process-relative path is a ledger nobody can find again.
|
|
118
|
+
*/
|
|
119
|
+
export declare const TURN_USAGE_LEDGER_PATH_ENV: "DAIMON_TURN_USAGE_LEDGER_PATH";
|
|
120
|
+
export declare const resolveTurnUsageLedgerPath: (environment?: NodeJS.ProcessEnv) => string;
|
|
121
|
+
/** One complete line, newline-terminated. `JSON.stringify` escapes any embedded newline. */
|
|
122
|
+
export declare const renderTurnUsageLine: (entry: TurnUsageEntry) => string;
|
|
123
|
+
/**
|
|
124
|
+
* Collapse rows that share a `turn` key to the first one, keeping rows without
|
|
125
|
+
* a key untouched. Every reader that sums the ledger applies this, because a
|
|
126
|
+
* turn key exists precisely so a re-appended turn can never be counted twice.
|
|
127
|
+
*/
|
|
128
|
+
export declare const dedupeTurnUsageRows: <T extends Readonly<{
|
|
129
|
+
turn?: unknown;
|
|
130
|
+
}>>(rows: readonly T[]) => T[];
|
|
131
|
+
/**
|
|
132
|
+
* Advisory. Never rejects.
|
|
133
|
+
*
|
|
134
|
+
* The caller runs this inside the broker's turn `try` block, after the turn has
|
|
135
|
+
* already been recorded as *completed*. That block's `catch` calls
|
|
136
|
+
* `finish(..., failed)` unconditionally, and `finish` has no terminal-state
|
|
137
|
+
* guard — it renames over an existing record. An escaping append error would
|
|
138
|
+
* therefore rewrite an already-completed turn as failed. This guard is the only
|
|
139
|
+
* thing preventing that, so it is the one place where getting "advisory" wrong
|
|
140
|
+
* corrupts turn state instead of merely dropping a line.
|
|
141
|
+
*/
|
|
142
|
+
export declare const recordTurnUsage: (file: string, entry: TurnUsageEntry) => Promise<void>;
|
|
143
|
+
//# sourceMappingURL=turnUsageLedger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turnUsageLedger.d.ts","sourceRoot":"","sources":["../../src/runtime/turnUsageLedger.ts"],"names":[],"mappings":"AAIA,OAAO,EAA+B,KAAK,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC5G,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAElE;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,EAAG,+BAAwC,CAAC;AAElF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,iBAAiB;;;;;;;CAOpB,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,+BAA+B,MAAM,CAAC;AAEnD,oFAAoF;AACpF,eAAO,MAAM,uBAAuB,QAAmB,CAAC;AAExD,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,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;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,mCAAoC,CAAC;AAEpE;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB,kCAAmC,CAAC;AAEpE;;;;;;;;GAQG;AACH,eAAO,MAAM,0BAA0B,0HAQ7B,CAAC;AAEX,MAAM,MAAM,sBAAsB,GAAG,OAAO,0BAA0B,CAAC,MAAM,CAAC,CAAC;AAE/E,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,MAAM,EAAE,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,CAAC,EAAE,sBAAsB,CAAC;CACjC,CAAC,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC1C,KAAK,EAAE,oBAAoB,CAAC;IAC5B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,uBAAuB,CAAC;IACtC,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,gIAAgI;IAChI,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC,CAAC;AAEH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,0BAA0B,EAAG,+BAAwC,CAAC;AAEnF,eAAO,MAAM,0BAA0B,GAAI,cAAa,MAAM,CAAC,UAAwB,KAAG,MAGzF,CAAC;AAuBF,4FAA4F;AAC5F,eAAO,MAAM,mBAAmB,GAAI,OAAO,cAAc,KAAG,MAgBtD,CAAC;AASP;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,QAAQ,CAAC;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,EAAE,MAAM,SAAS,CAAC,EAAE,KAAG,CAAC,EAGjG,CAAC;AAuBF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,GAAU,MAAM,MAAM,EAAE,OAAO,cAAc,KAAG,OAAO,CAAC,IAAI,CAOvF,CAAC"}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { constants } from "node:fs";
|
|
2
|
+
import { open, rename, stat } from "node:fs/promises";
|
|
3
|
+
import { GROK_BROKER_MODELS } from "../contracts/grokWorkerContract.js";
|
|
4
|
+
import { ENGINE_BROKER_LIMIT_REASONS } from "./engineBrokerTurnAccounting.js";
|
|
5
|
+
/**
|
|
6
|
+
* Append-only per-turn token accounting for one container.
|
|
7
|
+
*
|
|
8
|
+
* The record carries no organization: there is one ledger per container and one
|
|
9
|
+
* organization per container, so identity comes from which container was
|
|
10
|
+
* queried. Nothing engine-controlled and non-numeric is ever persisted.
|
|
11
|
+
*/
|
|
12
|
+
export const TURN_USAGE_LEDGER_VERSION = "noopolis.daimon.turn-usage.v1";
|
|
13
|
+
/**
|
|
14
|
+
* Where the broker writes, and what Spawnfile provisions.
|
|
15
|
+
*
|
|
16
|
+
* Deliberately *not* folded into `RUNTIME_CONTRACT_MANIFEST`. That manifest's
|
|
17
|
+
* canonical bytes are digest-pinned by Spawnfile
|
|
18
|
+
* (`DAIMON_CONTRACT_MANIFEST_SHA256`) and attested against the runtime image
|
|
19
|
+
* selected at compile time, so any new key there makes every pinned image fail
|
|
20
|
+
* to attest and blocks all Daimon compiles until an image is rebuilt and
|
|
21
|
+
* re-pinned. Nothing about metering needs digest attestation: this is a path
|
|
22
|
+
* both sides agree on, mirrored in `spawnfile/src/runtime/daimon/`. Registering
|
|
23
|
+
* the schema in the manifest is bookkeeping that belongs with the next image
|
|
24
|
+
* rebuild.
|
|
25
|
+
*/
|
|
26
|
+
export const TURN_USAGE_LEDGER = {
|
|
27
|
+
version: TURN_USAGE_LEDGER_VERSION,
|
|
28
|
+
directoryPath: "/var/lib/spawnfile/daimon/usage",
|
|
29
|
+
filePath: "/var/lib/spawnfile/daimon/usage/usage.jsonl",
|
|
30
|
+
rotatedFilePath: "/var/lib/spawnfile/daimon/usage/usage.jsonl.1",
|
|
31
|
+
directoryMode: 0o750,
|
|
32
|
+
fileMode: 0o640
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* `agent` and `wake` are caller-supplied external text (`wake` is `event.id`
|
|
36
|
+
* from the wake request, schema-bounded to 4096 codepoints). They are truncated
|
|
37
|
+
* so one record cannot grow past a size where a single `write(2)` stops being
|
|
38
|
+
* atomic. JSON escaping already prevents line injection.
|
|
39
|
+
*/
|
|
40
|
+
export const TURN_USAGE_MAX_IDENTIFIER_CHARS = 128;
|
|
41
|
+
/** Rotate to a single `.1` sibling. ~2.5k lines/day observed, so this is months. */
|
|
42
|
+
export const TURN_USAGE_ROTATE_BYTES = 64 * 1024 * 1024;
|
|
43
|
+
/**
|
|
44
|
+
* Every engine whose headless stream reports its own token accounting.
|
|
45
|
+
*
|
|
46
|
+
* Codex, AGY, and Grok all publish decoded terminal-stream accounting here.
|
|
47
|
+
* Spawnfile's reader mirrors this list and is updated separately in packet
|
|
48
|
+
* A1b; until then, a reader that rejects `codex` will drop every Codex line.
|
|
49
|
+
*/
|
|
50
|
+
export const TURN_USAGE_ENGINES = ["agy", "codex", "grok"];
|
|
51
|
+
/**
|
|
52
|
+
* Whether the wake that spent these tokens went on to succeed.
|
|
53
|
+
*
|
|
54
|
+
* Money is spent by a failed wake exactly as by a successful one, so a row is
|
|
55
|
+
* written whenever the engine actually reported usage — see
|
|
56
|
+
* `../pi/cliSession.ts`. Without this field every failed wake's spend was
|
|
57
|
+
* simply absent from the ledger, and an organization's cost total silently
|
|
58
|
+
* undercounted by however much its failures burned.
|
|
59
|
+
*
|
|
60
|
+
* `reason` is a closed vocabulary, never an engine- or error-supplied string:
|
|
61
|
+
* the record's rule that nothing engine-controlled and non-numeric is
|
|
62
|
+
* persisted still holds, and `renderTurnUsageLine` degrades anything outside
|
|
63
|
+
* the list to `unknown` rather than writing it through.
|
|
64
|
+
*/
|
|
65
|
+
export const TURN_USAGE_OUTCOMES = ["completed", "failed"];
|
|
66
|
+
/**
|
|
67
|
+
* - `token_ceiling` — the turn's own reported usage crossed the per-wake ceiling.
|
|
68
|
+
* - `request_ceiling` — the broker refused a model request past the turn's request limit.
|
|
69
|
+
* - `wake_timeout` — the wall-clock bound fired before the child finished.
|
|
70
|
+
* - `output_limit` — the retained-output bound was exceeded.
|
|
71
|
+
* - `engine_exit` — the child exited non-zero (or died) after reporting usage.
|
|
72
|
+
* - `turn_rejected` — usage was reported but the decoded turn was not publishable.
|
|
73
|
+
* - `unknown` — any other failure (verification, cleanup, spawn).
|
|
74
|
+
*/
|
|
75
|
+
export const TURN_USAGE_FAILURE_REASONS = [
|
|
76
|
+
"token_ceiling",
|
|
77
|
+
"request_ceiling",
|
|
78
|
+
"wake_timeout",
|
|
79
|
+
"output_limit",
|
|
80
|
+
"engine_exit",
|
|
81
|
+
"turn_rejected",
|
|
82
|
+
"unknown"
|
|
83
|
+
];
|
|
84
|
+
/**
|
|
85
|
+
* Where a metered turn is appended.
|
|
86
|
+
*
|
|
87
|
+
* Production is {@link TURN_USAGE_LEDGER}`.filePath`, which Spawnfile
|
|
88
|
+
* provisions as a non-run-scoped volume. `DAIMON_TURN_USAGE_LEDGER_PATH`
|
|
89
|
+
* redirects it to an absolute path elsewhere; it exists so the wiring between a
|
|
90
|
+
* live engine session and this ledger can be exercised end to end, and so an
|
|
91
|
+
* operator can relocate the ledger without a rebuild. A relative or empty value
|
|
92
|
+
* is ignored rather than honoured, because a ledger written to a
|
|
93
|
+
* process-relative path is a ledger nobody can find again.
|
|
94
|
+
*/
|
|
95
|
+
export const TURN_USAGE_LEDGER_PATH_ENV = "DAIMON_TURN_USAGE_LEDGER_PATH";
|
|
96
|
+
export const resolveTurnUsageLedgerPath = (environment = process.env) => {
|
|
97
|
+
const override = environment[TURN_USAGE_LEDGER_PATH_ENV]?.trim();
|
|
98
|
+
return override !== undefined && override.startsWith("/") ? override : TURN_USAGE_LEDGER.filePath;
|
|
99
|
+
};
|
|
100
|
+
const bounded = (value) => [...value].slice(0, TURN_USAGE_MAX_IDENTIFIER_CHARS).join("");
|
|
101
|
+
/**
|
|
102
|
+
* `outcome`/`reason` are an additive field pair inside the *unchanged* `v1`
|
|
103
|
+
* record, deliberately not a `v2`.
|
|
104
|
+
*
|
|
105
|
+
* Spawnfile's reader (`spawnfile/src/runtime/usageLedger.ts`) rejects any `v`
|
|
106
|
+
* that is not `noopolis.daimon.turn-usage.v1` and returns `null` for the whole
|
|
107
|
+
* line, while picking only the fields it knows and ignoring the rest. Bumping
|
|
108
|
+
* the version would therefore make an unreleased Spawnfile drop *every* row —
|
|
109
|
+
* strictly worse than the defect being fixed. Reading the pair is opt-in;
|
|
110
|
+
* every historical row lacks it and, since a failed wake previously recorded
|
|
111
|
+
* nothing at all, absent can be read as `completed` without ambiguity.
|
|
112
|
+
*/
|
|
113
|
+
const outcomeFields = (outcome) => {
|
|
114
|
+
const status = outcome?.status === "failed" ? "failed" : "completed";
|
|
115
|
+
if (status === "completed")
|
|
116
|
+
return { outcome: status };
|
|
117
|
+
const reason = outcome?.reason;
|
|
118
|
+
return { outcome: status, reason: reason !== undefined && TURN_USAGE_FAILURE_REASONS.includes(reason) ? reason : "unknown" };
|
|
119
|
+
};
|
|
120
|
+
/** One complete line, newline-terminated. `JSON.stringify` escapes any embedded newline. */
|
|
121
|
+
export const renderTurnUsageLine = (entry) => `${JSON.stringify({
|
|
122
|
+
v: TURN_USAGE_LEDGER_VERSION,
|
|
123
|
+
agent: bounded(entry.agent),
|
|
124
|
+
wake: bounded(entry.wake),
|
|
125
|
+
engine: entry.engine,
|
|
126
|
+
at: entry.at ?? new Date().toISOString(),
|
|
127
|
+
input: entry.usage.input,
|
|
128
|
+
output: entry.usage.output,
|
|
129
|
+
cache_read: entry.usage.cacheRead,
|
|
130
|
+
cache_write: entry.usage.cacheWrite,
|
|
131
|
+
total: entry.usage.total,
|
|
132
|
+
calls: entry.usage.calls,
|
|
133
|
+
notional_usd: entry.usage.notionalUsd,
|
|
134
|
+
complete: entry.usage.complete,
|
|
135
|
+
...outcomeFields(entry.outcome),
|
|
136
|
+
...brokerFields(entry)
|
|
137
|
+
})}\n`;
|
|
138
|
+
const brokerFields = (entry) => ({
|
|
139
|
+
...(entry.turn !== undefined && /^[a-f0-9]{64}$/u.test(entry.turn) ? { turn: entry.turn } : {}),
|
|
140
|
+
...(entry.limitReason !== undefined && ENGINE_BROKER_LIMIT_REASONS.includes(entry.limitReason) ? { limit_reason: entry.limitReason } : {}),
|
|
141
|
+
...(entry.model !== undefined && GROK_BROKER_MODELS.includes(entry.model) ? { model: entry.model } : {}),
|
|
142
|
+
...(entry.estimatedRequests !== undefined && Number.isSafeInteger(entry.estimatedRequests) && entry.estimatedRequests > 0 ? { estimated_requests: entry.estimatedRequests } : {})
|
|
143
|
+
});
|
|
144
|
+
/**
|
|
145
|
+
* Collapse rows that share a `turn` key to the first one, keeping rows without
|
|
146
|
+
* a key untouched. Every reader that sums the ledger applies this, because a
|
|
147
|
+
* turn key exists precisely so a re-appended turn can never be counted twice.
|
|
148
|
+
*/
|
|
149
|
+
export const dedupeTurnUsageRows = (rows) => {
|
|
150
|
+
const seen = new Set();
|
|
151
|
+
return rows.filter((row) => { if (typeof row.turn !== "string")
|
|
152
|
+
return true; if (seen.has(row.turn))
|
|
153
|
+
return false; seen.add(row.turn); return true; });
|
|
154
|
+
};
|
|
155
|
+
const rotate = async (file) => {
|
|
156
|
+
let size;
|
|
157
|
+
try {
|
|
158
|
+
size = (await stat(file)).size;
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
if (size >= TURN_USAGE_ROTATE_BYTES)
|
|
164
|
+
await rename(file, `${file}.1`);
|
|
165
|
+
};
|
|
166
|
+
/**
|
|
167
|
+
* One `write(2)` per complete line. Turns for different agents run concurrently
|
|
168
|
+
* inside the single broker process, and `O_APPEND` makes a single sub-page write
|
|
169
|
+
* atomic against them. The directory is root-provisioned, so this never creates
|
|
170
|
+
* it: a missing directory is a provisioning failure, not something to paper over.
|
|
171
|
+
*/
|
|
172
|
+
const appendLine = async (file, line) => {
|
|
173
|
+
const bytes = Buffer.from(line, "utf8");
|
|
174
|
+
const handle = await open(file, constants.O_WRONLY | constants.O_APPEND | constants.O_CREAT | constants.O_NOFOLLOW, TURN_USAGE_LEDGER.fileMode);
|
|
175
|
+
try {
|
|
176
|
+
const { bytesWritten } = await handle.write(bytes, 0, bytes.length);
|
|
177
|
+
if (bytesWritten !== bytes.length)
|
|
178
|
+
throw new Error("turn usage ledger append was torn");
|
|
179
|
+
}
|
|
180
|
+
finally {
|
|
181
|
+
await handle.close();
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
/**
|
|
185
|
+
* Advisory. Never rejects.
|
|
186
|
+
*
|
|
187
|
+
* The caller runs this inside the broker's turn `try` block, after the turn has
|
|
188
|
+
* already been recorded as *completed*. That block's `catch` calls
|
|
189
|
+
* `finish(..., failed)` unconditionally, and `finish` has no terminal-state
|
|
190
|
+
* guard — it renames over an existing record. An escaping append error would
|
|
191
|
+
* therefore rewrite an already-completed turn as failed. This guard is the only
|
|
192
|
+
* thing preventing that, so it is the one place where getting "advisory" wrong
|
|
193
|
+
* corrupts turn state instead of merely dropping a line.
|
|
194
|
+
*/
|
|
195
|
+
export const recordTurnUsage = async (file, entry) => {
|
|
196
|
+
try {
|
|
197
|
+
await rotate(file);
|
|
198
|
+
await appendLine(file, renderTurnUsageLine(entry));
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
/* advisory: a failed append never fails a turn that published */
|
|
202
|
+
}
|
|
203
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type TransitionLock = Readonly<{
|
|
2
|
+
owner_id: string;
|
|
3
|
+
generation: string;
|
|
4
|
+
pid: number;
|
|
5
|
+
process_start: string;
|
|
6
|
+
boot_id: string;
|
|
7
|
+
pid_namespace_dev: number;
|
|
8
|
+
pid_namespace_ino: number;
|
|
9
|
+
}>;
|
|
10
|
+
export declare class WakeTransitionLockBlockedError extends Error {
|
|
11
|
+
readonly code: "offline_reconciliation_required";
|
|
12
|
+
constructor();
|
|
13
|
+
}
|
|
14
|
+
export declare function sameNamespace(left: Pick<TransitionLock, "pid_namespace_dev" | "pid_namespace_ino">, right: Pick<TransitionLock, "pid_namespace_dev" | "pid_namespace_ino">): boolean;
|
|
15
|
+
export declare function currentProcessIdentity(): Promise<Omit<TransitionLock, "owner_id" | "generation">>;
|
|
16
|
+
export declare function processIsAlive(lock: TransitionLock): Promise<boolean>;
|
|
17
|
+
//# sourceMappingURL=wakeAcceptanceProcessIdentity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wakeAcceptanceProcessIdentity.d.ts","sourceRoot":"","sources":["../../src/runtime/wakeAcceptanceProcessIdentity.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAC3L,qBAAa,8BAA+B,SAAQ,KAAK;IAAG,QAAQ,CAAC,IAAI,EAAG,iCAAiC,CAAU;;CAAmF;AAC1M,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,mBAAmB,GAAG,mBAAmB,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,mBAAmB,GAAG,mBAAmB,CAAC,GAAG,OAAO,CAAqH;AAC1S,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,UAAU,GAAG,YAAY,CAAC,CAAC,CAKvG;AACD,wBAAsB,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAO3E"}
|