@the-open-engine/zeroshot 6.38.1 → 6.39.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 (383) hide show
  1. package/README.md +6 -0
  2. package/cli/event-copy.js +8 -7
  3. package/cli/event-copy.ts +12 -0
  4. package/cli/index.js +67 -48
  5. package/cli/json-export.js +61 -64
  6. package/cli/json-export.ts +112 -0
  7. package/cli/message-formatter-utils.js +68 -56
  8. package/cli/message-formatter-utils.ts +121 -0
  9. package/cli/message-formatters-normal.js +124 -259
  10. package/cli/message-formatters-normal.ts +250 -0
  11. package/cli/message-formatters-watch.js +81 -84
  12. package/cli/message-formatters-watch.ts +189 -0
  13. package/lib/cluster/generated/protocol-schema.cjs +1 -1
  14. package/lib/cluster/generated/protocol-schema.mjs +1 -1
  15. package/lib/cluster/generated/protocol.d.cts +8 -0
  16. package/lib/cluster/generated/protocol.d.mts +8 -0
  17. package/lib/cluster/generated/protocol.d.ts +8 -0
  18. package/lib/clusters-registry.d.ts +23 -0
  19. package/lib/clusters-registry.js +17 -29
  20. package/lib/completion.d.ts +12 -0
  21. package/lib/completion.js +84 -94
  22. package/lib/compose-utils.d.ts +32 -0
  23. package/lib/compose-utils.js +57 -72
  24. package/lib/detached-startup.d.ts +84 -0
  25. package/lib/detached-startup.js +232 -302
  26. package/lib/docker-config.d.ts +43 -0
  27. package/lib/docker-config.js +150 -325
  28. package/lib/docker-env-auth.d.ts +17 -0
  29. package/lib/docker-env-auth.js +75 -0
  30. package/lib/git-remote-utils.d.ts +48 -0
  31. package/lib/git-remote-utils.js +147 -213
  32. package/lib/id-detector.d.ts +15 -0
  33. package/lib/id-detector.js +37 -41
  34. package/lib/path-check.d.ts +30 -0
  35. package/lib/path-check.js +42 -45
  36. package/lib/process-liveness.d.ts +16 -0
  37. package/lib/process-liveness.js +19 -12
  38. package/lib/provider-credential-path.d.ts +16 -0
  39. package/lib/provider-credential-path.js +31 -29
  40. package/lib/provider-defaults.d.ts +30 -0
  41. package/lib/provider-defaults.js +47 -42
  42. package/lib/provider-detection.d.ts +11 -0
  43. package/lib/provider-detection.js +91 -54
  44. package/lib/provider-names.d.ts +38 -0
  45. package/lib/provider-names.js +56 -64
  46. package/lib/repo-settings.d.ts +28 -0
  47. package/lib/repo-settings.js +83 -59
  48. package/lib/run-mode.d.ts +21 -0
  49. package/lib/run-mode.js +21 -20
  50. package/lib/run-plan.d.ts +28 -0
  51. package/lib/run-plan.js +17 -16
  52. package/lib/settings/claude-auth.d.ts +35 -0
  53. package/lib/settings/claude-auth.js +30 -47
  54. package/lib/settings-defaults.d.ts +20 -0
  55. package/lib/settings-defaults.js +149 -0
  56. package/lib/settings-error.d.ts +7 -0
  57. package/lib/settings-error.js +8 -0
  58. package/lib/settings-issue-providers.d.ts +10 -0
  59. package/lib/settings-issue-providers.js +12 -0
  60. package/lib/settings-models.d.ts +22 -0
  61. package/lib/settings-models.js +93 -0
  62. package/lib/settings-storage.d.ts +23 -0
  63. package/lib/settings-storage.js +205 -0
  64. package/lib/settings-validation.d.ts +7 -0
  65. package/lib/settings-validation.js +182 -0
  66. package/lib/settings.d.ts +29 -0
  67. package/lib/settings.js +41 -736
  68. package/lib/setup-apply-types.d.ts +66 -0
  69. package/lib/setup-apply-types.js +2 -0
  70. package/lib/setup-apply.d.ts +39 -0
  71. package/lib/setup-apply.js +267 -264
  72. package/lib/setup-journal.d.ts +41 -0
  73. package/lib/setup-journal.js +119 -76
  74. package/lib/setup-plan-types.d.ts +102 -0
  75. package/lib/setup-plan-types.js +2 -0
  76. package/lib/setup-plan.d.ts +30 -0
  77. package/lib/setup-plan.js +300 -324
  78. package/lib/setup-undo.d.ts +44 -0
  79. package/lib/setup-undo.js +61 -74
  80. package/lib/start-cluster-config.d.ts +26 -0
  81. package/lib/start-cluster-config.js +56 -0
  82. package/lib/start-cluster-environment.d.ts +41 -0
  83. package/lib/start-cluster-environment.js +134 -0
  84. package/lib/start-cluster-run-options.d.ts +54 -0
  85. package/lib/start-cluster-run-options.js +148 -0
  86. package/lib/start-cluster.d.ts +64 -0
  87. package/lib/start-cluster.js +98 -454
  88. package/lib/stream-json-parser.d.ts +17 -0
  89. package/lib/stream-json-parser.js +51 -52
  90. package/npm-shrinkwrap.json +6 -8
  91. package/package.json +14 -8
  92. package/scripts/postinstall.js +27 -0
  93. package/scripts/rust-distribution.js +36 -45
  94. package/src/agent/agent-command-proofs-context.js +35 -45
  95. package/src/agent/agent-command-proofs-context.ts +87 -0
  96. package/src/agent/agent-config-settings.js +19 -0
  97. package/src/agent/agent-config-settings.ts +41 -0
  98. package/src/agent/agent-config.js +122 -231
  99. package/src/agent/agent-config.ts +285 -0
  100. package/src/agent/agent-context-builder.js +38 -273
  101. package/src/agent/agent-context-builder.ts +51 -0
  102. package/src/agent/agent-context-environment-sections.js +105 -0
  103. package/src/agent/agent-context-environment-sections.ts +134 -0
  104. package/src/agent/agent-context-packs.js +165 -0
  105. package/src/agent/agent-context-packs.ts +296 -0
  106. package/src/agent/agent-context-prompt-sections.js +100 -0
  107. package/src/agent/agent-context-prompt-sections.ts +148 -0
  108. package/src/agent/agent-context-sections.js +25 -334
  109. package/src/agent/agent-context-sections.ts +36 -0
  110. package/src/agent/agent-context-sources.js +96 -149
  111. package/src/agent/agent-context-sources.ts +253 -0
  112. package/src/agent/agent-context-types.js +2 -0
  113. package/src/agent/agent-context-types.ts +132 -0
  114. package/src/agent/agent-context-validation-sections.js +73 -0
  115. package/src/agent/agent-context-validation-sections.ts +129 -0
  116. package/src/agent/agent-input-injector.js +99 -118
  117. package/src/agent/agent-input-injector.ts +195 -0
  118. package/src/agent/agent-liveness-poll.js +74 -78
  119. package/src/agent/agent-liveness-poll.ts +163 -0
  120. package/src/agent/agent-quality-gate-schema.js +77 -86
  121. package/src/agent/agent-quality-gate-schema.ts +135 -0
  122. package/src/agent/agent-quality-gates-context.js +44 -50
  123. package/src/agent/agent-quality-gates-context.ts +91 -0
  124. package/src/agent/agent-stuck-detector.js +171 -239
  125. package/src/agent/agent-stuck-detector.ts +288 -0
  126. package/src/agent/agent-trigger-evaluator.js +29 -46
  127. package/src/agent/agent-trigger-evaluator.ts +98 -0
  128. package/src/agent/context-metrics.js +110 -141
  129. package/src/agent/context-metrics.ts +261 -0
  130. package/src/agent/context-pack-builder.js +72 -358
  131. package/src/agent/context-pack-builder.ts +105 -0
  132. package/src/agent/context-pack-core.js +70 -0
  133. package/src/agent/context-pack-core.ts +96 -0
  134. package/src/agent/context-pack-selection.js +119 -0
  135. package/src/agent/context-pack-selection.ts +187 -0
  136. package/src/agent/context-pack-truncation.js +139 -0
  137. package/src/agent/context-pack-truncation.ts +208 -0
  138. package/src/agent/context-pack-types.js +2 -0
  139. package/src/agent/context-pack-types.ts +98 -0
  140. package/src/agent/context-replay-policy.js +30 -39
  141. package/src/agent/context-replay-policy.ts +71 -0
  142. package/src/agent/critical-agent-policy.js +6 -10
  143. package/src/agent/critical-agent-policy.ts +20 -0
  144. package/src/agent/guidance-queue.js +74 -87
  145. package/src/agent/guidance-queue.ts +166 -0
  146. package/src/agent/output-extraction-error-detail.js +45 -0
  147. package/src/agent/output-extraction-error-detail.ts +49 -0
  148. package/src/agent/output-extraction-failures.js +125 -0
  149. package/src/agent/output-extraction-failures.ts +149 -0
  150. package/src/agent/output-extraction-json.js +234 -0
  151. package/src/agent/output-extraction-json.ts +235 -0
  152. package/src/agent/output-extraction-pi.js +124 -0
  153. package/src/agent/output-extraction-pi.ts +137 -0
  154. package/src/agent/output-extraction-types.js +2 -0
  155. package/src/agent/output-extraction-types.ts +49 -0
  156. package/src/agent/output-extraction.js +17 -617
  157. package/src/agent/output-extraction.ts +30 -0
  158. package/src/agent/output-reformatter-errors.js +83 -0
  159. package/src/agent/output-reformatter-errors.ts +106 -0
  160. package/src/agent/output-reformatter-types.js +2 -0
  161. package/src/agent/output-reformatter-types.ts +86 -0
  162. package/src/agent/output-reformatter.js +140 -185
  163. package/src/agent/output-reformatter.ts +238 -0
  164. package/src/agent/pi-terminal-lifecycle-types.js +2 -0
  165. package/src/agent/pi-terminal-lifecycle-types.ts +41 -0
  166. package/src/agent/pi-terminal-lifecycle.js +186 -206
  167. package/src/agent/pi-terminal-lifecycle.ts +297 -0
  168. package/src/agent/provider-control-plane.js +22 -21
  169. package/src/agent/provider-control-plane.ts +52 -0
  170. package/src/agent/provider-terminal-failure-types.js +2 -0
  171. package/src/agent/provider-terminal-failure-types.ts +60 -0
  172. package/src/agent/provider-terminal-failure.js +194 -191
  173. package/src/agent/provider-terminal-failure.ts +262 -0
  174. package/src/agent/rate-limit-backoff.js +31 -74
  175. package/src/agent/rate-limit-backoff.ts +71 -0
  176. package/src/agent/schema-utils.js +85 -125
  177. package/src/agent/schema-utils.ts +148 -0
  178. package/src/agent/structured-output-error.js +34 -33
  179. package/src/agent/structured-output-error.ts +105 -0
  180. package/src/agent/validation-platform.js +27 -27
  181. package/src/agent/validation-platform.ts +49 -0
  182. package/src/agents/git-pusher-template.js +17 -34
  183. package/src/attach/attach-client.js +232 -405
  184. package/src/attach/attach-client.ts +300 -0
  185. package/src/attach/attach-server-cleanup.js +43 -0
  186. package/src/attach/attach-server-cleanup.ts +39 -0
  187. package/src/attach/attach-server-clients.js +117 -0
  188. package/src/attach/attach-server-clients.ts +122 -0
  189. package/src/attach/attach-server-events.js +38 -0
  190. package/src/attach/attach-server-events.ts +36 -0
  191. package/src/attach/attach-server-pty.js +45 -0
  192. package/src/attach/attach-server-pty.ts +64 -0
  193. package/src/attach/attach-server-runtime.js +73 -0
  194. package/src/attach/attach-server-runtime.ts +62 -0
  195. package/src/attach/attach-server-socket.js +28 -0
  196. package/src/attach/attach-server-socket.ts +23 -0
  197. package/src/attach/attach-server-types.js +2 -0
  198. package/src/attach/attach-server-types.ts +82 -0
  199. package/src/attach/attach-server.js +106 -523
  200. package/src/attach/attach-server.ts +158 -0
  201. package/src/attach/index.js +18 -35
  202. package/src/attach/index.ts +18 -0
  203. package/src/attach/protocol.js +95 -184
  204. package/src/attach/protocol.ts +181 -0
  205. package/src/attach/ring-buffer.js +76 -102
  206. package/src/attach/ring-buffer.ts +109 -0
  207. package/src/attach/send-input.js +64 -75
  208. package/src/attach/send-input.ts +94 -0
  209. package/src/attach/socket-discovery.js +164 -218
  210. package/src/attach/socket-discovery.ts +230 -0
  211. package/src/attach/socket-paths.js +42 -61
  212. package/src/attach/socket-paths.ts +81 -0
  213. package/src/claude-credentials.js +51 -54
  214. package/src/claude-credentials.ts +89 -0
  215. package/src/cluster/generated/protocol-schema.ts +1 -1
  216. package/src/cluster/generated/protocol.ts +2 -1
  217. package/src/command-proofs.js +110 -141
  218. package/src/command-proofs.ts +216 -0
  219. package/src/config-router.js +81 -73
  220. package/src/config-router.ts +131 -0
  221. package/src/copy-containment.js +191 -0
  222. package/src/copy-containment.ts +259 -0
  223. package/src/copy-worker.js +53 -30
  224. package/src/copy-worker.ts +88 -0
  225. package/src/darwin-keychain-boundary.js +80 -111
  226. package/src/darwin-keychain-boundary.ts +148 -0
  227. package/src/guidance-topics.js +4 -5
  228. package/src/guidance-topics.ts +10 -0
  229. package/src/input-helpers.js +33 -54
  230. package/src/input-helpers.ts +58 -0
  231. package/src/isolation-manager.js +59 -20
  232. package/src/ledger-sequence.js +45 -48
  233. package/src/ledger-sequence.ts +63 -0
  234. package/src/legacy-lib/clusters-registry.ts +40 -0
  235. package/src/legacy-lib/completion.ts +148 -0
  236. package/src/legacy-lib/compose-utils.ts +102 -0
  237. package/src/legacy-lib/detached-startup.ts +451 -0
  238. package/src/legacy-lib/docker-config.ts +282 -0
  239. package/src/legacy-lib/docker-env-auth.ts +116 -0
  240. package/src/legacy-lib/git-remote-utils.ts +244 -0
  241. package/src/legacy-lib/id-detector.ts +57 -0
  242. package/src/legacy-lib/js-yaml.d.ts +3 -0
  243. package/src/legacy-lib/omelette.d.ts +15 -0
  244. package/src/legacy-lib/path-check.ts +89 -0
  245. package/src/legacy-lib/process-liveness.ts +36 -0
  246. package/src/legacy-lib/provider-credential-path.ts +57 -0
  247. package/src/legacy-lib/provider-defaults.ts +114 -0
  248. package/src/legacy-lib/provider-detection.ts +67 -0
  249. package/src/legacy-lib/provider-names.ts +126 -0
  250. package/src/legacy-lib/repo-settings.ts +88 -0
  251. package/src/legacy-lib/run-mode.ts +58 -0
  252. package/src/legacy-lib/run-plan.ts +49 -0
  253. package/src/legacy-lib/settings/claude-auth.ts +80 -0
  254. package/src/legacy-lib/settings-defaults.ts +212 -0
  255. package/src/legacy-lib/settings-error.ts +8 -0
  256. package/src/legacy-lib/settings-issue-providers.ts +18 -0
  257. package/src/legacy-lib/settings-models.ts +124 -0
  258. package/src/legacy-lib/settings-storage.ts +277 -0
  259. package/src/legacy-lib/settings-validation.ts +220 -0
  260. package/src/legacy-lib/settings.ts +87 -0
  261. package/src/legacy-lib/setup-apply-types.ts +70 -0
  262. package/src/legacy-lib/setup-apply.ts +456 -0
  263. package/src/legacy-lib/setup-journal.ts +185 -0
  264. package/src/legacy-lib/setup-plan-types.ts +96 -0
  265. package/src/legacy-lib/setup-plan.ts +500 -0
  266. package/src/legacy-lib/setup-undo.ts +142 -0
  267. package/src/legacy-lib/start-cluster-config.ts +124 -0
  268. package/src/legacy-lib/start-cluster-environment.ts +166 -0
  269. package/src/legacy-lib/start-cluster-run-options.ts +281 -0
  270. package/src/legacy-lib/start-cluster.ts +237 -0
  271. package/src/legacy-lib/stream-json-parser.ts +88 -0
  272. package/src/message-buffer.js +55 -71
  273. package/src/message-buffer.ts +107 -0
  274. package/src/message-bus-bridge.js +92 -133
  275. package/src/message-bus-bridge.ts +149 -0
  276. package/src/name-generator-shared.js +220 -0
  277. package/src/name-generator-shared.ts +231 -0
  278. package/src/name-generator.js +8 -217
  279. package/src/name-generator.ts +27 -0
  280. package/src/omp-blob-root.js +83 -64
  281. package/src/omp-blob-root.ts +116 -0
  282. package/src/omp-config-overlay.js +65 -38
  283. package/src/omp-config-overlay.ts +110 -0
  284. package/src/omp-execution-fingerprint.js +38 -43
  285. package/src/omp-execution-fingerprint.ts +92 -0
  286. package/src/omp-session-limits.js +10 -15
  287. package/src/omp-session-limits.ts +53 -0
  288. package/src/omp-session-partition.js +2 -2
  289. package/src/omp-session-verifier.js +1 -1
  290. package/src/orchestrator.js +32 -7
  291. package/src/pr-body-template.js +71 -0
  292. package/src/providers/anthropic/index.js +3 -1
  293. package/src/providers/anthropic/index.ts +13 -0
  294. package/src/providers/capabilities.js +19 -27
  295. package/src/providers/capabilities.ts +44 -0
  296. package/src/providers/google/index.js +3 -1
  297. package/src/providers/google/index.ts +13 -0
  298. package/src/providers/openai/index.js +3 -1
  299. package/src/providers/openai/index.ts +13 -0
  300. package/src/providers/opencode/index.js +3 -1
  301. package/src/providers/opencode/index.ts +13 -0
  302. package/src/quality-gates.js +67 -127
  303. package/src/quality-gates.ts +149 -0
  304. package/src/repo-settings-access.js +40 -0
  305. package/src/repo-settings-access.ts +64 -0
  306. package/src/schemas/sub-cluster.js +127 -183
  307. package/src/schemas/sub-cluster.ts +238 -0
  308. package/src/state-snapshot-normalization.js +224 -0
  309. package/src/state-snapshot-normalization.ts +222 -0
  310. package/src/state-snapshot.js +192 -359
  311. package/src/state-snapshot.ts +291 -0
  312. package/src/state-snapshotter.js +118 -130
  313. package/src/state-snapshotter.ts +167 -0
  314. package/src/sub-cluster-wrapper.js +4 -13
  315. package/src/task-run-model-args.js +87 -124
  316. package/src/task-run-model-args.ts +204 -0
  317. package/src/task-runner.js +5 -25
  318. package/src/task-runner.ts +28 -0
  319. package/src/task-startup-error.js +73 -58
  320. package/src/task-startup-error.ts +126 -0
  321. package/src/template-validation/consensus-gate-contracts.js +2 -0
  322. package/src/template-validation/consensus-gate-contracts.ts +70 -0
  323. package/src/template-validation/consensus-gate-scenarios.js +76 -0
  324. package/src/template-validation/consensus-gate-scenarios.ts +130 -0
  325. package/src/template-validation/consensus-gate-stage.js +34 -0
  326. package/src/template-validation/consensus-gate-stage.ts +56 -0
  327. package/src/template-validation/random-topology-contracts.js +2 -0
  328. package/src/template-validation/random-topology-contracts.ts +54 -0
  329. package/src/template-validation/random-topology-dispatch.js +25 -0
  330. package/src/template-validation/random-topology-dispatch.ts +33 -0
  331. package/src/template-validation/random-topology-message-loop.js +53 -0
  332. package/src/template-validation/random-topology-message-loop.ts +73 -0
  333. package/src/template-validation/random-topology-operations.js +79 -0
  334. package/src/template-validation/random-topology-operations.ts +101 -0
  335. package/src/template-validation/random-topology-runtime.js +25 -0
  336. package/src/template-validation/random-topology-runtime.ts +43 -0
  337. package/src/template-validation/random-topology-scenario.js +52 -0
  338. package/src/template-validation/random-topology-scenario.ts +57 -0
  339. package/src/template-validation/random-topology-schema.js +159 -0
  340. package/src/template-validation/random-topology-schema.ts +190 -0
  341. package/src/template-validation/random-topology-state.js +28 -0
  342. package/src/template-validation/random-topology-state.ts +30 -0
  343. package/src/template-validation/random-topology-trigger-evaluation.js +45 -0
  344. package/src/template-validation/random-topology-trigger-evaluation.ts +65 -0
  345. package/src/template-validation/random-topology-trigger.js +75 -0
  346. package/src/template-validation/random-topology-trigger.ts +88 -0
  347. package/src/template-validation/report-formatter.js +40 -46
  348. package/src/template-validation/report-formatter.ts +101 -0
  349. package/src/template-validation/simulate-consensus-gates.js +111 -302
  350. package/src/template-validation/simulate-consensus-gates.ts +196 -0
  351. package/src/template-validation/simulate-random-topology.js +26 -519
  352. package/src/template-validation/simulate-random-topology.ts +57 -0
  353. package/src/template-validation/simulate-two-stage-validation.js +41 -265
  354. package/src/template-validation/simulate-two-stage-validation.ts +55 -0
  355. package/src/template-validation/simulation-agent-runtime.js +25 -0
  356. package/src/template-validation/simulation-agent-runtime.ts +40 -0
  357. package/src/template-validation/simulation-agent.js +29 -0
  358. package/src/template-validation/simulation-agent.ts +73 -0
  359. package/src/template-validation/simulation-runtime.js +34 -0
  360. package/src/template-validation/simulation-runtime.ts +72 -0
  361. package/src/template-validation/two-stage-contracts.js +2 -0
  362. package/src/template-validation/two-stage-contracts.ts +41 -0
  363. package/src/template-validation/two-stage-inputs.js +21 -0
  364. package/src/template-validation/two-stage-inputs.ts +29 -0
  365. package/src/template-validation/two-stage-results.js +30 -0
  366. package/src/template-validation/two-stage-results.ts +40 -0
  367. package/src/template-validation/two-stage-scenario.js +86 -0
  368. package/src/template-validation/two-stage-scenario.ts +120 -0
  369. package/src/worktree-claude-config.js +182 -220
  370. package/src/worktree-claude-config.ts +272 -0
  371. package/src/worktree-tooling-env.js +103 -125
  372. package/src/worktree-tooling-env.ts +142 -0
  373. package/task-lib/completion.js +2 -3
  374. package/task-lib/completion.ts +9 -0
  375. package/task-lib/config.js +1 -4
  376. package/task-lib/config.ts +11 -0
  377. package/task-lib/name-generator.js +4 -226
  378. package/task-lib/name-generator.ts +11 -0
  379. package/task-lib/omp-session-cleanup.js +1 -1
  380. package/task-lib/omp-storage-root.js +8 -12
  381. package/task-lib/omp-storage-root.ts +62 -0
  382. package/task-lib/process-termination.js +143 -166
  383. 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
+ }