@the-open-engine/zeroshot 6.38.1 → 6.39.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (377) hide show
  1. package/cli/event-copy.js +8 -7
  2. package/cli/event-copy.ts +12 -0
  3. package/cli/index.js +7 -31
  4. package/cli/json-export.js +61 -64
  5. package/cli/json-export.ts +112 -0
  6. package/cli/message-formatter-utils.js +68 -56
  7. package/cli/message-formatter-utils.ts +121 -0
  8. package/cli/message-formatters-normal.js +124 -259
  9. package/cli/message-formatters-normal.ts +250 -0
  10. package/cli/message-formatters-watch.js +81 -84
  11. package/cli/message-formatters-watch.ts +189 -0
  12. package/lib/cluster/generated/protocol-schema.cjs +1 -1
  13. package/lib/cluster/generated/protocol-schema.mjs +1 -1
  14. package/lib/cluster/generated/protocol.d.cts +8 -0
  15. package/lib/cluster/generated/protocol.d.mts +8 -0
  16. package/lib/cluster/generated/protocol.d.ts +8 -0
  17. package/lib/clusters-registry.d.ts +23 -0
  18. package/lib/clusters-registry.js +17 -29
  19. package/lib/completion.d.ts +12 -0
  20. package/lib/completion.js +84 -94
  21. package/lib/compose-utils.d.ts +32 -0
  22. package/lib/compose-utils.js +57 -72
  23. package/lib/detached-startup.d.ts +83 -0
  24. package/lib/detached-startup.js +231 -302
  25. package/lib/docker-config.d.ts +43 -0
  26. package/lib/docker-config.js +150 -325
  27. package/lib/docker-env-auth.d.ts +17 -0
  28. package/lib/docker-env-auth.js +75 -0
  29. package/lib/git-remote-utils.d.ts +48 -0
  30. package/lib/git-remote-utils.js +147 -213
  31. package/lib/id-detector.d.ts +15 -0
  32. package/lib/id-detector.js +37 -41
  33. package/lib/path-check.d.ts +30 -0
  34. package/lib/path-check.js +42 -45
  35. package/lib/process-liveness.d.ts +16 -0
  36. package/lib/process-liveness.js +19 -12
  37. package/lib/provider-credential-path.d.ts +16 -0
  38. package/lib/provider-credential-path.js +31 -29
  39. package/lib/provider-defaults.d.ts +30 -0
  40. package/lib/provider-defaults.js +47 -42
  41. package/lib/provider-detection.d.ts +11 -0
  42. package/lib/provider-detection.js +91 -54
  43. package/lib/provider-names.d.ts +38 -0
  44. package/lib/provider-names.js +56 -64
  45. package/lib/repo-settings.d.ts +28 -0
  46. package/lib/repo-settings.js +83 -59
  47. package/lib/run-mode.d.ts +21 -0
  48. package/lib/run-mode.js +21 -20
  49. package/lib/run-plan.d.ts +28 -0
  50. package/lib/run-plan.js +17 -16
  51. package/lib/settings/claude-auth.d.ts +35 -0
  52. package/lib/settings/claude-auth.js +30 -47
  53. package/lib/settings-defaults.d.ts +20 -0
  54. package/lib/settings-defaults.js +149 -0
  55. package/lib/settings-error.d.ts +7 -0
  56. package/lib/settings-error.js +8 -0
  57. package/lib/settings-issue-providers.d.ts +10 -0
  58. package/lib/settings-issue-providers.js +12 -0
  59. package/lib/settings-models.d.ts +22 -0
  60. package/lib/settings-models.js +93 -0
  61. package/lib/settings-storage.d.ts +23 -0
  62. package/lib/settings-storage.js +205 -0
  63. package/lib/settings-validation.d.ts +7 -0
  64. package/lib/settings-validation.js +182 -0
  65. package/lib/settings.d.ts +29 -0
  66. package/lib/settings.js +41 -736
  67. package/lib/setup-apply-types.d.ts +66 -0
  68. package/lib/setup-apply-types.js +2 -0
  69. package/lib/setup-apply.d.ts +39 -0
  70. package/lib/setup-apply.js +267 -264
  71. package/lib/setup-journal.d.ts +41 -0
  72. package/lib/setup-journal.js +119 -76
  73. package/lib/setup-plan-types.d.ts +102 -0
  74. package/lib/setup-plan-types.js +2 -0
  75. package/lib/setup-plan.d.ts +30 -0
  76. package/lib/setup-plan.js +300 -324
  77. package/lib/setup-undo.d.ts +44 -0
  78. package/lib/setup-undo.js +61 -74
  79. package/lib/start-cluster-config.d.ts +26 -0
  80. package/lib/start-cluster-config.js +56 -0
  81. package/lib/start-cluster-environment.d.ts +40 -0
  82. package/lib/start-cluster-environment.js +134 -0
  83. package/lib/start-cluster-run-options.d.ts +53 -0
  84. package/lib/start-cluster-run-options.js +147 -0
  85. package/lib/start-cluster.d.ts +64 -0
  86. package/lib/start-cluster.js +98 -454
  87. package/lib/stream-json-parser.d.ts +17 -0
  88. package/lib/stream-json-parser.js +51 -52
  89. package/npm-shrinkwrap.json +2 -2
  90. package/package.json +12 -6
  91. package/scripts/postinstall.js +27 -0
  92. package/scripts/rust-distribution.js +23 -14
  93. package/src/agent/agent-command-proofs-context.js +35 -45
  94. package/src/agent/agent-command-proofs-context.ts +87 -0
  95. package/src/agent/agent-config-settings.js +19 -0
  96. package/src/agent/agent-config-settings.ts +41 -0
  97. package/src/agent/agent-config.js +122 -231
  98. package/src/agent/agent-config.ts +285 -0
  99. package/src/agent/agent-context-builder.js +38 -273
  100. package/src/agent/agent-context-builder.ts +51 -0
  101. package/src/agent/agent-context-environment-sections.js +105 -0
  102. package/src/agent/agent-context-environment-sections.ts +134 -0
  103. package/src/agent/agent-context-packs.js +165 -0
  104. package/src/agent/agent-context-packs.ts +296 -0
  105. package/src/agent/agent-context-prompt-sections.js +100 -0
  106. package/src/agent/agent-context-prompt-sections.ts +148 -0
  107. package/src/agent/agent-context-sections.js +25 -334
  108. package/src/agent/agent-context-sections.ts +36 -0
  109. package/src/agent/agent-context-sources.js +96 -149
  110. package/src/agent/agent-context-sources.ts +253 -0
  111. package/src/agent/agent-context-types.js +2 -0
  112. package/src/agent/agent-context-types.ts +132 -0
  113. package/src/agent/agent-context-validation-sections.js +73 -0
  114. package/src/agent/agent-context-validation-sections.ts +129 -0
  115. package/src/agent/agent-input-injector.js +99 -118
  116. package/src/agent/agent-input-injector.ts +195 -0
  117. package/src/agent/agent-liveness-poll.js +74 -78
  118. package/src/agent/agent-liveness-poll.ts +163 -0
  119. package/src/agent/agent-quality-gate-schema.js +77 -86
  120. package/src/agent/agent-quality-gate-schema.ts +135 -0
  121. package/src/agent/agent-quality-gates-context.js +44 -50
  122. package/src/agent/agent-quality-gates-context.ts +91 -0
  123. package/src/agent/agent-stuck-detector.js +171 -239
  124. package/src/agent/agent-stuck-detector.ts +288 -0
  125. package/src/agent/agent-trigger-evaluator.js +29 -46
  126. package/src/agent/agent-trigger-evaluator.ts +98 -0
  127. package/src/agent/context-metrics.js +110 -141
  128. package/src/agent/context-metrics.ts +261 -0
  129. package/src/agent/context-pack-builder.js +72 -358
  130. package/src/agent/context-pack-builder.ts +105 -0
  131. package/src/agent/context-pack-core.js +70 -0
  132. package/src/agent/context-pack-core.ts +96 -0
  133. package/src/agent/context-pack-selection.js +119 -0
  134. package/src/agent/context-pack-selection.ts +187 -0
  135. package/src/agent/context-pack-truncation.js +139 -0
  136. package/src/agent/context-pack-truncation.ts +208 -0
  137. package/src/agent/context-pack-types.js +2 -0
  138. package/src/agent/context-pack-types.ts +98 -0
  139. package/src/agent/context-replay-policy.js +30 -39
  140. package/src/agent/context-replay-policy.ts +71 -0
  141. package/src/agent/critical-agent-policy.js +6 -10
  142. package/src/agent/critical-agent-policy.ts +20 -0
  143. package/src/agent/guidance-queue.js +74 -87
  144. package/src/agent/guidance-queue.ts +166 -0
  145. package/src/agent/output-extraction-error-detail.js +45 -0
  146. package/src/agent/output-extraction-error-detail.ts +49 -0
  147. package/src/agent/output-extraction-failures.js +125 -0
  148. package/src/agent/output-extraction-failures.ts +149 -0
  149. package/src/agent/output-extraction-json.js +234 -0
  150. package/src/agent/output-extraction-json.ts +235 -0
  151. package/src/agent/output-extraction-pi.js +124 -0
  152. package/src/agent/output-extraction-pi.ts +137 -0
  153. package/src/agent/output-extraction-types.js +2 -0
  154. package/src/agent/output-extraction-types.ts +49 -0
  155. package/src/agent/output-extraction.js +17 -617
  156. package/src/agent/output-extraction.ts +30 -0
  157. package/src/agent/output-reformatter-errors.js +83 -0
  158. package/src/agent/output-reformatter-errors.ts +106 -0
  159. package/src/agent/output-reformatter-types.js +2 -0
  160. package/src/agent/output-reformatter-types.ts +86 -0
  161. package/src/agent/output-reformatter.js +140 -185
  162. package/src/agent/output-reformatter.ts +238 -0
  163. package/src/agent/pi-terminal-lifecycle-types.js +2 -0
  164. package/src/agent/pi-terminal-lifecycle-types.ts +41 -0
  165. package/src/agent/pi-terminal-lifecycle.js +186 -206
  166. package/src/agent/pi-terminal-lifecycle.ts +297 -0
  167. package/src/agent/provider-control-plane.js +22 -21
  168. package/src/agent/provider-control-plane.ts +52 -0
  169. package/src/agent/provider-terminal-failure-types.js +2 -0
  170. package/src/agent/provider-terminal-failure-types.ts +60 -0
  171. package/src/agent/provider-terminal-failure.js +194 -191
  172. package/src/agent/provider-terminal-failure.ts +262 -0
  173. package/src/agent/rate-limit-backoff.js +31 -74
  174. package/src/agent/rate-limit-backoff.ts +71 -0
  175. package/src/agent/schema-utils.js +85 -125
  176. package/src/agent/schema-utils.ts +148 -0
  177. package/src/agent/structured-output-error.js +34 -33
  178. package/src/agent/structured-output-error.ts +105 -0
  179. package/src/agent/validation-platform.js +27 -27
  180. package/src/agent/validation-platform.ts +49 -0
  181. package/src/attach/attach-client.js +232 -405
  182. package/src/attach/attach-client.ts +300 -0
  183. package/src/attach/attach-server-cleanup.js +43 -0
  184. package/src/attach/attach-server-cleanup.ts +39 -0
  185. package/src/attach/attach-server-clients.js +117 -0
  186. package/src/attach/attach-server-clients.ts +122 -0
  187. package/src/attach/attach-server-events.js +38 -0
  188. package/src/attach/attach-server-events.ts +36 -0
  189. package/src/attach/attach-server-pty.js +45 -0
  190. package/src/attach/attach-server-pty.ts +64 -0
  191. package/src/attach/attach-server-runtime.js +73 -0
  192. package/src/attach/attach-server-runtime.ts +62 -0
  193. package/src/attach/attach-server-socket.js +28 -0
  194. package/src/attach/attach-server-socket.ts +23 -0
  195. package/src/attach/attach-server-types.js +2 -0
  196. package/src/attach/attach-server-types.ts +82 -0
  197. package/src/attach/attach-server.js +106 -523
  198. package/src/attach/attach-server.ts +158 -0
  199. package/src/attach/index.js +18 -35
  200. package/src/attach/index.ts +18 -0
  201. package/src/attach/protocol.js +95 -184
  202. package/src/attach/protocol.ts +181 -0
  203. package/src/attach/ring-buffer.js +76 -102
  204. package/src/attach/ring-buffer.ts +109 -0
  205. package/src/attach/send-input.js +64 -75
  206. package/src/attach/send-input.ts +94 -0
  207. package/src/attach/socket-discovery.js +164 -218
  208. package/src/attach/socket-discovery.ts +230 -0
  209. package/src/attach/socket-paths.js +42 -61
  210. package/src/attach/socket-paths.ts +81 -0
  211. package/src/claude-credentials.js +51 -54
  212. package/src/claude-credentials.ts +89 -0
  213. package/src/cluster/generated/protocol-schema.ts +1 -1
  214. package/src/cluster/generated/protocol.ts +2 -1
  215. package/src/command-proofs.js +110 -141
  216. package/src/command-proofs.ts +216 -0
  217. package/src/config-router.js +81 -73
  218. package/src/config-router.ts +131 -0
  219. package/src/copy-worker.js +53 -29
  220. package/src/copy-worker.ts +75 -0
  221. package/src/darwin-keychain-boundary.js +80 -111
  222. package/src/darwin-keychain-boundary.ts +148 -0
  223. package/src/guidance-topics.js +4 -5
  224. package/src/guidance-topics.ts +10 -0
  225. package/src/input-helpers.js +33 -54
  226. package/src/input-helpers.ts +58 -0
  227. package/src/ledger-sequence.js +45 -48
  228. package/src/ledger-sequence.ts +63 -0
  229. package/src/legacy-lib/clusters-registry.ts +40 -0
  230. package/src/legacy-lib/completion.ts +148 -0
  231. package/src/legacy-lib/compose-utils.ts +102 -0
  232. package/src/legacy-lib/detached-startup.ts +449 -0
  233. package/src/legacy-lib/docker-config.ts +282 -0
  234. package/src/legacy-lib/docker-env-auth.ts +116 -0
  235. package/src/legacy-lib/git-remote-utils.ts +244 -0
  236. package/src/legacy-lib/id-detector.ts +57 -0
  237. package/src/legacy-lib/js-yaml.d.ts +3 -0
  238. package/src/legacy-lib/omelette.d.ts +15 -0
  239. package/src/legacy-lib/path-check.ts +89 -0
  240. package/src/legacy-lib/process-liveness.ts +36 -0
  241. package/src/legacy-lib/provider-credential-path.ts +57 -0
  242. package/src/legacy-lib/provider-defaults.ts +114 -0
  243. package/src/legacy-lib/provider-detection.ts +67 -0
  244. package/src/legacy-lib/provider-names.ts +126 -0
  245. package/src/legacy-lib/repo-settings.ts +88 -0
  246. package/src/legacy-lib/run-mode.ts +58 -0
  247. package/src/legacy-lib/run-plan.ts +49 -0
  248. package/src/legacy-lib/settings/claude-auth.ts +80 -0
  249. package/src/legacy-lib/settings-defaults.ts +212 -0
  250. package/src/legacy-lib/settings-error.ts +8 -0
  251. package/src/legacy-lib/settings-issue-providers.ts +18 -0
  252. package/src/legacy-lib/settings-models.ts +124 -0
  253. package/src/legacy-lib/settings-storage.ts +277 -0
  254. package/src/legacy-lib/settings-validation.ts +220 -0
  255. package/src/legacy-lib/settings.ts +87 -0
  256. package/src/legacy-lib/setup-apply-types.ts +70 -0
  257. package/src/legacy-lib/setup-apply.ts +456 -0
  258. package/src/legacy-lib/setup-journal.ts +185 -0
  259. package/src/legacy-lib/setup-plan-types.ts +96 -0
  260. package/src/legacy-lib/setup-plan.ts +500 -0
  261. package/src/legacy-lib/setup-undo.ts +142 -0
  262. package/src/legacy-lib/start-cluster-config.ts +124 -0
  263. package/src/legacy-lib/start-cluster-environment.ts +165 -0
  264. package/src/legacy-lib/start-cluster-run-options.ts +279 -0
  265. package/src/legacy-lib/start-cluster.ts +237 -0
  266. package/src/legacy-lib/stream-json-parser.ts +88 -0
  267. package/src/message-buffer.js +55 -71
  268. package/src/message-buffer.ts +107 -0
  269. package/src/message-bus-bridge.js +92 -133
  270. package/src/message-bus-bridge.ts +149 -0
  271. package/src/name-generator-shared.js +220 -0
  272. package/src/name-generator-shared.ts +231 -0
  273. package/src/name-generator.js +8 -217
  274. package/src/name-generator.ts +27 -0
  275. package/src/omp-blob-root.js +83 -64
  276. package/src/omp-blob-root.ts +116 -0
  277. package/src/omp-config-overlay.js +65 -38
  278. package/src/omp-config-overlay.ts +110 -0
  279. package/src/omp-execution-fingerprint.js +38 -43
  280. package/src/omp-execution-fingerprint.ts +92 -0
  281. package/src/omp-session-limits.js +10 -15
  282. package/src/omp-session-limits.ts +53 -0
  283. package/src/omp-session-partition.js +2 -2
  284. package/src/omp-session-verifier.js +1 -1
  285. package/src/orchestrator.js +19 -4
  286. package/src/providers/anthropic/index.js +3 -1
  287. package/src/providers/anthropic/index.ts +13 -0
  288. package/src/providers/capabilities.js +19 -27
  289. package/src/providers/capabilities.ts +44 -0
  290. package/src/providers/google/index.js +3 -1
  291. package/src/providers/google/index.ts +13 -0
  292. package/src/providers/openai/index.js +3 -1
  293. package/src/providers/openai/index.ts +13 -0
  294. package/src/providers/opencode/index.js +3 -1
  295. package/src/providers/opencode/index.ts +13 -0
  296. package/src/quality-gates.js +67 -127
  297. package/src/quality-gates.ts +149 -0
  298. package/src/repo-settings-access.js +40 -0
  299. package/src/repo-settings-access.ts +64 -0
  300. package/src/schemas/sub-cluster.js +127 -183
  301. package/src/schemas/sub-cluster.ts +238 -0
  302. package/src/state-snapshot-normalization.js +224 -0
  303. package/src/state-snapshot-normalization.ts +222 -0
  304. package/src/state-snapshot.js +192 -359
  305. package/src/state-snapshot.ts +291 -0
  306. package/src/state-snapshotter.js +118 -130
  307. package/src/state-snapshotter.ts +167 -0
  308. package/src/sub-cluster-wrapper.js +4 -13
  309. package/src/task-run-model-args.js +87 -124
  310. package/src/task-run-model-args.ts +204 -0
  311. package/src/task-runner.js +5 -25
  312. package/src/task-runner.ts +28 -0
  313. package/src/task-startup-error.js +73 -58
  314. package/src/task-startup-error.ts +126 -0
  315. package/src/template-validation/consensus-gate-contracts.js +2 -0
  316. package/src/template-validation/consensus-gate-contracts.ts +70 -0
  317. package/src/template-validation/consensus-gate-scenarios.js +76 -0
  318. package/src/template-validation/consensus-gate-scenarios.ts +130 -0
  319. package/src/template-validation/consensus-gate-stage.js +34 -0
  320. package/src/template-validation/consensus-gate-stage.ts +56 -0
  321. package/src/template-validation/random-topology-contracts.js +2 -0
  322. package/src/template-validation/random-topology-contracts.ts +54 -0
  323. package/src/template-validation/random-topology-dispatch.js +25 -0
  324. package/src/template-validation/random-topology-dispatch.ts +33 -0
  325. package/src/template-validation/random-topology-message-loop.js +53 -0
  326. package/src/template-validation/random-topology-message-loop.ts +73 -0
  327. package/src/template-validation/random-topology-operations.js +79 -0
  328. package/src/template-validation/random-topology-operations.ts +101 -0
  329. package/src/template-validation/random-topology-runtime.js +25 -0
  330. package/src/template-validation/random-topology-runtime.ts +43 -0
  331. package/src/template-validation/random-topology-scenario.js +52 -0
  332. package/src/template-validation/random-topology-scenario.ts +57 -0
  333. package/src/template-validation/random-topology-schema.js +159 -0
  334. package/src/template-validation/random-topology-schema.ts +190 -0
  335. package/src/template-validation/random-topology-state.js +28 -0
  336. package/src/template-validation/random-topology-state.ts +30 -0
  337. package/src/template-validation/random-topology-trigger-evaluation.js +45 -0
  338. package/src/template-validation/random-topology-trigger-evaluation.ts +65 -0
  339. package/src/template-validation/random-topology-trigger.js +75 -0
  340. package/src/template-validation/random-topology-trigger.ts +88 -0
  341. package/src/template-validation/report-formatter.js +40 -46
  342. package/src/template-validation/report-formatter.ts +101 -0
  343. package/src/template-validation/simulate-consensus-gates.js +111 -302
  344. package/src/template-validation/simulate-consensus-gates.ts +196 -0
  345. package/src/template-validation/simulate-random-topology.js +26 -519
  346. package/src/template-validation/simulate-random-topology.ts +57 -0
  347. package/src/template-validation/simulate-two-stage-validation.js +41 -265
  348. package/src/template-validation/simulate-two-stage-validation.ts +55 -0
  349. package/src/template-validation/simulation-agent-runtime.js +25 -0
  350. package/src/template-validation/simulation-agent-runtime.ts +40 -0
  351. package/src/template-validation/simulation-agent.js +29 -0
  352. package/src/template-validation/simulation-agent.ts +73 -0
  353. package/src/template-validation/simulation-runtime.js +34 -0
  354. package/src/template-validation/simulation-runtime.ts +72 -0
  355. package/src/template-validation/two-stage-contracts.js +2 -0
  356. package/src/template-validation/two-stage-contracts.ts +41 -0
  357. package/src/template-validation/two-stage-inputs.js +21 -0
  358. package/src/template-validation/two-stage-inputs.ts +29 -0
  359. package/src/template-validation/two-stage-results.js +30 -0
  360. package/src/template-validation/two-stage-results.ts +40 -0
  361. package/src/template-validation/two-stage-scenario.js +86 -0
  362. package/src/template-validation/two-stage-scenario.ts +120 -0
  363. package/src/worktree-claude-config.js +182 -220
  364. package/src/worktree-claude-config.ts +272 -0
  365. package/src/worktree-tooling-env.js +103 -125
  366. package/src/worktree-tooling-env.ts +142 -0
  367. package/task-lib/completion.js +2 -3
  368. package/task-lib/completion.ts +9 -0
  369. package/task-lib/config.js +1 -4
  370. package/task-lib/config.ts +11 -0
  371. package/task-lib/name-generator.js +4 -226
  372. package/task-lib/name-generator.ts +11 -0
  373. package/task-lib/omp-session-cleanup.js +1 -1
  374. package/task-lib/omp-storage-root.js +8 -12
  375. package/task-lib/omp-storage-root.ts +62 -0
  376. package/task-lib/process-termination.js +143 -166
  377. package/task-lib/process-termination.ts +268 -0
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createSeededRng = createSeededRng;
4
+ exports.sampleFromSchema = sampleFromSchema;
5
+ exports.sampleResultData = sampleResultData;
6
+ function isRecord(value) {
7
+ return typeof value === 'object' && value !== null;
8
+ }
9
+ function createSeededRng(seed) {
10
+ let state = seed >>> 0 || 0x9e3779b9;
11
+ return () => {
12
+ state ^= state << 13;
13
+ state >>>= 0;
14
+ state ^= state >>> 17;
15
+ state >>>= 0;
16
+ state ^= state << 5;
17
+ state >>>= 0;
18
+ return state / 4_294_967_296;
19
+ };
20
+ }
21
+ function randomInt(rng, min, max) {
22
+ if (!Number.isFinite(min) || !Number.isFinite(max)) {
23
+ return 0;
24
+ }
25
+ if (max <= min) {
26
+ return Math.round(min);
27
+ }
28
+ return Math.floor(rng() * (max - min + 1)) + min;
29
+ }
30
+ function randomPick(rng, values, fallback) {
31
+ if (values.length === 0) {
32
+ return fallback;
33
+ }
34
+ return values[randomInt(rng, 0, values.length - 1)];
35
+ }
36
+ function normalizeType(schema) {
37
+ if (!schema.type)
38
+ return null;
39
+ if (Array.isArray(schema.type)) {
40
+ return schema.type[0] ?? null;
41
+ }
42
+ return schema.type;
43
+ }
44
+ function sampleString(schema, rng) {
45
+ const candidates = stringCandidates(schema);
46
+ let value = randomPick(rng, candidates, 'sample');
47
+ if (value === undefined)
48
+ value = 'sample';
49
+ const minLength = Number.isInteger(schema.minLength) ? Number(schema.minLength) : 0;
50
+ const maxLength = Number.isInteger(schema.maxLength) ? Number(schema.maxLength) : value.length;
51
+ while (value.length < minLength)
52
+ value += 'x';
53
+ if (maxLength >= 0 && value.length > maxLength)
54
+ value = value.slice(0, maxLength);
55
+ if (!value && minLength > 0)
56
+ value = 'x'.repeat(minLength);
57
+ return value;
58
+ }
59
+ function stringCandidates(schema) {
60
+ const candidates = [];
61
+ if (typeof schema.default === 'string')
62
+ candidates.push(schema.default);
63
+ if (typeof schema.description === 'string')
64
+ candidates.push(schema.description);
65
+ candidates.push('sample', 'ok', 'done', 'pass', 'fail');
66
+ return candidates;
67
+ }
68
+ function finiteNumber(value, fallback) {
69
+ return typeof value === 'number' && Number.isFinite(value) ? value : fallback;
70
+ }
71
+ function sampleNumber(schema, rng, asInteger) {
72
+ const minimum = finiteNumber(schema.minimum, 0);
73
+ const maximum = finiteNumber(schema.maximum, 10);
74
+ if (maximum < minimum) {
75
+ return asInteger ? Math.round(minimum) : minimum;
76
+ }
77
+ if (asInteger) {
78
+ return randomInt(rng, Math.ceil(minimum), Math.floor(maximum));
79
+ }
80
+ return minimum + (maximum - minimum) * rng();
81
+ }
82
+ function sampleArray(schema, rng, depth) {
83
+ const minItems = Number.isInteger(schema.minItems) ? Number(schema.minItems) : 0;
84
+ const rawMaximum = Number.isInteger(schema.maxItems) ? Number(schema.maxItems) : minItems + 2;
85
+ const maxItems = Math.max(minItems, Math.min(rawMaximum, 3));
86
+ const length = randomInt(rng, minItems, maxItems);
87
+ const itemsSchema = Array.isArray(schema.items)
88
+ ? randomPick(rng, schema.items, {})
89
+ : schema.items || {};
90
+ const values = [];
91
+ for (let index = 0; index < length; index += 1) {
92
+ values.push(sampleFromSchema(itemsSchema, rng, depth + 1));
93
+ }
94
+ return values;
95
+ }
96
+ function sampleObject(schema, rng, depth) {
97
+ const properties = isRecord(schema.properties) ? schema.properties : {};
98
+ const value = {};
99
+ for (const [key, propertySchema] of Object.entries(properties)) {
100
+ value[key] = sampleFromSchema(propertySchema, rng, depth + 1);
101
+ }
102
+ return value;
103
+ }
104
+ function isNonEmptyArray(value) {
105
+ return Array.isArray(value) && value.length > 0;
106
+ }
107
+ function sampleSchemaKeyword(schema, rng, depth) {
108
+ if (schema.const !== undefined)
109
+ return { matched: true, value: schema.const };
110
+ if (isNonEmptyArray(schema.enum)) {
111
+ return { matched: true, value: randomPick(rng, schema.enum, null) };
112
+ }
113
+ if (isNonEmptyArray(schema.oneOf)) {
114
+ const selected = randomPick(rng, schema.oneOf, null);
115
+ return { matched: true, value: sampleFromSchema(selected, rng, depth + 1) };
116
+ }
117
+ if (isNonEmptyArray(schema.anyOf)) {
118
+ const selected = randomPick(rng, schema.anyOf, null);
119
+ return { matched: true, value: sampleFromSchema(selected, rng, depth + 1) };
120
+ }
121
+ if (isNonEmptyArray(schema.allOf)) {
122
+ return { matched: true, value: sampleFromSchema(schema.allOf[0], rng, depth + 1) };
123
+ }
124
+ return { matched: false };
125
+ }
126
+ function sampleSchemaType(schema, rng, depth) {
127
+ const type = normalizeType(schema);
128
+ if (type === 'boolean')
129
+ return { matched: true, value: rng() >= 0.5 };
130
+ if (type === 'integer')
131
+ return { matched: true, value: sampleNumber(schema, rng, true) };
132
+ if (type === 'number')
133
+ return { matched: true, value: sampleNumber(schema, rng, false) };
134
+ if (type === 'array')
135
+ return { matched: true, value: sampleArray(schema, rng, depth) };
136
+ if (type === 'object' || schema.properties) {
137
+ return { matched: true, value: sampleObject(schema, rng, depth) };
138
+ }
139
+ return { matched: false };
140
+ }
141
+ function sampleFromSchema(schemaValue, rng, depth = 0) {
142
+ if (!isRecord(schemaValue) || depth > 4) {
143
+ return null;
144
+ }
145
+ const keyword = sampleSchemaKeyword(schemaValue, rng, depth);
146
+ if (keyword.matched)
147
+ return keyword.value;
148
+ const typed = sampleSchemaType(schemaValue, rng, depth);
149
+ if (typed.matched)
150
+ return typed.value;
151
+ return sampleString(schemaValue, rng);
152
+ }
153
+ function sampleResultData(agentConfig, rng) {
154
+ const schema = agentConfig.jsonSchema || agentConfig.structuredOutput || null;
155
+ if (schema) {
156
+ return sampleFromSchema(schema, rng);
157
+ }
158
+ return { summary: 'sample', result: 'sample' };
159
+ }
@@ -0,0 +1,190 @@
1
+ import type { RandomAgentConfig, RandomNumberGenerator } from './random-topology-contracts';
2
+
3
+ type SchemaRecord = Record<string, unknown>;
4
+
5
+ function isRecord(value: unknown): value is SchemaRecord {
6
+ return typeof value === 'object' && value !== null;
7
+ }
8
+
9
+ export function createSeededRng(seed: number): RandomNumberGenerator {
10
+ let state = seed >>> 0 || 0x9e3779b9;
11
+ return () => {
12
+ state ^= state << 13;
13
+ state >>>= 0;
14
+ state ^= state >>> 17;
15
+ state >>>= 0;
16
+ state ^= state << 5;
17
+ state >>>= 0;
18
+ return state / 4_294_967_296;
19
+ };
20
+ }
21
+
22
+ function randomInt(rng: RandomNumberGenerator, min: number, max: number): number {
23
+ if (!Number.isFinite(min) || !Number.isFinite(max)) {
24
+ return 0;
25
+ }
26
+ if (max <= min) {
27
+ return Math.round(min);
28
+ }
29
+ return Math.floor(rng() * (max - min + 1)) + min;
30
+ }
31
+
32
+ function randomPick<T>(
33
+ rng: RandomNumberGenerator,
34
+ values: readonly T[],
35
+ fallback: T
36
+ ): T | undefined {
37
+ if (values.length === 0) {
38
+ return fallback;
39
+ }
40
+ return values[randomInt(rng, 0, values.length - 1)];
41
+ }
42
+
43
+ function normalizeType(schema: SchemaRecord): unknown {
44
+ if (!schema.type) return null;
45
+ if (Array.isArray(schema.type)) {
46
+ return schema.type[0] ?? null;
47
+ }
48
+ return schema.type;
49
+ }
50
+
51
+ function sampleString(schema: SchemaRecord, rng: RandomNumberGenerator): string {
52
+ const candidates = stringCandidates(schema);
53
+ let value = randomPick(rng, candidates, 'sample');
54
+ if (value === undefined) value = 'sample';
55
+
56
+ const minLength = Number.isInteger(schema.minLength) ? Number(schema.minLength) : 0;
57
+ const maxLength = Number.isInteger(schema.maxLength) ? Number(schema.maxLength) : value.length;
58
+
59
+ while (value.length < minLength) value += 'x';
60
+ if (maxLength >= 0 && value.length > maxLength) value = value.slice(0, maxLength);
61
+ if (!value && minLength > 0) value = 'x'.repeat(minLength);
62
+ return value;
63
+ }
64
+
65
+ function stringCandidates(schema: SchemaRecord): string[] {
66
+ const candidates: string[] = [];
67
+ if (typeof schema.default === 'string') candidates.push(schema.default);
68
+ if (typeof schema.description === 'string') candidates.push(schema.description);
69
+ candidates.push('sample', 'ok', 'done', 'pass', 'fail');
70
+ return candidates;
71
+ }
72
+
73
+ function finiteNumber(value: unknown, fallback: number): number {
74
+ return typeof value === 'number' && Number.isFinite(value) ? value : fallback;
75
+ }
76
+
77
+ function sampleNumber(
78
+ schema: SchemaRecord,
79
+ rng: RandomNumberGenerator,
80
+ asInteger: boolean
81
+ ): number {
82
+ const minimum = finiteNumber(schema.minimum, 0);
83
+ const maximum = finiteNumber(schema.maximum, 10);
84
+ if (maximum < minimum) {
85
+ return asInteger ? Math.round(minimum) : minimum;
86
+ }
87
+ if (asInteger) {
88
+ return randomInt(rng, Math.ceil(minimum), Math.floor(maximum));
89
+ }
90
+ return minimum + (maximum - minimum) * rng();
91
+ }
92
+
93
+ function sampleArray(schema: SchemaRecord, rng: RandomNumberGenerator, depth: number): unknown[] {
94
+ const minItems = Number.isInteger(schema.minItems) ? Number(schema.minItems) : 0;
95
+ const rawMaximum = Number.isInteger(schema.maxItems) ? Number(schema.maxItems) : minItems + 2;
96
+ const maxItems = Math.max(minItems, Math.min(rawMaximum, 3));
97
+ const length = randomInt(rng, minItems, maxItems);
98
+ const itemsSchema = Array.isArray(schema.items)
99
+ ? randomPick<unknown>(rng, schema.items, {})
100
+ : schema.items || {};
101
+ const values: unknown[] = [];
102
+ for (let index = 0; index < length; index += 1) {
103
+ values.push(sampleFromSchema(itemsSchema, rng, depth + 1));
104
+ }
105
+ return values;
106
+ }
107
+
108
+ function sampleObject(
109
+ schema: SchemaRecord,
110
+ rng: RandomNumberGenerator,
111
+ depth: number
112
+ ): Record<string, unknown> {
113
+ const properties = isRecord(schema.properties) ? schema.properties : {};
114
+ const value: Record<string, unknown> = {};
115
+ for (const [key, propertySchema] of Object.entries(properties)) {
116
+ value[key] = sampleFromSchema(propertySchema, rng, depth + 1);
117
+ }
118
+ return value;
119
+ }
120
+
121
+ type SampleBranch = { matched: true; value: unknown } | { matched: false };
122
+
123
+ function isNonEmptyArray(value: unknown): value is unknown[] {
124
+ return Array.isArray(value) && value.length > 0;
125
+ }
126
+
127
+ function sampleSchemaKeyword(
128
+ schema: SchemaRecord,
129
+ rng: RandomNumberGenerator,
130
+ depth: number
131
+ ): SampleBranch {
132
+ if (schema.const !== undefined) return { matched: true, value: schema.const };
133
+ if (isNonEmptyArray(schema.enum)) {
134
+ return { matched: true, value: randomPick<unknown>(rng, schema.enum, null) };
135
+ }
136
+ if (isNonEmptyArray(schema.oneOf)) {
137
+ const selected = randomPick<unknown>(rng, schema.oneOf, null);
138
+ return { matched: true, value: sampleFromSchema(selected, rng, depth + 1) };
139
+ }
140
+ if (isNonEmptyArray(schema.anyOf)) {
141
+ const selected = randomPick<unknown>(rng, schema.anyOf, null);
142
+ return { matched: true, value: sampleFromSchema(selected, rng, depth + 1) };
143
+ }
144
+ if (isNonEmptyArray(schema.allOf)) {
145
+ return { matched: true, value: sampleFromSchema(schema.allOf[0], rng, depth + 1) };
146
+ }
147
+ return { matched: false };
148
+ }
149
+
150
+ function sampleSchemaType(
151
+ schema: SchemaRecord,
152
+ rng: RandomNumberGenerator,
153
+ depth: number
154
+ ): SampleBranch {
155
+ const type = normalizeType(schema);
156
+ if (type === 'boolean') return { matched: true, value: rng() >= 0.5 };
157
+ if (type === 'integer') return { matched: true, value: sampleNumber(schema, rng, true) };
158
+ if (type === 'number') return { matched: true, value: sampleNumber(schema, rng, false) };
159
+ if (type === 'array') return { matched: true, value: sampleArray(schema, rng, depth) };
160
+ if (type === 'object' || schema.properties) {
161
+ return { matched: true, value: sampleObject(schema, rng, depth) };
162
+ }
163
+ return { matched: false };
164
+ }
165
+
166
+ export function sampleFromSchema(
167
+ schemaValue: unknown,
168
+ rng: RandomNumberGenerator,
169
+ depth = 0
170
+ ): unknown {
171
+ if (!isRecord(schemaValue) || depth > 4) {
172
+ return null;
173
+ }
174
+ const keyword = sampleSchemaKeyword(schemaValue, rng, depth);
175
+ if (keyword.matched) return keyword.value;
176
+ const typed = sampleSchemaType(schemaValue, rng, depth);
177
+ if (typed.matched) return typed.value;
178
+ return sampleString(schemaValue, rng);
179
+ }
180
+
181
+ export function sampleResultData(
182
+ agentConfig: RandomAgentConfig,
183
+ rng: RandomNumberGenerator
184
+ ): unknown {
185
+ const schema = agentConfig.jsonSchema || agentConfig.structuredOutput || null;
186
+ if (schema) {
187
+ return sampleFromSchema(schema, rng);
188
+ }
189
+ return { summary: 'sample', result: 'sample' };
190
+ }
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cloneAgentConfigs = cloneAgentConfigs;
4
+ exports.addAgentsToState = addAgentsToState;
5
+ function isRecord(value) {
6
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
7
+ }
8
+ function isRandomAgentConfig(value) {
9
+ return (isRecord(value) &&
10
+ typeof value.id === 'string' &&
11
+ (value.role === undefined || typeof value.role === 'string'));
12
+ }
13
+ function cloneAgentConfigs(agents) {
14
+ const cloned = JSON.parse(JSON.stringify(agents));
15
+ return Array.isArray(cloned) ? cloned.filter(isRandomAgentConfig) : [];
16
+ }
17
+ function addAgentsToState(state, agents) {
18
+ if (!Array.isArray(agents))
19
+ return;
20
+ for (const agent of agents) {
21
+ if (!isRandomAgentConfig(agent))
22
+ continue;
23
+ if (state.agentConfigs.some((existing) => existing.id === agent.id))
24
+ continue;
25
+ state.agentConfigs.push(agent);
26
+ state.cluster.agents.push({ id: agent.id, role: agent.role });
27
+ }
28
+ }
@@ -0,0 +1,30 @@
1
+ import type { RandomAgentConfig, RandomSimulationState } from './random-topology-contracts';
2
+
3
+ type UnknownRecord = Record<string, unknown>;
4
+
5
+ function isRecord(value: unknown): value is UnknownRecord {
6
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
7
+ }
8
+
9
+ function isRandomAgentConfig(value: unknown): value is RandomAgentConfig {
10
+ return (
11
+ isRecord(value) &&
12
+ typeof value.id === 'string' &&
13
+ (value.role === undefined || typeof value.role === 'string')
14
+ );
15
+ }
16
+
17
+ export function cloneAgentConfigs(agents: RandomAgentConfig[]): RandomAgentConfig[] {
18
+ const cloned: unknown = JSON.parse(JSON.stringify(agents));
19
+ return Array.isArray(cloned) ? cloned.filter(isRandomAgentConfig) : [];
20
+ }
21
+
22
+ export function addAgentsToState(state: RandomSimulationState, agents: unknown): void {
23
+ if (!Array.isArray(agents)) return;
24
+ for (const agent of agents) {
25
+ if (!isRandomAgentConfig(agent)) continue;
26
+ if (state.agentConfigs.some((existing) => existing.id === agent.id)) continue;
27
+ state.agentConfigs.push(agent);
28
+ state.cluster.agents.push({ id: agent.id, role: agent.role });
29
+ }
30
+ }
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.publishTerminal = publishTerminal;
4
+ exports.evaluateAgentTrigger = evaluateAgentTrigger;
5
+ const randomTopologyRuntime = require("./random-topology-runtime");
6
+ function errorMessage(error) {
7
+ return error instanceof Error ? error.message : String(error);
8
+ }
9
+ function publishTerminal(options) {
10
+ const { context, agentConfig, topic, text, data } = options;
11
+ context.messageBus.publish({
12
+ cluster_id: context.state.cluster.id,
13
+ topic,
14
+ sender: agentConfig.id,
15
+ receiver: 'system',
16
+ content: { text, data },
17
+ });
18
+ }
19
+ function evaluateAgentTrigger(context, agentConfig, trigger, message) {
20
+ try {
21
+ return {
22
+ kind: 'match',
23
+ matches: randomTopologyRuntime.evaluateTrigger({
24
+ trigger,
25
+ message,
26
+ agent: {
27
+ id: agentConfig.id,
28
+ role: agentConfig.role,
29
+ iteration: context.iterations.get(agentConfig.id) || 0,
30
+ cluster_id: context.state.cluster.id,
31
+ },
32
+ logicEngine: context.logicEngine,
33
+ }),
34
+ };
35
+ }
36
+ catch (error) {
37
+ return {
38
+ kind: 'outcome',
39
+ outcome: {
40
+ ok: false,
41
+ reason: `trigger logic error (${agentConfig.id} on ${message.topic}): ${errorMessage(error)}`,
42
+ },
43
+ };
44
+ }
45
+ }
@@ -0,0 +1,65 @@
1
+ import type {
2
+ RandomAgentConfig,
3
+ RandomDispatchContext,
4
+ RandomTrigger,
5
+ ScenarioOutcome,
6
+ SimulationMessage,
7
+ } from './random-topology-contracts';
8
+ import randomTopologyRuntime = require('./random-topology-runtime');
9
+
10
+ export type TriggerEvaluation =
11
+ | { kind: 'match'; matches: boolean }
12
+ | { kind: 'outcome'; outcome: ScenarioOutcome };
13
+
14
+ function errorMessage(error: unknown): string {
15
+ return error instanceof Error ? error.message : String(error);
16
+ }
17
+
18
+ export function publishTerminal(options: {
19
+ context: RandomDispatchContext;
20
+ agentConfig: RandomAgentConfig;
21
+ topic: 'CLUSTER_COMPLETE' | 'CLUSTER_FAILED';
22
+ text: string;
23
+ data: Record<string, unknown>;
24
+ }): void {
25
+ const { context, agentConfig, topic, text, data } = options;
26
+ context.messageBus.publish({
27
+ cluster_id: context.state.cluster.id,
28
+ topic,
29
+ sender: agentConfig.id,
30
+ receiver: 'system',
31
+ content: { text, data },
32
+ });
33
+ }
34
+
35
+ export function evaluateAgentTrigger(
36
+ context: RandomDispatchContext,
37
+ agentConfig: RandomAgentConfig,
38
+ trigger: RandomTrigger,
39
+ message: SimulationMessage
40
+ ): TriggerEvaluation {
41
+ try {
42
+ return {
43
+ kind: 'match',
44
+ matches: randomTopologyRuntime.evaluateTrigger({
45
+ trigger,
46
+ message,
47
+ agent: {
48
+ id: agentConfig.id,
49
+ role: agentConfig.role,
50
+ iteration: context.iterations.get(agentConfig.id) || 0,
51
+ cluster_id: context.state.cluster.id,
52
+ },
53
+ logicEngine: context.logicEngine,
54
+ }),
55
+ };
56
+ } catch (error) {
57
+ return {
58
+ kind: 'outcome',
59
+ outcome: {
60
+ ok: false,
61
+ reason: `trigger logic error (${agentConfig.id} on ${message.topic}): ${errorMessage(error)}`,
62
+ },
63
+ };
64
+ }
65
+ }
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.executeAgentTrigger = executeAgentTrigger;
4
+ const simulationAgentRuntime = require("./simulation-agent-runtime");
5
+ const simulation_agent_1 = require("./simulation-agent");
6
+ const random_topology_trigger_evaluation_1 = require("./random-topology-trigger-evaluation");
7
+ const random_topology_schema_1 = require("./random-topology-schema");
8
+ function errorMessage(error) {
9
+ return error instanceof Error ? error.message : String(error);
10
+ }
11
+ async function executeAgentTrigger(context, agentConfig, trigger, message) {
12
+ const evaluation = (0, random_topology_trigger_evaluation_1.evaluateAgentTrigger)(context, agentConfig, trigger, message);
13
+ if (evaluation.kind === 'outcome')
14
+ return evaluation.outcome;
15
+ if (!evaluation.matches)
16
+ return null;
17
+ const action = trigger.action || 'execute_task';
18
+ if (action === 'stop_cluster') {
19
+ (0, random_topology_trigger_evaluation_1.publishTerminal)({
20
+ context,
21
+ agentConfig,
22
+ topic: 'CLUSTER_COMPLETE',
23
+ text: 'simulated completion',
24
+ data: { topic: message.topic },
25
+ });
26
+ return null;
27
+ }
28
+ if (action !== 'execute_task')
29
+ return null;
30
+ const nextIteration = (context.iterations.get(agentConfig.id) || 0) + 1;
31
+ context.iterations.set(agentConfig.id, nextIteration);
32
+ const maxIterations = maximumIterations(agentConfig);
33
+ if (nextIteration > maxIterations) {
34
+ (0, random_topology_trigger_evaluation_1.publishTerminal)({
35
+ context,
36
+ agentConfig,
37
+ topic: 'CLUSTER_FAILED',
38
+ text: `maxIterations exceeded: ${agentConfig.id}`,
39
+ data: { maxIterations, iteration: nextIteration },
40
+ });
41
+ return null;
42
+ }
43
+ const sampledResult = (0, random_topology_schema_1.sampleResultData)(agentConfig, context.rng);
44
+ const simulationAgent = (0, simulation_agent_1.createSimulationAgent)({
45
+ agentConfig,
46
+ cluster: context.state.cluster,
47
+ messageBus: context.messageBus,
48
+ iteration: nextIteration,
49
+ currentTaskId: `sim-${agentConfig.id}-${nextIteration}`,
50
+ });
51
+ try {
52
+ await simulationAgentRuntime.executeHook({
53
+ hook: agentConfig.hooks?.onComplete,
54
+ agent: simulationAgent,
55
+ message,
56
+ result: {
57
+ output: JSON.stringify(sampledResult || {}),
58
+ success: true,
59
+ taskId: `sim-task-${agentConfig.id}-${nextIteration}`,
60
+ },
61
+ messageBus: context.messageBus,
62
+ cluster: context.state.cluster,
63
+ });
64
+ return null;
65
+ }
66
+ catch (error) {
67
+ return {
68
+ ok: false,
69
+ reason: `hook execution failed (${agentConfig.id}): ${errorMessage(error)}`,
70
+ };
71
+ }
72
+ }
73
+ function maximumIterations(agentConfig) {
74
+ return Number.isInteger(agentConfig.maxIterations) ? Number(agentConfig.maxIterations) : 100;
75
+ }
@@ -0,0 +1,88 @@
1
+ import simulationAgentRuntime = require('./simulation-agent-runtime');
2
+ import { createSimulationAgent } from './simulation-agent';
3
+ import type {
4
+ RandomAgentConfig,
5
+ RandomDispatchContext,
6
+ RandomTrigger,
7
+ ScenarioOutcome,
8
+ SimulationMessage,
9
+ } from './random-topology-contracts';
10
+ import { evaluateAgentTrigger, publishTerminal } from './random-topology-trigger-evaluation';
11
+ import { sampleResultData } from './random-topology-schema';
12
+
13
+ type TriggerOutcome = ScenarioOutcome | null;
14
+
15
+ function errorMessage(error: unknown): string {
16
+ return error instanceof Error ? error.message : String(error);
17
+ }
18
+
19
+ export async function executeAgentTrigger(
20
+ context: RandomDispatchContext,
21
+ agentConfig: RandomAgentConfig,
22
+ trigger: RandomTrigger,
23
+ message: SimulationMessage
24
+ ): Promise<TriggerOutcome> {
25
+ const evaluation = evaluateAgentTrigger(context, agentConfig, trigger, message);
26
+ if (evaluation.kind === 'outcome') return evaluation.outcome;
27
+ if (!evaluation.matches) return null;
28
+
29
+ const action = trigger.action || 'execute_task';
30
+ if (action === 'stop_cluster') {
31
+ publishTerminal({
32
+ context,
33
+ agentConfig,
34
+ topic: 'CLUSTER_COMPLETE',
35
+ text: 'simulated completion',
36
+ data: { topic: message.topic },
37
+ });
38
+ return null;
39
+ }
40
+ if (action !== 'execute_task') return null;
41
+
42
+ const nextIteration = (context.iterations.get(agentConfig.id) || 0) + 1;
43
+ context.iterations.set(agentConfig.id, nextIteration);
44
+ const maxIterations = maximumIterations(agentConfig);
45
+ if (nextIteration > maxIterations) {
46
+ publishTerminal({
47
+ context,
48
+ agentConfig,
49
+ topic: 'CLUSTER_FAILED',
50
+ text: `maxIterations exceeded: ${agentConfig.id}`,
51
+ data: { maxIterations, iteration: nextIteration },
52
+ });
53
+ return null;
54
+ }
55
+
56
+ const sampledResult = sampleResultData(agentConfig, context.rng);
57
+ const simulationAgent = createSimulationAgent({
58
+ agentConfig,
59
+ cluster: context.state.cluster,
60
+ messageBus: context.messageBus,
61
+ iteration: nextIteration,
62
+ currentTaskId: `sim-${agentConfig.id}-${nextIteration}`,
63
+ });
64
+ try {
65
+ await simulationAgentRuntime.executeHook({
66
+ hook: agentConfig.hooks?.onComplete,
67
+ agent: simulationAgent,
68
+ message,
69
+ result: {
70
+ output: JSON.stringify(sampledResult || {}),
71
+ success: true,
72
+ taskId: `sim-task-${agentConfig.id}-${nextIteration}`,
73
+ },
74
+ messageBus: context.messageBus,
75
+ cluster: context.state.cluster,
76
+ });
77
+ return null;
78
+ } catch (error) {
79
+ return {
80
+ ok: false,
81
+ reason: `hook execution failed (${agentConfig.id}): ${errorMessage(error)}`,
82
+ };
83
+ }
84
+ }
85
+
86
+ function maximumIterations(agentConfig: RandomAgentConfig): number {
87
+ return Number.isInteger(agentConfig.maxIterations) ? Number(agentConfig.maxIterations) : 100;
88
+ }