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