@noopolis/daimon 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (255) hide show
  1. package/README.md +6 -0
  2. package/dist/contracts/attentionContract.d.ts +25 -0
  3. package/dist/contracts/attentionContract.d.ts.map +1 -1
  4. package/dist/contracts/attentionContract.js +8 -1
  5. package/dist/contracts/grokBrokerTaskClock.d.ts +18 -0
  6. package/dist/contracts/grokBrokerTaskClock.d.ts.map +1 -0
  7. package/dist/contracts/grokBrokerTaskClock.js +16 -0
  8. package/dist/contracts/organizationRuntimeContract.d.ts +76 -0
  9. package/dist/contracts/organizationRuntimeContract.d.ts.map +1 -1
  10. package/dist/contracts/organizationRuntimeContract.js +2 -0
  11. package/dist/contracts/runtimeContractManifest.d.ts +222 -15
  12. package/dist/contracts/runtimeContractManifest.d.ts.map +1 -1
  13. package/dist/contracts/runtimeContractManifest.js +35 -10
  14. package/dist/contracts/shellEnvironmentPolicy.d.ts +3 -0
  15. package/dist/contracts/shellEnvironmentPolicy.d.ts.map +1 -0
  16. package/dist/contracts/shellEnvironmentPolicy.js +5 -0
  17. package/dist/contracts/wakeMomentContract.d.ts +61 -0
  18. package/dist/contracts/wakeMomentContract.d.ts.map +1 -0
  19. package/dist/contracts/wakeMomentContract.js +27 -0
  20. package/dist/core/types.d.ts +2 -0
  21. package/dist/core/types.d.ts.map +1 -1
  22. package/dist/examples/jungianPlayAgent.d.ts +1 -0
  23. package/dist/examples/jungianPlayAgent.d.ts.map +1 -1
  24. package/dist/examples/jungianPlayAgent.js +6 -2
  25. package/dist/observability/causalEvents.d.ts +3 -3
  26. package/dist/observability/causalEvents.d.ts.map +1 -1
  27. package/dist/observability/causalEvents.js +4 -4
  28. package/dist/pi/cliEngineSpawn.d.ts +2 -2
  29. package/dist/pi/cliEngineSpawn.d.ts.map +1 -1
  30. package/dist/pi/cliEngineSpawn.js +7 -2
  31. package/dist/pi/cliEnvironment.d.ts.map +1 -1
  32. package/dist/pi/cliEnvironment.js +2 -0
  33. package/dist/pi/cliMcpRegistration.d.ts +1 -1
  34. package/dist/pi/cliMcpRegistration.d.ts.map +1 -1
  35. package/dist/pi/cliMcpRegistration.js +1 -1
  36. package/dist/pi/cliSession.d.ts +2 -0
  37. package/dist/pi/cliSession.d.ts.map +1 -1
  38. package/dist/pi/cliSession.js +3 -80
  39. package/dist/pi/cliSessionMcp.d.ts +9 -0
  40. package/dist/pi/cliSessionMcp.d.ts.map +1 -0
  41. package/dist/pi/cliSessionMcp.js +80 -0
  42. package/dist/pi/engineTaskClock.d.ts +9 -0
  43. package/dist/pi/engineTaskClock.d.ts.map +1 -0
  44. package/dist/pi/engineTaskClock.js +28 -0
  45. package/dist/pi/grokHomeMcpRegistration.d.ts.map +1 -1
  46. package/dist/pi/grokHomeMcpRegistration.js +2 -1
  47. package/dist/pi/grokSandbox.js +1 -1
  48. package/dist/pi/memoryClock.d.ts +25 -0
  49. package/dist/pi/memoryClock.d.ts.map +1 -0
  50. package/dist/pi/memoryClock.js +18 -0
  51. package/dist/pi/piAgentHandle.d.ts +3 -1
  52. package/dist/pi/piAgentHandle.d.ts.map +1 -1
  53. package/dist/pi/piAgentHandle.js +5 -2
  54. package/dist/pi/piHarness.d.ts +8 -2
  55. package/dist/pi/piHarness.d.ts.map +1 -1
  56. package/dist/pi/piHarness.js +28 -12
  57. package/dist/pi/taskClockProcess.d.ts +6 -0
  58. package/dist/pi/taskClockProcess.d.ts.map +1 -0
  59. package/dist/pi/taskClockProcess.js +8 -0
  60. package/dist/pi/turnCausal.d.ts +4 -2
  61. package/dist/pi/turnCausal.d.ts.map +1 -1
  62. package/dist/pi/turnCausal.js +4 -4
  63. package/dist/pi/wakeAcceptance.d.ts +1 -1
  64. package/dist/pi/wakeAcceptance.d.ts.map +1 -1
  65. package/dist/pi/wakeAcceptance.js +2 -2
  66. package/dist/runtime/agySubscriptionBootstrap.js +1 -1
  67. package/dist/runtime/agySubscriptionRealm.js +1 -1
  68. package/dist/runtime/attention.d.ts +5 -0
  69. package/dist/runtime/attention.d.ts.map +1 -1
  70. package/dist/runtime/attention.js +14 -1
  71. package/dist/runtime/attentionDispatcher.d.ts +14 -2
  72. package/dist/runtime/attentionDispatcher.d.ts.map +1 -1
  73. package/dist/runtime/attentionDispatcher.js +127 -33
  74. package/dist/runtime/cli.js +5 -0
  75. package/dist/runtime/contract-manifest.json +1 -1
  76. package/dist/runtime/contract-manifest.sha256 +1 -1
  77. package/dist/runtime/engineBrokerCapabilities.d.ts +10 -0
  78. package/dist/runtime/engineBrokerCapabilities.d.ts.map +1 -1
  79. package/dist/runtime/engineBrokerCapabilities.js +10 -0
  80. package/dist/runtime/engineBrokerControlClient.d.ts +12 -1
  81. package/dist/runtime/engineBrokerControlClient.d.ts.map +1 -1
  82. package/dist/runtime/engineBrokerControlClient.js +139 -43
  83. package/dist/runtime/engineBrokerCredentialJournal.d.ts +2 -0
  84. package/dist/runtime/engineBrokerCredentialJournal.d.ts.map +1 -1
  85. package/dist/runtime/engineBrokerCredentialJournal.js +9 -0
  86. package/dist/runtime/engineBrokerInferenceProtocol.d.ts +3 -2
  87. package/dist/runtime/engineBrokerInferenceProtocol.d.ts.map +1 -1
  88. package/dist/runtime/engineBrokerInferenceProtocol.js +4 -4
  89. package/dist/runtime/engineBrokerMcpCallLog.d.ts +11 -0
  90. package/dist/runtime/engineBrokerMcpCallLog.d.ts.map +1 -1
  91. package/dist/runtime/engineBrokerMcpCallLog.js +13 -1
  92. package/dist/runtime/engineBrokerMcpFacade.d.ts +5 -2
  93. package/dist/runtime/engineBrokerMcpFacade.d.ts.map +1 -1
  94. package/dist/runtime/engineBrokerMcpFacade.js +5 -2
  95. package/dist/runtime/engineBrokerNativeClient.js +2 -2
  96. package/dist/runtime/engineBrokerProtocol.d.ts +42 -10
  97. package/dist/runtime/engineBrokerProtocol.d.ts.map +1 -1
  98. package/dist/runtime/engineBrokerProtocol.js +97 -14
  99. package/dist/runtime/engineBrokerSealLedger.d.ts.map +1 -1
  100. package/dist/runtime/engineBrokerSealLedger.js +9 -0
  101. package/dist/runtime/engineBrokerService.d.ts +8 -2
  102. package/dist/runtime/engineBrokerService.d.ts.map +1 -1
  103. package/dist/runtime/engineBrokerService.js +95 -37
  104. package/dist/runtime/engineBrokerServiceCli.js +1 -1
  105. package/dist/runtime/engineBrokerServiceConfig.d.ts +5 -0
  106. package/dist/runtime/engineBrokerServiceConfig.d.ts.map +1 -1
  107. package/dist/runtime/engineBrokerServiceConfig.js +47 -9
  108. package/dist/runtime/engineBrokerTurnRegistry.d.ts +1 -1
  109. package/dist/runtime/engineBrokerTurnRegistry.d.ts.map +1 -1
  110. package/dist/runtime/engineBrokerTurnRegistry.js +7 -6
  111. package/dist/runtime/engineDispatcher.d.ts +2 -0
  112. package/dist/runtime/engineDispatcher.d.ts.map +1 -1
  113. package/dist/runtime/engineDispatcher.js +14 -2
  114. package/dist/runtime/engineReadiness.js +1 -1
  115. package/dist/runtime/grokBrokerCredentialAuthority.d.ts +1 -0
  116. package/dist/runtime/grokBrokerCredentialAuthority.d.ts.map +1 -1
  117. package/dist/runtime/grokBrokerCredentialAuthority.js +48 -22
  118. package/dist/runtime/grokBrokerCredentialReader.d.ts +1 -0
  119. package/dist/runtime/grokBrokerCredentialReader.d.ts.map +1 -1
  120. package/dist/runtime/grokBrokerCredentialReader.js +2 -1
  121. package/dist/runtime/grokBrokerProjection.d.ts +9 -1
  122. package/dist/runtime/grokBrokerProjection.d.ts.map +1 -1
  123. package/dist/runtime/grokBrokerProjection.js +11 -4
  124. package/dist/runtime/grokBrokerProviderClock.d.ts +26 -0
  125. package/dist/runtime/grokBrokerProviderClock.d.ts.map +1 -0
  126. package/dist/runtime/grokBrokerProviderClock.js +133 -0
  127. package/dist/runtime/grokBrokerProxy.d.ts +17 -3
  128. package/dist/runtime/grokBrokerProxy.d.ts.map +1 -1
  129. package/dist/runtime/grokBrokerProxy.js +73 -9
  130. package/dist/runtime/grokBrokerProxyJson.d.ts +10 -0
  131. package/dist/runtime/grokBrokerProxyJson.d.ts.map +1 -0
  132. package/dist/runtime/grokBrokerProxyJson.js +31 -0
  133. package/dist/runtime/grokBrokerProxyRequest.d.ts.map +1 -1
  134. package/dist/runtime/grokBrokerProxyRequest.js +17 -6
  135. package/dist/runtime/grokBrokerRealmLease.js +1 -1
  136. package/dist/runtime/grokBrokerRefresh.js +1 -1
  137. package/dist/runtime/grokBrokerRunBudget.d.ts +20 -0
  138. package/dist/runtime/grokBrokerRunBudget.d.ts.map +1 -0
  139. package/dist/runtime/grokBrokerRunBudget.js +85 -0
  140. package/dist/runtime/grokBrokerSlot.d.ts +6 -0
  141. package/dist/runtime/grokBrokerSlot.d.ts.map +1 -0
  142. package/dist/runtime/grokBrokerSlot.js +21 -0
  143. package/dist/runtime/grokBrokerTaskClock.d.ts +32 -0
  144. package/dist/runtime/grokBrokerTaskClock.d.ts.map +1 -0
  145. package/dist/runtime/grokBrokerTaskClock.js +120 -0
  146. package/dist/runtime/grokBrokerTurnMeter.d.ts +55 -3
  147. package/dist/runtime/grokBrokerTurnMeter.d.ts.map +1 -1
  148. package/dist/runtime/grokBrokerTurnMeter.js +90 -4
  149. package/dist/runtime/grokBrokerWorkerConfig.d.ts +5 -2
  150. package/dist/runtime/grokBrokerWorkerConfig.d.ts.map +1 -1
  151. package/dist/runtime/grokBrokerWorkerConfig.js +22 -3
  152. package/dist/runtime/grokEngineBroker.d.ts +43 -3
  153. package/dist/runtime/grokEngineBroker.d.ts.map +1 -1
  154. package/dist/runtime/grokEngineBroker.js +159 -71
  155. package/dist/runtime/grokEngineBrokerTurn.d.ts +32 -8
  156. package/dist/runtime/grokEngineBrokerTurn.d.ts.map +1 -1
  157. package/dist/runtime/grokEngineBrokerTurn.js +204 -21
  158. package/dist/runtime/grokEngineBrokerTurnEnd.d.ts +88 -0
  159. package/dist/runtime/grokEngineBrokerTurnEnd.d.ts.map +1 -0
  160. package/dist/runtime/grokEngineBrokerTurnEnd.js +148 -0
  161. package/dist/runtime/grokInferenceProxy.d.ts.map +1 -1
  162. package/dist/runtime/grokInferenceProxy.js +3 -0
  163. package/dist/runtime/grokSubscriptionRealm.js +1 -1
  164. package/dist/runtime/grokWorkerAttestation.d.ts +9 -4
  165. package/dist/runtime/grokWorkerAttestation.d.ts.map +1 -1
  166. package/dist/runtime/grokWorkerAttestation.js +2 -2
  167. package/dist/runtime/grokWorkerHomeAttestation.d.ts +4 -2
  168. package/dist/runtime/grokWorkerHomeAttestation.d.ts.map +1 -1
  169. package/dist/runtime/grokWorkerHomeAttestation.js +10 -4
  170. package/dist/runtime/index.d.ts +7 -2
  171. package/dist/runtime/index.d.ts.map +1 -1
  172. package/dist/runtime/index.js +5 -1
  173. package/dist/runtime/native/daimon-engine-broker +0 -0
  174. package/dist/runtime/organizationRuntime.d.ts +3 -0
  175. package/dist/runtime/organizationRuntime.d.ts.map +1 -1
  176. package/dist/runtime/organizationRuntimeAdmission.d.ts +6 -0
  177. package/dist/runtime/organizationRuntimeAdmission.d.ts.map +1 -0
  178. package/dist/runtime/organizationRuntimeAdmission.js +22 -0
  179. package/dist/runtime/organizationRuntimeControl.d.ts +9 -0
  180. package/dist/runtime/organizationRuntimeControl.d.ts.map +1 -1
  181. package/dist/runtime/organizationRuntimeControl.js +72 -24
  182. package/dist/runtime/organizationRuntimeHost.d.ts.map +1 -1
  183. package/dist/runtime/organizationRuntimeHost.js +13 -4
  184. package/dist/runtime/organizationRuntimeParsing.d.ts.map +1 -1
  185. package/dist/runtime/organizationRuntimeParsing.js +4 -1
  186. package/dist/runtime/organizationRuntimeReadiness.d.ts.map +1 -1
  187. package/dist/runtime/organizationRuntimeReadiness.js +8 -0
  188. package/dist/runtime/organizationRuntimeRecording.d.ts +7 -0
  189. package/dist/runtime/organizationRuntimeRecording.d.ts.map +1 -0
  190. package/dist/runtime/organizationRuntimeRecording.js +58 -0
  191. package/dist/runtime/physicalReadiness.d.ts +12 -0
  192. package/dist/runtime/physicalReadiness.d.ts.map +1 -1
  193. package/dist/runtime/physicalReadiness.js +43 -9
  194. package/dist/runtime/productionAgentTools.d.ts.map +1 -1
  195. package/dist/runtime/productionAgentTools.js +13 -5
  196. package/dist/runtime/relocateRuntimeConfig.d.ts +14 -0
  197. package/dist/runtime/relocateRuntimeConfig.d.ts.map +1 -0
  198. package/dist/runtime/relocateRuntimeConfig.js +38 -0
  199. package/dist/runtime/schedule.d.ts.map +1 -1
  200. package/dist/runtime/schedule.js +12 -7
  201. package/dist/runtime/storeCoordination.d.ts +10 -0
  202. package/dist/runtime/storeCoordination.d.ts.map +1 -1
  203. package/dist/runtime/storeCoordination.js +23 -0
  204. package/dist/runtime/taskClock.d.ts +42 -0
  205. package/dist/runtime/taskClock.d.ts.map +1 -0
  206. package/dist/runtime/taskClock.js +102 -0
  207. package/dist/runtime/taskClockProcess.d.ts +17 -0
  208. package/dist/runtime/taskClockProcess.d.ts.map +1 -0
  209. package/dist/runtime/taskClockProcess.js +58 -0
  210. package/dist/runtime/turnRequestLedger.d.ts +0 -5
  211. package/dist/runtime/turnRequestLedger.d.ts.map +1 -1
  212. package/dist/runtime/turnRequestLedger.js +23 -21
  213. package/dist/runtime/wakeAcceptanceClaimDiagnostics.d.ts +34 -0
  214. package/dist/runtime/wakeAcceptanceClaimDiagnostics.d.ts.map +1 -0
  215. package/dist/runtime/wakeAcceptanceClaimDiagnostics.js +79 -0
  216. package/dist/runtime/wakeAcceptanceIndex.d.ts +55 -0
  217. package/dist/runtime/wakeAcceptanceIndex.d.ts.map +1 -0
  218. package/dist/runtime/wakeAcceptanceIndex.js +158 -0
  219. package/dist/runtime/wakeAcceptanceProcessIdentity.d.ts +9 -1
  220. package/dist/runtime/wakeAcceptanceProcessIdentity.d.ts.map +1 -1
  221. package/dist/runtime/wakeAcceptanceProcessIdentity.js +5 -1
  222. package/dist/runtime/wakeAcceptanceRecord.d.ts +2 -0
  223. package/dist/runtime/wakeAcceptanceRecord.d.ts.map +1 -1
  224. package/dist/runtime/wakeAcceptanceRecord.js +4 -2
  225. package/dist/runtime/wakeAcceptanceRetention.d.ts +25 -1
  226. package/dist/runtime/wakeAcceptanceRetention.d.ts.map +1 -1
  227. package/dist/runtime/wakeAcceptanceRetention.js +28 -2
  228. package/dist/runtime/wakeAcceptanceStore.d.ts +8 -8
  229. package/dist/runtime/wakeAcceptanceStore.d.ts.map +1 -1
  230. package/dist/runtime/wakeAcceptanceStore.js +66 -63
  231. package/dist/runtime/wakeFuse.d.ts +58 -3
  232. package/dist/runtime/wakeFuse.d.ts.map +1 -1
  233. package/dist/runtime/wakeFuse.js +106 -7
  234. package/dist/runtime/wakeMomentFs.d.ts +27 -0
  235. package/dist/runtime/wakeMomentFs.d.ts.map +1 -0
  236. package/dist/runtime/wakeMomentFs.js +223 -0
  237. package/dist/runtime/wakeMomentHistory.d.ts +26 -0
  238. package/dist/runtime/wakeMomentHistory.d.ts.map +1 -0
  239. package/dist/runtime/wakeMomentHistory.js +109 -0
  240. package/dist/runtime/wakeMomentIo.d.ts +22 -0
  241. package/dist/runtime/wakeMomentIo.d.ts.map +1 -0
  242. package/dist/runtime/wakeMomentIo.js +114 -0
  243. package/dist/runtime/wakeMomentRecorder.d.ts +33 -0
  244. package/dist/runtime/wakeMomentRecorder.d.ts.map +1 -0
  245. package/dist/runtime/wakeMomentRecorder.js +81 -0
  246. package/dist/runtime/wakeMomentRetention.d.ts +7 -0
  247. package/dist/runtime/wakeMomentRetention.d.ts.map +1 -0
  248. package/dist/runtime/wakeMomentRetention.js +143 -0
  249. package/dist/runtime/wakeMomentRows.d.ts +8 -0
  250. package/dist/runtime/wakeMomentRows.d.ts.map +1 -0
  251. package/dist/runtime/wakeMomentRows.js +66 -0
  252. package/dist/runtime/wakeMomentSnapshot.d.ts +56 -0
  253. package/dist/runtime/wakeMomentSnapshot.d.ts.map +1 -0
  254. package/dist/runtime/wakeMomentSnapshot.js +248 -0
  255. package/package.json +4 -4
@@ -1,17 +1,27 @@
1
+ import { type BrokerClockObservation } from "./grokBrokerTaskClock.js";
1
2
  import { type EngineBrokerInferenceRequest, type EngineBrokerInferenceResponse } from "./engineBrokerInferenceProtocol.js";
2
3
  import { type EngineBrokerMcpCallObservation } from "./engineBrokerMcpCallLog.js";
3
4
  import { type EngineBrokerTurnAccounting, type EngineBrokerTurnLimitOverrides } from "./engineBrokerTurnAccounting.js";
4
5
  /**
5
- * Control protocol v2. Both ends ship in the same Daimon package and image
6
- * (organization runtime client, broker service), so the wire moved to v2 in
7
- * one step: v1 frames are refused. v1 survives only as a *durable record*
8
- * shape, which {@link parseEngineBrokerV1TerminalResponse} still reads so
9
- * turns sealed before the upgrade keep replaying.
6
+ * Control protocol v4 adds slot routing and reset. Both ends ship in the same
7
+ * package; v1/v2/v3 frames are refused on the wire. Durable terminal adapters
8
+ * retain those record formats. A missing slot is allowed only for a unique
9
+ * agent registration (unclocked production compatibility).
10
10
  */
11
- declare const VERSION: "noopolis.daimon.engine-broker.v2";
12
- export declare const ENGINE_BROKER_VERSION: "noopolis.daimon.engine-broker.v2";
11
+ declare const VERSION: "noopolis.daimon.engine-broker.v4";
12
+ export declare const ENGINE_BROKER_VERSION: "noopolis.daimon.engine-broker.v4";
13
13
  declare const V1: "noopolis.daimon.engine-broker.v1";
14
14
  export declare const ENGINE_BROKER_MAX_FRAME_BYTES = 1048576;
15
+ /** Version refusal is independent of the incompatible operation's schema. */
16
+ export type EngineBrokerProtocolDiagnostic = Readonly<{
17
+ kind: "protocol_mismatch";
18
+ receivedVersion: string;
19
+ expectedVersion: string;
20
+ }>;
21
+ export declare class EngineBrokerProtocolMismatch extends TypeError {
22
+ readonly diagnostic: EngineBrokerProtocolDiagnostic;
23
+ constructor(received: unknown, expected?: unknown);
24
+ }
15
25
  export type EngineBrokerRequest = Readonly<{
16
26
  version: typeof VERSION;
17
27
  kind: "health";
@@ -21,16 +31,23 @@ export type EngineBrokerRequest = Readonly<{
21
31
  kind: "start_turn";
22
32
  requestId: string;
23
33
  turnId: string;
34
+ slot?: number;
24
35
  agentId: string;
25
36
  wakeId: string;
26
37
  prompt: string;
27
38
  mcpEndpoint: string;
28
39
  limits?: EngineBrokerTurnLimitOverrides;
40
+ processClock?: string;
29
41
  }> | Readonly<{
30
42
  version: typeof VERSION;
31
43
  kind: "cancel_turn";
32
44
  requestId: string;
33
45
  turnId: string;
46
+ }> | Readonly<{
47
+ version: typeof VERSION;
48
+ kind: "reset_slot";
49
+ requestId: string;
50
+ slot: number;
34
51
  }> | EngineBrokerInferenceRequest;
35
52
  /**
36
53
  * `reason` is the worker's own last words (`engineBrokerNativeClient.ts`),
@@ -52,6 +69,11 @@ export interface EngineBrokerFailureDiagnostic {
52
69
  startTicks: string;
53
70
  }
54
71
  export declare const ENGINE_BROKER_MAX_DIAGNOSTIC_REASON_BYTES = 768;
72
+ /** Operational state after sealing; never raw filesystem errors or worker text. */
73
+ export declare const ENGINE_BROKER_TASK_CLOCK_RESET_FAILED = "task clock reset failed; slot fenced until restart";
74
+ export type EngineBrokerCleanupObservation = Readonly<{
75
+ cleanupDiagnostic?: typeof ENGINE_BROKER_TASK_CLOCK_RESET_FAILED;
76
+ }>;
55
77
  export type EngineBrokerResponse = Readonly<{
56
78
  version: typeof VERSION;
57
79
  kind: "ready";
@@ -77,7 +99,7 @@ export type EngineBrokerResponse = Readonly<{
77
99
  workerPid: number;
78
100
  workerUid: number;
79
101
  workerStartTime: string;
80
- }> & EngineBrokerTurnAccounting) | (Readonly<{
102
+ }> & EngineBrokerTurnAccounting & BrokerClockObservation & EngineBrokerCleanupObservation) | (Readonly<{
81
103
  version: typeof VERSION;
82
104
  kind: "failed";
83
105
  requestId: string;
@@ -85,7 +107,12 @@ export type EngineBrokerResponse = Readonly<{
85
107
  code: EngineBrokerFailureCode;
86
108
  diagnostic?: EngineBrokerFailureDiagnostic;
87
109
  mcpCalls?: EngineBrokerMcpCallObservation;
88
- }> & EngineBrokerTurnAccounting) | EngineBrokerInferenceResponse;
110
+ }> & EngineBrokerTurnAccounting & BrokerClockObservation & EngineBrokerCleanupObservation) | Readonly<{
111
+ version: typeof VERSION;
112
+ kind: "slot_reset";
113
+ requestId: string;
114
+ slot: number;
115
+ }> | EngineBrokerInferenceResponse;
89
116
  /**
90
117
  * The one name for a fenced credential realm. The turn's failure code, the
91
118
  * proxy's refusal reason on a worker request, and the grant path's 401 body
@@ -125,7 +152,12 @@ export declare function parseEngineBrokerResponse(value: unknown): EngineBrokerR
125
152
  * the wire.
126
153
  */
127
154
  export declare function parseEngineBrokerV1TerminalResponse(value: unknown): EngineBrokerV1TerminalResponse;
128
- export declare function encodeEngineBrokerFrame(value: EngineBrokerRequest | EngineBrokerResponse): Buffer;
155
+ export declare function parseEngineBrokerSlot(value: unknown): number;
156
+ /** v3 survives only in durable records. */
157
+ export declare function parseEngineBrokerV3TerminalResponse(value: unknown): EngineBrokerTerminalResponse;
158
+ /** v2 survives only in durable records. The wire always refuses it. */
159
+ export declare function parseEngineBrokerV2TerminalResponse(value: unknown): EngineBrokerTerminalResponse;
160
+ export declare function encodeEngineBrokerFrame(value: EngineBrokerRequest | EngineBrokerResponse | EngineBrokerProtocolDiagnostic): Buffer;
129
161
  export declare class EngineBrokerFrameDecoder {
130
162
  private buffered;
131
163
  push(chunk: Uint8Array): unknown[];
@@ -1 +1 @@
1
- {"version":3,"file":"engineBrokerProtocol.d.ts","sourceRoot":"","sources":["../../src/runtime/engineBrokerProtocol.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"engineBrokerProtocol.d.ts","sourceRoot":"","sources":["../../src/runtime/engineBrokerProtocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,KAAK,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAEhG,OAAO,EAAkJ,KAAK,4BAA4B,EAAE,KAAK,6BAA6B,EAAE,MAAM,oCAAoC,CAAC;AAC3Q,OAAO,EAAmI,KAAK,8BAA8B,EAAiF,MAAM,6BAA6B,CAAC;AAClS,OAAO,EAAwE,KAAK,0BAA0B,EAAE,KAAK,8BAA8B,EAAE,MAAM,iCAAiC,CAAC;AAE7L;;;;;GAKG;AACH,QAAA,MAAM,OAAO,EAAG,kCAA2C,CAAC;AAC5D,eAAO,MAAM,qBAAqB,oCAAU,CAAC;AAC7C,QAAA,MAAM,EAAE,EAAG,kCAA2C,CAAC;AACvD,eAAO,MAAM,6BAA6B,UAAY,CAAC;AAKvD,6EAA6E;AAC7E,MAAM,MAAM,8BAA8B,GAAG,QAAQ,CAAC;IACpD,IAAI,EAAE,mBAAmB,CAAC;IAAC,eAAe,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAC;CAC7E,CAAC,CAAC;AAEH,qBAAa,4BAA6B,SAAQ,SAAS;IACzD,QAAQ,CAAC,UAAU,EAAE,8BAA8B,CAAC;gBACxC,QAAQ,EAAE,OAAO,EAAE,QAAQ,GAAE,OAAiB;CAM3D;AAGD,MAAM,MAAM,mBAAmB,GAC3B,QAAQ,CAAC;IAAE,OAAO,EAAE,OAAO,OAAO,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,GACxE,QAAQ,CAAC;IAAE,OAAO,EAAE,OAAO,OAAO,CAAC;IAAC,IAAI,EAAE,YAAY,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,8BAA8B,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GACjP,QAAQ,CAAC;IAAE,OAAO,EAAE,OAAO,OAAO,CAAC;IAAC,IAAI,EAAE,aAAa,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,GAC7F,QAAQ,CAAC;IAAE,OAAO,EAAE,OAAO,OAAO,CAAC;IAAC,IAAI,EAAE,YAAY,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAC1F,4BAA4B,CAAC;AAEjC;;;;;;GAMG;AACH,MAAM,WAAW,6BAA6B;IAAG,MAAM,EAAC,MAAM,CAAC;IAAA,KAAK,EAAC,MAAM,CAAC;IAAA,YAAY,EAAC,MAAM,CAAC;IAAA,cAAc,EAAC,OAAO,CAAC;IAAA,MAAM,CAAC,EAAC,MAAM,CAAC;IAAA,QAAQ,EAAC,MAAM,CAAC;IAAA,UAAU,EAAC,MAAM,CAAC;IAAA,SAAS,EAAC,MAAM,CAAC;IAAA,SAAS,EAAC,MAAM,CAAC;IAAA,UAAU,EAAC,MAAM,CAAA;CAAE;AAC7N,eAAO,MAAM,yCAAyC,MAAM,CAAC;AAE7D,mFAAmF;AACnF,eAAO,MAAM,qCAAqC,uDAAuD,CAAC;AAC1G,MAAM,MAAM,8BAA8B,GAAG,QAAQ,CAAC;IACpD,iBAAiB,CAAC,EAAE,OAAO,qCAAqC,CAAC;CAClE,CAAC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAC5B,QAAQ,CAAC;IAAE,OAAO,EAAE,OAAO,OAAO,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,IAAI,CAAC;IAAC,iBAAiB,EAAE,KAAK,CAAC;IAAC,aAAa,EAAE,KAAK,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,KAAK,CAAC;IAAC,UAAU,EAAE,IAAI,CAAC;IAAC,eAAe,EAAE,IAAI,CAAA;CAAE,CAAC,GAChO,QAAQ,CAAC;IAAE,OAAO,EAAE,OAAO,OAAO,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,GAC1F,CAAC,QAAQ,CAAC;IACV,OAAO,EAAE,OAAO,OAAO,CAAC;IAAC,IAAI,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAC9E,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAC;CAC7E,CAAC,GAAG,0BAA0B,GAAG,sBAAsB,GAAG,8BAA8B,CAAC,GACxF,CAAC,QAAQ,CAAC;IACV,OAAO,EAAE,OAAO,OAAO,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAC3E,IAAI,EAAE,uBAAuB,CAAC;IAAC,UAAU,CAAC,EAAE,6BAA6B,CAAC;IAC1E,QAAQ,CAAC,EAAE,8BAA8B,CAAC;CAC3C,CAAC,GAAG,0BAA0B,GAAG,sBAAsB,GAAG,8BAA8B,CAAC,GACxF,QAAQ,CAAC;IAAE,OAAO,EAAE,OAAO,OAAO,CAAC;IAAC,IAAI,EAAE,YAAY,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAC1F,6BAA6B,CAAC;AAClC;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,EAAG,YAAqB,CAAC;AAC9D,eAAO,MAAM,2BAA2B,4HAAyI,CAAC;AAClL,MAAM,MAAM,uBAAuB,GAAG,CAAC,OAAO,2BAA2B,CAAC,CAAC,MAAM,CAAC,CAAC;AACnF,MAAM,MAAM,4BAA4B,GAAG,OAAO,CAAC,oBAAoB,EAAE;IAAE,IAAI,EAAE,WAAW,GAAG,QAAQ,CAAA;CAAE,CAAC,CAAC;AAC3G,KAAK,WAAW,GAAG,QAAQ,CAAC;IAAE,OAAO,EAAE,OAAO,EAAE,CAAC;IAAC,IAAI,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AACvL,KAAK,QAAQ,GAAG,QAAQ,CAAC;IAAE,OAAO,EAAE,OAAO,EAAE,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC,uBAAuB,EAAE,gBAAgB,CAAC,CAAC;IAAC,UAAU,CAAC,EAAE,6BAA6B,CAAA;CAAE,CAAC,CAAC;AAC1M,MAAM,MAAM,8BAA8B,GAAG,WAAW,GAAG,QAAQ,CAAC;AAqBpE,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,CAuB5E;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,oBAAoB,CAsB9E;AAED;;;;GAIG;AACH,wBAAgB,mCAAmC,CAAC,KAAK,EAAE,OAAO,GAAG,8BAA8B,CAGlG;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAG5D;AAED,2CAA2C;AAC3C,wBAAgB,mCAAmC,CAAC,KAAK,EAAE,OAAO,GAAG,4BAA4B,CAIhG;AAED,uEAAuE;AACvE,wBAAgB,mCAAmC,CAAC,KAAK,EAAE,OAAO,GAAG,4BAA4B,CAShG;AA8HD,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,mBAAmB,GAAG,oBAAoB,GAAG,8BAA8B,GACjF,MAAM,CAIR;AAED,qBAAa,wBAAwB;IACnC,OAAO,CAAC,QAAQ,CAAmB;IACnC,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,EAAE;IAYlC,MAAM,IAAI,IAAI;CACf"}
@@ -1,19 +1,33 @@
1
+ import { parseBrokerProcessClock } from "./grokBrokerTaskClock.js";
2
+ import { parseGrokBrokerProviderClockObservation } from "./grokBrokerProviderClock.js";
1
3
  import { isEngineBrokerInferenceRequestKind, isEngineBrokerInferenceResponseKind, parseEngineBrokerInferenceRequest, parseEngineBrokerInferenceResponse } from "./engineBrokerInferenceProtocol.js";
2
4
  import { ENGINE_BROKER_MCP_CALL_NAME, ENGINE_BROKER_MCP_OUTSTANDING_MAX, ENGINE_BROKER_MCP_REFUSAL_REASONS, ENGINE_BROKER_MCP_TUNNEL_MAX } from "./engineBrokerMcpCallLog.js";
3
5
  import { parseEngineBrokerTurnAccounting, parseEngineBrokerTurnLimitOverrides } from "./engineBrokerTurnAccounting.js";
4
6
  /**
5
- * Control protocol v2. Both ends ship in the same Daimon package and image
6
- * (organization runtime client, broker service), so the wire moved to v2 in
7
- * one step: v1 frames are refused. v1 survives only as a *durable record*
8
- * shape, which {@link parseEngineBrokerV1TerminalResponse} still reads so
9
- * turns sealed before the upgrade keep replaying.
7
+ * Control protocol v4 adds slot routing and reset. Both ends ship in the same
8
+ * package; v1/v2/v3 frames are refused on the wire. Durable terminal adapters
9
+ * retain those record formats. A missing slot is allowed only for a unique
10
+ * agent registration (unclocked production compatibility).
10
11
  */
11
- const VERSION = "noopolis.daimon.engine-broker.v2";
12
+ const VERSION = "noopolis.daimon.engine-broker.v4";
12
13
  export const ENGINE_BROKER_VERSION = VERSION;
13
14
  const V1 = "noopolis.daimon.engine-broker.v1";
14
15
  export const ENGINE_BROKER_MAX_FRAME_BYTES = 1_048_576;
16
+ const PROTOCOL_NAME = /^noopolis\.daimon\.engine-broker\.v[0-9]{1,6}$/u;
17
+ const boundedProtocol = (value) => typeof value === "string" && PROTOCOL_NAME.test(value) ? value : "<invalid>";
18
+ export class EngineBrokerProtocolMismatch extends TypeError {
19
+ diagnostic;
20
+ constructor(received, expected = VERSION) {
21
+ const receivedVersion = boundedProtocol(received);
22
+ const expectedVersion = boundedProtocol(expected);
23
+ super(`invalid broker frame: protocol version mismatch (received ${receivedVersion}; expected ${expectedVersion})`);
24
+ this.diagnostic = { kind: "protocol_mismatch", receivedVersion, expectedVersion };
25
+ }
26
+ }
15
27
  const ID = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
16
28
  export const ENGINE_BROKER_MAX_DIAGNOSTIC_REASON_BYTES = 768;
29
+ /** Operational state after sealing; never raw filesystem errors or worker text. */
30
+ export const ENGINE_BROKER_TASK_CLOCK_RESET_FAILED = "task clock reset failed; slot fenced until restart";
17
31
  /**
18
32
  * The one name for a fenced credential realm. The turn's failure code, the
19
33
  * proxy's refusal reason on a worker request, and the grant path's 401 body
@@ -39,8 +53,11 @@ const text = (value, maxBytes) => {
39
53
  };
40
54
  const id = (value) => { const result = text(value, 128); if (!ID.test(result))
41
55
  throw new TypeError("invalid broker frame"); return result; };
42
- const version = (value) => { if (value !== VERSION)
43
- throw new TypeError("invalid broker frame"); return VERSION; };
56
+ const version = (value) => {
57
+ if (value !== VERSION)
58
+ throw new EngineBrokerProtocolMismatch(value);
59
+ return VERSION;
60
+ };
44
61
  export function parseEngineBrokerRequest(value) {
45
62
  const input = record(value);
46
63
  version(input.version);
@@ -50,7 +67,16 @@ export function parseEngineBrokerRequest(value) {
50
67
  }
51
68
  if (input.kind === "start_turn") {
52
69
  const fields = ["version", "kind", "requestId", "turnId", "agentId", "wakeId", "prompt", "mcpEndpoint"];
53
- exact(input, input.limits === undefined ? fields : [...fields, "limits"]);
70
+ exact(input, [...fields, ...(input.slot === undefined ? [] : ["slot"]), ...(input.limits === undefined ? [] : ["limits"]), ...(input.processClock === undefined ? [] : ["processClock"])]);
71
+ let processClock;
72
+ if (input.processClock !== undefined) {
73
+ try {
74
+ processClock = parseBrokerProcessClock(input.processClock);
75
+ }
76
+ catch {
77
+ throw new TypeError("invalid broker frame");
78
+ }
79
+ }
54
80
  const mcpEndpoint = text(input.mcpEndpoint, 2048);
55
81
  const url = new URL(mcpEndpoint);
56
82
  if (url.protocol !== "http:" || url.hostname !== "127.0.0.1" || url.pathname !== "/mcp")
@@ -64,7 +90,11 @@ export function parseEngineBrokerRequest(value) {
64
90
  throw new TypeError("invalid broker frame");
65
91
  }
66
92
  }
67
- return { version: VERSION, kind: "start_turn", requestId: id(input.requestId), turnId: id(input.turnId), agentId: id(input.agentId), wakeId: id(input.wakeId), prompt: text(input.prompt, 65_536), mcpEndpoint, ...(limits === undefined ? {} : { limits }) };
93
+ return { version: VERSION, kind: "start_turn", ...(input.slot === undefined ? {} : { slot: parseEngineBrokerSlot(input.slot) }), requestId: id(input.requestId), turnId: id(input.turnId), agentId: id(input.agentId), wakeId: id(input.wakeId), prompt: text(input.prompt, 65_536), mcpEndpoint, ...(limits === undefined ? {} : { limits }), ...(processClock === undefined ? {} : { processClock }) };
94
+ }
95
+ if (input.kind === "reset_slot") {
96
+ exact(input, ["version", "kind", "requestId", "slot"]);
97
+ return { version: VERSION, kind: "reset_slot", requestId: id(input.requestId), slot: parseEngineBrokerSlot(input.slot) };
68
98
  }
69
99
  if (input.kind === "cancel_turn") {
70
100
  exact(input, ["version", "kind", "requestId", "turnId"]);
@@ -76,6 +106,14 @@ export function parseEngineBrokerRequest(value) {
76
106
  }
77
107
  export function parseEngineBrokerResponse(value) {
78
108
  const input = record(value);
109
+ if (input.kind === "protocol_mismatch") {
110
+ exact(input, ["kind", "receivedVersion", "expectedVersion"]);
111
+ for (const field of [input.receivedVersion, input.expectedVersion]) {
112
+ if (field !== "<invalid>" && boundedProtocol(field) !== field)
113
+ throw new TypeError("invalid broker frame");
114
+ }
115
+ throw new EngineBrokerProtocolMismatch(input.receivedVersion, input.expectedVersion);
116
+ }
79
117
  version(input.version);
80
118
  if (input.kind === "ready") {
81
119
  exact(input, ["version", "kind", "requestId", "brokerUid", "providerProxyPort", "mcpFacadePort", "registrations", "credentialStale", "realmLease", "workerIsolation"]);
@@ -83,6 +121,10 @@ export function parseEngineBrokerResponse(value) {
83
121
  throw new TypeError("invalid broker frame");
84
122
  return { version: VERSION, kind: "ready", requestId: id(input.requestId), brokerUid: 2100, providerProxyPort: 43123, mcpFacadePort: 43124, registrations: input.registrations, credentialStale: false, realmLease: true, workerIsolation: true };
85
123
  }
124
+ if (input.kind === "slot_reset") {
125
+ exact(input, ["version", "kind", "requestId", "slot"]);
126
+ return { version: VERSION, kind: "slot_reset", requestId: id(input.requestId), slot: parseEngineBrokerSlot(input.slot) };
127
+ }
86
128
  if (input.kind === "accepted") {
87
129
  exact(input, ["version", "kind", "requestId", "turnId"]);
88
130
  return { version: VERSION, kind: "accepted", requestId: id(input.requestId), turnId: id(input.turnId) };
@@ -104,21 +146,62 @@ export function parseEngineBrokerV1TerminalResponse(value) {
104
146
  throw new TypeError("invalid broker frame");
105
147
  return parseTerminal(input, V1);
106
148
  }
149
+ export function parseEngineBrokerSlot(value) {
150
+ if (!Number.isSafeInteger(value) || value < 0)
151
+ throw new TypeError("invalid broker slot");
152
+ return value;
153
+ }
154
+ /** v3 survives only in durable records. */
155
+ export function parseEngineBrokerV3TerminalResponse(value) {
156
+ const input = record(value);
157
+ if (input.version !== "noopolis.daimon.engine-broker.v3" || (input.kind !== "completed" && input.kind !== "failed"))
158
+ throw new TypeError("invalid broker frame");
159
+ return parseTerminal({ ...input, version: VERSION }, VERSION);
160
+ }
161
+ /** v2 survives only in durable records. The wire always refuses it. */
162
+ export function parseEngineBrokerV2TerminalResponse(value) {
163
+ const input = record(value);
164
+ if (input.version !== "noopolis.daimon.engine-broker.v2" ||
165
+ (input.kind !== "completed" && input.kind !== "failed") ||
166
+ Object.hasOwn(input, "shellClock") || Object.hasOwn(input, "providerClock") ||
167
+ Object.hasOwn(input, "cleanupDiagnostic")) {
168
+ throw new TypeError("invalid broker frame");
169
+ }
170
+ return parseTerminal({ ...input, version: VERSION }, VERSION);
171
+ }
107
172
  function parseTerminal(input, expected) {
108
173
  const accounting = expected === VERSION ? ACCOUNTING : [];
174
+ const shellClock = input.shellClock;
175
+ if (shellClock !== undefined && (expected !== VERSION || !["task", "real", "gap"].includes(shellClock)))
176
+ throw new TypeError("invalid broker frame");
177
+ if (input.providerClock !== undefined && expected !== VERSION)
178
+ throw new TypeError("invalid broker frame");
179
+ const cleanupDiagnostic = input.cleanupDiagnostic;
180
+ if (cleanupDiagnostic !== undefined &&
181
+ (expected !== VERSION || cleanupDiagnostic !== ENGINE_BROKER_TASK_CLOCK_RESET_FAILED)) {
182
+ throw new TypeError("invalid broker frame");
183
+ }
184
+ const observation = {
185
+ ...(cleanupDiagnostic === undefined ? {} : { cleanupDiagnostic }),
186
+ ...(shellClock === undefined ? {} : { shellClock: shellClock }),
187
+ ...(input.providerClock === undefined ? {} : {
188
+ providerClock: parseGrokBrokerProviderClockObservation(input.providerClock)
189
+ })
190
+ };
191
+ const clockFields = Object.keys(observation);
109
192
  if (input.kind === "completed") {
110
- exact(input, ["version", "kind", "requestId", "turnId", "text", "workerPid", "workerUid", "workerStartTime", ...accounting]);
193
+ exact(input, ["version", "kind", "requestId", "turnId", "text", "workerPid", "workerUid", "workerStartTime", ...accounting, ...clockFields]);
111
194
  if (!Number.isSafeInteger(input.workerPid) || input.workerPid < 1 || !Number.isSafeInteger(input.workerUid) || input.workerUid < 1)
112
195
  throw new TypeError("invalid broker frame");
113
196
  const base = { kind: "completed", requestId: id(input.requestId), turnId: id(input.turnId), text: text(input.text, 262_144), workerPid: input.workerPid, workerUid: input.workerUid, workerStartTime: id(input.workerStartTime) };
114
- return expected === VERSION ? { version: VERSION, ...base, ...parseEngineBrokerTurnAccounting(input, "completed") } : { version: V1, ...base };
197
+ return expected === VERSION ? { version: VERSION, ...base, ...observation, ...parseEngineBrokerTurnAccounting(input, "completed") } : { version: V1, ...base };
115
198
  }
116
199
  // `mcpCalls` is the broker's own observation of the worker's tool calls
117
200
  // (`engineBrokerMcpCallLog.ts`), additive in v2 and never part of a v1
118
201
  // record, which predates the instrument entirely.
119
202
  if (expected === V1 && input.mcpCalls !== undefined)
120
203
  throw new TypeError("invalid broker frame");
121
- const fields = ["version", "kind", "requestId", "turnId", "code", ...accounting, ...(input.diagnostic === undefined ? [] : ["diagnostic"]), ...(input.mcpCalls === undefined ? [] : ["mcpCalls"])];
204
+ const fields = ["version", "kind", "requestId", "turnId", "code", ...accounting, ...clockFields, ...(input.diagnostic === undefined ? [] : ["diagnostic"]), ...(input.mcpCalls === undefined ? [] : ["mcpCalls"])];
122
205
  exact(input, fields);
123
206
  const codes = expected === VERSION ? ENGINE_BROKER_FAILURE_CODES : ENGINE_BROKER_FAILURE_CODES.filter((code) => code !== "limit_exceeded");
124
207
  if (!codes.includes(input.code))
@@ -142,7 +225,7 @@ function parseTerminal(input, expected) {
142
225
  if ((input.code === "limit_exceeded") !== (accountingValue.limitReason !== "none"))
143
226
  throw new TypeError("invalid broker frame");
144
227
  const mcpCalls = input.mcpCalls === undefined ? undefined : parseMcpCallObservation(input.mcpCalls);
145
- return { version: VERSION, ...base, ...(mcpCalls === undefined ? {} : { mcpCalls }), ...accountingValue };
228
+ return { version: VERSION, ...base, ...observation, ...(mcpCalls === undefined ? {} : { mcpCalls }), ...accountingValue };
146
229
  }
147
230
  /**
148
231
  * Names and timings, bounded, and internally consistent: a report can never
@@ -1 +1 @@
1
- {"version":3,"file":"engineBrokerSealLedger.d.ts","sourceRoot":"","sources":["../../src/runtime/engineBrokerSealLedger.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAG9E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,eAAO,MAAM,wBAAwB,EAAG,8BAAuC,CAAC;AAEhF,iFAAiF;AACjF,eAAO,MAAM,gBAAgB;;;;;;CAMnB,CAAC;AAEX,qHAAqH;AACrH,eAAO,MAAM,wBAAwB,OAAQ,CAAC;AAE9C,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAIxF;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,GAAI,UAAU,4BAA4B,EAAE,OAAO,mBAAmB,KAAG,MAyDxG,CAAC"}
1
+ {"version":3,"file":"engineBrokerSealLedger.d.ts","sourceRoot":"","sources":["../../src/runtime/engineBrokerSealLedger.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAG9E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,eAAO,MAAM,wBAAwB,EAAG,8BAAuC,CAAC;AAEhF,iFAAiF;AACjF,eAAO,MAAM,gBAAgB;;;;;;CAMnB,CAAC;AAEX,qHAAqH;AACrH,eAAO,MAAM,wBAAwB,OAAQ,CAAC;AAE9C,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAIxF;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,GAAI,UAAU,4BAA4B,EAAE,OAAO,mBAAmB,KAAG,MAkExG,CAAC"}
@@ -74,6 +74,15 @@ export const renderBrokerTurnSealLine = (terminal, entry) => `${JSON.stringify({
74
74
  requests: terminal.requests,
75
75
  model: terminal.model,
76
76
  limit_reason: terminal.limitReason,
77
+ ...(terminal.shellClock === undefined ? {} : { shell_clock: terminal.shellClock }),
78
+ ...(terminal.providerClock === undefined ? {} : { provider_clock: {
79
+ requests: terminal.providerClock.requests,
80
+ linesRewritten: terminal.providerClock.linesRewritten,
81
+ requestsWithoutDateLine: terminal.providerClock.requestsWithoutDateLine,
82
+ ...(terminal.providerClock.linesIgnored === undefined ? {} : { linesIgnored: terminal.providerClock.linesIgnored }),
83
+ injectedDate: terminal.providerClock.injectedDate,
84
+ taskDate: terminal.providerClock.taskDate
85
+ } }),
77
86
  ...(terminal.kind === "failed" ? { code: terminal.code } : {}),
78
87
  ...(terminal.kind === "failed" && terminal.diagnostic !== undefined
79
88
  ? {
@@ -1,12 +1,15 @@
1
+ import { type BrokerClockObservation } from "./grokBrokerTaskClock.js";
2
+ import { type Socket } from "node:net";
3
+ import { type EngineBrokerCleanupObservation } from "./engineBrokerProtocol.js";
1
4
  import type { EngineBrokerTurnAccounting, EngineBrokerTurnLimitOverrides } from "./engineBrokerTurnAccounting.js";
2
5
  import { type GrokInferenceGrantIssued, type GrokInferenceGrantRequest } from "./grokInferenceGrants.js";
3
6
  export interface EngineBrokerServiceEngine {
4
- turn(agentId: string, wakeId: string, prompt: string, mcpEndpoint: string, signal?: AbortSignal, limits?: EngineBrokerTurnLimitOverrides): Promise<Readonly<{
7
+ turn(agentId: string, wakeId: string, prompt: string, mcpEndpoint: string, signal?: AbortSignal, limits?: EngineBrokerTurnLimitOverrides, processClock?: string, slot?: number): Promise<Readonly<{
5
8
  text: string;
6
9
  workerPid: number;
7
10
  workerUid: number;
8
11
  workerStartTime: string;
9
- }> & EngineBrokerTurnAccounting>;
12
+ }> & EngineBrokerTurnAccounting & BrokerClockObservation & EngineBrokerCleanupObservation>;
10
13
  readiness(): Readonly<{
11
14
  providerProxyPort: number;
12
15
  mcpFacadePort: number;
@@ -16,6 +19,7 @@ export interface EngineBrokerServiceEngine {
16
19
  workerIsolation: boolean;
17
20
  }>;
18
21
  close(): Promise<void>;
22
+ resetSlot?(slot: number): Promise<void>;
19
23
  /** Evaluator inference grants; an engine without them refuses every grant request as `unavailable`. Refusals throw {@link GrokInferenceGrantRefused}. */
20
24
  requestInferenceGrant?(request: GrokInferenceGrantRequest): GrokInferenceGrantIssued;
21
25
  releaseInferenceGrant?(grantId: string): boolean;
@@ -34,4 +38,6 @@ export declare function startEngineBrokerServiceWithIdentity(broker: EngineBroke
34
38
  socketPath: string;
35
39
  };
36
40
  }>;
41
+ /** @internal The production connection handler, also exercised over an in-memory transport. */
42
+ export declare function serveEngineBrokerConnection(socket: Socket, broker: EngineBrokerServiceEngine, active?: Map<string, AbortController>): void;
37
43
  //# sourceMappingURL=engineBrokerService.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"engineBrokerService.d.ts","sourceRoot":"","sources":["../../src/runtime/engineBrokerService.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,0BAA0B,EAAE,8BAA8B,EAAE,MAAM,iCAAiC,CAAC;AAGlH,OAAO,EAA6B,KAAK,wBAAwB,EAAE,KAAK,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACpI,MAAM,WAAW,yBAAyB;IACxC,IAAI,CAAC,OAAO,EAAC,MAAM,EAAC,MAAM,EAAC,MAAM,EAAC,MAAM,EAAC,MAAM,EAAC,WAAW,EAAC,MAAM,EAAC,MAAM,CAAC,EAAC,WAAW,EAAC,MAAM,CAAC,EAAC,8BAA8B,GAAE,OAAO,CAAC,QAAQ,CAAC;QAAC,IAAI,EAAC,MAAM,CAAC;QAAA,SAAS,EAAC,MAAM,CAAC;QAAA,SAAS,EAAC,MAAM,CAAC;QAAA,eAAe,EAAC,MAAM,CAAA;KAAC,CAAC,GAAC,0BAA0B,CAAC,CAAC;IACpP,SAAS,IAAG,QAAQ,CAAC;QAAC,iBAAiB,EAAC,MAAM,CAAC;QAAA,aAAa,EAAC,MAAM,CAAC;QAAA,aAAa,EAAC,MAAM,CAAC;QAAA,eAAe,EAAC,OAAO,CAAC;QAAA,UAAU,EAAC,OAAO,CAAC;QAAA,eAAe,EAAC,OAAO,CAAA;KAAC,CAAC,CAAC;IAC9J,KAAK,IAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,yJAAyJ;IACzJ,qBAAqB,CAAC,CAAC,OAAO,EAAC,yBAAyB,GAAE,wBAAwB,CAAC;IACnF,qBAAqB,CAAC,CAAC,OAAO,EAAC,MAAM,GAAE,OAAO,CAAC;CAChD;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAC,yBAAyB,EAAC,UAAU,SAAyC;;;;;;GAE5H;AACD,wBAAsB,oCAAoC,CAAC,MAAM,EAAC,yBAAyB,EAAC,UAAU,EAAC,MAAM,EAAC,WAAW,EAAC,MAAM;;;;;;GAK/H"}
1
+ {"version":3,"file":"engineBrokerService.d.ts","sourceRoot":"","sources":["../../src/runtime/engineBrokerService.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAE/F,OAAO,EAA6B,KAAK,MAAM,EAAE,MAAM,UAAU,CAAC;AAClE,OAAO,EAEqB,KAAK,8BAA8B,EAC9D,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,0BAA0B,EAAE,8BAA8B,EAAE,MAAM,iCAAiC,CAAC;AAGlH,OAAO,EAA6B,KAAK,wBAAwB,EAAE,KAAK,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACpI,MAAM,WAAW,yBAAyB;IACxC,IAAI,CACF,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EACpE,MAAM,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,8BAA8B,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAClG,OAAO,CAAC,QAAQ,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;KAC7E,CAAC,GAAG,0BAA0B,GAAG,sBAAsB,GAAG,8BAA8B,CAAC,CAAC;IAC3F,SAAS,IAAG,QAAQ,CAAC;QAAC,iBAAiB,EAAC,MAAM,CAAC;QAAA,aAAa,EAAC,MAAM,CAAC;QAAA,aAAa,EAAC,MAAM,CAAC;QAAA,eAAe,EAAC,OAAO,CAAC;QAAA,UAAU,EAAC,OAAO,CAAC;QAAA,eAAe,EAAC,OAAO,CAAA;KAAC,CAAC,CAAC;IAC9J,KAAK,IAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,SAAS,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,yJAAyJ;IACzJ,qBAAqB,CAAC,CAAC,OAAO,EAAC,yBAAyB,GAAE,wBAAwB,CAAC;IACnF,qBAAqB,CAAC,CAAC,OAAO,EAAC,MAAM,GAAE,OAAO,CAAC;CAChD;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAC,yBAAyB,EAAC,UAAU,SAAyC;;;;;;GAE5H;AACD,wBAAsB,oCAAoC,CAAC,MAAM,EAAC,yBAAyB,EAAC,UAAU,EAAC,MAAM,EAAC,WAAW,EAAC,MAAM;;;;;;GAU/H;AAoBD,+FAA+F;AAC/F,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,yBAAyB,EAAE,MAAM,+BAAqC,GAC7F,IAAI,CA0EN"}
@@ -1,6 +1,7 @@
1
+ import { brokerClockObservation } from "./grokBrokerTaskClock.js";
1
2
  import { chmod, lstat, unlink } from "node:fs/promises";
2
3
  import { createServer } from "node:net";
3
- import { encodeEngineBrokerFrame, EngineBrokerFrameDecoder, parseEngineBrokerRequest } from "./engineBrokerProtocol.js";
4
+ import { encodeEngineBrokerFrame, EngineBrokerFrameDecoder, EngineBrokerProtocolMismatch, parseEngineBrokerRequest } from "./engineBrokerProtocol.js";
4
5
  import { EngineBrokerTurnFailure } from "./grokEngineBroker.js";
5
6
  import { GROK_INFERENCE_PROXY_BASE_URL } from "./engineBrokerInferenceProtocol.js";
6
7
  import { GrokInferenceGrantRefused } from "./grokInferenceGrants.js";
@@ -12,7 +13,11 @@ export async function startEngineBrokerServiceWithIdentity(broker, socketPath, e
12
13
  throw new Error("engine broker service requires broker identity");
13
14
  await removeOwnedSocket(socketPath, expectedUid);
14
15
  const active = new Map(), connections = new Set();
15
- const server = createServer((socket) => { connections.add(socket); socket.once("close", () => connections.delete(socket)); handle(socket, broker, active); });
16
+ const server = createServer((socket) => {
17
+ connections.add(socket);
18
+ socket.once("close", () => connections.delete(socket));
19
+ serveEngineBrokerConnection(socket, broker, active);
20
+ });
16
21
  await listen(server, socketPath);
17
22
  try {
18
23
  await chmod(socketPath, 0o600);
@@ -48,43 +53,88 @@ export async function startEngineBrokerServiceWithIdentity(broker, socketPath, e
48
53
  * reader has disconnected.
49
54
  */
50
55
  function handleSocketError(socket, owned) { socket.on("error", () => { owned()?.controller.abort(); socket.destroy(); }); }
51
- function handle(socket, broker, active) { const decoder = new EngineBrokerFrameDecoder(); let started = false, owned; handleSocketError(socket, () => owned); socket.once("close", () => owned?.controller.abort()); socket.on("data", (chunk) => { try {
52
- for (const value of decoder.push(chunk)) {
53
- const request = parseEngineBrokerRequest(value);
54
- if (request.kind === "health") {
55
- if (started)
56
- throw new Error();
57
- started = true;
58
- const ready = broker.readiness();
59
- if (ready.providerProxyPort !== 43123 || ready.mcpFacadePort !== 43124 || ready.registrations < 1 || ready.credentialStale || !ready.realmLease || !ready.workerIsolation)
60
- throw new Error();
61
- return send(socket, { version: request.version, kind: "ready", requestId: request.requestId, brokerUid: 2100, providerProxyPort: 43123, mcpFacadePort: 43124, registrations: ready.registrations, credentialStale: false, realmLease: true, workerIsolation: true });
56
+ /** @internal The production connection handler, also exercised over an in-memory transport. */
57
+ export function serveEngineBrokerConnection(socket, broker, active = new Map()) {
58
+ const decoder = new EngineBrokerFrameDecoder();
59
+ let started = false;
60
+ let owned;
61
+ handleSocketError(socket, () => owned);
62
+ socket.once("close", () => owned?.controller.abort());
63
+ socket.on("data", (chunk) => {
64
+ try {
65
+ for (const value of decoder.push(chunk)) {
66
+ const request = parseEngineBrokerRequest(value);
67
+ if (request.kind === "health") {
68
+ if (started)
69
+ throw new Error();
70
+ started = true;
71
+ const ready = broker.readiness();
72
+ if (ready.providerProxyPort !== 43123 || ready.mcpFacadePort !== 43124 ||
73
+ ready.registrations < 1 || ready.credentialStale || !ready.realmLease || !ready.workerIsolation) {
74
+ throw new Error();
75
+ }
76
+ return send(socket, {
77
+ version: request.version, kind: "ready", requestId: request.requestId, brokerUid: 2100,
78
+ providerProxyPort: 43123, mcpFacadePort: 43124, registrations: ready.registrations,
79
+ credentialStale: false, realmLease: true, workerIsolation: true
80
+ });
81
+ }
82
+ if (request.kind === "cancel_turn") {
83
+ if (owned?.turnId !== request.turnId)
84
+ throw new Error("turn not owned by connection");
85
+ owned.controller.abort();
86
+ continue;
87
+ }
88
+ if (request.kind === "request_inference_grant" || request.kind === "release_inference_grant") {
89
+ if (started)
90
+ throw new Error();
91
+ started = true;
92
+ serveInferenceGrant(socket, broker, request);
93
+ continue;
94
+ }
95
+ if (request.kind === "reset_slot") {
96
+ if (started || broker.resetSlot === undefined)
97
+ throw new Error();
98
+ started = true;
99
+ void broker.resetSlot(request.slot).then(() => send(socket, {
100
+ version: request.version, kind: "slot_reset", requestId: request.requestId, slot: request.slot
101
+ }), () => socket.destroy());
102
+ continue;
103
+ }
104
+ const key = `${request.slot ?? request.agentId}:${request.turnId}`;
105
+ if (started || active.has(key))
106
+ throw new Error();
107
+ started = true;
108
+ const controller = new AbortController();
109
+ owned = { turnId: request.turnId, controller };
110
+ active.set(key, controller);
111
+ socket.write(encodeEngineBrokerFrame({
112
+ version: request.version, kind: "accepted", requestId: request.requestId, turnId: request.turnId
113
+ }));
114
+ void broker.turn(request.agentId, request.wakeId, request.prompt, request.mcpEndpoint, controller.signal, request.limits, request.processClock, request.slot).then((result) => send(socket, {
115
+ version: request.version, kind: "completed", requestId: request.requestId, turnId: request.turnId,
116
+ text: result.text, ...brokerClockObservation(result.shellClock, result.providerClock),
117
+ ...(result.cleanupDiagnostic === undefined ? {} : { cleanupDiagnostic: result.cleanupDiagnostic }),
118
+ workerPid: result.workerPid, workerUid: result.workerUid, workerStartTime: result.workerStartTime,
119
+ outcome: "completed", usage: result.usage, model: result.model, requests: result.requests, limitReason: "none"
120
+ }), (error) => failed(socket, request, error, controller.signal.aborted)).finally(() => {
121
+ if (active.get(key) === controller)
122
+ active.delete(key);
123
+ owned = undefined;
124
+ });
125
+ }
62
126
  }
63
- if (request.kind === "cancel_turn") {
64
- active.get(request.turnId)?.abort();
65
- continue;
127
+ catch (error) {
128
+ if (error instanceof EngineBrokerProtocolMismatch && !socket.writableEnded) {
129
+ // Flush one small, closed diagnostic before FIN; destroy would lose it.
130
+ socket.pause();
131
+ socket.end(encodeEngineBrokerFrame(error.diagnostic));
132
+ }
133
+ else
134
+ socket.destroy();
66
135
  }
67
- if (request.kind === "request_inference_grant" || request.kind === "release_inference_grant") {
68
- if (started)
69
- throw new Error();
70
- started = true;
71
- serveInferenceGrant(socket, broker, request);
72
- continue;
73
- }
74
- if (started || active.has(request.turnId))
75
- throw new Error();
76
- started = true;
77
- const controller = new AbortController();
78
- owned = { turnId: request.turnId, controller };
79
- active.set(request.turnId, controller);
80
- socket.write(encodeEngineBrokerFrame({ version: request.version, kind: "accepted", requestId: request.requestId, turnId: request.turnId }));
81
- void broker.turn(request.agentId, request.wakeId, request.prompt, request.mcpEndpoint, controller.signal, request.limits).then((result) => send(socket, { version: request.version, kind: "completed", requestId: request.requestId, turnId: request.turnId, text: result.text, workerPid: result.workerPid, workerUid: result.workerUid, workerStartTime: result.workerStartTime, outcome: "completed", usage: result.usage, model: result.model, requests: result.requests, limitReason: "none" }), (error) => failed(socket, request, error, controller.signal.aborted)).finally(() => { if (active.get(request.turnId) === controller)
82
- active.delete(request.turnId); owned = undefined; });
83
- }
136
+ });
84
137
  }
85
- catch {
86
- socket.destroy();
87
- } }); }
88
138
  /**
89
139
  * Every failure the broker raises for a known registration carries its
90
140
  * accounting (a wake that tried to raise a limit: `usage: null`, zero
@@ -99,7 +149,15 @@ function failed(socket, request, error, aborted) {
99
149
  return;
100
150
  }
101
151
  const code = error instanceof EngineBrokerTurnFailure ? error.code : aborted ? "cancelled" : "engine_failed";
102
- send(socket, { version: request.version, kind: "failed", requestId: request.requestId, turnId: request.turnId, code, ...(error instanceof EngineBrokerTurnFailure && error.diagnostic ? { diagnostic: error.diagnostic } : {}), ...(error instanceof EngineBrokerTurnFailure && error.mcpCalls ? { mcpCalls: error.mcpCalls } : {}), outcome: "failed", usage: accounting.usage, model: accounting.model, requests: accounting.requests, limitReason: accounting.limitReason });
152
+ send(socket, {
153
+ version: request.version, kind: "failed", requestId: request.requestId, turnId: request.turnId, code,
154
+ ...(error instanceof EngineBrokerTurnFailure ? brokerClockObservation(error.shellClock, error.providerClock) : {}),
155
+ ...(error instanceof EngineBrokerTurnFailure && error.diagnostic ? { diagnostic: error.diagnostic } : {}),
156
+ ...(error instanceof EngineBrokerTurnFailure && error.mcpCalls ? { mcpCalls: error.mcpCalls } : {}),
157
+ ...(error instanceof EngineBrokerTurnFailure && error.cleanupDiagnostic ? { cleanupDiagnostic: error.cleanupDiagnostic } : {}),
158
+ outcome: "failed", usage: accounting.usage, model: accounting.model,
159
+ requests: accounting.requests, limitReason: accounting.limitReason
160
+ });
103
161
  }
104
162
  /** One grant verb per connection, answered and closed; any failure becomes a closed-code refusal and never touches turn state. */
105
163
  function serveInferenceGrant(socket, broker, request) {
@@ -10,7 +10,7 @@ export async function runEngineBrokerServiceCli() {
10
10
  if (process.getuid?.() !== 2100)
11
11
  throw new Error("engine broker service requires broker identity");
12
12
  const config = parseEngineBrokerServiceConfig(await readRootConfig(ENGINE_BROKER_SERVICE_CONFIG));
13
- const broker = await startGrokEngineBroker({ grokCommand: "/usr/local/bin/grok", nativeClient: "/opt/daimon/bin/daimon-engine-broker", credentialHome: config.credentialHome, turnStore: config.turnStore, registrations: config.registrations, ...(config.inferenceLedgerPath === undefined ? {} : { inferenceLedgerPath: config.inferenceLedgerPath }) });
13
+ const broker = await startGrokEngineBroker({ grokCommand: "/usr/local/bin/grok", nativeClient: "/opt/daimon/bin/daimon-engine-broker", credentialHome: config.credentialHome, turnStore: config.turnStore, registrations: config.registrations, maxRunRequests: config.maxRunRequests, runRequestStore: config.runRequestStore, ...(config.inferenceLedgerPath === undefined ? {} : { inferenceLedgerPath: config.inferenceLedgerPath }) });
14
14
  const service = await startEngineBrokerService(broker);
15
15
  let stopping;
16
16
  const stop = () => { stopping ??= service.close(); return stopping; };
@@ -1,6 +1,7 @@
1
1
  import { type EngineBrokerTurnLimits } from "./engineBrokerTurnAccounting.js";
2
2
  import { type GrokBrokerModelPolicy } from "./grokBrokerModelPolicy.js";
3
3
  export declare const ENGINE_BROKER_SERVICE_V1: "noopolis.daimon.engine-broker-service.v1";
4
+ export declare const ENGINE_BROKER_SERVICE_V3: "noopolis.daimon.engine-broker-service.v3";
4
5
  export declare const ENGINE_BROKER_SERVICE_V2: "noopolis.daimon.engine-broker-service.v2";
5
6
  /** One root-provisioned broker slot. Every field is fixed at provisioning time; a wake can only lower `limits`. */
6
7
  export type EngineBrokerServiceRegistration = Readonly<{
@@ -28,6 +29,8 @@ export type EngineBrokerServiceConfig = Readonly<{
28
29
  turnStore: string;
29
30
  registrations: readonly EngineBrokerServiceRegistration[];
30
31
  inferenceLedgerPath?: string;
32
+ maxRunRequests?: number;
33
+ runRequestStore?: string;
31
34
  }>;
32
35
  /** The per-request stream written beside a registration's usage ledger. */
33
36
  export declare const engineBrokerRequestLedgerPathFor: (usageLedgerPath: string) => string;
@@ -40,6 +43,8 @@ export declare const engineBrokerSealLedgerPathFor: (usageLedgerPath: string) =>
40
43
  /**
41
44
  * Strict `service.json` parser.
42
45
  *
46
+ * v3 retains seven-field registrations and binds slotPolicies by slot; agent IDs
47
+ * may repeat, while worker UIDs, slots and ledger streams must be distinct.
43
48
  * v2 requires every registration to declare its usage ledger, limits and model
44
49
  * (`model.id`/`model.reasoningEffort` from the closed lists); unknown keys at
45
50
  * any level are refused. v1 is still accepted and receives today's defaults:
@@ -1 +1 @@
1
- {"version":3,"file":"engineBrokerServiceConfig.d.ts","sourceRoot":"","sources":["../../src/runtime/engineBrokerServiceConfig.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgE,KAAK,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAC5I,OAAO,EAAuF,KAAK,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAK7J,eAAO,MAAM,wBAAwB,EAAG,0CAAmD,CAAC;AAC5F,eAAO,MAAM,wBAAwB,EAAG,0CAAmD,CAAC;AAE5F,mHAAmH;AACnH,MAAM,MAAM,+BAA+B,GAAG,QAAQ,CAAC;IACrD,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IACpI,oJAAoJ;IACpJ,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,sBAAsB,CAAC;IAC/B,KAAK,EAAE,qBAAqB,CAAC;CAC9B,CAAC,CAAC;AACH;;;;;;GAMG;AACH,MAAM,MAAM,yBAAyB,GAAG,QAAQ,CAAC;IAAE,cAAc,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,SAAS,+BAA+B,EAAE,CAAC;IAAC,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAczL,2EAA2E;AAC3E,eAAO,MAAM,gCAAgC,GAAI,iBAAiB,MAAM,KAAG,MAAgF,CAAC;AAE5J;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,GAAI,iBAAiB,MAAM,KAAG,MAA6E,CAAC;AAEtJ;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,yBAAyB,CA6BxF"}
1
+ {"version":3,"file":"engineBrokerServiceConfig.d.ts","sourceRoot":"","sources":["../../src/runtime/engineBrokerServiceConfig.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgE,KAAK,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAC5I,OAAO,EAAuF,KAAK,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAK7J,eAAO,MAAM,wBAAwB,EAAG,0CAAmD,CAAC;AAC5F,eAAO,MAAM,wBAAwB,EAAG,0CAAmD,CAAC;AAC5F,eAAO,MAAM,wBAAwB,EAAG,0CAAmD,CAAC;AAE5F,mHAAmH;AACnH,MAAM,MAAM,+BAA+B,GAAG,QAAQ,CAAC;IACrD,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IACpI,oJAAoJ;IACpJ,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,sBAAsB,CAAC;IAC/B,KAAK,EAAE,qBAAqB,CAAC;CAC9B,CAAC,CAAC;AACH;;;;;;GAMG;AACH,MAAM,MAAM,yBAAyB,GAAG,QAAQ,CAAC;IAAE,cAAc,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,SAAS,+BAA+B,EAAE,CAAC;IAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAc5O,2EAA2E;AAC3E,eAAO,MAAM,gCAAgC,GAAI,iBAAiB,MAAM,KAAG,MAAgF,CAAC;AAE5J;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,GAAI,iBAAiB,MAAM,KAAG,MAA6E,CAAC;AAEtJ;;;;;;;;;;GAUG;AACH,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,yBAAyB,CAwDxF"}