@noopolis/daimon 0.2.0 → 0.2.2
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 +6 -0
- package/dist/contracts/attentionContract.d.ts +25 -0
- package/dist/contracts/attentionContract.d.ts.map +1 -1
- package/dist/contracts/attentionContract.js +8 -1
- 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/organizationRuntimeContract.d.ts +76 -0
- package/dist/contracts/organizationRuntimeContract.d.ts.map +1 -1
- package/dist/contracts/organizationRuntimeContract.js +2 -0
- package/dist/contracts/runtimeContractManifest.d.ts +222 -15
- package/dist/contracts/runtimeContractManifest.d.ts.map +1 -1
- package/dist/contracts/runtimeContractManifest.js +35 -10
- 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/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/observability/causalEvents.d.ts +3 -3
- package/dist/observability/causalEvents.d.ts.map +1 -1
- package/dist/observability/causalEvents.js +4 -4
- package/dist/pi/cliEngineSpawn.d.ts +2 -2
- package/dist/pi/cliEngineSpawn.d.ts.map +1 -1
- package/dist/pi/cliEngineSpawn.js +7 -2
- package/dist/pi/cliEnvironment.d.ts.map +1 -1
- package/dist/pi/cliEnvironment.js +2 -0
- package/dist/pi/cliMcpRegistration.d.ts +1 -1
- package/dist/pi/cliMcpRegistration.d.ts.map +1 -1
- package/dist/pi/cliMcpRegistration.js +1 -1
- package/dist/pi/cliSession.d.ts +2 -0
- package/dist/pi/cliSession.d.ts.map +1 -1
- package/dist/pi/cliSession.js +3 -80
- 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/engineTaskClock.d.ts +9 -0
- package/dist/pi/engineTaskClock.d.ts.map +1 -0
- package/dist/pi/engineTaskClock.js +28 -0
- package/dist/pi/grokHomeMcpRegistration.d.ts.map +1 -1
- package/dist/pi/grokHomeMcpRegistration.js +2 -1
- package/dist/pi/grokSandbox.js +1 -1
- 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 +3 -1
- package/dist/pi/piAgentHandle.d.ts.map +1 -1
- package/dist/pi/piAgentHandle.js +5 -2
- package/dist/pi/piHarness.d.ts +8 -2
- package/dist/pi/piHarness.d.ts.map +1 -1
- package/dist/pi/piHarness.js +28 -12
- 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/wakeAcceptance.d.ts +1 -1
- package/dist/pi/wakeAcceptance.d.ts.map +1 -1
- package/dist/pi/wakeAcceptance.js +2 -2
- package/dist/runtime/agentSkillsDirectory.d.ts +25 -0
- package/dist/runtime/agentSkillsDirectory.d.ts.map +1 -0
- package/dist/runtime/agentSkillsDirectory.js +101 -0
- package/dist/runtime/agySubscriptionBootstrap.js +1 -1
- package/dist/runtime/agySubscriptionRealm.js +1 -1
- package/dist/runtime/attention.d.ts +5 -0
- package/dist/runtime/attention.d.ts.map +1 -1
- package/dist/runtime/attention.js +14 -1
- package/dist/runtime/attentionDispatcher.d.ts +14 -2
- package/dist/runtime/attentionDispatcher.d.ts.map +1 -1
- package/dist/runtime/attentionDispatcher.js +127 -33
- package/dist/runtime/cli.js +5 -0
- package/dist/runtime/contract-manifest.json +1 -1
- package/dist/runtime/contract-manifest.sha256 +1 -1
- package/dist/runtime/engineBrokerCapabilities.d.ts +10 -0
- package/dist/runtime/engineBrokerCapabilities.d.ts.map +1 -1
- package/dist/runtime/engineBrokerCapabilities.js +10 -0
- package/dist/runtime/engineBrokerControlClient.d.ts +12 -1
- package/dist/runtime/engineBrokerControlClient.d.ts.map +1 -1
- package/dist/runtime/engineBrokerControlClient.js +139 -43
- package/dist/runtime/engineBrokerCredentialJournal.d.ts +2 -0
- package/dist/runtime/engineBrokerCredentialJournal.d.ts.map +1 -1
- package/dist/runtime/engineBrokerCredentialJournal.js +9 -0
- package/dist/runtime/engineBrokerInferenceProtocol.d.ts +3 -2
- package/dist/runtime/engineBrokerInferenceProtocol.d.ts.map +1 -1
- package/dist/runtime/engineBrokerInferenceProtocol.js +4 -4
- package/dist/runtime/engineBrokerMcpCallLog.d.ts +11 -0
- package/dist/runtime/engineBrokerMcpCallLog.d.ts.map +1 -1
- package/dist/runtime/engineBrokerMcpCallLog.js +13 -1
- package/dist/runtime/engineBrokerMcpFacade.d.ts +5 -2
- package/dist/runtime/engineBrokerMcpFacade.d.ts.map +1 -1
- package/dist/runtime/engineBrokerMcpFacade.js +5 -2
- package/dist/runtime/engineBrokerNativeClient.js +2 -2
- package/dist/runtime/engineBrokerProtocol.d.ts +42 -10
- package/dist/runtime/engineBrokerProtocol.d.ts.map +1 -1
- package/dist/runtime/engineBrokerProtocol.js +97 -14
- package/dist/runtime/engineBrokerSealLedger.d.ts.map +1 -1
- package/dist/runtime/engineBrokerSealLedger.js +9 -0
- package/dist/runtime/engineBrokerService.d.ts +8 -2
- package/dist/runtime/engineBrokerService.d.ts.map +1 -1
- package/dist/runtime/engineBrokerService.js +95 -37
- package/dist/runtime/engineBrokerServiceCli.js +1 -1
- package/dist/runtime/engineBrokerServiceConfig.d.ts +15 -2
- package/dist/runtime/engineBrokerServiceConfig.d.ts.map +1 -1
- package/dist/runtime/engineBrokerServiceConfig.js +53 -11
- package/dist/runtime/engineBrokerTurnRegistry.d.ts +1 -1
- package/dist/runtime/engineBrokerTurnRegistry.d.ts.map +1 -1
- package/dist/runtime/engineBrokerTurnRegistry.js +7 -6
- package/dist/runtime/engineDispatcher.d.ts +2 -0
- package/dist/runtime/engineDispatcher.d.ts.map +1 -1
- package/dist/runtime/engineDispatcher.js +14 -2
- package/dist/runtime/engineReadiness.js +1 -1
- package/dist/runtime/grokBrokerCredentialAuthority.d.ts +1 -0
- package/dist/runtime/grokBrokerCredentialAuthority.d.ts.map +1 -1
- package/dist/runtime/grokBrokerCredentialAuthority.js +48 -22
- package/dist/runtime/grokBrokerCredentialReader.d.ts +1 -0
- package/dist/runtime/grokBrokerCredentialReader.d.ts.map +1 -1
- package/dist/runtime/grokBrokerCredentialReader.js +2 -1
- package/dist/runtime/grokBrokerProjection.d.ts +26 -2
- package/dist/runtime/grokBrokerProjection.d.ts.map +1 -1
- package/dist/runtime/grokBrokerProjection.js +18 -7
- 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 +17 -3
- package/dist/runtime/grokBrokerProxy.d.ts.map +1 -1
- package/dist/runtime/grokBrokerProxy.js +73 -9
- 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.map +1 -1
- package/dist/runtime/grokBrokerProxyRequest.js +17 -6
- package/dist/runtime/grokBrokerRealmLease.js +1 -1
- package/dist/runtime/grokBrokerRefresh.js +1 -1
- 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 +55 -3
- package/dist/runtime/grokBrokerTurnMeter.d.ts.map +1 -1
- package/dist/runtime/grokBrokerTurnMeter.js +90 -4
- package/dist/runtime/grokBrokerWorkerConfig.d.ts +5 -2
- package/dist/runtime/grokBrokerWorkerConfig.d.ts.map +1 -1
- package/dist/runtime/grokBrokerWorkerConfig.js +22 -3
- package/dist/runtime/grokEngineBroker.d.ts +43 -3
- package/dist/runtime/grokEngineBroker.d.ts.map +1 -1
- package/dist/runtime/grokEngineBroker.js +159 -71
- package/dist/runtime/grokEngineBrokerTurn.d.ts +32 -8
- package/dist/runtime/grokEngineBrokerTurn.d.ts.map +1 -1
- package/dist/runtime/grokEngineBrokerTurn.js +204 -21
- 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/grokInferenceProxy.d.ts.map +1 -1
- package/dist/runtime/grokInferenceProxy.js +3 -0
- package/dist/runtime/grokSubscriptionRealm.js +1 -1
- package/dist/runtime/grokWorkerAttestation.d.ts +12 -5
- package/dist/runtime/grokWorkerAttestation.d.ts.map +1 -1
- package/dist/runtime/grokWorkerAttestation.js +5 -3
- package/dist/runtime/grokWorkerHomeAttestation.d.ts +51 -5
- package/dist/runtime/grokWorkerHomeAttestation.d.ts.map +1 -1
- package/dist/runtime/grokWorkerHomeAttestation.js +103 -8
- package/dist/runtime/grokWorkerSkills.d.ts +86 -0
- package/dist/runtime/grokWorkerSkills.d.ts.map +1 -0
- package/dist/runtime/grokWorkerSkills.js +135 -0
- package/dist/runtime/index.d.ts +10 -2
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +8 -1
- package/dist/runtime/native/daimon-engine-broker +0 -0
- package/dist/runtime/organizationRuntime.d.ts +3 -0
- package/dist/runtime/organizationRuntime.d.ts.map +1 -1
- 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 +9 -0
- package/dist/runtime/organizationRuntimeControl.d.ts.map +1 -1
- package/dist/runtime/organizationRuntimeControl.js +72 -24
- package/dist/runtime/organizationRuntimeHost.d.ts.map +1 -1
- package/dist/runtime/organizationRuntimeHost.js +13 -4
- package/dist/runtime/organizationRuntimeParsing.d.ts.map +1 -1
- package/dist/runtime/organizationRuntimeParsing.js +4 -1
- package/dist/runtime/organizationRuntimeReadiness.d.ts.map +1 -1
- package/dist/runtime/organizationRuntimeReadiness.js +8 -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 +12 -0
- package/dist/runtime/physicalReadiness.d.ts.map +1 -1
- package/dist/runtime/physicalReadiness.js +43 -9
- package/dist/runtime/productionAgentTools.d.ts.map +1 -1
- package/dist/runtime/productionAgentTools.js +13 -5
- 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/schedule.d.ts.map +1 -1
- package/dist/runtime/schedule.js +12 -7
- package/dist/runtime/storeCoordination.d.ts +10 -0
- package/dist/runtime/storeCoordination.d.ts.map +1 -1
- package/dist/runtime/storeCoordination.js +23 -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/turnRequestLedger.d.ts +0 -5
- package/dist/runtime/turnRequestLedger.d.ts.map +1 -1
- package/dist/runtime/turnRequestLedger.js +23 -21
- 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 +9 -1
- package/dist/runtime/wakeAcceptanceProcessIdentity.d.ts.map +1 -1
- package/dist/runtime/wakeAcceptanceProcessIdentity.js +5 -1
- package/dist/runtime/wakeAcceptanceRecord.d.ts +2 -0
- package/dist/runtime/wakeAcceptanceRecord.d.ts.map +1 -1
- package/dist/runtime/wakeAcceptanceRecord.js +4 -2
- package/dist/runtime/wakeAcceptanceRetention.d.ts +25 -1
- package/dist/runtime/wakeAcceptanceRetention.d.ts.map +1 -1
- package/dist/runtime/wakeAcceptanceRetention.js +28 -2
- package/dist/runtime/wakeAcceptanceStore.d.ts +8 -8
- package/dist/runtime/wakeAcceptanceStore.d.ts.map +1 -1
- package/dist/runtime/wakeAcceptanceStore.js +66 -63
- package/dist/runtime/wakeFuse.d.ts +58 -3
- package/dist/runtime/wakeFuse.d.ts.map +1 -1
- package/dist/runtime/wakeFuse.js +106 -7
- 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 +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grokBrokerCredentialReader.d.ts","sourceRoot":"","sources":["../../src/runtime/grokBrokerCredentialReader.ts"],"names":[],"mappings":"AAIA,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"grokBrokerCredentialReader.d.ts","sourceRoot":"","sources":["../../src/runtime/grokBrokerCredentialReader.ts"],"names":[],"mappings":"AAIA,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAW3I"}
|
|
@@ -22,7 +22,8 @@ export async function readGrokBrokerCredential(file) {
|
|
|
22
22
|
const rows = Object.values(root).filter((value) => value !== null && typeof value === "object" && !Array.isArray(value));
|
|
23
23
|
if (rows.length !== 1 || typeof rows[0].key !== "string" || rows[0].key.length < 32 || typeof rows[0].refresh_token !== "string" || rows[0].refresh_token.length < 16)
|
|
24
24
|
throw new Error();
|
|
25
|
-
|
|
25
|
+
const expiresAt = typeof rows[0].expires_at === "string" ? Date.parse(rows[0].expires_at) : NaN;
|
|
26
|
+
return { accessToken: rows[0].key, digest: createHash("sha256").update(bytes).digest("hex"), ...(Number.isFinite(expiresAt) ? { expiresAt } : {}) };
|
|
26
27
|
}
|
|
27
28
|
catch {
|
|
28
29
|
throw new Error("Grok broker credential authority unavailable");
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { GROK_BROKER_TASK_CLOCK, type GrokWorkerConfigVariant } from "../contracts/grokBrokerTaskClock.js";
|
|
1
2
|
import { type EngineBrokerServiceRegistration } from "./engineBrokerServiceConfig.js";
|
|
2
3
|
import { type EngineBrokerTurnLimits } from "./engineBrokerTurnAccounting.js";
|
|
3
4
|
import type { GrokBrokerModel, GrokBrokerReasoningEffort } from "./grokBrokerModelPolicy.js";
|
|
5
|
+
import { type AgentSkill } from "./grokWorkerSkills.js";
|
|
4
6
|
import { GROK_WORKER_SANDBOX_PROFILE } from "./grokWorkerSandboxProfile.js";
|
|
5
|
-
export declare const GROK_BROKER_PROJECTION_VERSION: "noopolis.daimon.grok-broker-projection.
|
|
7
|
+
export declare const GROK_BROKER_PROJECTION_VERSION: "noopolis.daimon.grok-broker-projection.v3";
|
|
6
8
|
/**
|
|
7
9
|
* Everything a consumer (Spawnfile provisioning, Paideia's native adapter, the
|
|
8
10
|
* root slot supervisor) needs to know about one brokered Grok agent's slot,
|
|
@@ -20,7 +22,19 @@ export type OrganizationGrokBrokerProjection = Readonly<{
|
|
|
20
22
|
profileSha256: string;
|
|
21
23
|
denyPaths: readonly string[];
|
|
22
24
|
workerConfigSha256: string;
|
|
25
|
+
workerConfigVariant: GrokWorkerConfigVariant;
|
|
26
|
+
taskClock?: Omit<typeof GROK_BROKER_TASK_CLOCK, "directoryPath" | "timestampFilePath"> & Readonly<{
|
|
27
|
+
directoryPath: string;
|
|
28
|
+
timestampFilePath: string;
|
|
29
|
+
}>;
|
|
23
30
|
systemPromptSha256: string;
|
|
31
|
+
/**
|
|
32
|
+
* Digest of the declared skills rendered into `$GROK_HOME/skills`
|
|
33
|
+
* (`grokWorkerSkillsSha256`). Present only when the agent declares at least
|
|
34
|
+
* one skill, so a skill-less projection is byte-identical to one computed
|
|
35
|
+
* before skills existed.
|
|
36
|
+
*/
|
|
37
|
+
skillsSha256?: string;
|
|
24
38
|
grokCliVersion: string;
|
|
25
39
|
grokExecutableSha256: string;
|
|
26
40
|
nativeAbiVersion: number;
|
|
@@ -40,6 +54,8 @@ export type OrganizationGrokBrokerProjection = Readonly<{
|
|
|
40
54
|
}>;
|
|
41
55
|
}>;
|
|
42
56
|
export type OrganizationGrokBrokerProjectionOptions = Readonly<{
|
|
57
|
+
/** Clocked configs require an isolated clock directory per slot. Defaults to the unchanged production bytes. */
|
|
58
|
+
workerConfigVariant?: GrokWorkerConfigVariant;
|
|
43
59
|
/** Deployment-assigned slot identity. */
|
|
44
60
|
slot: number;
|
|
45
61
|
workerUid: number;
|
|
@@ -70,6 +86,13 @@ export type OrganizationGrokBrokerProjectionOptions = Readonly<{
|
|
|
70
86
|
seccompProfileSha256: string;
|
|
71
87
|
/** When the caller already holds a rendered profile digest, it must equal Daimon's. */
|
|
72
88
|
profileSha256?: string;
|
|
89
|
+
/**
|
|
90
|
+
* The agent's declared skills: the compiled workspace `.agents/skills` tree
|
|
91
|
+
* every engine is given (`readAgentSkillsDirectory`), which root provisioning
|
|
92
|
+
* renders into `$GROK_HOME/skills` (`renderGrokWorkerSkillsTree`). Omitted or
|
|
93
|
+
* empty means no skills.
|
|
94
|
+
*/
|
|
95
|
+
skills?: readonly AgentSkill[];
|
|
73
96
|
}>;
|
|
74
97
|
/**
|
|
75
98
|
* Resolve the public Grok broker projection for one agent.
|
|
@@ -90,7 +113,8 @@ export type OrganizationGrokBrokerProjectionOptions = Readonly<{
|
|
|
90
113
|
* this agent (realm, bootstrap, peers, and the mask covering the acceptance
|
|
91
114
|
* store) plus the caller's evaluator paths, sorted and deduplicated exactly as
|
|
92
115
|
* the profile renderer does. A supplied `profileSha256` that differs is
|
|
93
|
-
* refused.
|
|
116
|
+
* refused. Declared `skills` add `skillsSha256`, which the implied
|
|
117
|
+
* registration carries and the broker attests against `$GROK_HOME/skills`.
|
|
94
118
|
*/
|
|
95
119
|
export declare function resolveOrganizationGrokBrokerProjection(config: unknown, agentId: string, options: OrganizationGrokBrokerProjectionOptions): OrganizationGrokBrokerProjection;
|
|
96
120
|
/** sha256 over the projection's canonical JSON; what a slot preflight receipt binds. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grokBrokerProjection.d.ts","sourceRoot":"","sources":["../../src/runtime/grokBrokerProjection.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"grokBrokerProjection.d.ts","sourceRoot":"","sources":["../../src/runtime/grokBrokerProjection.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,KAAK,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAQ3G,OAAO,EAAkC,KAAK,+BAA+B,EAAE,MAAM,gCAAgC,CAAC;AACtH,OAAO,EAA+B,KAAK,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAE3G,OAAO,KAAK,EAAE,eAAe,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAC7F,OAAO,EAA4C,KAAK,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAClG,OAAO,EAAE,2BAA2B,EAA2F,MAAM,+BAA+B,CAAC;AAGrK,eAAO,MAAM,8BAA8B,6CAAuC,CAAC;AAEnF;;;;;GAKG;AACH,MAAM,MAAM,gCAAgC,GAAG,QAAQ,CAAC;IACtD,OAAO,EAAE,OAAO,8BAA8B,CAAC;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,uBAAuB,CAAC;IAC7C,SAAS,CAAC,EAAE,IAAI,CAAC,OAAO,sBAAsB,EAAE,eAAe,GAAG,mBAAmB,CAAC,GAAG,QAAQ,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,iBAAiB,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxJ,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,gBAAgB,EAAE,MAAM,CAAC;IACzB,KAAK,EAAE,eAAe,CAAC;IACvB,eAAe,EAAE,yBAAyB,CAAC;IAC3C,MAAM,EAAE,sBAAsB,CAAC;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,yHAAyH;IACzH,oBAAoB,EAAE,MAAM,CAAC;IAC7B,WAAW,EAAE,QAAQ,CAAC;QAAE,QAAQ,EAAE,gBAAgB,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAC;QAAC,eAAe,EAAE,IAAI,CAAC;QAAC,WAAW,EAAE,OAAO,2BAA2B,CAAC;QAAC,cAAc,EAAE,YAAY,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjM,CAAC,CAAC;AAEH,MAAM,MAAM,uCAAuC,GAAG,QAAQ,CAAC;IAC7D,gHAAgH;IAChH,mBAAmB,CAAC,EAAE,uBAAuB,CAAC;IAC9C,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,OAAO,GAAG,KAAK,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,sBAAsB,CAAC;IAC/B;;;;;;;;;;;;;;OAcG;IACH,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mFAAmF;IACnF,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,gFAAgF;IAChF,oBAAoB,EAAE,MAAM,CAAC;IAC7B,uFAAuF;IACvF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;CAChC,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,uCAAuC,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,uCAAuC,GAAG,gCAAgC,CAmC5K;AAED,wFAAwF;AACxF,eAAO,MAAM,0BAA0B,GAAI,YAAY,gCAAgC,KAAG,MACpB,CAAC;AAEvE,4HAA4H;AAC5H,wBAAgB,gCAAgC,CAAC,UAAU,EAAE,gCAAgC,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAShI;AAED;;;;GAIG;AACH,wBAAgB,6CAA6C,CAAC,YAAY,EAAE,+BAA+B,EAAE,UAAU,EAAE,gCAAgC,GAAG,IAAI,CAG/J"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { brokerTaskClockFileFor } from "./grokBrokerSlot.js";
|
|
2
|
+
import { GROK_BROKER_TASK_CLOCK } from "../contracts/grokBrokerTaskClock.js";
|
|
1
3
|
import { createHash } from "node:crypto";
|
|
2
4
|
import path from "node:path";
|
|
3
5
|
import { canonicalJson } from "../contracts/canonicalJson.js";
|
|
@@ -6,7 +8,8 @@ import { GROK_ENGINE_BROKER } from "../contracts/runtimeContractManifest.js";
|
|
|
6
8
|
import { grokSandboxProtectedPaths } from "./engineDispatcher.js";
|
|
7
9
|
import { parseEngineBrokerServiceConfig } from "./engineBrokerServiceConfig.js";
|
|
8
10
|
import { parseEngineBrokerTurnLimits } from "./engineBrokerTurnAccounting.js";
|
|
9
|
-
import { grokBrokerWorkerConfigSha256 } from "./grokBrokerWorkerConfig.js";
|
|
11
|
+
import { grokBrokerWorkerConfigPins, grokBrokerWorkerConfigSha256 } from "./grokBrokerWorkerConfig.js";
|
|
12
|
+
import { grokWorkerSkillsSha256, parseAgentSkills } from "./grokWorkerSkills.js";
|
|
10
13
|
import { GROK_WORKER_SANDBOX_PROFILE, grokWorkerEventsPathFor, renderGrokWorkerSandboxProfile, grokWorkerSandboxProfileSha256 } from "./grokWorkerSandboxProfile.js";
|
|
11
14
|
import { parseOrganizationRuntimeConfig } from "./organizationRuntime.js";
|
|
12
15
|
export const GROK_BROKER_PROJECTION_VERSION = GROK_ENGINE_BROKER.projectionVersion;
|
|
@@ -29,7 +32,8 @@ export const GROK_BROKER_PROJECTION_VERSION = GROK_ENGINE_BROKER.projectionVersi
|
|
|
29
32
|
* this agent (realm, bootstrap, peers, and the mask covering the acceptance
|
|
30
33
|
* store) plus the caller's evaluator paths, sorted and deduplicated exactly as
|
|
31
34
|
* the profile renderer does. A supplied `profileSha256` that differs is
|
|
32
|
-
* refused.
|
|
35
|
+
* refused. Declared `skills` add `skillsSha256`, which the implied
|
|
36
|
+
* registration carries and the broker attests against `$GROK_HOME/skills`.
|
|
33
37
|
*/
|
|
34
38
|
export function resolveOrganizationGrokBrokerProjection(config, agentId, options) {
|
|
35
39
|
const parsed = parseOrganizationRuntimeConfig(config);
|
|
@@ -50,19 +54,25 @@ export function resolveOrganizationGrokBrokerProjection(config, agentId, options
|
|
|
50
54
|
const profileSha256 = grokWorkerSandboxProfileSha256(denyPaths);
|
|
51
55
|
if (options.profileSha256 !== undefined && options.profileSha256 !== profileSha256)
|
|
52
56
|
throw new Error("Grok broker projection profile digest mismatch");
|
|
53
|
-
const
|
|
54
|
-
|
|
57
|
+
const workerConfigVariant = options.workerConfigVariant ?? "unclocked";
|
|
58
|
+
const workerConfigSha256 = grokBrokerWorkerConfigSha256({ model, reasoningEffort }, workerConfigVariant, options.slot);
|
|
59
|
+
const pin = grokBrokerWorkerConfigPins({ model, reasoningEffort }, options.slot)[workerConfigVariant];
|
|
60
|
+
if (workerConfigVariant === "clocked" && denyPaths.some((denied) => [brokerTaskClockFileFor(options.slot), GROK_BROKER_TASK_CLOCK.preloadPath].some((file) => file === denied || file.startsWith(`${denied}/`))))
|
|
61
|
+
throw new Error("Grok broker task clock path is denied");
|
|
62
|
+
if (workerConfigSha256 !== pin)
|
|
55
63
|
throw new Error("Grok broker projection worker config drifted from the manifest");
|
|
56
64
|
if (createHash("sha256").update(DAIMON_GROK_SYSTEM_PROMPT).digest("hex") !== GROK_ENGINE_BROKER.worker.systemPromptSha256)
|
|
57
65
|
throw new Error("Grok broker projection system prompt drifted from the manifest");
|
|
58
66
|
const artifact = GROK_ENGINE_BROKER.grokCliArtifacts[options.architecture];
|
|
59
67
|
if (artifact === undefined)
|
|
60
68
|
throw new Error("Grok broker projection requires a pinned architecture");
|
|
69
|
+
const skills = parseAgentSkills(options.skills ?? []);
|
|
61
70
|
const profilePath = path.posix.join(options.workerHomePath, ".grok", "sandbox.toml");
|
|
62
71
|
const projection = {
|
|
63
72
|
version: GROK_BROKER_PROJECTION_VERSION, agentId, workspacePath: agent.workspacePath, runtimeHomePath: agent.runtimeHomePath,
|
|
64
|
-
workerUid: options.workerUid, slot: options.slot, profilePath, profileSha256, denyPaths, workerConfigSha256,
|
|
65
|
-
|
|
73
|
+
workerUid: options.workerUid, slot: options.slot, profilePath, profileSha256, denyPaths, workerConfigSha256, workerConfigVariant,
|
|
74
|
+
...(workerConfigVariant === "clocked" ? { taskClock: { ...GROK_BROKER_TASK_CLOCK, directoryPath: path.posix.dirname(brokerTaskClockFileFor(options.slot)), timestampFilePath: brokerTaskClockFileFor(options.slot) } } : {}),
|
|
75
|
+
systemPromptSha256: GROK_ENGINE_BROKER.worker.systemPromptSha256, ...(skills.length === 0 ? {} : { skillsSha256: grokWorkerSkillsSha256(skills) }), grokCliVersion: GROK_ENGINE_BROKER.grokCliVersion, grokExecutableSha256: artifact.sha256,
|
|
66
76
|
nativeAbiVersion: GROK_ENGINE_BROKER.nativeAbiVersion, model, reasoningEffort, limits: parseEngineBrokerTurnLimits(options.limits), usageLedgerPath: options.usageLedgerPath, seccompProfileSha256: options.seccompProfileSha256,
|
|
67
77
|
attestation: { platform: "linux/landlock", enforced: true, restrictNetwork: true, profileName: GROK_WORKER_SANDBOX_PROFILE, sandboxRuntime: "bubblewrap", eventsPath: grokWorkerEventsPathFor(profilePath) }
|
|
68
78
|
};
|
|
@@ -77,7 +87,8 @@ export function grokBrokerServiceRegistrationFor(projection) {
|
|
|
77
87
|
const registration = {
|
|
78
88
|
agentId: projection.agentId, slot: projection.slot, workerUid: projection.workerUid, workspace: projection.workspacePath,
|
|
79
89
|
profilePath: projection.profilePath, eventsPath: projection.attestation.eventsPath, profileSha256: projection.profileSha256,
|
|
80
|
-
usageLedgerPath: projection.usageLedgerPath, limits: projection.limits, model: { id: projection.model, reasoningEffort: projection.reasoningEffort }
|
|
90
|
+
usageLedgerPath: projection.usageLedgerPath, limits: projection.limits, model: { id: projection.model, reasoningEffort: projection.reasoningEffort },
|
|
91
|
+
...(projection.skillsSha256 === undefined ? {} : { skillsSha256: projection.skillsSha256 })
|
|
81
92
|
};
|
|
82
93
|
parseEngineBrokerServiceConfig({ version: "noopolis.daimon.engine-broker-service.v2", credentialHome: GROK_ENGINE_BROKER.credentialHomePath, turnStore: GROK_ENGINE_BROKER.turnStorePath, registrations: [registration] });
|
|
83
94
|
return registration;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type GrokBrokerProviderClockObservation = Readonly<{
|
|
2
|
+
requests: number;
|
|
3
|
+
linesRewritten: number;
|
|
4
|
+
requestsWithoutDateLine: number;
|
|
5
|
+
/** Date-like message lines outside the injected block; absent on older seals. */
|
|
6
|
+
linesIgnored?: number;
|
|
7
|
+
/** The last rewritten line's dates; null until a line is rewritten. */
|
|
8
|
+
injectedDate: string | null;
|
|
9
|
+
taskDate: string | null;
|
|
10
|
+
}>;
|
|
11
|
+
export declare class GrokBrokerProviderClockRefusal extends Error {
|
|
12
|
+
readonly reason: "task_clock_date_format" | "task_clock_date_range" | "request_body_rejected";
|
|
13
|
+
constructor(reason: "task_clock_date_format" | "task_clock_date_range" | "request_body_rejected");
|
|
14
|
+
}
|
|
15
|
+
/** One processClock, owned by one turn; never reads the broker's ambient TZ. */
|
|
16
|
+
export declare class GrokBrokerProviderClock {
|
|
17
|
+
private readonly now;
|
|
18
|
+
private readonly offsetMs;
|
|
19
|
+
private observation;
|
|
20
|
+
constructor(processClock: string, now?: () => number);
|
|
21
|
+
rewrite(body: Uint8Array): Uint8Array;
|
|
22
|
+
snapshot(): GrokBrokerProviderClockObservation;
|
|
23
|
+
}
|
|
24
|
+
/** Closed, dates-only observation on the v3 terminal frame and durable seal. */
|
|
25
|
+
export declare function parseGrokBrokerProviderClockObservation(value: unknown): GrokBrokerProviderClockObservation;
|
|
26
|
+
//# sourceMappingURL=grokBrokerProviderClock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grokBrokerProviderClock.d.ts","sourceRoot":"","sources":["../../src/runtime/grokBrokerProviderClock.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,kCAAkC,GAAG,QAAQ,CAAC;IACxD,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,uBAAuB,EAAE,MAAM,CAAC;IAChC,iFAAiF;IACjF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC,CAAC;AAEH,qBAAa,8BAA+B,SAAQ,KAAK;IAC3C,QAAQ,CAAC,MAAM,EAAE,wBAAwB,GAAG,uBAAuB,GAAG,uBAAuB;gBAApF,MAAM,EAAE,wBAAwB,GAAG,uBAAuB,GAAG,uBAAuB;CAG1G;AAOD,gFAAgF;AAChF,qBAAa,uBAAuB;IAOA,OAAO,CAAC,QAAQ,CAAC,GAAG;IANtD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,WAAW,CAGjB;gBAEU,YAAY,EAAE,MAAM,EAAmB,GAAG,GAAE,MAAM,MAAyB;IAIvF,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU;IAuErC,QAAQ,IAAI,kCAAkC;CAG/C;AAKD,gFAAgF;AAChF,wBAAgB,uCAAuC,CAAC,KAAK,EAAE,OAAO,GAAG,kCAAkC,CAuB1G"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { parseBrokerProcessClock } from "./grokBrokerTaskClock.js";
|
|
2
|
+
import { parseGrokBrokerProxyJson } from "./grokBrokerProxyJson.js";
|
|
3
|
+
export class GrokBrokerProviderClockRefusal extends Error {
|
|
4
|
+
reason;
|
|
5
|
+
constructor(reason) {
|
|
6
|
+
super(`grok broker proxy refused: ${reason}`);
|
|
7
|
+
this.reason = reason;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
const DATE = /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/u;
|
|
11
|
+
const DATE_LINE = /^Today's date: ([0-9]{4}-[0-9]{2}-[0-9]{2})$/u;
|
|
12
|
+
const DATE_LIKE = /today['’]?s\s+date\b/iu;
|
|
13
|
+
const MAX_TASK_MS = 253_402_300_799_999;
|
|
14
|
+
/** One processClock, owned by one turn; never reads the broker's ambient TZ. */
|
|
15
|
+
export class GrokBrokerProviderClock {
|
|
16
|
+
now;
|
|
17
|
+
offsetMs;
|
|
18
|
+
observation = {
|
|
19
|
+
requests: 0, linesRewritten: 0, requestsWithoutDateLine: 0, linesIgnored: 0,
|
|
20
|
+
injectedDate: null, taskDate: null
|
|
21
|
+
};
|
|
22
|
+
constructor(processClock, now = () => Date.now()) {
|
|
23
|
+
this.now = now;
|
|
24
|
+
this.offsetMs = Math.round(Number(parseBrokerProcessClock(processClock)) * 1000);
|
|
25
|
+
}
|
|
26
|
+
rewrite(body) {
|
|
27
|
+
this.observation = { ...this.observation, requests: this.observation.requests + 1 };
|
|
28
|
+
let parsed;
|
|
29
|
+
try {
|
|
30
|
+
parsed = parseGrokBrokerProxyJson(body);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
throw new GrokBrokerProviderClockRefusal("request_body_rejected");
|
|
34
|
+
}
|
|
35
|
+
const taskMs = this.now() + this.offsetMs;
|
|
36
|
+
if (!Number.isSafeInteger(taskMs) || taskMs < 0 || taskMs > MAX_TASK_MS) {
|
|
37
|
+
throw new GrokBrokerProviderClockRefusal("task_clock_date_range");
|
|
38
|
+
}
|
|
39
|
+
// The native launcher pins TZ=UTC. Compute once per request, including
|
|
40
|
+
// history resends; a long turn may cross midnight between requests.
|
|
41
|
+
const taskDate = new Date(taskMs).toISOString().slice(0, 10);
|
|
42
|
+
let lines = 0;
|
|
43
|
+
let ignored = 0;
|
|
44
|
+
let injectedDate = null;
|
|
45
|
+
const countIgnored = (text) => text.split(/\r\n|\r|\n/u).filter((line) => DATE_LIKE.test(line)).length;
|
|
46
|
+
const rewriteText = (text, injected) => {
|
|
47
|
+
const block = injected ? /<user_info>([\s\S]*?)<\/user_info>/u.exec(text) : null;
|
|
48
|
+
if (block === null) {
|
|
49
|
+
ignored += countIgnored(text);
|
|
50
|
+
return text;
|
|
51
|
+
}
|
|
52
|
+
const before = text.slice(0, block.index), after = text.slice(block.index + block[0].length);
|
|
53
|
+
ignored += countIgnored(before) + countIgnored(after);
|
|
54
|
+
const rewritten = block[1].split(/(\r\n|\r|\n)/u).map((line) => {
|
|
55
|
+
if (!DATE_LIKE.test(line))
|
|
56
|
+
return line;
|
|
57
|
+
const match = DATE_LINE.exec(line);
|
|
58
|
+
if (match === null)
|
|
59
|
+
throw new GrokBrokerProviderClockRefusal("task_clock_date_format");
|
|
60
|
+
lines++;
|
|
61
|
+
injectedDate = match[1];
|
|
62
|
+
return `Today's date: ${taskDate}`;
|
|
63
|
+
}).join("");
|
|
64
|
+
return `${before}<user_info>${rewritten}</user_info>${after}`;
|
|
65
|
+
};
|
|
66
|
+
if (Array.isArray(parsed.value.messages)) {
|
|
67
|
+
let firstUser = true;
|
|
68
|
+
for (const message of parsed.value.messages) {
|
|
69
|
+
if (!isRecord(message))
|
|
70
|
+
continue;
|
|
71
|
+
const injected = message.role === "user" && firstUser;
|
|
72
|
+
if (message.role === "user")
|
|
73
|
+
firstUser = false;
|
|
74
|
+
if (typeof message.content === "string") {
|
|
75
|
+
message.content = rewriteText(message.content, injected);
|
|
76
|
+
}
|
|
77
|
+
else if (Array.isArray(message.content)) {
|
|
78
|
+
const parts = message.content.filter((part) => isRecord(part) && part.type === "text" && typeof part.text === "string");
|
|
79
|
+
// A block or date can straddle text parts. Replacements have exactly
|
|
80
|
+
// the same width, so slicing restores every original part boundary.
|
|
81
|
+
const rewritten = rewriteText(parts.map((part) => part.text).join(""), injected);
|
|
82
|
+
let start = 0;
|
|
83
|
+
for (const part of parts) {
|
|
84
|
+
const end = start + part.text.length;
|
|
85
|
+
part.text = rewritten.slice(start, end);
|
|
86
|
+
start = end;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Commit only after the entire body passes: a refused request rewrites no
|
|
92
|
+
// lines upstream, even when an earlier line had the recognized format.
|
|
93
|
+
this.observation = {
|
|
94
|
+
requests: this.observation.requests,
|
|
95
|
+
linesRewritten: this.observation.linesRewritten + lines,
|
|
96
|
+
requestsWithoutDateLine: this.observation.requestsWithoutDateLine + (lines === 0 ? 1 : 0),
|
|
97
|
+
linesIgnored: (this.observation.linesIgnored ?? 0) + ignored,
|
|
98
|
+
injectedDate: lines === 0 ? this.observation.injectedDate : injectedDate,
|
|
99
|
+
taskDate: lines === 0 ? this.observation.taskDate : taskDate
|
|
100
|
+
};
|
|
101
|
+
return lines === 0 ? parsed.body : Buffer.from(JSON.stringify(parsed.value));
|
|
102
|
+
}
|
|
103
|
+
snapshot() {
|
|
104
|
+
return { ...this.observation };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const isRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
108
|
+
/** Closed, dates-only observation on the v3 terminal frame and durable seal. */
|
|
109
|
+
export function parseGrokBrokerProviderClockObservation(value) {
|
|
110
|
+
if (!isRecord(value))
|
|
111
|
+
throw new TypeError("invalid broker frame");
|
|
112
|
+
const fields = ["requests", "linesRewritten", "requestsWithoutDateLine", "injectedDate", "taskDate"];
|
|
113
|
+
if (Object.keys(value).some((key) => !fields.includes(key) && key !== "linesIgnored") ||
|
|
114
|
+
fields.some((key) => !Object.hasOwn(value, key))) {
|
|
115
|
+
throw new TypeError("invalid broker frame");
|
|
116
|
+
}
|
|
117
|
+
for (const key of [...fields.slice(0, 3), ...(Object.hasOwn(value, "linesIgnored") ? ["linesIgnored"] : [])]) {
|
|
118
|
+
if (!Number.isSafeInteger(value[key]) || value[key] < 0) {
|
|
119
|
+
throw new TypeError("invalid broker frame");
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
const result = value;
|
|
123
|
+
if (result.requestsWithoutDateLine > result.requests ||
|
|
124
|
+
(result.linesRewritten > 0 && result.requestsWithoutDateLine === result.requests)) {
|
|
125
|
+
throw new TypeError("invalid broker frame");
|
|
126
|
+
}
|
|
127
|
+
for (const date of [result.injectedDate, result.taskDate]) {
|
|
128
|
+
if (result.linesRewritten === 0 ? date !== null : typeof date !== "string" || !DATE.test(date)) {
|
|
129
|
+
throw new TypeError("invalid broker frame");
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return { ...result };
|
|
133
|
+
}
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
+
import { type GrokBrokerRunBudget } from "./grokBrokerRunBudget.js";
|
|
2
|
+
import { type IncomingMessage, type ServerResponse } from "node:http";
|
|
1
3
|
import { EngineBrokerCapabilities } from "./engineBrokerCapabilities.js";
|
|
2
4
|
import { type GrokBrokerModelPolicy } from "./grokBrokerModelPolicy.js";
|
|
3
5
|
import { authorizeGrokBrokerProxyRequest } from "./grokBrokerProxyRequest.js";
|
|
4
6
|
import { type GrokBrokerTurnMeter } from "./grokBrokerTurnMeter.js";
|
|
5
7
|
import type { GrokInferenceGrants } from "./grokInferenceGrants.js";
|
|
8
|
+
import { type GrokBrokerProviderClock } from "./grokBrokerProviderClock.js";
|
|
6
9
|
/** One running turn as the proxy sees it: its declared model/effort and its spend gate. */
|
|
7
10
|
export type GrokBrokerProxyTurn = Readonly<{
|
|
8
11
|
policy: GrokBrokerModelPolicy;
|
|
9
12
|
meter: GrokBrokerTurnMeter;
|
|
13
|
+
clock?: GrokBrokerProviderClock;
|
|
10
14
|
}>;
|
|
11
15
|
export type GrokBrokerCredentialAuthority = Readonly<{
|
|
12
16
|
accessToken(forceRefresh: boolean): Promise<string>;
|
|
@@ -30,15 +34,25 @@ export type GrokBrokerUpstream = (request: ReturnType<typeof authorizeGrokBroker
|
|
|
30
34
|
* `grokInferenceProxy.ts`; every other bearer is looked up only among turn
|
|
31
35
|
* capabilities. Without `grants` a prefixed bearer is simply refused.
|
|
32
36
|
*/
|
|
33
|
-
export declare function startGrokBrokerProxy(authority: GrokBrokerCredentialAuthority, upstream?: GrokBrokerUpstream, policy?: GrokBrokerModelPolicy, listenPort?: number, grants?: GrokInferenceGrants): Promise<
|
|
37
|
+
export declare function startGrokBrokerProxy(authority: GrokBrokerCredentialAuthority, upstream?: GrokBrokerUpstream, policy?: GrokBrokerModelPolicy, listenPort?: number, grants?: GrokInferenceGrants, runBudget?: GrokBrokerRunBudget): Promise<{
|
|
34
38
|
port: number;
|
|
39
|
+
close: () => Promise<void>;
|
|
35
40
|
capabilities: EngineBrokerCapabilities;
|
|
36
41
|
registerIsolationGuard(turnId: string, guard: () => Promise<void>): void;
|
|
37
42
|
revokeIsolationGuard(turnId: string): void;
|
|
38
43
|
registerTurn(turnId: string, turn: GrokBrokerProxyTurn): void;
|
|
39
44
|
revokeTurn(turnId: string): void;
|
|
40
|
-
|
|
41
|
-
}
|
|
45
|
+
serve: (request: IncomingMessage, response: ServerResponse) => Promise<void>;
|
|
46
|
+
}>;
|
|
47
|
+
/** @internal The production request handler, usable without opening a socket. */
|
|
48
|
+
export declare function createGrokBrokerProxyHandler(authority: GrokBrokerCredentialAuthority, upstream?: GrokBrokerUpstream, policy?: GrokBrokerModelPolicy, grants?: GrokInferenceGrants, runBudget?: GrokBrokerRunBudget): {
|
|
49
|
+
capabilities: EngineBrokerCapabilities;
|
|
50
|
+
registerIsolationGuard(turnId: string, guard: () => Promise<void>): void;
|
|
51
|
+
revokeIsolationGuard(turnId: string): void;
|
|
52
|
+
registerTurn(turnId: string, turn: GrokBrokerProxyTurn): void;
|
|
53
|
+
revokeTurn(turnId: string): void;
|
|
54
|
+
serve: (request: IncomingMessage, response: ServerResponse) => Promise<void>;
|
|
55
|
+
};
|
|
42
56
|
/**
|
|
43
57
|
* A refusal the caller must not retry.
|
|
44
58
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grokBrokerProxy.d.ts","sourceRoot":"","sources":["../../src/runtime/grokBrokerProxy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"grokBrokerProxy.d.ts","sourceRoot":"","sources":["../../src/runtime/grokBrokerProxy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAExF,OAAO,EAAgB,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAIpF,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,EAA2E,KAAK,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAG7I,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAkC,KAAK,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAE5G,2FAA2F;AAC3F,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,MAAM,EAAE,qBAAqB,CAAC;IAC9B,KAAK,EAAE,mBAAmB,CAAC;IAC3B,KAAK,CAAC,EAAE,uBAAuB,CAAC;CACjC,CAAC,CAAC;AAEH,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,CACxC,SAAS,EAAE,6BAA6B,EAAE,QAAQ,GAAE,kBAAoC,EACxF,MAAM,GAAE,qBAAwD,EAAE,UAAU,SAAS,EACrF,MAAM,CAAC,EAAE,mBAAmB,EAAE,SAAS,CAAC,EAAE,mBAAmB;;;;mCAoC5B,MAAM,SAAS,MAAM,OAAO,CAAC,IAAI,CAAC;iCACpC,MAAM;yBACd,MAAM,QAAQ,mBAAmB;uBAMnC,MAAM;qBACR,eAAe,YAAY,cAAc;GA5B7D;AAED,iFAAiF;AACjF,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,6BAA6B,EAAE,QAAQ,GAAE,kBAAoC,EACxF,MAAM,GAAE,qBAAwD,EAAE,MAAM,CAAC,EAAE,mBAAmB,EAAE,SAAS,CAAC,EAAE,mBAAmB;;mCAc9F,MAAM,SAAS,MAAM,OAAO,CAAC,IAAI,CAAC;iCACpC,MAAM;yBACd,MAAM,QAAQ,mBAAmB;uBAMnC,MAAM;qBACR,eAAe,YAAY,cAAc;EAI7D;AAED;;;;;;;;GAQG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM;gBAAd,MAAM,EAAE,MAAM;CACpC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { GrokBrokerRunLimit } from "./grokBrokerRunBudget.js";
|
|
1
2
|
import { createHash } from "node:crypto";
|
|
2
3
|
import { createServer } from "node:http";
|
|
3
4
|
import { redactCredentialText } from "../core/credentialRedaction.js";
|
|
@@ -7,9 +8,10 @@ import { ENGINE_BROKER_AUTH_STALE } from "./engineBrokerProtocol.js";
|
|
|
7
8
|
import { DEFAULT_GROK_BROKER_MODEL_POLICY, parseGrokBrokerModelPolicy } from "./grokBrokerModelPolicy.js";
|
|
8
9
|
import { authorizeGrokBrokerProxyRequest } from "./grokBrokerProxyRequest.js";
|
|
9
10
|
import { GROK_SESSION_TITLE_SINK_KEY } from "./grokBrokerWorkerConfig.js";
|
|
10
|
-
import { parseGrokResponseToolNames, parseGrokUpstreamUsage } from "./grokBrokerTurnMeter.js";
|
|
11
|
+
import { parseGrokFinalReply, parseGrokResponseToolNames, parseGrokUpstreamUsage } from "./grokBrokerTurnMeter.js";
|
|
11
12
|
import { GROK_ENGINE_BROKER } from "../contracts/runtimeContractManifest.js";
|
|
12
13
|
import { serveGrokInferenceGrant } from "./grokInferenceProxy.js";
|
|
14
|
+
import { GrokBrokerProviderClockRefusal } from "./grokBrokerProviderClock.js";
|
|
13
15
|
/**
|
|
14
16
|
* `policy` is the fallback declared model/effort (closed list); a registered
|
|
15
17
|
* turn's own policy wins. A request whose turn has no registered meter is
|
|
@@ -21,15 +23,48 @@ import { serveGrokInferenceGrant } from "./grokInferenceProxy.js";
|
|
|
21
23
|
* `grokInferenceProxy.ts`; every other bearer is looked up only among turn
|
|
22
24
|
* capabilities. Without `grants` a prefixed bearer is simply refused.
|
|
23
25
|
*/
|
|
24
|
-
export async function startGrokBrokerProxy(authority, upstream = defaultUpstream, policy = DEFAULT_GROK_BROKER_MODEL_POLICY, listenPort = 43_123, grants) {
|
|
26
|
+
export async function startGrokBrokerProxy(authority, upstream = defaultUpstream, policy = DEFAULT_GROK_BROKER_MODEL_POLICY, listenPort = 43_123, grants, runBudget) {
|
|
27
|
+
const handler = createGrokBrokerProxyHandler(authority, upstream, policy, grants, runBudget);
|
|
28
|
+
const server = createServer((request, response) => { void handler.serve(request, response); });
|
|
29
|
+
await new Promise((resolve, reject) => {
|
|
30
|
+
server.once("error", reject);
|
|
31
|
+
server.listen(listenPort, "127.0.0.1", () => { server.off("error", reject); resolve(); });
|
|
32
|
+
});
|
|
33
|
+
const address = server.address();
|
|
34
|
+
return {
|
|
35
|
+
...handler, port: address.port,
|
|
36
|
+
close: () => new Promise((resolve, reject) => {
|
|
37
|
+
server.close((error) => error === undefined ? resolve() : reject(error));
|
|
38
|
+
// A worker's idle pooled socket otherwise leaves close() without a bound.
|
|
39
|
+
server.closeAllConnections();
|
|
40
|
+
})
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/** @internal The production request handler, usable without opening a socket. */
|
|
44
|
+
export function createGrokBrokerProxyHandler(authority, upstream = defaultUpstream, policy = DEFAULT_GROK_BROKER_MODEL_POLICY, grants, runBudget) {
|
|
45
|
+
const admittedUpstream = async (request, signal) => {
|
|
46
|
+
signal?.throwIfAborted();
|
|
47
|
+
await runBudget?.reserve();
|
|
48
|
+
signal?.throwIfAborted();
|
|
49
|
+
return upstream(request, signal);
|
|
50
|
+
};
|
|
25
51
|
const declared = parseGrokBrokerModelPolicy(policy);
|
|
26
52
|
const capabilities = new EngineBrokerCapabilities();
|
|
27
53
|
const guards = new Map();
|
|
28
54
|
const turns = new Map();
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
55
|
+
return {
|
|
56
|
+
capabilities,
|
|
57
|
+
registerIsolationGuard(turnId, guard) { guards.set(turnId, guard); },
|
|
58
|
+
revokeIsolationGuard(turnId) { guards.delete(turnId); },
|
|
59
|
+
registerTurn(turnId, turn) {
|
|
60
|
+
turns.set(turnId, {
|
|
61
|
+
policy: parseGrokBrokerModelPolicy(turn.policy), meter: turn.meter,
|
|
62
|
+
...(turn.clock === undefined ? {} : { clock: turn.clock })
|
|
63
|
+
});
|
|
64
|
+
},
|
|
65
|
+
revokeTurn(turnId) { turns.delete(turnId); },
|
|
66
|
+
serve: (request, response) => serve(request, response, authority, admittedUpstream, capabilities, guards, turns, declared, grants)
|
|
67
|
+
};
|
|
33
68
|
}
|
|
34
69
|
/**
|
|
35
70
|
* A refusal the caller must not retry.
|
|
@@ -55,7 +90,7 @@ async function serve(request, response, authority, upstream, capabilities, guard
|
|
|
55
90
|
// child and launcher diagnostics are. Nothing reads them but {@link brokerFaultCause}.
|
|
56
91
|
const secrets = [];
|
|
57
92
|
try {
|
|
58
|
-
|
|
93
|
+
let body = await readBody(request);
|
|
59
94
|
const headers = Object.fromEntries(Object.entries(request.headers).map(([key, value]) => [key, Array.isArray(value) ? value[0] : value]));
|
|
60
95
|
titleSink = headers.authorization === `Bearer ${GROK_SESSION_TITLE_SINK_KEY}`;
|
|
61
96
|
const match = headers.authorization?.match(/^Bearer ([A-Za-z0-9_-]{40,})$/u);
|
|
@@ -78,6 +113,17 @@ async function serve(request, response, authority, upstream, capabilities, guard
|
|
|
78
113
|
catch (error) {
|
|
79
114
|
throw new GrokBrokerProxyRefusal("worker_isolation_unverified");
|
|
80
115
|
}
|
|
116
|
+
// Neutralize engine context before the existing body gate or bearer read.
|
|
117
|
+
// The clock belongs to this turn, never to the slot's installed variant.
|
|
118
|
+
try {
|
|
119
|
+
if (turn.clock !== undefined)
|
|
120
|
+
body = Buffer.from(turn.clock.rewrite(body));
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
if (error instanceof GrokBrokerProviderClockRefusal)
|
|
124
|
+
throw new GrokBrokerProxyRefusal(error.reason);
|
|
125
|
+
throw error;
|
|
126
|
+
}
|
|
81
127
|
// A fenced realm is not a transient fault: the credential is gone until an
|
|
82
128
|
// operator re-logs in, and 503 made Grok blind-retry it (observed: fifteen
|
|
83
129
|
// retries over five minutes, $0 spent, nothing learned). Named, 400, and
|
|
@@ -102,7 +148,7 @@ async function serve(request, response, authority, upstream, capabilities, guard
|
|
|
102
148
|
response.end('{"error":"turn request in flight"}');
|
|
103
149
|
return;
|
|
104
150
|
}
|
|
105
|
-
settle = (usage, toolCalls) => { turn.meter.settle(admission.index, usage, body.byteLength, toolCalls); settle = undefined; };
|
|
151
|
+
settle = (usage, toolCalls, finalReply) => { turn.meter.settle(admission.index, usage, body.byteLength, toolCalls, finalReply); settle = undefined; };
|
|
106
152
|
let result = await upstream(prepared, admission.signal);
|
|
107
153
|
if (result.status === 401) {
|
|
108
154
|
token = authority.refreshAfterRejection ? await authority.refreshAfterRejection(rejectedDigest) : await authority.accessToken(true);
|
|
@@ -118,12 +164,21 @@ async function serve(request, response, authority, upstream, capabilities, guard
|
|
|
118
164
|
// is already buffered here for its usage block, so what the model tried to
|
|
119
165
|
// call is in hand. A decoder fault records no attempt rather than a false
|
|
120
166
|
// empty one, and never disturbs the turn.
|
|
121
|
-
|
|
167
|
+
// A successful answer that called nothing and stopped is the turn's final
|
|
168
|
+
// reply: the broker ends a worker that finished but did not exit on it
|
|
169
|
+
// (`grokEngineBrokerTurnEnd.ts`), and reports it when the launcher refused
|
|
170
|
+
// the worker's stdout. Observation only, exactly like the tool names.
|
|
171
|
+
settle?.(usageOrEstimate(result.body, result.headers["content-type"]), toolCallsOrNothing(result.body, result.headers["content-type"]), result.status === 200 ? finalReplyOrNothing(result.body, result.headers["content-type"]) : undefined);
|
|
122
172
|
response.writeHead(result.status, { "content-type": result.headers["content-type"] ?? "application/json", "cache-control": "no-store" });
|
|
123
173
|
response.end(result.body);
|
|
124
174
|
}
|
|
125
175
|
catch (error) {
|
|
126
176
|
settle?.(undefined);
|
|
177
|
+
if (error instanceof GrokBrokerRunLimit) {
|
|
178
|
+
response.writeHead(429, { "content-type": "application/json", "cache-control": "no-store" });
|
|
179
|
+
response.end('{"error":"run_request_limit"}');
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
127
182
|
// Name the refusal on the broker's own stderr (reason code only, never a body
|
|
128
183
|
// or a token) so a failing turn is diagnosable without a stub harness —
|
|
129
184
|
// except for the two requests every healthy turn makes anyway.
|
|
@@ -243,6 +298,15 @@ const toolCallsOrNothing = (body, contentType) => {
|
|
|
243
298
|
return undefined;
|
|
244
299
|
}
|
|
245
300
|
};
|
|
301
|
+
/** Instrumentation must never fail a turn: a throwing decoder reports no final reply. */
|
|
302
|
+
const finalReplyOrNothing = (body, contentType) => {
|
|
303
|
+
try {
|
|
304
|
+
return parseGrokFinalReply(body, contentType);
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
return undefined;
|
|
308
|
+
}
|
|
309
|
+
};
|
|
246
310
|
/** The body gate, refused non-retryably: a rejected body is a policy miss, never a transient fault. */
|
|
247
311
|
function authorizeRequestOrRefuse(...args) {
|
|
248
312
|
try {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preserve ordinary JSON bytes, including whitespace and escaping. Ambiguous
|
|
3
|
+
* duplicate members still normalize to the validated values, as the spend gate
|
|
4
|
+
* requires: an upstream parser must never select a different model or tool set.
|
|
5
|
+
*/
|
|
6
|
+
export declare function parseGrokBrokerProxyJson(body: Uint8Array): {
|
|
7
|
+
value: Record<string, unknown>;
|
|
8
|
+
body: Uint8Array;
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=grokBrokerProxyJson.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grokBrokerProxyJson.d.ts","sourceRoot":"","sources":["../../src/runtime/grokBrokerProxyJson.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,UAAU,GAAG;IAC1D,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,IAAI,EAAE,UAAU,CAAC;CAClB,CAuBA"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preserve ordinary JSON bytes, including whitespace and escaping. Ambiguous
|
|
3
|
+
* duplicate members still normalize to the validated values, as the spend gate
|
|
4
|
+
* requires: an upstream parser must never select a different model or tool set.
|
|
5
|
+
*/
|
|
6
|
+
export function parseGrokBrokerProxyJson(body) {
|
|
7
|
+
const source = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(body);
|
|
8
|
+
let properties = 0;
|
|
9
|
+
const value = JSON.parse(source, (key, entry) => {
|
|
10
|
+
if (key === "__proto__")
|
|
11
|
+
throw new Error("broker proxy request rejected");
|
|
12
|
+
if (entry !== null && typeof entry === "object" && !Array.isArray(entry)) {
|
|
13
|
+
properties += Object.keys(entry).length;
|
|
14
|
+
}
|
|
15
|
+
return entry;
|
|
16
|
+
});
|
|
17
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
18
|
+
throw new Error("broker proxy request rejected");
|
|
19
|
+
}
|
|
20
|
+
// JSON.parse established the grammar. Match whole string tokens (including
|
|
21
|
+
// escaped quotes), so a colon inside message content cannot count as a key.
|
|
22
|
+
let sourceProperties = 0;
|
|
23
|
+
for (const token of source.matchAll(/"(?:[^"\\]|\\[\s\S])*"\s*(:)?/gu)) {
|
|
24
|
+
if (token[1] !== undefined)
|
|
25
|
+
sourceProperties++;
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
value: value,
|
|
29
|
+
body: sourceProperties === properties ? body : Buffer.from(JSON.stringify(value))
|
|
30
|
+
};
|
|
31
|
+
}
|
|
@@ -1 +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,
|
|
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,CAmChO;AASD,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAStD"}
|
|
@@ -34,8 +34,11 @@ export function authorizeGrokBrokerProxyRequest(input, capabilities, bearer, pol
|
|
|
34
34
|
// `__proto__` is refused at any depth: JSON.parse makes it an ordinary own
|
|
35
35
|
// member, but an upstream JavaScript parser may treat it as a prototype.
|
|
36
36
|
try {
|
|
37
|
-
parsed = JSON.parse(Buffer.from(input.body).toString("utf8"), (key, value) => {
|
|
38
|
-
|
|
37
|
+
parsed = JSON.parse(Buffer.from(input.body).toString("utf8"), (key, value) => {
|
|
38
|
+
if (key === "__proto__")
|
|
39
|
+
throw new Error("broker proxy request rejected");
|
|
40
|
+
return value;
|
|
41
|
+
});
|
|
39
42
|
}
|
|
40
43
|
catch {
|
|
41
44
|
throw new Error("broker proxy request rejected");
|
|
@@ -48,10 +51,18 @@ export function authorizeGrokBrokerProxyRequest(input, capabilities, bearer, pol
|
|
|
48
51
|
throw new Error("broker proxy request rejected");
|
|
49
52
|
if (Object.keys(parsed).some((key) => !LEAN_BODY_MEMBERS.has(key)) || !validStreamOptions(parsed.stream_options))
|
|
50
53
|
throw new Error("broker proxy request rejected");
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
//
|
|
54
|
-
return {
|
|
54
|
+
// Keep origin/main's production handling: UTF-8 replacement decoding, then
|
|
55
|
+
// serialize the validated object (including last-member-wins duplicates).
|
|
56
|
+
// Only a clocked turn takes the stricter date rewrite before this gate.
|
|
57
|
+
return {
|
|
58
|
+
url: "https://cli-chat-proxy.grok.com/v1/chat/completions",
|
|
59
|
+
headers: {
|
|
60
|
+
authorization: `Bearer ${bearer}`, "content-type": "application/json",
|
|
61
|
+
"x-xai-token-auth": "xai-grok-cli", "x-grok-model-override": declared.model,
|
|
62
|
+
"x-grok-client-version": clientVersion, "x-grok-client-identifier": "grok-shell"
|
|
63
|
+
},
|
|
64
|
+
body: Buffer.from(JSON.stringify(parsed))
|
|
65
|
+
};
|
|
55
66
|
}
|
|
56
67
|
/** Top-level members of a Grok 1.0.34 lean worker chat-completions body (live stub capture). */
|
|
57
68
|
const LEAN_BODY_MEMBERS = new Set(["messages", "model", "reasoning_effort", "stream", "stream_options", "tools"]);
|