@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,94 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { canonicalJson } from "../contracts/canonicalJson.js";
|
|
4
|
+
import { DAIMON_GROK_SYSTEM_PROMPT } from "../contracts/grokWorkerContract.js";
|
|
5
|
+
import { GROK_ENGINE_BROKER } from "../contracts/runtimeContractManifest.js";
|
|
6
|
+
import { grokSandboxProtectedPaths } from "./engineDispatcher.js";
|
|
7
|
+
import { parseEngineBrokerServiceConfig } from "./engineBrokerServiceConfig.js";
|
|
8
|
+
import { parseEngineBrokerTurnLimits } from "./engineBrokerTurnAccounting.js";
|
|
9
|
+
import { grokBrokerWorkerConfigSha256 } from "./grokBrokerWorkerConfig.js";
|
|
10
|
+
import { GROK_WORKER_SANDBOX_PROFILE, grokWorkerEventsPathFor, renderGrokWorkerSandboxProfile, grokWorkerSandboxProfileSha256 } from "./grokWorkerSandboxProfile.js";
|
|
11
|
+
import { parseOrganizationRuntimeConfig } from "./organizationRuntime.js";
|
|
12
|
+
export const GROK_BROKER_PROJECTION_VERSION = GROK_ENGINE_BROKER.projectionVersion;
|
|
13
|
+
/**
|
|
14
|
+
* Resolve the public Grok broker projection for one agent.
|
|
15
|
+
*
|
|
16
|
+
* Paths are taken as given, never resolved: the caller (Spawnfile provisioning)
|
|
17
|
+
* must supply canonical, non-symlink paths — the fixed tmpfs/workspace roots it
|
|
18
|
+
* creates — and its provisioning must verify they are not symlinks before a
|
|
19
|
+
* slot is used; the broker's own attestation re-checks the worker home at
|
|
20
|
+
* every turn.
|
|
21
|
+
*
|
|
22
|
+
* Deterministic and I/O-free on purpose: its digest
|
|
23
|
+
* ({@link grokBrokerProjectionSha256}) is what the slot preflight receipt
|
|
24
|
+
* binds, so the supervisor that writes the receipt and the evaluator that reads
|
|
25
|
+
* it must compute byte-equal projections from the same inputs.
|
|
26
|
+
*
|
|
27
|
+
* The agent must be a Grok agent that *declares* its model and reasoning
|
|
28
|
+
* effort; nothing is defaulted. The deny list is Daimon's own protected set for
|
|
29
|
+
* this agent (realm, bootstrap, peers, and the mask covering the acceptance
|
|
30
|
+
* store) plus the caller's evaluator paths, sorted and deduplicated exactly as
|
|
31
|
+
* the profile renderer does. A supplied `profileSha256` that differs is
|
|
32
|
+
* refused.
|
|
33
|
+
*/
|
|
34
|
+
export function resolveOrganizationGrokBrokerProjection(config, agentId, options) {
|
|
35
|
+
const parsed = parseOrganizationRuntimeConfig(config);
|
|
36
|
+
const agent = parsed.agents.find((entry) => entry.id === agentId);
|
|
37
|
+
if (agent === undefined || agent.engine.kind !== "grok")
|
|
38
|
+
throw new Error("Grok broker projection requires a known Grok agent");
|
|
39
|
+
if (agent.engine.model === undefined || agent.engine.reasoningEffort === undefined)
|
|
40
|
+
throw new Error("Grok broker projection requires a declared model and reasoning effort");
|
|
41
|
+
for (const [label, value] of [["workerHomePath", options.workerHomePath], ["acceptanceStorePath", options.acceptanceStorePath]]) {
|
|
42
|
+
if (!path.posix.isAbsolute(value) || path.posix.normalize(value) !== value || value === "/" || value.endsWith("/"))
|
|
43
|
+
throw new Error(`Grok broker projection requires a canonical absolute ${label}`);
|
|
44
|
+
}
|
|
45
|
+
if (!/^[a-f0-9]{64}$/u.test(options.seccompProfileSha256))
|
|
46
|
+
throw new Error("Grok broker projection requires a seccomp profile sha256");
|
|
47
|
+
const model = agent.engine.model, reasoningEffort = agent.engine.reasoningEffort;
|
|
48
|
+
const denyPaths = [...new Set([...grokSandboxProtectedPaths(agent.id, parsed.agents, [options.acceptanceStorePath]), ...(options.denyPaths ?? [])])].sort();
|
|
49
|
+
renderGrokWorkerSandboxProfile(denyPaths);
|
|
50
|
+
const profileSha256 = grokWorkerSandboxProfileSha256(denyPaths);
|
|
51
|
+
if (options.profileSha256 !== undefined && options.profileSha256 !== profileSha256)
|
|
52
|
+
throw new Error("Grok broker projection profile digest mismatch");
|
|
53
|
+
const workerConfigSha256 = grokBrokerWorkerConfigSha256({ model, reasoningEffort });
|
|
54
|
+
if (workerConfigSha256 !== GROK_ENGINE_BROKER.worker.configSha256[model][reasoningEffort])
|
|
55
|
+
throw new Error("Grok broker projection worker config drifted from the manifest");
|
|
56
|
+
if (createHash("sha256").update(DAIMON_GROK_SYSTEM_PROMPT).digest("hex") !== GROK_ENGINE_BROKER.worker.systemPromptSha256)
|
|
57
|
+
throw new Error("Grok broker projection system prompt drifted from the manifest");
|
|
58
|
+
const artifact = GROK_ENGINE_BROKER.grokCliArtifacts[options.architecture];
|
|
59
|
+
if (artifact === undefined)
|
|
60
|
+
throw new Error("Grok broker projection requires a pinned architecture");
|
|
61
|
+
const profilePath = path.posix.join(options.workerHomePath, ".grok", "sandbox.toml");
|
|
62
|
+
const projection = {
|
|
63
|
+
version: GROK_BROKER_PROJECTION_VERSION, agentId, workspacePath: agent.workspacePath, runtimeHomePath: agent.runtimeHomePath,
|
|
64
|
+
workerUid: options.workerUid, slot: options.slot, profilePath, profileSha256, denyPaths, workerConfigSha256,
|
|
65
|
+
systemPromptSha256: GROK_ENGINE_BROKER.worker.systemPromptSha256, grokCliVersion: GROK_ENGINE_BROKER.grokCliVersion, grokExecutableSha256: artifact.sha256,
|
|
66
|
+
nativeAbiVersion: GROK_ENGINE_BROKER.nativeAbiVersion, model, reasoningEffort, limits: parseEngineBrokerTurnLimits(options.limits), usageLedgerPath: options.usageLedgerPath, seccompProfileSha256: options.seccompProfileSha256,
|
|
67
|
+
attestation: { platform: "linux/landlock", enforced: true, restrictNetwork: true, profileName: GROK_WORKER_SANDBOX_PROFILE, sandboxRuntime: "bubblewrap", eventsPath: grokWorkerEventsPathFor(profilePath) }
|
|
68
|
+
};
|
|
69
|
+
// The registration this projection implies must itself be a valid v2 service.json entry.
|
|
70
|
+
grokBrokerServiceRegistrationFor(projection);
|
|
71
|
+
return projection;
|
|
72
|
+
}
|
|
73
|
+
/** sha256 over the projection's canonical JSON; what a slot preflight receipt binds. */
|
|
74
|
+
export const grokBrokerProjectionSha256 = (projection) => createHash("sha256").update(canonicalJson(projection)).digest("hex");
|
|
75
|
+
/** The `service.json` v2 registration a deployment provisions for this projection, validated by the broker's own parser. */
|
|
76
|
+
export function grokBrokerServiceRegistrationFor(projection) {
|
|
77
|
+
const registration = {
|
|
78
|
+
agentId: projection.agentId, slot: projection.slot, workerUid: projection.workerUid, workspace: projection.workspacePath,
|
|
79
|
+
profilePath: projection.profilePath, eventsPath: projection.attestation.eventsPath, profileSha256: projection.profileSha256,
|
|
80
|
+
usageLedgerPath: projection.usageLedgerPath, limits: projection.limits, model: { id: projection.model, reasoningEffort: projection.reasoningEffort }
|
|
81
|
+
};
|
|
82
|
+
parseEngineBrokerServiceConfig({ version: "noopolis.daimon.engine-broker-service.v2", credentialHome: GROK_ENGINE_BROKER.credentialHomePath, turnStore: GROK_ENGINE_BROKER.turnStorePath, registrations: [registration] });
|
|
83
|
+
return registration;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Refuses a provisioned registration that does not describe this projection:
|
|
87
|
+
* any differing member — a weaker profile digest, another model, raised
|
|
88
|
+
* limits, a different ledger — is a mismatch, never a merge.
|
|
89
|
+
*/
|
|
90
|
+
export function verifyGrokBrokerRegistrationMatchesProjection(registration, projection) {
|
|
91
|
+
const expected = parseEngineBrokerServiceConfig({ version: "noopolis.daimon.engine-broker-service.v2", credentialHome: GROK_ENGINE_BROKER.credentialHomePath, turnStore: GROK_ENGINE_BROKER.turnStorePath, registrations: [grokBrokerServiceRegistrationFor(projection)] }).registrations[0];
|
|
92
|
+
if (canonicalJson(expected) !== canonicalJson(registration))
|
|
93
|
+
throw new Error("Grok broker registration does not match its projection");
|
|
94
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { EngineBrokerCapabilities } from "./engineBrokerCapabilities.js";
|
|
2
|
+
import { type GrokBrokerModelPolicy } from "./grokBrokerModelPolicy.js";
|
|
3
|
+
import { authorizeGrokBrokerProxyRequest } from "./grokBrokerProxyRequest.js";
|
|
4
|
+
import { type GrokBrokerTurnMeter } from "./grokBrokerTurnMeter.js";
|
|
5
|
+
import type { GrokInferenceGrants } from "./grokInferenceGrants.js";
|
|
6
|
+
/** One running turn as the proxy sees it: its declared model/effort and its spend gate. */
|
|
7
|
+
export type GrokBrokerProxyTurn = Readonly<{
|
|
8
|
+
policy: GrokBrokerModelPolicy;
|
|
9
|
+
meter: GrokBrokerTurnMeter;
|
|
10
|
+
}>;
|
|
11
|
+
export type GrokBrokerCredentialAuthority = Readonly<{
|
|
12
|
+
accessToken(forceRefresh: boolean): Promise<string>;
|
|
13
|
+
refreshAfterRejection?(rejectedTokenDigest: string): Promise<string>;
|
|
14
|
+
markRejected(rejectedTokenDigest?: string): Promise<void>;
|
|
15
|
+
isStale?(): boolean;
|
|
16
|
+
}>;
|
|
17
|
+
export type GrokBrokerUpstream = (request: ReturnType<typeof authorizeGrokBrokerProxyRequest>, signal?: AbortSignal) => Promise<Readonly<{
|
|
18
|
+
status: number;
|
|
19
|
+
headers: Readonly<Record<string, string>>;
|
|
20
|
+
body: Uint8Array;
|
|
21
|
+
}>>;
|
|
22
|
+
/**
|
|
23
|
+
* `policy` is the fallback declared model/effort (closed list); a registered
|
|
24
|
+
* turn's own policy wins. A request whose turn has no registered meter is
|
|
25
|
+
* refused like one without an isolation guard: nothing is forwarded unmetered.
|
|
26
|
+
* `listenPort` exists for tests that must not contend for the production port.
|
|
27
|
+
*
|
|
28
|
+
* `grants` are evaluator inference grants (`grokInferenceGrants.ts`): a bearer
|
|
29
|
+
* carrying the grant prefix is looked up only there and served by
|
|
30
|
+
* `grokInferenceProxy.ts`; every other bearer is looked up only among turn
|
|
31
|
+
* capabilities. Without `grants` a prefixed bearer is simply refused.
|
|
32
|
+
*/
|
|
33
|
+
export declare function startGrokBrokerProxy(authority: GrokBrokerCredentialAuthority, upstream?: GrokBrokerUpstream, policy?: GrokBrokerModelPolicy, listenPort?: number, grants?: GrokInferenceGrants): Promise<Readonly<{
|
|
34
|
+
port: number;
|
|
35
|
+
capabilities: EngineBrokerCapabilities;
|
|
36
|
+
registerIsolationGuard(turnId: string, guard: () => Promise<void>): void;
|
|
37
|
+
revokeIsolationGuard(turnId: string): void;
|
|
38
|
+
registerTurn(turnId: string, turn: GrokBrokerProxyTurn): void;
|
|
39
|
+
revokeTurn(turnId: string): void;
|
|
40
|
+
close(): Promise<void>;
|
|
41
|
+
}>>;
|
|
42
|
+
/**
|
|
43
|
+
* A refusal the caller must not retry.
|
|
44
|
+
*
|
|
45
|
+
* Every internal refusal used to collapse into one bare 503. Grok treats 503 as
|
|
46
|
+
* transient and blind-retries the same request (observed: 14 retries, ~141k
|
|
47
|
+
* estimated tokens, then `exit 1`), so a policy miss burned a turn's budget and
|
|
48
|
+
* reported itself as an engine crash. Policy refusals now answer 400 with a
|
|
49
|
+
* reason, and only genuinely transient faults keep 503.
|
|
50
|
+
*/
|
|
51
|
+
export declare class GrokBrokerProxyRefusal extends Error {
|
|
52
|
+
readonly reason: string;
|
|
53
|
+
constructor(reason: string);
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=grokBrokerProxy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grokBrokerProxy.d.ts","sourceRoot":"","sources":["../../src/runtime/grokBrokerProxy.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAEzE,OAAO,EAAgE,KAAK,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACtI,OAAO,EAAE,+BAA+B,EAAE,MAAM,6BAA6B,CAAC;AAE9E,OAAO,EAAsD,KAAK,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAGxH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAEpE,2FAA2F;AAC3F,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IAAE,MAAM,EAAE,qBAAqB,CAAC;IAAC,KAAK,EAAE,mBAAmB,CAAA;CAAE,CAAC,CAAC;AAE1G,MAAM,MAAM,6BAA6B,GAAG,QAAQ,CAAC;IAAE,WAAW,CAAC,YAAY,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAAC,qBAAqB,CAAC,CAAC,mBAAmB,EAAC,MAAM,GAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAAC,YAAY,CAAC,mBAAmB,CAAC,EAAC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,OAAO,CAAC,IAAI,OAAO,CAAA;CAAE,CAAC,CAAC;AACjQ,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,+BAA+B,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC,CAAC,CAAC;AAE3N;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,CAAC,SAAS,EAAE,6BAA6B,EAAE,QAAQ,GAAE,kBAAoC,EAAE,MAAM,GAAE,qBAAwD,EAAE,UAAU,SAAS,EAAE,MAAM,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,wBAAwB,CAAC;IAAC,sBAAsB,CAAC,MAAM,EAAC,MAAM,EAAC,KAAK,EAAC,MAAI,OAAO,CAAC,IAAI,CAAC,GAAE,IAAI,CAAC;IAAC,oBAAoB,CAAC,MAAM,EAAC,MAAM,GAAE,IAAI,CAAC;IAAC,YAAY,CAAC,MAAM,EAAC,MAAM,EAAC,IAAI,EAAC,mBAAmB,GAAE,IAAI,CAAC;IAAC,UAAU,CAAC,MAAM,EAAC,MAAM,GAAE,IAAI,CAAC;IAAC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CAAC,CAMtiB;AAED;;;;;;;;GAQG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM;gBAAd,MAAM,EAAE,MAAM;CACpC"}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { createServer } from "node:http";
|
|
3
|
+
import { redactCredentialText } from "../core/credentialRedaction.js";
|
|
4
|
+
import { CLI_ENGINE_MAX_DIAGNOSTIC_BYTES } from "../pi/cliChildOutput.js";
|
|
5
|
+
import { EngineBrokerCapabilities } from "./engineBrokerCapabilities.js";
|
|
6
|
+
import { ENGINE_BROKER_AUTH_STALE } from "./engineBrokerProtocol.js";
|
|
7
|
+
import { DEFAULT_GROK_BROKER_MODEL_POLICY, parseGrokBrokerModelPolicy } from "./grokBrokerModelPolicy.js";
|
|
8
|
+
import { authorizeGrokBrokerProxyRequest } from "./grokBrokerProxyRequest.js";
|
|
9
|
+
import { GROK_SESSION_TITLE_SINK_KEY } from "./grokBrokerWorkerConfig.js";
|
|
10
|
+
import { parseGrokResponseToolNames, parseGrokUpstreamUsage } from "./grokBrokerTurnMeter.js";
|
|
11
|
+
import { GROK_ENGINE_BROKER } from "../contracts/runtimeContractManifest.js";
|
|
12
|
+
import { serveGrokInferenceGrant } from "./grokInferenceProxy.js";
|
|
13
|
+
/**
|
|
14
|
+
* `policy` is the fallback declared model/effort (closed list); a registered
|
|
15
|
+
* turn's own policy wins. A request whose turn has no registered meter is
|
|
16
|
+
* refused like one without an isolation guard: nothing is forwarded unmetered.
|
|
17
|
+
* `listenPort` exists for tests that must not contend for the production port.
|
|
18
|
+
*
|
|
19
|
+
* `grants` are evaluator inference grants (`grokInferenceGrants.ts`): a bearer
|
|
20
|
+
* carrying the grant prefix is looked up only there and served by
|
|
21
|
+
* `grokInferenceProxy.ts`; every other bearer is looked up only among turn
|
|
22
|
+
* capabilities. Without `grants` a prefixed bearer is simply refused.
|
|
23
|
+
*/
|
|
24
|
+
export async function startGrokBrokerProxy(authority, upstream = defaultUpstream, policy = DEFAULT_GROK_BROKER_MODEL_POLICY, listenPort = 43_123, grants) {
|
|
25
|
+
const declared = parseGrokBrokerModelPolicy(policy);
|
|
26
|
+
const capabilities = new EngineBrokerCapabilities();
|
|
27
|
+
const guards = new Map();
|
|
28
|
+
const turns = new Map();
|
|
29
|
+
const server = createServer((request, response) => { void serve(request, response, authority, upstream, capabilities, guards, turns, declared, grants); });
|
|
30
|
+
await new Promise((resolve, reject) => { server.once("error", reject); server.listen(listenPort, "127.0.0.1", () => { server.off("error", reject); resolve(); }); });
|
|
31
|
+
const address = server.address();
|
|
32
|
+
return { port: address.port, capabilities, registerIsolationGuard(turnId, guard) { guards.set(turnId, guard); }, revokeIsolationGuard(turnId) { guards.delete(turnId); }, registerTurn(turnId, turn) { turns.set(turnId, { policy: parseGrokBrokerModelPolicy(turn.policy), meter: turn.meter }); }, revokeTurn(turnId) { turns.delete(turnId); }, close: () => new Promise((resolve, reject) => { server.close((error) => error === undefined ? resolve() : reject(error)); /* `close` waits for every open connection, and a worker keeps its client pool's socket to this proxy open with nothing here accounting for it — so that wait has no bound. Ending them is this listener's to do, exactly as the MCP facade does. */ /* `close` waits for every open connection, and a worker keeps its client pool's socket to this proxy open with nothing here accounting for it — so that wait has no bound. Ending them is this listener's to do, exactly as the MCP facade does. */ server.closeAllConnections(); }) };
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A refusal the caller must not retry.
|
|
36
|
+
*
|
|
37
|
+
* Every internal refusal used to collapse into one bare 503. Grok treats 503 as
|
|
38
|
+
* transient and blind-retries the same request (observed: 14 retries, ~141k
|
|
39
|
+
* estimated tokens, then `exit 1`), so a policy miss burned a turn's budget and
|
|
40
|
+
* reported itself as an engine crash. Policy refusals now answer 400 with a
|
|
41
|
+
* reason, and only genuinely transient faults keep 503.
|
|
42
|
+
*/
|
|
43
|
+
export class GrokBrokerProxyRefusal extends Error {
|
|
44
|
+
reason;
|
|
45
|
+
constructor(reason) {
|
|
46
|
+
super(`grok broker proxy refused: ${reason}`);
|
|
47
|
+
this.reason = reason;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
async function serve(request, response, authority, upstream, capabilities, guards, turns, fallback, grants) {
|
|
51
|
+
let settle;
|
|
52
|
+
let titleSink = false;
|
|
53
|
+
// Every credential this request holds, kept only for this request and only so
|
|
54
|
+
// that a fault's own words can be redacted against them exactly as the CLI
|
|
55
|
+
// child and launcher diagnostics are. Nothing reads them but {@link brokerFaultCause}.
|
|
56
|
+
const secrets = [];
|
|
57
|
+
try {
|
|
58
|
+
const body = await readBody(request);
|
|
59
|
+
const headers = Object.fromEntries(Object.entries(request.headers).map(([key, value]) => [key, Array.isArray(value) ? value[0] : value]));
|
|
60
|
+
titleSink = headers.authorization === `Bearer ${GROK_SESSION_TITLE_SINK_KEY}`;
|
|
61
|
+
const match = headers.authorization?.match(/^Bearer ([A-Za-z0-9_-]{40,})$/u);
|
|
62
|
+
if (match)
|
|
63
|
+
secrets.push(match[1]);
|
|
64
|
+
if (match && match[1].startsWith(GROK_ENGINE_BROKER.inferenceGrants.tokenPrefix)) {
|
|
65
|
+
if (!grants)
|
|
66
|
+
throw new GrokBrokerProxyRefusal("inference_grants_unavailable");
|
|
67
|
+
return await serveGrokInferenceGrant({ method: request.method ?? "", pathname: new URL(request.url ?? "/", "http://127.0.0.1").pathname, headers, body, token: match[1] }, response, grants, authority, upstream);
|
|
68
|
+
}
|
|
69
|
+
const scope = match ? capabilities.inspectToken(match[1]) : undefined;
|
|
70
|
+
if (!scope)
|
|
71
|
+
throw new GrokBrokerProxyRefusal("unknown_capability");
|
|
72
|
+
const guard = guards.get(scope.turnId), turn = turns.get(scope.turnId);
|
|
73
|
+
if (!guard || !turn)
|
|
74
|
+
throw new GrokBrokerProxyRefusal("no_active_turn");
|
|
75
|
+
try {
|
|
76
|
+
await guard();
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
throw new GrokBrokerProxyRefusal("worker_isolation_unverified");
|
|
80
|
+
}
|
|
81
|
+
// A fenced realm is not a transient fault: the credential is gone until an
|
|
82
|
+
// operator re-logs in, and 503 made Grok blind-retry it (observed: fifteen
|
|
83
|
+
// retries over five minutes, $0 spent, nothing learned). Named, 400, and
|
|
84
|
+
// checked before the credential read, so the miss costs one round trip.
|
|
85
|
+
if (authority.isStale?.() === true)
|
|
86
|
+
throw new GrokBrokerProxyRefusal(ENGINE_BROKER_AUTH_STALE);
|
|
87
|
+
let token = await authority.accessToken(false);
|
|
88
|
+
secrets.push(token);
|
|
89
|
+
const rejectedDigest = createHash("sha256").update(token).digest("hex");
|
|
90
|
+
let prepared = authorizeRequestOrRefuse({ method: request.method ?? "", pathname: new URL(request.url ?? "/", "http://127.0.0.1").pathname, headers, body }, capabilities, token, turn.policy ?? fallback);
|
|
91
|
+
token = "";
|
|
92
|
+
// The spend gate runs after the body is proven a real lean worker request
|
|
93
|
+
// (a refused session-title body never counts) and before any upstream call.
|
|
94
|
+
const admission = turn.meter.admit();
|
|
95
|
+
if ("refused" in admission) {
|
|
96
|
+
response.writeHead(429, { "content-type": "application/json", "cache-control": "no-store" });
|
|
97
|
+
response.end(JSON.stringify({ error: "turn limit reached", limit: admission.refused }));
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if ("busy" in admission) {
|
|
101
|
+
response.writeHead(429, { "content-type": "application/json", "cache-control": "no-store" });
|
|
102
|
+
response.end('{"error":"turn request in flight"}');
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
settle = (usage, toolCalls) => { turn.meter.settle(admission.index, usage, body.byteLength, toolCalls); settle = undefined; };
|
|
106
|
+
let result = await upstream(prepared, admission.signal);
|
|
107
|
+
if (result.status === 401) {
|
|
108
|
+
token = authority.refreshAfterRejection ? await authority.refreshAfterRejection(rejectedDigest) : await authority.accessToken(true);
|
|
109
|
+
secrets.push(token);
|
|
110
|
+
const refreshedDigest = createHash("sha256").update(token).digest("hex");
|
|
111
|
+
prepared = { ...prepared, headers: { ...prepared.headers, authorization: `Bearer ${token}` } };
|
|
112
|
+
token = "";
|
|
113
|
+
result = await upstream(prepared, admission.signal);
|
|
114
|
+
if (result.status === 401)
|
|
115
|
+
await authority.markRejected(refreshedDigest);
|
|
116
|
+
}
|
|
117
|
+
// Names only, bounded, and never a reason to fail the request: the response
|
|
118
|
+
// is already buffered here for its usage block, so what the model tried to
|
|
119
|
+
// call is in hand. A decoder fault records no attempt rather than a false
|
|
120
|
+
// empty one, and never disturbs the turn.
|
|
121
|
+
settle?.(usageOrEstimate(result.body, result.headers["content-type"]), toolCallsOrNothing(result.body, result.headers["content-type"]));
|
|
122
|
+
response.writeHead(result.status, { "content-type": result.headers["content-type"] ?? "application/json", "cache-control": "no-store" });
|
|
123
|
+
response.end(result.body);
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
settle?.(undefined);
|
|
127
|
+
// Name the refusal on the broker's own stderr (reason code only, never a body
|
|
128
|
+
// or a token) so a failing turn is diagnosable without a stub harness —
|
|
129
|
+
// except for the two requests every healthy turn makes anyway.
|
|
130
|
+
// The request that *discovers* the fence throws an ordinary error from the
|
|
131
|
+
// credential authority, so it is promoted to the same named refusal: one
|
|
132
|
+
// stale realm must not read as one transient fault plus fourteen retries.
|
|
133
|
+
const fenced = !(error instanceof GrokBrokerProxyRefusal) && authority.isStale?.() === true;
|
|
134
|
+
const refused = error instanceof GrokBrokerProxyRefusal || fenced;
|
|
135
|
+
const refusal = error instanceof GrokBrokerProxyRefusal ? error.reason : fenced ? ENGINE_BROKER_AUTH_STALE : "broker_unavailable";
|
|
136
|
+
// A named refusal is its own account; anything else used to reach the log as
|
|
137
|
+
// the bare word `broker_unavailable`, which names nothing — so it carries the
|
|
138
|
+
// fault's own class and message, and nothing else, beside it.
|
|
139
|
+
const named = refused ? refusal : `${refusal} (${brokerFaultCause(error, secrets)})`;
|
|
140
|
+
if (!titleSink && !expectedWorkerProbe(request))
|
|
141
|
+
process.stderr.write(`[grok-proxy] refused: ${named}\n`);
|
|
142
|
+
// Grok's own session-title call is refused by design, and keeps the transient
|
|
143
|
+
// 503 shape it has always had. Forcing 400 and 503 on it were both observed
|
|
144
|
+
// to end the turn `exit=0, result: success`, so the shape is kept because it
|
|
145
|
+
// is the one every live capture was taken with, not because a 4xx there ends
|
|
146
|
+
// Grok's session — it does not.
|
|
147
|
+
if (titleSink) {
|
|
148
|
+
response.writeHead(503, { "content-type": "application/json", "cache-control": "no-store" });
|
|
149
|
+
response.end('{"error":"broker unavailable"}');
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (refused) {
|
|
153
|
+
response.writeHead(400, { "content-type": "application/json", "cache-control": "no-store" });
|
|
154
|
+
response.end(JSON.stringify({ error: "broker refused this request", reason: refusal }));
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
response.writeHead(503, { "content-type": "application/json", "cache-control": "no-store" });
|
|
158
|
+
response.end('{"error":"broker unavailable"}');
|
|
159
|
+
}
|
|
160
|
+
finally {
|
|
161
|
+
secrets.length = 0;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* A non-refusal fault, named on one bounded line.
|
|
166
|
+
*
|
|
167
|
+
* `broker_unavailable` on its own carries no diagnostic content at all, and it
|
|
168
|
+
* is answered 503, which Grok blind-retries: one live turn emitted it fifteen
|
|
169
|
+
* times over five minutes, spent $0 — so no upstream call ever succeeded — and
|
|
170
|
+
* died with no account of why. The error's own class and message are the whole
|
|
171
|
+
* of what is logged: never a request body, bearer, capability, session id or
|
|
172
|
+
* header. It is redacted exactly as the failed CLI child and the launcher's
|
|
173
|
+
* worker diagnostic are — `redactCredentialText` with this request's own
|
|
174
|
+
* capabilities as exact secrets and the same `CLI_ENGINE_MAX_DIAGNOSTIC_BYTES`
|
|
175
|
+
* bound — and flattened to one line, because it travels on a log line. Naming
|
|
176
|
+
* a fault must never be able to fail the response that reports it, so a value
|
|
177
|
+
* that cannot even be described degrades to a marker.
|
|
178
|
+
*
|
|
179
|
+
* One level of `cause` is named too, because the fault this exists for names
|
|
180
|
+
* nothing without it: every failed `fetch` to the provider is `TypeError:
|
|
181
|
+
* fetch failed`, and which fault it was — `ENOTFOUND`, `ECONNREFUSED`, a TLS
|
|
182
|
+
* refusal, an abort — is only in the cause. An errno error whose message is
|
|
183
|
+
* empty is named by its `code`.
|
|
184
|
+
*/
|
|
185
|
+
const brokerFaultCause = (error, secrets) => {
|
|
186
|
+
try {
|
|
187
|
+
const described = `${describeFault(error)}${error instanceof Error && error.cause !== undefined && error.cause !== null ? ` <- ${describeFault(error.cause)}` : ""}`;
|
|
188
|
+
const flattened = described.replace(/[\u0000-\u001f\u007f]+/gu, " ").replace(/\s+/gu, " ").trim();
|
|
189
|
+
const named = redactCredentialText(flattened, secrets, CLI_ENGINE_MAX_DIAGNOSTIC_BYTES).trim();
|
|
190
|
+
return named.length === 0 ? "unnamed" : named;
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
return "unnameable";
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
/** One value's class and words: an error's own, or the type of whatever else was thrown. */
|
|
197
|
+
const describeFault = (error) => {
|
|
198
|
+
if (!(error instanceof Error))
|
|
199
|
+
return `${typeof error}: ${String(error)}`;
|
|
200
|
+
const code = error.code;
|
|
201
|
+
const words = error.message.length > 0 ? error.message : typeof code === "string" ? code : "(no message)";
|
|
202
|
+
return `${error.constructor?.name ?? error.name}: ${words}`;
|
|
203
|
+
};
|
|
204
|
+
/**
|
|
205
|
+
* The unauthenticated connectivity probe Grok sends before its own requests: a
|
|
206
|
+
* bare `GET /` with no Authorization header, which has no capability to look up
|
|
207
|
+
* and answers 400.
|
|
208
|
+
*
|
|
209
|
+
* It and the per-turn `session_title` POST are the only two requests a healthy
|
|
210
|
+
* turn makes that this proxy does not forward, and both used to print the same
|
|
211
|
+
* `refused: unknown_capability` line as a real policy miss — so every healthy
|
|
212
|
+
* turn read as two refusals and cost a live investigation. They answer exactly
|
|
213
|
+
* as before; they simply stop claiming a refusal on the broker's stderr, which
|
|
214
|
+
* is left for the misses that are actually worth reading.
|
|
215
|
+
*/
|
|
216
|
+
const expectedWorkerProbe = (request) => request.headers.authorization === undefined && (request.method ?? "") === "GET" &&
|
|
217
|
+
new URL(request.url ?? "/", "http://127.0.0.1").pathname === "/";
|
|
218
|
+
/**
|
|
219
|
+
* Upstream-reported usage, or the documented conservative estimate.
|
|
220
|
+
*
|
|
221
|
+
* The decoder faulting must not fail the request that already cost real
|
|
222
|
+
* money: the upstream call succeeded, the worker is owed its answer, and a
|
|
223
|
+
* 503 here would throw away a paid response and have Grok buy it again. The
|
|
224
|
+
* `undefined` this returns is not "no usage" — `GrokBrokerTurnMeter.settle`
|
|
225
|
+
* charges it `ceil(bodyBytes/2) + 4096` and marks the row
|
|
226
|
+
* `usage_source: "estimated"`, so the token ceiling still counts it and no
|
|
227
|
+
* fabricated zero ever reaches a ledger.
|
|
228
|
+
*/
|
|
229
|
+
const usageOrEstimate = (body, contentType) => {
|
|
230
|
+
try {
|
|
231
|
+
return parseGrokUpstreamUsage(body, contentType);
|
|
232
|
+
}
|
|
233
|
+
catch {
|
|
234
|
+
return undefined;
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
/** Instrumentation must never fail a turn: a throwing decoder records nothing, exactly as an undecodable response does. */
|
|
238
|
+
const toolCallsOrNothing = (body, contentType) => {
|
|
239
|
+
try {
|
|
240
|
+
return parseGrokResponseToolNames(body, contentType);
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
return undefined;
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
/** The body gate, refused non-retryably: a rejected body is a policy miss, never a transient fault. */
|
|
247
|
+
function authorizeRequestOrRefuse(...args) {
|
|
248
|
+
try {
|
|
249
|
+
return authorizeGrokBrokerProxyRequest(...args);
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
throw new GrokBrokerProxyRefusal("request_body_rejected");
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
async function readBody(request) { const chunks = []; let bytes = 0; for await (const chunk of request) {
|
|
256
|
+
const value = Buffer.from(chunk);
|
|
257
|
+
bytes += value.length;
|
|
258
|
+
if (bytes > 2 * 1024 * 1024)
|
|
259
|
+
throw new Error("too large");
|
|
260
|
+
chunks.push(value);
|
|
261
|
+
} return Buffer.concat(chunks); }
|
|
262
|
+
const defaultUpstream = async (request, signal) => { const result = await fetch(request.url, { method: "POST", headers: request.headers, body: Buffer.from(request.body), ...(signal === undefined ? {} : { signal }) }); return { status: result.status, headers: { "content-type": result.headers.get("content-type") ?? "application/json" }, body: new Uint8Array(await result.arrayBuffer()) }; };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { EngineBrokerCapabilities } from "./engineBrokerCapabilities.js";
|
|
2
|
+
import { type GrokBrokerModelPolicy } from "./grokBrokerModelPolicy.js";
|
|
3
|
+
export type GrokBrokerProxyInput = Readonly<{
|
|
4
|
+
method: string;
|
|
5
|
+
pathname: string;
|
|
6
|
+
headers: Readonly<Record<string, string | undefined>>;
|
|
7
|
+
body: Uint8Array;
|
|
8
|
+
agentId?: string;
|
|
9
|
+
turnId?: string;
|
|
10
|
+
}>;
|
|
11
|
+
export type GrokBrokerUpstreamRequest = Readonly<{
|
|
12
|
+
url: "https://cli-chat-proxy.grok.com/v1/chat/completions";
|
|
13
|
+
headers: Readonly<Record<string, string>>;
|
|
14
|
+
body: Uint8Array;
|
|
15
|
+
}>;
|
|
16
|
+
/**
|
|
17
|
+
* Authorizes one worker request and rebuilds it for the provider.
|
|
18
|
+
*
|
|
19
|
+
* Everything that decides spend is checked here, before a bearer is attached
|
|
20
|
+
* and before any upstream call:
|
|
21
|
+
* - the client version is exactly the pinned Grok CLI (`GROK_ENGINE_BROKER.grokCliVersion`);
|
|
22
|
+
* - the body model and `reasoning_effort` are exactly the declared policy, and
|
|
23
|
+
* the model override header follows that declaration instead of a constant;
|
|
24
|
+
* - the offered tool names are exactly the lean visible set. Grok 1.0.34 turns
|
|
25
|
+
* an unmappable `--tools` entry into its full 19-tool set, and its per-turn
|
|
26
|
+
* `session_title` request carries a single forced tool; both are refused.
|
|
27
|
+
*/
|
|
28
|
+
export declare function authorizeGrokBrokerProxyRequest(input: GrokBrokerProxyInput, capabilities: EngineBrokerCapabilities, bearer: string, policy?: GrokBrokerModelPolicy): GrokBrokerUpstreamRequest;
|
|
29
|
+
export declare function exactLeanTools(tools: unknown): boolean;
|
|
30
|
+
//# sourceMappingURL=grokBrokerProxyRequest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grokBrokerProxyRequest.d.ts","sourceRoot":"","sources":["../../src/runtime/grokBrokerProxyRequest.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,EAAgE,KAAK,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAGtI,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAC9L,MAAM,MAAM,yBAAyB,GAAG,QAAQ,CAAC;IAAE,GAAG,EAAE,qDAAqD,CAAC;IAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC,CAAC;AAE9K;;;;;;;;;;;GAWG;AACH,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,wBAAwB,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,qBAAwD,GAAG,yBAAyB,CAsBhO;AASD,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAStD"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { GROK_ENGINE_BROKER } from "../contracts/runtimeContractManifest.js";
|
|
2
|
+
import { GROK_WORKER_VISIBLE_TOOLS } from "../contracts/grokWorkerContract.js";
|
|
3
|
+
import { DEFAULT_GROK_BROKER_MODEL_POLICY, parseGrokBrokerModelPolicy } from "./grokBrokerModelPolicy.js";
|
|
4
|
+
const MAX_BODY = 2 * 1024 * 1024;
|
|
5
|
+
/**
|
|
6
|
+
* Authorizes one worker request and rebuilds it for the provider.
|
|
7
|
+
*
|
|
8
|
+
* Everything that decides spend is checked here, before a bearer is attached
|
|
9
|
+
* and before any upstream call:
|
|
10
|
+
* - the client version is exactly the pinned Grok CLI (`GROK_ENGINE_BROKER.grokCliVersion`);
|
|
11
|
+
* - the body model and `reasoning_effort` are exactly the declared policy, and
|
|
12
|
+
* the model override header follows that declaration instead of a constant;
|
|
13
|
+
* - the offered tool names are exactly the lean visible set. Grok 1.0.34 turns
|
|
14
|
+
* an unmappable `--tools` entry into its full 19-tool set, and its per-turn
|
|
15
|
+
* `session_title` request carries a single forced tool; both are refused.
|
|
16
|
+
*/
|
|
17
|
+
export function authorizeGrokBrokerProxyRequest(input, capabilities, bearer, policy = DEFAULT_GROK_BROKER_MODEL_POLICY) {
|
|
18
|
+
const declared = parseGrokBrokerModelPolicy(policy);
|
|
19
|
+
if (input.method !== "POST" || input.pathname !== "/v1/chat/completions" || input.body.byteLength < 2 || input.body.byteLength > MAX_BODY)
|
|
20
|
+
throw new Error("broker proxy request rejected");
|
|
21
|
+
const authorization = input.headers.authorization;
|
|
22
|
+
const match = authorization?.match(/^Bearer ([A-Za-z0-9_-]{40,})$/u);
|
|
23
|
+
if (match === null || match === undefined)
|
|
24
|
+
throw new Error("broker proxy request rejected");
|
|
25
|
+
const scope = capabilities.authorizeToken(match[1]);
|
|
26
|
+
if (scope === undefined || (input.agentId !== undefined && scope.agentId !== input.agentId) || (input.turnId !== undefined && scope.turnId !== input.turnId))
|
|
27
|
+
throw new Error("broker proxy request rejected");
|
|
28
|
+
if (!bearer || /[\r\n]/u.test(bearer))
|
|
29
|
+
throw new Error("broker credential authority unavailable");
|
|
30
|
+
const clientVersion = input.headers["x-grok-client-version"];
|
|
31
|
+
if (clientVersion !== GROK_ENGINE_BROKER.grokCliVersion)
|
|
32
|
+
throw new Error("broker proxy request rejected");
|
|
33
|
+
let parsed;
|
|
34
|
+
// `__proto__` is refused at any depth: JSON.parse makes it an ordinary own
|
|
35
|
+
// member, but an upstream JavaScript parser may treat it as a prototype.
|
|
36
|
+
try {
|
|
37
|
+
parsed = JSON.parse(Buffer.from(input.body).toString("utf8"), (key, value) => { if (key === "__proto__")
|
|
38
|
+
throw new Error(); return value; });
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
throw new Error("broker proxy request rejected");
|
|
42
|
+
}
|
|
43
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed) || parsed.stream !== true || !Array.isArray(parsed.messages))
|
|
44
|
+
throw new Error("broker proxy request rejected");
|
|
45
|
+
if (parsed.model !== declared.model || parsed.reasoning_effort !== declared.reasoningEffort)
|
|
46
|
+
throw new Error("broker proxy request rejected");
|
|
47
|
+
if (!exactLeanTools(parsed.tools))
|
|
48
|
+
throw new Error("broker proxy request rejected");
|
|
49
|
+
if (Object.keys(parsed).some((key) => !LEAN_BODY_MEMBERS.has(key)) || !validStreamOptions(parsed.stream_options))
|
|
50
|
+
throw new Error("broker proxy request rejected");
|
|
51
|
+
// Forward what was validated, never the worker's bytes: JSON.parse keeps the
|
|
52
|
+
// last of duplicate keys, and an upstream that keeps the first would
|
|
53
|
+
// otherwise see a different `tools`/`model`/`reasoning_effort` than the gate.
|
|
54
|
+
return { url: "https://cli-chat-proxy.grok.com/v1/chat/completions", headers: { authorization: `Bearer ${bearer}`, "content-type": "application/json", "x-xai-token-auth": "xai-grok-cli", "x-grok-model-override": declared.model, "x-grok-client-version": clientVersion, "x-grok-client-identifier": "grok-shell" }, body: Buffer.from(JSON.stringify(parsed)) };
|
|
55
|
+
}
|
|
56
|
+
/** Top-level members of a Grok 1.0.34 lean worker chat-completions body (live stub capture). */
|
|
57
|
+
const LEAN_BODY_MEMBERS = new Set(["messages", "model", "reasoning_effort", "stream", "stream_options", "tools"]);
|
|
58
|
+
/** Members of each lean tool `function` entry (live stub capture). */
|
|
59
|
+
const LEAN_FUNCTION_MEMBERS = new Set(["description", "name", "parameters"]);
|
|
60
|
+
const validStreamOptions = (value) => value === undefined
|
|
61
|
+
|| (value !== null && typeof value === "object" && !Array.isArray(value) && Object.keys(value).every((key) => key === "include_usage") && typeof value.include_usage === "boolean");
|
|
62
|
+
export function exactLeanTools(tools) {
|
|
63
|
+
if (!Array.isArray(tools) || tools.length !== GROK_WORKER_VISIBLE_TOOLS.length)
|
|
64
|
+
return false;
|
|
65
|
+
const names = tools.map((tool) => {
|
|
66
|
+
if (tool === null || typeof tool !== "object" || Array.isArray(tool) || tool.type !== "function" || Object.keys(tool).some((key) => key !== "type" && key !== "function"))
|
|
67
|
+
return undefined;
|
|
68
|
+
const fn = tool.function;
|
|
69
|
+
if (fn === null || typeof fn !== "object" || Array.isArray(fn) || Object.keys(fn).some((key) => !LEAN_FUNCTION_MEMBERS.has(key)))
|
|
70
|
+
return undefined;
|
|
71
|
+
return fn.name;
|
|
72
|
+
});
|
|
73
|
+
return JSON.stringify([...names].sort()) === JSON.stringify(GROK_WORKER_VISIBLE_TOOLS);
|
|
74
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grokBrokerRealmLease.d.ts","sourceRoot":"","sources":["../../src/runtime/grokBrokerRealmLease.ts"],"names":[],"mappings":"AAMA,wBAAsB,2BAA2B,CAAC,IAAI,EAAC,MAAM,EAAC,KAAK,SAAQ,GAAE,OAAO,CAAC,QAAQ,CAAC;IAAC,KAAK,IAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAAC,CAAC,CAAC,CAGtH"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { constants } from "node:fs";
|
|
3
|
+
import { open } from "node:fs/promises";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { terminateChild, trackCliChild } from "../pi/cliProcess.js";
|
|
6
|
+
export async function acquireGrokBrokerRealmLease(root, flock = "flock") {
|
|
7
|
+
const handle = await open(path.join(root, ".daimon-broker-lease"), constants.O_CREAT | constants.O_RDWR | constants.O_NOFOLLOW, 0o600);
|
|
8
|
+
let child;
|
|
9
|
+
try {
|
|
10
|
+
const stat = await handle.stat();
|
|
11
|
+
if (!stat.isFile() || stat.uid !== process.getuid?.() || stat.nlink !== 1 || (stat.mode & 0o777) !== 0o600)
|
|
12
|
+
throw new Error();
|
|
13
|
+
child = trackCliChild(spawn("/bin/sh", ["-c", '"$1" --exclusive --nonblock --conflict-exit-code 73 3 || exit 73; printf "ready\\n"; IFS= read -r _hold || :', "daimon-grok-broker-lease", flock], { detached: process.platform !== "win32", env: { PATH: process.env.PATH, LANG: "C", LC_ALL: "C", TZ: "UTC" }, stdio: ["pipe", "pipe", "ignore", handle.fd] }));
|
|
14
|
+
await ready(child);
|
|
15
|
+
let closed = false;
|
|
16
|
+
return { close: async () => { if (closed)
|
|
17
|
+
return; closed = true; const exited = new Promise((resolve) => { if (child.exitCode !== null || child.signalCode !== null)
|
|
18
|
+
return resolve(true); child.once("close", () => resolve(true)); setTimeout(() => resolve(false), 500); }); child.stdin?.end(); if (!await exited)
|
|
19
|
+
await terminateChild(child); } };
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
if (child)
|
|
23
|
+
await terminateChild(child).catch(() => undefined);
|
|
24
|
+
throw new Error("Grok broker realm is already in use or cannot be leased");
|
|
25
|
+
}
|
|
26
|
+
finally {
|
|
27
|
+
await handle.close();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function ready(child) { return new Promise((resolve, reject) => { const timer = setTimeout(() => reject(new Error()), 5000); const fail = () => { clearTimeout(timer); reject(new Error()); }; child.once("error", fail); child.once("close", fail); child.stdout?.once("data", (chunk) => { clearTimeout(timer); if (chunk.toString() === "ready\n")
|
|
31
|
+
resolve();
|
|
32
|
+
else
|
|
33
|
+
reject(new Error()); }); }); }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grokBrokerRefresh.d.ts","sourceRoot":"","sources":["../../src/runtime/grokBrokerRefresh.ts"],"names":[],"mappings":"AAIA,wBAAsB,2BAA2B,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAKtH"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { readChild } from "../pi/cliChildOutput.js";
|
|
3
|
+
import { terminateChild, trackCliChild } from "../pi/cliProcess.js";
|
|
4
|
+
export async function refreshGrokBrokerCredential(command, grokHome, timeoutMs = 15_000) {
|
|
5
|
+
const child = trackCliChild(spawn(command, ["models"], { detached: process.platform !== "win32", env: { GROK_HOME: grokHome, HOME: grokHome, PATH: process.env.PATH, LANG: "C", LC_ALL: "C", TZ: "UTC" }, stdio: ["ignore", "pipe", "pipe"] }));
|
|
6
|
+
try {
|
|
7
|
+
await readChild(child, timeoutMs, []);
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
throw new Error("Grok broker credential refresh failed");
|
|
11
|
+
}
|
|
12
|
+
finally {
|
|
13
|
+
await terminateChild(child).catch(() => undefined);
|
|
14
|
+
}
|
|
15
|
+
}
|