@elizaos/plugin-training 2.0.3-beta.6 → 2.0.3-beta.7

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 (363) hide show
  1. package/dist/backends/native.d.ts +96 -0
  2. package/dist/backends/native.d.ts.map +1 -0
  3. package/dist/backends/native.js +308 -0
  4. package/dist/backends/native.js.map +1 -0
  5. package/dist/cli/train.d.ts +22 -0
  6. package/dist/cli/train.d.ts.map +1 -0
  7. package/dist/cli/train.js +219 -0
  8. package/dist/cli/train.js.map +1 -0
  9. package/dist/core/action-benchmark-runner.d.ts +55 -0
  10. package/dist/core/action-benchmark-runner.d.ts.map +1 -0
  11. package/dist/core/action-benchmark-runner.js +341 -0
  12. package/dist/core/action-benchmark-runner.js.map +1 -0
  13. package/dist/core/artifact-store.d.ts +72 -0
  14. package/dist/core/artifact-store.d.ts.map +1 -0
  15. package/dist/core/artifact-store.js +50 -0
  16. package/dist/core/artifact-store.js.map +1 -0
  17. package/dist/core/benchmark-matrix-artifact.d.ts +102 -0
  18. package/dist/core/benchmark-matrix-artifact.d.ts.map +1 -0
  19. package/dist/core/benchmark-matrix-artifact.js +381 -0
  20. package/dist/core/benchmark-matrix-artifact.js.map +1 -0
  21. package/dist/core/benchmark-vs-cerebras-runner.d.ts +37 -0
  22. package/dist/core/benchmark-vs-cerebras-runner.d.ts.map +1 -0
  23. package/dist/core/benchmark-vs-cerebras-runner.js +151 -0
  24. package/dist/core/benchmark-vs-cerebras-runner.js.map +1 -0
  25. package/dist/core/cerebras-eval-model.d.ts +54 -0
  26. package/dist/core/cerebras-eval-model.d.ts.map +1 -0
  27. package/dist/core/cerebras-eval-model.js +249 -0
  28. package/dist/core/cerebras-eval-model.js.map +1 -0
  29. package/dist/core/cli.d.ts +15 -0
  30. package/dist/core/cli.d.ts.map +1 -0
  31. package/dist/core/cli.js +1003 -0
  32. package/dist/core/cli.js.map +1 -0
  33. package/dist/core/context-audit.d.ts +51 -0
  34. package/dist/core/context-audit.d.ts.map +1 -0
  35. package/dist/core/context-audit.js +166 -0
  36. package/dist/core/context-audit.js.map +1 -0
  37. package/dist/core/context-catalog.d.ts +47 -0
  38. package/dist/core/context-catalog.d.ts.map +1 -0
  39. package/dist/core/context-catalog.js +269 -0
  40. package/dist/core/context-catalog.js.map +1 -0
  41. package/dist/core/context-types.d.ts +3 -0
  42. package/dist/core/context-types.d.ts.map +1 -0
  43. package/dist/core/context-types.js +18 -0
  44. package/dist/core/context-types.js.map +1 -0
  45. package/dist/core/dataset-generator.d.ts +135 -0
  46. package/dist/core/dataset-generator.d.ts.map +1 -0
  47. package/dist/core/dataset-generator.js +895 -0
  48. package/dist/core/dataset-generator.js.map +1 -0
  49. package/dist/core/eliza1-benchmark-recipe.d.ts +18 -0
  50. package/dist/core/eliza1-benchmark-recipe.d.ts.map +1 -0
  51. package/dist/core/eliza1-benchmark-recipe.js +64 -0
  52. package/dist/core/eliza1-benchmark-recipe.js.map +1 -0
  53. package/dist/core/eliza1-bundle-stager.d.ts +57 -0
  54. package/dist/core/eliza1-bundle-stager.d.ts.map +1 -0
  55. package/dist/core/eliza1-bundle-stager.js +149 -0
  56. package/dist/core/eliza1-bundle-stager.js.map +1 -0
  57. package/dist/core/ensure-cron-job.d.ts +53 -0
  58. package/dist/core/ensure-cron-job.d.ts.map +1 -0
  59. package/dist/core/ensure-cron-job.js +51 -0
  60. package/dist/core/ensure-cron-job.js.map +1 -0
  61. package/dist/core/eval-comparison-artifact.d.ts +72 -0
  62. package/dist/core/eval-comparison-artifact.d.ts.map +1 -0
  63. package/dist/core/eval-comparison-artifact.js +281 -0
  64. package/dist/core/eval-comparison-artifact.js.map +1 -0
  65. package/dist/core/feed-generation-runner.d.ts +37 -0
  66. package/dist/core/feed-generation-runner.d.ts.map +1 -0
  67. package/dist/core/feed-generation-runner.js +232 -0
  68. package/dist/core/feed-generation-runner.js.map +1 -0
  69. package/dist/core/html-escape.d.ts +5 -0
  70. package/dist/core/html-escape.d.ts.map +1 -0
  71. package/dist/core/html-escape.js +11 -0
  72. package/dist/core/html-escape.js.map +1 -0
  73. package/dist/core/huggingface-dataset-ingest.d.ts +52 -0
  74. package/dist/core/huggingface-dataset-ingest.d.ts.map +1 -0
  75. package/dist/core/huggingface-dataset-ingest.js +134 -0
  76. package/dist/core/huggingface-dataset-ingest.js.map +1 -0
  77. package/dist/core/index.d.ts +29 -0
  78. package/dist/core/index.d.ts.map +1 -0
  79. package/dist/core/index.js +204 -0
  80. package/dist/core/index.js.map +1 -0
  81. package/dist/core/privacy-filter.d.ts +95 -0
  82. package/dist/core/privacy-filter.d.ts.map +1 -0
  83. package/dist/core/privacy-filter.js +324 -0
  84. package/dist/core/privacy-filter.js.map +1 -0
  85. package/dist/core/promotion-gate.d.ts +117 -0
  86. package/dist/core/promotion-gate.d.ts.map +1 -0
  87. package/dist/core/promotion-gate.js +85 -0
  88. package/dist/core/promotion-gate.js.map +1 -0
  89. package/dist/core/promotion-persist.d.ts +116 -0
  90. package/dist/core/promotion-persist.d.ts.map +1 -0
  91. package/dist/core/promotion-persist.js +93 -0
  92. package/dist/core/promotion-persist.js.map +1 -0
  93. package/dist/core/prompt-compare.d.ts +99 -0
  94. package/dist/core/prompt-compare.d.ts.map +1 -0
  95. package/dist/core/prompt-compare.js +210 -0
  96. package/dist/core/prompt-compare.js.map +1 -0
  97. package/dist/core/replay-validator.d.ts +136 -0
  98. package/dist/core/replay-validator.d.ts.map +1 -0
  99. package/dist/core/replay-validator.js +312 -0
  100. package/dist/core/replay-validator.js.map +1 -0
  101. package/dist/core/roleplay-executor.d.ts +123 -0
  102. package/dist/core/roleplay-executor.d.ts.map +1 -0
  103. package/dist/core/roleplay-executor.js +675 -0
  104. package/dist/core/roleplay-executor.js.map +1 -0
  105. package/dist/core/roleplay-trajectories.d.ts +54 -0
  106. package/dist/core/roleplay-trajectories.d.ts.map +1 -0
  107. package/dist/core/roleplay-trajectories.js +88 -0
  108. package/dist/core/roleplay-trajectories.js.map +1 -0
  109. package/dist/core/scenario-blueprints.d.ts +62 -0
  110. package/dist/core/scenario-blueprints.d.ts.map +1 -0
  111. package/dist/core/scenario-blueprints.js +850 -0
  112. package/dist/core/scenario-blueprints.js.map +1 -0
  113. package/dist/core/scenario-runner.d.ts +36 -0
  114. package/dist/core/scenario-runner.d.ts.map +1 -0
  115. package/dist/core/scenario-runner.js +216 -0
  116. package/dist/core/scenario-runner.js.map +1 -0
  117. package/dist/core/skill-scoring-cron.d.ts +57 -0
  118. package/dist/core/skill-scoring-cron.d.ts.map +1 -0
  119. package/dist/core/skill-scoring-cron.js +180 -0
  120. package/dist/core/skill-scoring-cron.js.map +1 -0
  121. package/dist/core/test-trajectory-collector.d.ts +37 -0
  122. package/dist/core/test-trajectory-collector.d.ts.map +1 -0
  123. package/dist/core/test-trajectory-collector.js +225 -0
  124. package/dist/core/test-trajectory-collector.js.map +1 -0
  125. package/dist/core/track-c-queue-task.d.ts +37 -0
  126. package/dist/core/track-c-queue-task.d.ts.map +1 -0
  127. package/dist/core/track-c-queue-task.js +104 -0
  128. package/dist/core/track-c-queue-task.js.map +1 -0
  129. package/dist/core/training-analysis-index.d.ts +104 -0
  130. package/dist/core/training-analysis-index.d.ts.map +1 -0
  131. package/dist/core/training-analysis-index.js +3297 -0
  132. package/dist/core/training-analysis-index.js.map +1 -0
  133. package/dist/core/training-collection-runner.d.ts +508 -0
  134. package/dist/core/training-collection-runner.d.ts.map +1 -0
  135. package/dist/core/training-collection-runner.js +2299 -0
  136. package/dist/core/training-collection-runner.js.map +1 -0
  137. package/dist/core/training-config.d.ts +52 -0
  138. package/dist/core/training-config.d.ts.map +1 -0
  139. package/dist/core/training-config.js +117 -0
  140. package/dist/core/training-config.js.map +1 -0
  141. package/dist/core/training-orchestrator.d.ts +112 -0
  142. package/dist/core/training-orchestrator.d.ts.map +1 -0
  143. package/dist/core/training-orchestrator.js +729 -0
  144. package/dist/core/training-orchestrator.js.map +1 -0
  145. package/dist/core/training-readiness-report.d.ts +52 -0
  146. package/dist/core/training-readiness-report.d.ts.map +1 -0
  147. package/dist/core/training-readiness-report.js +765 -0
  148. package/dist/core/training-readiness-report.js.map +1 -0
  149. package/dist/core/trajectory-consumer.d.ts +15 -0
  150. package/dist/core/trajectory-consumer.d.ts.map +1 -0
  151. package/dist/core/trajectory-consumer.js +61 -0
  152. package/dist/core/trajectory-consumer.js.map +1 -0
  153. package/dist/core/trajectory-export-bundle.d.ts +95 -0
  154. package/dist/core/trajectory-export-bundle.d.ts.map +1 -0
  155. package/dist/core/trajectory-export-bundle.js +561 -0
  156. package/dist/core/trajectory-export-bundle.js.map +1 -0
  157. package/dist/core/trajectory-export-cron.d.ts +57 -0
  158. package/dist/core/trajectory-export-cron.d.ts.map +1 -0
  159. package/dist/core/trajectory-export-cron.js +170 -0
  160. package/dist/core/trajectory-export-cron.js.map +1 -0
  161. package/dist/core/trajectory-hf-upload.d.ts +50 -0
  162. package/dist/core/trajectory-hf-upload.d.ts.map +1 -0
  163. package/dist/core/trajectory-hf-upload.js +111 -0
  164. package/dist/core/trajectory-hf-upload.js.map +1 -0
  165. package/dist/core/trajectory-task-datasets.d.ts +62 -0
  166. package/dist/core/trajectory-task-datasets.d.ts.map +1 -0
  167. package/dist/core/trajectory-task-datasets.js +427 -0
  168. package/dist/core/trajectory-task-datasets.js.map +1 -0
  169. package/dist/core/wait-for-service.d.ts +25 -0
  170. package/dist/core/wait-for-service.d.ts.map +1 -0
  171. package/dist/core/wait-for-service.js +19 -0
  172. package/dist/core/wait-for-service.js.map +1 -0
  173. package/dist/core/workspace-runtime.d.ts +4 -0
  174. package/dist/core/workspace-runtime.d.ts.map +1 -0
  175. package/dist/core/workspace-runtime.js +25 -0
  176. package/dist/core/workspace-runtime.js.map +1 -0
  177. package/dist/dspy/artifact.d.ts +54 -0
  178. package/dist/dspy/artifact.d.ts.map +1 -0
  179. package/dist/dspy/artifact.js +61 -0
  180. package/dist/dspy/artifact.js.map +1 -0
  181. package/dist/dspy/chain-of-thought.d.ts +27 -0
  182. package/dist/dspy/chain-of-thought.d.ts.map +1 -0
  183. package/dist/dspy/chain-of-thought.js +43 -0
  184. package/dist/dspy/chain-of-thought.js.map +1 -0
  185. package/dist/dspy/examples.d.ts +72 -0
  186. package/dist/dspy/examples.d.ts.map +1 -0
  187. package/dist/dspy/examples.js +105 -0
  188. package/dist/dspy/examples.js.map +1 -0
  189. package/dist/dspy/index.d.ts +15 -0
  190. package/dist/dspy/index.d.ts.map +1 -0
  191. package/dist/dspy/index.js +40 -0
  192. package/dist/dspy/index.js.map +1 -0
  193. package/dist/dspy/lm-adapter.d.ts +100 -0
  194. package/dist/dspy/lm-adapter.d.ts.map +1 -0
  195. package/dist/dspy/lm-adapter.js +81 -0
  196. package/dist/dspy/lm-adapter.js.map +1 -0
  197. package/dist/dspy/optimizers/dspy-bootstrap-fewshot.d.ts +23 -0
  198. package/dist/dspy/optimizers/dspy-bootstrap-fewshot.d.ts.map +1 -0
  199. package/dist/dspy/optimizers/dspy-bootstrap-fewshot.js +85 -0
  200. package/dist/dspy/optimizers/dspy-bootstrap-fewshot.js.map +1 -0
  201. package/dist/dspy/optimizers/dspy-copro.d.ts +29 -0
  202. package/dist/dspy/optimizers/dspy-copro.d.ts.map +1 -0
  203. package/dist/dspy/optimizers/dspy-copro.js +141 -0
  204. package/dist/dspy/optimizers/dspy-copro.js.map +1 -0
  205. package/dist/dspy/optimizers/dspy-mipro.d.ts +37 -0
  206. package/dist/dspy/optimizers/dspy-mipro.d.ts.map +1 -0
  207. package/dist/dspy/optimizers/dspy-mipro.js +194 -0
  208. package/dist/dspy/optimizers/dspy-mipro.js.map +1 -0
  209. package/dist/dspy/optimizers/index.d.ts +5 -0
  210. package/dist/dspy/optimizers/index.d.ts.map +1 -0
  211. package/dist/dspy/optimizers/index.js +11 -0
  212. package/dist/dspy/optimizers/index.js.map +1 -0
  213. package/dist/dspy/optimizers/types.d.ts +39 -0
  214. package/dist/dspy/optimizers/types.d.ts.map +1 -0
  215. package/dist/dspy/optimizers/types.js +1 -0
  216. package/dist/dspy/optimizers/types.js.map +1 -0
  217. package/dist/dspy/predict.d.ts +49 -0
  218. package/dist/dspy/predict.d.ts.map +1 -0
  219. package/dist/dspy/predict.js +73 -0
  220. package/dist/dspy/predict.js.map +1 -0
  221. package/dist/dspy/signature.d.ts +88 -0
  222. package/dist/dspy/signature.d.ts.map +1 -0
  223. package/dist/dspy/signature.js +205 -0
  224. package/dist/dspy/signature.js.map +1 -0
  225. package/dist/index.d.ts +15 -0
  226. package/dist/index.d.ts.map +1 -0
  227. package/dist/index.js +15 -0
  228. package/dist/index.js.map +1 -0
  229. package/dist/optimizers/bootstrap-fewshot.d.ts +42 -0
  230. package/dist/optimizers/bootstrap-fewshot.d.ts.map +1 -0
  231. package/dist/optimizers/bootstrap-fewshot.js +92 -0
  232. package/dist/optimizers/bootstrap-fewshot.js.map +1 -0
  233. package/dist/optimizers/gepa.d.ts +63 -0
  234. package/dist/optimizers/gepa.d.ts.map +1 -0
  235. package/dist/optimizers/gepa.js +232 -0
  236. package/dist/optimizers/gepa.js.map +1 -0
  237. package/dist/optimizers/index.d.ts +7 -0
  238. package/dist/optimizers/index.d.ts.map +1 -0
  239. package/dist/optimizers/index.js +51 -0
  240. package/dist/optimizers/index.js.map +1 -0
  241. package/dist/optimizers/instruction-search.d.ts +39 -0
  242. package/dist/optimizers/instruction-search.d.ts.map +1 -0
  243. package/dist/optimizers/instruction-search.js +108 -0
  244. package/dist/optimizers/instruction-search.js.map +1 -0
  245. package/dist/optimizers/prompt-evolution.d.ts +39 -0
  246. package/dist/optimizers/prompt-evolution.d.ts.map +1 -0
  247. package/dist/optimizers/prompt-evolution.js +101 -0
  248. package/dist/optimizers/prompt-evolution.js.map +1 -0
  249. package/dist/optimizers/scoring.d.ts +139 -0
  250. package/dist/optimizers/scoring.d.ts.map +1 -0
  251. package/dist/optimizers/scoring.js +299 -0
  252. package/dist/optimizers/scoring.js.map +1 -0
  253. package/dist/optimizers/types.d.ts +105 -0
  254. package/dist/optimizers/types.d.ts.map +1 -0
  255. package/dist/optimizers/types.js +1 -0
  256. package/dist/optimizers/types.js.map +1 -0
  257. package/dist/register-runtime.d.ts +3 -0
  258. package/dist/register-runtime.d.ts.map +1 -0
  259. package/dist/register-runtime.js +60 -0
  260. package/dist/register-runtime.js.map +1 -0
  261. package/dist/register-terminal-view.d.ts +15 -0
  262. package/dist/register-terminal-view.d.ts.map +1 -0
  263. package/dist/register-terminal-view.js +31 -0
  264. package/dist/register-terminal-view.js.map +1 -0
  265. package/dist/routes/experience-routes.d.ts +21 -0
  266. package/dist/routes/experience-routes.d.ts.map +1 -0
  267. package/dist/routes/experience-routes.js +513 -0
  268. package/dist/routes/experience-routes.js.map +1 -0
  269. package/dist/routes/index.d.ts +5 -0
  270. package/dist/routes/index.d.ts.map +1 -0
  271. package/dist/routes/index.js +17 -0
  272. package/dist/routes/index.js.map +1 -0
  273. package/dist/routes/training-routes.d.ts +10 -0
  274. package/dist/routes/training-routes.d.ts.map +1 -0
  275. package/dist/routes/training-routes.js +1239 -0
  276. package/dist/routes/training-routes.js.map +1 -0
  277. package/dist/routes/training-vast-routes.d.ts +35 -0
  278. package/dist/routes/training-vast-routes.d.ts.map +1 -0
  279. package/dist/routes/training-vast-routes.js +249 -0
  280. package/dist/routes/training-vast-routes.js.map +1 -0
  281. package/dist/routes/trajectory-routes.d.ts +19 -0
  282. package/dist/routes/trajectory-routes.d.ts.map +1 -0
  283. package/dist/routes/trajectory-routes.js +1122 -0
  284. package/dist/routes/trajectory-routes.js.map +1 -0
  285. package/dist/services/index.d.ts +9 -0
  286. package/dist/services/index.d.ts.map +1 -0
  287. package/dist/services/index.js +63 -0
  288. package/dist/services/index.js.map +1 -0
  289. package/dist/services/training-backend-check.d.ts +8 -0
  290. package/dist/services/training-backend-check.d.ts.map +1 -0
  291. package/dist/services/training-backend-check.js +31 -0
  292. package/dist/services/training-backend-check.js.map +1 -0
  293. package/dist/services/training-service-like.d.ts +40 -0
  294. package/dist/services/training-service-like.d.ts.map +1 -0
  295. package/dist/services/training-service-like.js +1 -0
  296. package/dist/services/training-service-like.js.map +1 -0
  297. package/dist/services/training-service-registry.d.ts +4 -0
  298. package/dist/services/training-service-registry.d.ts.map +1 -0
  299. package/dist/services/training-service-registry.js +12 -0
  300. package/dist/services/training-service-registry.js.map +1 -0
  301. package/dist/services/training-service.d.ts +59 -0
  302. package/dist/services/training-service.d.ts.map +1 -0
  303. package/dist/services/training-service.js +154 -0
  304. package/dist/services/training-service.js.map +1 -0
  305. package/dist/services/training-trigger.d.ts +177 -0
  306. package/dist/services/training-trigger.d.ts.map +1 -0
  307. package/dist/services/training-trigger.js +300 -0
  308. package/dist/services/training-trigger.js.map +1 -0
  309. package/dist/services/training-vast-service.d.ts +149 -0
  310. package/dist/services/training-vast-service.d.ts.map +1 -0
  311. package/dist/services/training-vast-service.js +648 -0
  312. package/dist/services/training-vast-service.js.map +1 -0
  313. package/dist/services/vast-inference-stats.d.ts +37 -0
  314. package/dist/services/vast-inference-stats.d.ts.map +1 -0
  315. package/dist/services/vast-inference-stats.js +81 -0
  316. package/dist/services/vast-inference-stats.js.map +1 -0
  317. package/dist/services/vast-job-store.d.ts +74 -0
  318. package/dist/services/vast-job-store.d.ts.map +1 -0
  319. package/dist/services/vast-job-store.js +194 -0
  320. package/dist/services/vast-job-store.js.map +1 -0
  321. package/dist/services/vast-subprocess.d.ts +27 -0
  322. package/dist/services/vast-subprocess.d.ts.map +1 -0
  323. package/dist/services/vast-subprocess.js +78 -0
  324. package/dist/services/vast-subprocess.js.map +1 -0
  325. package/dist/setup-routes.d.ts +17 -0
  326. package/dist/setup-routes.d.ts.map +1 -0
  327. package/dist/setup-routes.js +319 -0
  328. package/dist/setup-routes.js.map +1 -0
  329. package/dist/ui/FineTuningSpatialView.d.ts +49 -0
  330. package/dist/ui/FineTuningSpatialView.d.ts.map +1 -0
  331. package/dist/ui/FineTuningSpatialView.js +154 -0
  332. package/dist/ui/FineTuningSpatialView.js.map +1 -0
  333. package/dist/ui/FineTuningView.d.ts +7 -0
  334. package/dist/ui/FineTuningView.d.ts.map +1 -0
  335. package/dist/ui/FineTuningView.helpers.d.ts +17 -0
  336. package/dist/ui/FineTuningView.helpers.d.ts.map +1 -0
  337. package/dist/ui/FineTuningView.helpers.js +30 -0
  338. package/dist/ui/FineTuningView.helpers.js.map +1 -0
  339. package/dist/ui/FineTuningView.interact.d.ts +2 -0
  340. package/dist/ui/FineTuningView.interact.d.ts.map +1 -0
  341. package/dist/ui/FineTuningView.interact.js +300 -0
  342. package/dist/ui/FineTuningView.interact.js.map +1 -0
  343. package/dist/ui/FineTuningView.js +4653 -0
  344. package/dist/ui/FineTuningView.js.map +1 -0
  345. package/dist/ui/fine-tuning-panels.d.ts +100 -0
  346. package/dist/ui/fine-tuning-panels.d.ts.map +1 -0
  347. package/dist/ui/fine-tuning-panels.helpers.d.ts +19 -0
  348. package/dist/ui/fine-tuning-panels.helpers.d.ts.map +1 -0
  349. package/dist/ui/fine-tuning-panels.helpers.js +77 -0
  350. package/dist/ui/fine-tuning-panels.helpers.js.map +1 -0
  351. package/dist/ui/fine-tuning-panels.js +928 -0
  352. package/dist/ui/fine-tuning-panels.js.map +1 -0
  353. package/dist/ui/index.d.ts +5 -0
  354. package/dist/ui/index.d.ts.map +1 -0
  355. package/dist/ui/index.js +5 -0
  356. package/dist/ui/index.js.map +1 -0
  357. package/dist/ui/training-view-bundle.d.ts +3 -0
  358. package/dist/ui/training-view-bundle.d.ts.map +1 -0
  359. package/dist/ui/training-view-bundle.js +7 -0
  360. package/dist/ui/training-view-bundle.js.map +1 -0
  361. package/dist/views/bundle.js +5312 -0
  362. package/dist/views/bundle.js.map +1 -0
  363. package/package.json +7 -7
@@ -0,0 +1,1239 @@
1
+ import { parsePositiveInteger } from "@elizaos/shared";
2
+ import { runActionBenchmark } from "../core/action-benchmark-runner.js";
3
+ import {
4
+ writeBenchmarkMatrixArtifact,
5
+ writeBenchmarkMatrixArtifactFromArtifacts
6
+ } from "../core/benchmark-matrix-artifact.js";
7
+ import { runBenchmarkVsCerebras } from "../core/benchmark-vs-cerebras-runner.js";
8
+ import { AGENT_CONTEXTS } from "../core/context-types.js";
9
+ import { stageEliza1Bundle } from "../core/eliza1-bundle-stager.js";
10
+ import {
11
+ runLocalEvalComparison,
12
+ writeEvalComparisonArtifact
13
+ } from "../core/eval-comparison-artifact.js";
14
+ import { runFeedGeneration } from "../core/feed-generation-runner.js";
15
+ import { ingestHuggingFaceDataset } from "../core/huggingface-dataset-ingest.js";
16
+ import { createHashAnonymizer } from "../core/privacy-filter.js";
17
+ import { runScenarios } from "../core/scenario-runner.js";
18
+ import { buildTrainingAnalysisIndex } from "../core/training-analysis-index.js";
19
+ import {
20
+ buildTrainingCollectionPreflightWithProbes,
21
+ listTrainingCollections,
22
+ runTrainingCollection
23
+ } from "../core/training-collection-runner.js";
24
+ import {
25
+ ALL_TRAINING_BACKENDS,
26
+ ALL_TRAINING_TASKS,
27
+ loadTrainingConfig,
28
+ normalizeTrainingConfig,
29
+ saveTrainingConfig
30
+ } from "../core/training-config.js";
31
+ import {
32
+ listRuns,
33
+ loadRun,
34
+ triggerTraining
35
+ } from "../core/training-orchestrator.js";
36
+ import { writeTrainingReadinessReport } from "../core/training-readiness-report.js";
37
+ import { resolveHfUploadConfig } from "../core/trajectory-hf-upload.js";
38
+ import {
39
+ buildTaskRecord
40
+ } from "../core/trajectory-task-datasets.js";
41
+ import { detectAvailableBackends } from "../services/training-backend-check.js";
42
+ import { isNotImplementedError } from "../services/training-service.js";
43
+ import {
44
+ TRAINING_TRIGGER_SERVICE
45
+ } from "../services/training-trigger.js";
46
+ function resolveStringSetting(value) {
47
+ return typeof value === "string" && value.trim() ? value : void 0;
48
+ }
49
+ function resolveBooleanSetting(value) {
50
+ return typeof value === "boolean" ? value : void 0;
51
+ }
52
+ function sendServiceError(error, res, err, status = 400) {
53
+ if (isNotImplementedError(err)) {
54
+ error(res, err.message, 501);
55
+ return;
56
+ }
57
+ error(res, String(err), status);
58
+ }
59
+ function emptyTaskCounters() {
60
+ return buildTaskRecord(() => 0);
61
+ }
62
+ function getTriggerEntry(runtime) {
63
+ if (!runtime) return null;
64
+ const services = runtime.services;
65
+ if (!services) return null;
66
+ const entries = services.get(TRAINING_TRIGGER_SERVICE);
67
+ if (!Array.isArray(entries) || entries.length === 0) return null;
68
+ const candidate = entries[0];
69
+ if (candidate && typeof candidate === "object" && typeof candidate.notifyTrajectoryCompleted === "function") {
70
+ return candidate;
71
+ }
72
+ return null;
73
+ }
74
+ const AGENT_DECISIONS = ["RESPOND", "IGNORE", "STOP"];
75
+ function narrowAgentContexts(input) {
76
+ if (!Array.isArray(input)) return void 0;
77
+ const out = [];
78
+ for (const entry of input) {
79
+ if (typeof entry === "string" && AGENT_CONTEXTS.includes(entry)) {
80
+ out.push(entry);
81
+ }
82
+ }
83
+ return out.length > 0 ? out : void 0;
84
+ }
85
+ function narrowAgentDecisions(input) {
86
+ if (!Array.isArray(input)) return void 0;
87
+ const out = [];
88
+ for (const entry of input) {
89
+ if (typeof entry === "string" && AGENT_DECISIONS.includes(entry)) {
90
+ out.push(entry);
91
+ }
92
+ }
93
+ return out.length > 0 ? out : void 0;
94
+ }
95
+ function narrowTrainingTasks(input) {
96
+ if (!Array.isArray(input)) return void 0;
97
+ const out = [];
98
+ for (const entry of input) {
99
+ if (typeof entry === "string" && ALL_TRAINING_TASKS.includes(entry)) {
100
+ out.push(entry);
101
+ }
102
+ }
103
+ return out.length > 0 ? out : void 0;
104
+ }
105
+ function normalizeRunId(input) {
106
+ return typeof input === "string" && input.trim().length > 0 ? input.trim() : void 0;
107
+ }
108
+ function trajectoryHasRunId(trajectory, runId) {
109
+ const record = trajectory;
110
+ if (normalizeRunId(record.runId) === runId) return true;
111
+ if (normalizeRunId(record.metadata?.runId) === runId) return true;
112
+ if (normalizeRunId(record.metadata?.appRunId) === runId) return true;
113
+ for (const step of trajectory.steps ?? []) {
114
+ for (const call of step.llmCalls ?? []) {
115
+ if (normalizeRunId(call.runId) === runId) return true;
116
+ }
117
+ for (const access of step.providerAccesses ?? []) {
118
+ if (normalizeRunId(access.runId) === runId) return true;
119
+ }
120
+ }
121
+ return false;
122
+ }
123
+ function parseTaskOrNull(input) {
124
+ if (input === void 0 || input === null || input === "") return {};
125
+ if (typeof input !== "string") {
126
+ return { error: "task must be a string" };
127
+ }
128
+ if (!ALL_TRAINING_TASKS.includes(input)) {
129
+ return {
130
+ error: `task must be one of: ${ALL_TRAINING_TASKS.join(", ")}`
131
+ };
132
+ }
133
+ return { value: input };
134
+ }
135
+ function parseBackendOrNull(input) {
136
+ if (input === void 0 || input === null || input === "") return {};
137
+ if (typeof input !== "string") {
138
+ return { error: "backend must be a string" };
139
+ }
140
+ if (!ALL_TRAINING_BACKENDS.includes(input)) {
141
+ return {
142
+ error: `backend must be one of: ${ALL_TRAINING_BACKENDS.join(", ")}`
143
+ };
144
+ }
145
+ return { value: input };
146
+ }
147
+ function resolveOllamaUrlRejection(rawUrl, isLoopbackHost) {
148
+ const trimmed = rawUrl.trim();
149
+ if (!trimmed) return null;
150
+ let parsed;
151
+ try {
152
+ parsed = new URL(trimmed);
153
+ } catch {
154
+ return "ollamaUrl must be a valid URL";
155
+ }
156
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
157
+ return "ollamaUrl must use http:// or https://";
158
+ }
159
+ if (!isLoopbackHost(parsed.hostname)) {
160
+ return "ollamaUrl must target a loopback host (localhost, 127.0.0.1, or ::1)";
161
+ }
162
+ return null;
163
+ }
164
+ async function handleTrainingRoutes(ctx) {
165
+ const {
166
+ req,
167
+ res,
168
+ method,
169
+ pathname,
170
+ runtime,
171
+ trainingService,
172
+ json,
173
+ error,
174
+ readJsonBody,
175
+ isLoopbackHost
176
+ } = ctx;
177
+ if (!pathname.startsWith("/api/training")) return false;
178
+ if (method === "GET" && pathname === "/api/training/status") {
179
+ const status = trainingService.getStatus();
180
+ const trigger = getTriggerEntry(runtime);
181
+ const triggerStatus = trigger?.getStatus() ?? null;
182
+ json(res, {
183
+ ...status,
184
+ runtimeAvailable: runtime !== null,
185
+ autoTrain: triggerStatus
186
+ });
187
+ return true;
188
+ }
189
+ if (method === "GET" && pathname === "/api/training/auto/status") {
190
+ const trigger = getTriggerEntry(runtime);
191
+ if (!trigger) {
192
+ const config = loadTrainingConfig();
193
+ json(res, {
194
+ autoTrainEnabled: config.autoTrain,
195
+ triggerThreshold: config.triggerThreshold,
196
+ cooldownHours: config.triggerCooldownHours,
197
+ counters: emptyTaskCounters(),
198
+ lastTrain: {},
199
+ perTaskThresholds: emptyTaskCounters(),
200
+ perTaskCooldownMs: emptyTaskCounters(),
201
+ serviceRegistered: false
202
+ });
203
+ return true;
204
+ }
205
+ const snapshot = trigger.getStatus();
206
+ json(res, { ...snapshot, serviceRegistered: true });
207
+ return true;
208
+ }
209
+ if (method === "POST" && pathname === "/api/training/auto/trigger") {
210
+ const body = await readJsonBody(req, res);
211
+ if (!body) return true;
212
+ const taskRejection = parseTaskOrNull(body.task);
213
+ if (taskRejection.error) {
214
+ error(res, taskRejection.error, 400);
215
+ return true;
216
+ }
217
+ const backendRejection = parseBackendOrNull(body.backend);
218
+ if (backendRejection.error) {
219
+ error(res, backendRejection.error, 400);
220
+ return true;
221
+ }
222
+ if (!runtime) {
223
+ error(res, "Runtime is required to trigger training", 503);
224
+ return true;
225
+ }
226
+ const trigger = getTriggerEntry(runtime);
227
+ const record = trigger ? await trigger.runManually({
228
+ task: taskRejection.value,
229
+ backend: backendRejection.value,
230
+ dryRun: body.dryRun === true
231
+ }) : await triggerTraining(runtime, {
232
+ task: taskRejection.value,
233
+ backend: backendRejection.value,
234
+ source: "manual",
235
+ dryRun: body.dryRun === true
236
+ });
237
+ json(res, { runId: record.runId, status: record.status, run: record }, 201);
238
+ return true;
239
+ }
240
+ if (method === "GET" && pathname === "/api/training/auto/runs") {
241
+ const url = new URL(
242
+ req.url ?? "/",
243
+ `http://${req.headers.host ?? "localhost"}`
244
+ );
245
+ const limit = parsePositiveInteger(url.searchParams.get("limit"), 20);
246
+ const runs = await listRuns(limit);
247
+ json(res, { runs });
248
+ return true;
249
+ }
250
+ const runMatch = /^\/api\/training\/auto\/runs\/([^/]+)$/.exec(pathname);
251
+ if (method === "GET" && runMatch) {
252
+ const runId = decodeURIComponent(runMatch[1]);
253
+ const run = await loadRun(runId);
254
+ if (!run) {
255
+ error(res, "Run not found", 404);
256
+ return true;
257
+ }
258
+ json(res, { run });
259
+ return true;
260
+ }
261
+ if (method === "GET" && pathname === "/api/training/auto/config") {
262
+ json(res, { config: loadTrainingConfig() });
263
+ return true;
264
+ }
265
+ if (method === "POST" && pathname === "/api/training/auto/config") {
266
+ const body = await readJsonBody(req, res);
267
+ if (!body) return true;
268
+ const merged = normalizeTrainingConfig({
269
+ ...loadTrainingConfig(),
270
+ ...body
271
+ });
272
+ saveTrainingConfig(merged);
273
+ json(res, { config: merged });
274
+ return true;
275
+ }
276
+ if (method === "POST" && pathname === "/api/training/analysis/index") {
277
+ const body = await readJsonBody(req, res);
278
+ if (!body) return true;
279
+ const roots = Array.isArray(body.roots) ? body.roots.filter(
280
+ (root) => typeof root === "string" && root.trim().length > 0
281
+ ) : void 0;
282
+ const outputDir = typeof body.outputDir === "string" && body.outputDir.trim().length > 0 ? body.outputDir.trim() : void 0;
283
+ const maxDepth = typeof body.maxDepth === "number" && Number.isFinite(body.maxDepth) ? Math.max(0, Math.floor(body.maxDepth)) : void 0;
284
+ try {
285
+ const index = await buildTrainingAnalysisIndex({
286
+ roots,
287
+ outputDir,
288
+ maxDepth
289
+ });
290
+ json(
291
+ res,
292
+ {
293
+ outputDir: index.outputDir,
294
+ indexHtmlPath: index.indexHtmlPath,
295
+ manifestPath: index.manifestPath,
296
+ manifest: index.manifest
297
+ },
298
+ 201
299
+ );
300
+ } catch (err) {
301
+ error(res, `Training analysis index failed: ${String(err)}`, 500);
302
+ }
303
+ return true;
304
+ }
305
+ if (method === "POST" && pathname === "/api/training/analysis/readiness") {
306
+ const body = await readJsonBody(req, res);
307
+ if (!body) return true;
308
+ const roots = Array.isArray(body.roots) ? body.roots.filter(
309
+ (entry) => typeof entry === "string" && entry.trim().length > 0
310
+ ) : void 0;
311
+ try {
312
+ const index = await buildTrainingAnalysisIndex({
313
+ roots,
314
+ outputDir: resolveStringSetting(body.outputDir),
315
+ maxDepth: typeof body.maxDepth === "number" && Number.isFinite(body.maxDepth) ? Math.max(1, Math.floor(body.maxDepth)) : void 0
316
+ });
317
+ const result = await writeTrainingReadinessReport(index, {
318
+ outputDir: resolveStringSetting(body.reportOutputDir),
319
+ reportPath: resolveStringSetting(body.reportPath)
320
+ });
321
+ json(res, result, 201);
322
+ } catch (err) {
323
+ error(res, `Training readiness report failed: ${String(err)}`, 500);
324
+ }
325
+ return true;
326
+ }
327
+ if (method === "POST" && pathname === "/api/training/datasets/ingest-hf") {
328
+ const body = await readJsonBody(req, res);
329
+ if (!body) return true;
330
+ try {
331
+ const result = await ingestHuggingFaceDataset({
332
+ repoId: resolveStringSetting(body.repoId),
333
+ revision: resolveStringSetting(body.revision),
334
+ files: Array.isArray(body.files) ? body.files.filter(
335
+ (file) => typeof file === "string" && file.trim().length > 0
336
+ ) : void 0,
337
+ outputDir: resolveStringSetting(body.outputDir),
338
+ token: resolveStringSetting(body.token),
339
+ dryRun: body.dryRun === true
340
+ });
341
+ json(res, result, 201);
342
+ } catch (err) {
343
+ error(res, `Hugging Face dataset ingest failed: ${String(err)}`, 500);
344
+ }
345
+ return true;
346
+ }
347
+ if (method === "POST" && pathname === "/api/training/feed/generate") {
348
+ const body = await readJsonBody(req, res);
349
+ if (!body) return true;
350
+ try {
351
+ const result = await runFeedGeneration({
352
+ workspaceRoot: resolveStringSetting(body.workspaceRoot),
353
+ bun: resolveStringSetting(body.bun),
354
+ archetypes: resolveStringSetting(body.archetypes),
355
+ numAgents: typeof body.numAgents === "number" && Number.isFinite(body.numAgents) ? Math.max(1, Math.floor(body.numAgents)) : void 0,
356
+ ticks: typeof body.ticks === "number" && Number.isFinite(body.ticks) ? Math.max(1, Math.floor(body.ticks)) : void 0,
357
+ parallel: typeof body.parallel === "number" && Number.isFinite(body.parallel) ? Math.max(1, Math.floor(body.parallel)) : void 0,
358
+ managerId: resolveStringSetting(body.managerId),
359
+ cleanup: body.cleanup === true,
360
+ dryRun: body.dryRun === true,
361
+ outputDir: resolveStringSetting(body.outputDir)
362
+ });
363
+ json(res, result, 201);
364
+ } catch (err) {
365
+ error(res, `Feed generation failed: ${String(err)}`, 500);
366
+ }
367
+ return true;
368
+ }
369
+ if (method === "POST" && pathname === "/api/training/scenarios/run") {
370
+ const body = await readJsonBody(req, res);
371
+ if (!body) return true;
372
+ try {
373
+ const result = await runScenarios({
374
+ workspaceRoot: resolveStringSetting(body.workspaceRoot),
375
+ bun: resolveStringSetting(body.bun),
376
+ scenarioDir: resolveStringSetting(body.scenarioDir),
377
+ outputDir: resolveStringSetting(body.outputDir),
378
+ runId: resolveStringSetting(body.runId),
379
+ scenario: resolveStringSetting(body.scenario),
380
+ fileGlobs: Array.isArray(body.fileGlobs) ? body.fileGlobs.filter(
381
+ (glob) => typeof glob === "string"
382
+ ) : void 0,
383
+ exportNative: typeof body.exportNative === "boolean" ? body.exportNative : void 0,
384
+ useDeterministicProxy: typeof body.useDeterministicProxy === "boolean" ? body.useDeterministicProxy : void 0,
385
+ dryRun: body.dryRun === true
386
+ });
387
+ json(res, result, 201);
388
+ } catch (err) {
389
+ error(res, `Scenario run failed: ${String(err)}`, 500);
390
+ }
391
+ return true;
392
+ }
393
+ if (method === "GET" && pathname === "/api/training/collections") {
394
+ const url = new URL(
395
+ req.url ?? "/",
396
+ `http://${req.headers.host ?? "localhost"}`
397
+ );
398
+ const limit = parsePositiveInteger(url.searchParams.get("limit"), 20);
399
+ const root = resolveStringSetting(url.searchParams.get("root"));
400
+ try {
401
+ const result = await listTrainingCollections({ root, limit });
402
+ json(res, result);
403
+ } catch (err) {
404
+ error(res, `Training collection listing failed: ${String(err)}`, 500);
405
+ }
406
+ return true;
407
+ }
408
+ if (method === "POST" && pathname === "/api/training/collect") {
409
+ const body = await readJsonBody(req, res);
410
+ if (!body) return true;
411
+ const objectSetting = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
412
+ const objectArraySetting = (value) => Array.isArray(value) ? value.filter(
413
+ (item) => item !== null && typeof item === "object" && !Array.isArray(item)
414
+ ) : void 0;
415
+ const actionBenchmarkPairsSetting = (value) => typeof value === "string" ? value : objectArraySetting(value);
416
+ const naturalTrajectoryOptions = objectSetting(body.naturalTrajectories);
417
+ const naturalTrajectoryIds = Array.isArray(
418
+ naturalTrajectoryOptions?.trajectoryIds
419
+ ) ? naturalTrajectoryOptions.trajectoryIds.filter(
420
+ (id) => typeof id === "string" && id.trim().length > 0
421
+ ) : [];
422
+ const naturalRunId = resolveStringSetting(naturalTrajectoryOptions?.runId);
423
+ const naturalLimit = typeof naturalTrajectoryOptions?.limit === "number" && Number.isFinite(naturalTrajectoryOptions.limit) ? Math.max(1, Math.floor(naturalTrajectoryOptions.limit)) : 100;
424
+ try {
425
+ let naturalTrajectories = naturalTrajectoryOptions;
426
+ if (body.includeNaturalTrajectories === true && body.preflightOnly !== true && !naturalTrajectoryOptions?.sanitizedJsonlPath && !naturalTrajectoryOptions?.rawJsonlPath) {
427
+ const listedTrajectories = naturalTrajectoryIds.length > 0 ? null : await trainingService.listTrajectories({
428
+ limit: naturalLimit,
429
+ offset: 0,
430
+ runId: naturalRunId
431
+ });
432
+ const ids = naturalTrajectoryIds.length > 0 ? naturalTrajectoryIds : (listedTrajectories?.trajectories ?? []).map((item) => item.id).filter((id) => id.length > 0);
433
+ const details = (await Promise.all(
434
+ ids.map(
435
+ (trajectoryId) => trainingService.getTrajectoryById(trajectoryId)
436
+ )
437
+ )).filter((trajectory) => trajectory !== null);
438
+ naturalTrajectories = {
439
+ ...naturalTrajectoryOptions ?? {},
440
+ trajectories: naturalRunId ? details.filter(
441
+ (trajectory) => trajectoryHasRunId(trajectory, naturalRunId)
442
+ ) : details,
443
+ source: {
444
+ kind: "training_collection_natural_trajectories",
445
+ ...objectSetting(naturalTrajectoryOptions?.source),
446
+ runId: naturalRunId,
447
+ metadata: {
448
+ ...objectSetting(
449
+ objectSetting(naturalTrajectoryOptions?.source)?.metadata
450
+ ),
451
+ requestedLimit: naturalLimit,
452
+ requestedRunId: naturalRunId ?? null,
453
+ explicitTrajectoryIds: naturalTrajectoryIds.length,
454
+ selectedTrajectoryIds: ids.length,
455
+ loadedTrajectories: details.length
456
+ }
457
+ }
458
+ };
459
+ }
460
+ const collectionOptions = {
461
+ preflightOnly: body.preflightOnly === true,
462
+ preflightProbe: body.preflightProbe === true,
463
+ outputDir: resolveStringSetting(body.outputDir),
464
+ workspaceRoot: resolveStringSetting(body.workspaceRoot),
465
+ includeHuggingFace: typeof body.includeHuggingFace === "boolean" ? body.includeHuggingFace : void 0,
466
+ includeFeed: typeof body.includeFeed === "boolean" ? body.includeFeed : void 0,
467
+ includeNaturalTrajectories: typeof body.includeNaturalTrajectories === "boolean" ? body.includeNaturalTrajectories : void 0,
468
+ includeTestTrajectories: typeof body.includeTestTrajectories === "boolean" ? body.includeTestTrajectories : void 0,
469
+ includeScenarios: typeof body.includeScenarios === "boolean" ? body.includeScenarios : void 0,
470
+ includeEvalComparison: typeof body.includeEvalComparison === "boolean" ? body.includeEvalComparison : void 0,
471
+ includeActionBenchmark: typeof body.includeActionBenchmark === "boolean" ? body.includeActionBenchmark : void 0,
472
+ includeBenchmarkVsCerebras: typeof body.includeBenchmarkVsCerebras === "boolean" ? body.includeBenchmarkVsCerebras : void 0,
473
+ includeEliza1ModelRegistry: typeof body.includeEliza1ModelRegistry === "boolean" ? body.includeEliza1ModelRegistry : void 0,
474
+ includeEliza1BundleStage: typeof body.includeEliza1BundleStage === "boolean" ? body.includeEliza1BundleStage : void 0,
475
+ includeBenchmarkMatrix: typeof body.includeBenchmarkMatrix === "boolean" ? body.includeBenchmarkMatrix : void 0,
476
+ huggingFace: objectSetting(body.huggingFace),
477
+ feed: objectSetting(body.feed),
478
+ naturalTrajectories,
479
+ testTrajectories: objectSetting(body.testTrajectories),
480
+ scenarios: objectSetting(body.scenarios),
481
+ evalComparison: objectSetting(body.evalComparison),
482
+ actionBenchmark: objectSetting(body.actionBenchmark),
483
+ actionBenchmarkPair: objectSetting(body.actionBenchmarkPair),
484
+ actionBenchmarkPairs: actionBenchmarkPairsSetting(
485
+ body.actionBenchmarkPairs
486
+ ),
487
+ benchmarkVsCerebras: objectSetting(body.benchmarkVsCerebras),
488
+ eliza1BundleStage: objectSetting(body.eliza1BundleStage),
489
+ benchmarkMatrix: objectSetting(body.benchmarkMatrix),
490
+ analysis: objectSetting(body.analysis)
491
+ };
492
+ if (body.preflightOnly === true) {
493
+ json(
494
+ res,
495
+ {
496
+ preflight: await buildTrainingCollectionPreflightWithProbes({
497
+ options: collectionOptions,
498
+ workspaceRoot: collectionOptions.workspaceRoot,
499
+ trainingRoot: collectionOptions.workspaceRoot ? `${collectionOptions.workspaceRoot}/packages/training` : void 0
500
+ })
501
+ },
502
+ 200
503
+ );
504
+ return true;
505
+ }
506
+ const result = await runTrainingCollection(collectionOptions);
507
+ json(res, result, 201);
508
+ } catch (err) {
509
+ error(res, `Training collection failed: ${String(err)}`, 500);
510
+ }
511
+ return true;
512
+ }
513
+ if (method === "POST" && pathname === "/api/training/benchmarks/action-selection/run") {
514
+ const body = await readJsonBody(req, res);
515
+ if (!body) return true;
516
+ try {
517
+ const result = await runActionBenchmark({
518
+ workspaceRoot: resolveStringSetting(body.workspaceRoot),
519
+ bun: resolveStringSetting(body.bun),
520
+ outputDir: resolveStringSetting(body.outputDir),
521
+ useMocks: resolveBooleanSetting(body.useMocks),
522
+ forceTrajectoryCapture: body.forceTrajectoryCapture === false ? false : void 0,
523
+ filter: resolveStringSetting(body.filter),
524
+ runsPerCase: typeof body.runsPerCase === "number" && Number.isFinite(body.runsPerCase) ? Math.max(1, Math.floor(body.runsPerCase)) : void 0,
525
+ provider: resolveStringSetting(body.provider),
526
+ modelId: resolveStringSetting(body.modelId),
527
+ runtimeModel: resolveStringSetting(body.runtimeModel),
528
+ smallModel: resolveStringSetting(body.smallModel),
529
+ largeModel: resolveStringSetting(body.largeModel),
530
+ baseUrl: resolveStringSetting(body.baseUrl),
531
+ variant: body.variant === "reference" || body.variant === "base" || body.variant === "trained" ? body.variant : void 0,
532
+ tier: resolveStringSetting(body.tier),
533
+ benchmark: resolveStringSetting(body.benchmark),
534
+ datasetVersion: resolveStringSetting(body.datasetVersion),
535
+ codeCommit: resolveStringSetting(body.codeCommit),
536
+ dryRun: body.dryRun === true
537
+ });
538
+ json(res, result, 201);
539
+ } catch (err) {
540
+ error(res, `Action benchmark failed: ${String(err)}`, 500);
541
+ }
542
+ return true;
543
+ }
544
+ if (method === "POST" && pathname === "/api/training/evals/record-comparison") {
545
+ const body = await readJsonBody(req, res);
546
+ if (!body) return true;
547
+ if (!body.report || typeof body.report !== "object" || Array.isArray(body.report)) {
548
+ error(res, "report must be a JSON object", 400);
549
+ return true;
550
+ }
551
+ try {
552
+ const result = await writeEvalComparisonArtifact({
553
+ report: body.report,
554
+ reportPath: resolveStringSetting(body.reportPath),
555
+ outputDir: resolveStringSetting(body.outputDir),
556
+ source: body.source && typeof body.source === "object" && !Array.isArray(body.source) ? body.source : void 0
557
+ });
558
+ json(res, result, 201);
559
+ } catch (err) {
560
+ error(res, `Eval comparison artifact failed: ${String(err)}`, 500);
561
+ }
562
+ return true;
563
+ }
564
+ if (method === "POST" && pathname === "/api/training/evals/run-local-comparison") {
565
+ const body = await readJsonBody(req, res);
566
+ if (!body) return true;
567
+ const backend = body.backend === "mlx" || body.backend === "cuda" || body.backend === "cpu" ? body.backend : void 0;
568
+ try {
569
+ const result = await runLocalEvalComparison({
570
+ trainingRoot: resolveStringSetting(body.trainingRoot),
571
+ python: resolveStringSetting(body.python),
572
+ manifestPath: resolveStringSetting(body.manifestPath),
573
+ model: resolveStringSetting(body.model),
574
+ trainedModelPath: resolveStringSetting(body.trainedModelPath),
575
+ backend,
576
+ promptFile: resolveStringSetting(body.promptFile),
577
+ maxTokens: typeof body.maxTokens === "number" && Number.isFinite(body.maxTokens) ? Math.max(1, Math.floor(body.maxTokens)) : void 0,
578
+ systemPrompt: resolveStringSetting(body.systemPrompt),
579
+ outputPath: resolveStringSetting(body.outputPath),
580
+ outputDir: resolveStringSetting(body.outputDir),
581
+ dryRun: body.dryRun === true
582
+ });
583
+ json(res, result, 201);
584
+ } catch (err) {
585
+ error(res, `Local eval comparison failed: ${String(err)}`, 500);
586
+ }
587
+ return true;
588
+ }
589
+ if (method === "POST" && pathname === "/api/training/benchmarks/matrix") {
590
+ const body = await readJsonBody(req, res);
591
+ if (!body) return true;
592
+ if (!Array.isArray(body.rows)) {
593
+ error(res, "rows must be an array", 400);
594
+ return true;
595
+ }
596
+ const rows = body.rows.filter(
597
+ (row) => row !== null && typeof row === "object" && !Array.isArray(row) && typeof row.modelId === "string" && typeof row.benchmark === "string" && typeof row.score === "number" && (row.variant === "reference" || row.variant === "base" || row.variant === "trained")
598
+ );
599
+ if (rows.length !== body.rows.length) {
600
+ error(
601
+ res,
602
+ "each row must include modelId, benchmark, numeric score, and variant reference|base|trained",
603
+ 400
604
+ );
605
+ return true;
606
+ }
607
+ try {
608
+ const result = await writeBenchmarkMatrixArtifact({
609
+ rows,
610
+ outputDir: resolveStringSetting(body.outputDir),
611
+ generatedAt: resolveStringSetting(body.generatedAt),
612
+ referenceModelId: resolveStringSetting(body.referenceModelId),
613
+ source: body.source && typeof body.source === "object" && !Array.isArray(body.source) ? body.source : void 0
614
+ });
615
+ json(res, result, 201);
616
+ } catch (err) {
617
+ error(res, `Benchmark matrix artifact failed: ${String(err)}`, 500);
618
+ }
619
+ return true;
620
+ }
621
+ if (method === "POST" && pathname === "/api/training/benchmarks/matrix/from-artifacts") {
622
+ const body = await readJsonBody(req, res);
623
+ if (!body) return true;
624
+ if (!Array.isArray(body.artifacts)) {
625
+ error(res, "artifacts must be an array", 400);
626
+ return true;
627
+ }
628
+ const artifacts = body.artifacts.filter(
629
+ (artifact) => artifact !== null && typeof artifact === "object" && !Array.isArray(artifact) && typeof artifact.path === "string" && (artifact.variant === void 0 || artifact.variant === "reference" || artifact.variant === "base" || artifact.variant === "trained")
630
+ );
631
+ if (artifacts.length !== body.artifacts.length) {
632
+ error(
633
+ res,
634
+ "each artifact must include path and optional variant reference|base|trained",
635
+ 400
636
+ );
637
+ return true;
638
+ }
639
+ try {
640
+ const result = await writeBenchmarkMatrixArtifactFromArtifacts({
641
+ artifacts,
642
+ outputDir: resolveStringSetting(body.outputDir),
643
+ generatedAt: resolveStringSetting(body.generatedAt),
644
+ referenceModelId: resolveStringSetting(body.referenceModelId),
645
+ source: body.source && typeof body.source === "object" && !Array.isArray(body.source) ? body.source : void 0
646
+ });
647
+ json(res, result, 201);
648
+ } catch (err) {
649
+ error(res, `Benchmark matrix from artifacts failed: ${String(err)}`, 500);
650
+ }
651
+ return true;
652
+ }
653
+ if (method === "POST" && pathname === "/api/training/benchmarks/run-vs-cerebras") {
654
+ const body = await readJsonBody(req, res);
655
+ if (!body) return true;
656
+ const benchmark = body.benchmark === "clawbench" || body.benchmark === "eliza_harness_action_selection" || body.benchmark === "hermes" || body.benchmark === "all" ? body.benchmark : void 0;
657
+ const variants = body.variants === "trained" || body.variants === "base" || body.variants === "both" ? body.variants : void 0;
658
+ try {
659
+ const result = await runBenchmarkVsCerebras({
660
+ trainingRoot: resolveStringSetting(body.trainingRoot),
661
+ python: resolveStringSetting(body.python),
662
+ tiers: resolveStringSetting(body.tiers),
663
+ benchmark,
664
+ variants,
665
+ cerebrasModel: resolveStringSetting(body.cerebrasModel),
666
+ maxSamples: typeof body.maxSamples === "number" && Number.isFinite(body.maxSamples) ? Math.max(1, Math.floor(body.maxSamples)) : void 0,
667
+ outputDir: resolveStringSetting(body.outputDir),
668
+ checkpointsDir: resolveStringSetting(body.checkpointsDir),
669
+ trainedModelPath: resolveStringSetting(body.trainedModelPath),
670
+ dryRun: body.dryRun === true,
671
+ resultsDb: resolveStringSetting(body.resultsDb),
672
+ datasetVersion: resolveStringSetting(body.datasetVersion),
673
+ codeCommit: resolveStringSetting(body.codeCommit),
674
+ matrixOutputDir: resolveStringSetting(body.matrixOutputDir)
675
+ });
676
+ json(res, result, 201);
677
+ } catch (err) {
678
+ error(res, `Benchmark vs Cerebras failed: ${String(err)}`, 500);
679
+ }
680
+ return true;
681
+ }
682
+ if (method === "POST" && pathname === "/api/training/models/stage-eliza1-bundle") {
683
+ const body = await readJsonBody(req, res);
684
+ if (!body) return true;
685
+ try {
686
+ const result = await stageEliza1Bundle({
687
+ trainingRoot: resolveStringSetting(body.trainingRoot),
688
+ python: resolveStringSetting(body.python),
689
+ repoId: resolveStringSetting(body.repoId),
690
+ tier: resolveStringSetting(body.tier),
691
+ localDir: resolveStringSetting(body.localDir),
692
+ outputDir: resolveStringSetting(body.outputDir),
693
+ maxBytes: typeof body.maxBytes === "number" && Number.isFinite(body.maxBytes) ? Math.max(1, Math.floor(body.maxBytes)) : void 0,
694
+ apply: body.apply === true
695
+ });
696
+ json(res, result, 201);
697
+ } catch (err) {
698
+ error(res, `Eliza-1 bundle staging failed: ${String(err)}`, 500);
699
+ }
700
+ return true;
701
+ }
702
+ if (method === "GET" && pathname === "/api/training/trajectories") {
703
+ const url = new URL(
704
+ req.url ?? "/",
705
+ `http://${req.headers.host ?? "localhost"}`
706
+ );
707
+ const limit = parsePositiveInteger(url.searchParams.get("limit"), 100);
708
+ const offset = Math.max(0, Number(url.searchParams.get("offset") ?? "0"));
709
+ const result = await trainingService.listTrajectories({ limit, offset });
710
+ json(res, result);
711
+ return true;
712
+ }
713
+ const trajectoryMatch = /^\/api\/training\/trajectories\/([^/]+)$/.exec(
714
+ pathname
715
+ );
716
+ if (method === "GET" && trajectoryMatch) {
717
+ const trajectoryId = decodeURIComponent(trajectoryMatch[1]);
718
+ const detail = await trainingService.getTrajectoryById(trajectoryId);
719
+ if (!detail) {
720
+ error(res, "Trajectory not found", 404);
721
+ return true;
722
+ }
723
+ json(res, { trajectory: detail });
724
+ return true;
725
+ }
726
+ if (method === "GET" && pathname === "/api/training/datasets") {
727
+ json(res, { datasets: trainingService.listDatasets() });
728
+ return true;
729
+ }
730
+ if (method === "POST" && pathname === "/api/training/datasets/build") {
731
+ const body = await readJsonBody(req, res);
732
+ if (!body) return true;
733
+ try {
734
+ const dataset = await trainingService.buildDataset({
735
+ limit: body.limit,
736
+ minLlmCallsPerTrajectory: body.minLlmCallsPerTrajectory
737
+ });
738
+ json(res, { dataset }, 201);
739
+ } catch (err) {
740
+ sendServiceError(error, res, err, 500);
741
+ }
742
+ return true;
743
+ }
744
+ if (method === "GET" && pathname === "/api/training/backends") {
745
+ const backends = await detectAvailableBackends();
746
+ json(res, { backends });
747
+ return true;
748
+ }
749
+ if (method === "GET" && pathname === "/api/training/jobs") {
750
+ json(res, { jobs: trainingService.listJobs() });
751
+ return true;
752
+ }
753
+ if (method === "POST" && pathname === "/api/training/jobs") {
754
+ const body = await readJsonBody(req, res);
755
+ if (!body) return true;
756
+ if (body.backend && body.backend !== "cpu") {
757
+ const backends = await detectAvailableBackends();
758
+ if (!backends[body.backend]) {
759
+ const available = Object.entries(backends).filter(([, ok]) => ok).map(([name]) => name).join(", ");
760
+ error(
761
+ res,
762
+ `Backend '${body.backend}' is not available on this system. Available backends: ${available}`,
763
+ 400
764
+ );
765
+ return true;
766
+ }
767
+ }
768
+ try {
769
+ const job = await trainingService.startTrainingJob({
770
+ datasetId: body.datasetId,
771
+ maxTrajectories: body.maxTrajectories,
772
+ backend: body.backend,
773
+ model: body.model,
774
+ iterations: body.iterations,
775
+ batchSize: body.batchSize,
776
+ learningRate: body.learningRate
777
+ });
778
+ json(res, { job }, 201);
779
+ } catch (err) {
780
+ sendServiceError(error, res, err, 400);
781
+ }
782
+ return true;
783
+ }
784
+ const jobMatch = /^\/api\/training\/jobs\/([^/]+)$/.exec(pathname);
785
+ if (method === "GET" && jobMatch) {
786
+ const jobId = decodeURIComponent(jobMatch[1]);
787
+ const job = trainingService.getJob(jobId);
788
+ if (!job) {
789
+ error(res, "Training job not found", 404);
790
+ return true;
791
+ }
792
+ json(res, { job });
793
+ return true;
794
+ }
795
+ const cancelMatch = /^\/api\/training\/jobs\/([^/]+)\/cancel$/.exec(pathname);
796
+ if (method === "POST" && cancelMatch) {
797
+ const jobId = decodeURIComponent(cancelMatch[1]);
798
+ try {
799
+ const job = await trainingService.cancelJob(jobId);
800
+ json(res, { job });
801
+ } catch (err) {
802
+ sendServiceError(error, res, err, 404);
803
+ }
804
+ return true;
805
+ }
806
+ if (method === "GET" && pathname === "/api/training/models") {
807
+ json(res, { models: trainingService.listModels() });
808
+ return true;
809
+ }
810
+ const importMatch = /^\/api\/training\/models\/([^/]+)\/import-ollama$/.exec(
811
+ pathname
812
+ );
813
+ if (method === "POST" && importMatch) {
814
+ const modelId = decodeURIComponent(importMatch[1]);
815
+ const body = await readJsonBody(req, res);
816
+ if (!body) return true;
817
+ if (body.ollamaUrl !== void 0 && typeof body.ollamaUrl !== "string") {
818
+ error(res, "ollamaUrl must be a string", 400);
819
+ return true;
820
+ }
821
+ if (typeof body.ollamaUrl === "string") {
822
+ const ollamaUrlRejection = resolveOllamaUrlRejection(
823
+ body.ollamaUrl,
824
+ isLoopbackHost
825
+ );
826
+ if (ollamaUrlRejection) {
827
+ error(res, ollamaUrlRejection, 400);
828
+ return true;
829
+ }
830
+ }
831
+ try {
832
+ const model = await trainingService.importModelToOllama(modelId, body);
833
+ json(res, { model });
834
+ } catch (err) {
835
+ sendServiceError(error, res, err, 400);
836
+ }
837
+ return true;
838
+ }
839
+ const activateMatch = /^\/api\/training\/models\/([^/]+)\/activate$/.exec(
840
+ pathname
841
+ );
842
+ if (method === "POST" && activateMatch) {
843
+ const modelId = decodeURIComponent(activateMatch[1]);
844
+ const body = await readJsonBody(req, res);
845
+ if (!body) return true;
846
+ try {
847
+ const result = await trainingService.activateModel(
848
+ modelId,
849
+ body.providerModel
850
+ );
851
+ json(res, result);
852
+ } catch (err) {
853
+ sendServiceError(error, res, err, 400);
854
+ }
855
+ return true;
856
+ }
857
+ const benchmarkMatch = /^\/api\/training\/models\/([^/]+)\/benchmark$/.exec(
858
+ pathname
859
+ );
860
+ if (method === "POST" && benchmarkMatch) {
861
+ const modelId = decodeURIComponent(benchmarkMatch[1]);
862
+ try {
863
+ const result = await trainingService.benchmarkModel(modelId);
864
+ json(res, result);
865
+ } catch (err) {
866
+ sendServiceError(error, res, err, 400);
867
+ }
868
+ return true;
869
+ }
870
+ if (method === "GET" && pathname === "/api/training/blueprints") {
871
+ const { ALL_BLUEPRINTS, BLUEPRINT_STATS } = await import("../core/scenario-blueprints.js");
872
+ json(res, {
873
+ count: ALL_BLUEPRINTS.length,
874
+ stats: BLUEPRINT_STATS,
875
+ blueprints: ALL_BLUEPRINTS.map((b) => ({
876
+ id: b.id,
877
+ decision: b.decision,
878
+ primaryContext: b.primaryContext,
879
+ pattern: b.pattern,
880
+ description: b.description
881
+ }))
882
+ });
883
+ return true;
884
+ }
885
+ if (method === "GET" && pathname === "/api/training/context-catalog") {
886
+ const { ACTION_CONTEXT_MAP, PROVIDER_CONTEXT_MAP, ALL_CONTEXTS } = await import("../core/context-catalog.js");
887
+ json(res, {
888
+ contexts: ALL_CONTEXTS,
889
+ actions: ACTION_CONTEXT_MAP,
890
+ providers: PROVIDER_CONTEXT_MAP
891
+ });
892
+ return true;
893
+ }
894
+ if (method === "GET" && pathname === "/api/training/context-audit") {
895
+ if (!runtime || !Array.isArray(runtime.plugins)) {
896
+ error(
897
+ res,
898
+ "Runtime with loaded plugins is required for context audit",
899
+ 503
900
+ );
901
+ return true;
902
+ }
903
+ const { auditRuntimeContextCoverage, hasContextAuditGaps } = await import("../core/context-audit.js");
904
+ const audit = auditRuntimeContextCoverage(
905
+ runtime
906
+ );
907
+ json(res, {
908
+ audit,
909
+ hasGaps: hasContextAuditGaps(audit)
910
+ });
911
+ return true;
912
+ }
913
+ if (method === "POST" && pathname === "/api/training/generate-dataset") {
914
+ const body = await readJsonBody(req, res);
915
+ if (!body) return true;
916
+ const cerebrasKey = process.env.CEREBRAS_API_KEY;
917
+ const trainProvider = process.env.TRAIN_MODEL_PROVIDER?.trim() ?? process.env.TRAINING_PROVIDER?.trim();
918
+ const anthropicKey = resolveStringSetting(runtime?.getSetting?.("ANTHROPIC_API_KEY")) ?? process.env.ANTHROPIC_API_KEY;
919
+ const openaiKey = resolveStringSetting(runtime?.getSetting?.("OPENAI_API_KEY")) ?? process.env.OPENAI_API_KEY;
920
+ if (!cerebrasKey && !anthropicKey && !openaiKey) {
921
+ error(
922
+ res,
923
+ "No teacher model API key found. Set CEREBRAS_API_KEY (preferred), ANTHROPIC_API_KEY, or OPENAI_API_KEY.",
924
+ 400
925
+ );
926
+ return true;
927
+ }
928
+ const {
929
+ generateDataset,
930
+ exportToElizaNativeJSONL,
931
+ createAnthropicTeacher,
932
+ createCerebrasTeacher,
933
+ createOpenAITeacher
934
+ } = await import("../core/dataset-generator.js");
935
+ const { buildRoleplayEpisodes, exportRoleplayEpisodes } = await import("../core/roleplay-trajectories.js");
936
+ const teacher = trainProvider === "cerebras" && cerebrasKey ? createCerebrasTeacher(runtime ?? void 0) : anthropicKey ? createAnthropicTeacher(anthropicKey, runtime ?? void 0) : createOpenAITeacher(openaiKey, runtime ?? void 0);
937
+ const outputDir = `.tmp/training-data-${Date.now()}`;
938
+ try {
939
+ const samples = await generateDataset({
940
+ variantsPerBlueprint: body.variantsPerBlueprint ?? 5,
941
+ teacher,
942
+ outputDir,
943
+ concurrency: body.concurrency ?? 5,
944
+ limitBlueprints: body.limitBlueprints,
945
+ filterContexts: narrowAgentContexts(body.filterContexts),
946
+ filterDecisions: narrowAgentDecisions(body.filterDecisions)
947
+ });
948
+ const { validateDataset } = await import("../core/replay-validator.js");
949
+ const report = validateDataset(samples);
950
+ const paths = await exportToElizaNativeJSONL(samples, outputDir);
951
+ const roleplayPaths = body.includeRoleplay === false ? void 0 : await exportRoleplayEpisodes(
952
+ buildRoleplayEpisodes(samples),
953
+ samples,
954
+ outputDir
955
+ );
956
+ json(
957
+ res,
958
+ {
959
+ samplesGenerated: samples.length,
960
+ report,
961
+ paths,
962
+ roleplayPaths,
963
+ outputDir
964
+ },
965
+ 201
966
+ );
967
+ } catch (err) {
968
+ error(res, `Dataset generation failed: ${String(err)}`, 500);
969
+ }
970
+ return true;
971
+ }
972
+ if (method === "POST" && pathname === "/api/training/generate-roleplay") {
973
+ const body = await readJsonBody(req, res);
974
+ if (!body) return true;
975
+ const cerebrasKey = process.env.CEREBRAS_API_KEY;
976
+ const trainProvider = process.env.TRAIN_MODEL_PROVIDER?.trim() ?? process.env.TRAINING_PROVIDER?.trim();
977
+ const anthropicKey = resolveStringSetting(runtime?.getSetting?.("ANTHROPIC_API_KEY")) ?? process.env.ANTHROPIC_API_KEY;
978
+ const openaiKey = resolveStringSetting(runtime?.getSetting?.("OPENAI_API_KEY")) ?? process.env.OPENAI_API_KEY;
979
+ if (!cerebrasKey && !anthropicKey && !openaiKey) {
980
+ error(
981
+ res,
982
+ "No teacher model API key found. Set CEREBRAS_API_KEY (preferred), ANTHROPIC_API_KEY, or OPENAI_API_KEY.",
983
+ 400
984
+ );
985
+ return true;
986
+ }
987
+ const {
988
+ generateDataset,
989
+ createAnthropicTeacher,
990
+ createCerebrasTeacher,
991
+ createOpenAITeacher
992
+ } = await import("../core/dataset-generator.js");
993
+ const { buildRoleplayEpisodes, exportRoleplayEpisodes } = await import("../core/roleplay-trajectories.js");
994
+ const teacher = trainProvider === "cerebras" && cerebrasKey ? createCerebrasTeacher(runtime ?? void 0) : anthropicKey ? createAnthropicTeacher(anthropicKey, runtime ?? void 0) : createOpenAITeacher(openaiKey, runtime ?? void 0);
995
+ const outputDir = `.tmp/training-roleplay-${Date.now()}`;
996
+ try {
997
+ const samples = await generateDataset({
998
+ variantsPerBlueprint: body.variantsPerBlueprint ?? 3,
999
+ teacher,
1000
+ outputDir,
1001
+ concurrency: body.concurrency ?? 5,
1002
+ limitBlueprints: body.limitBlueprints,
1003
+ filterContexts: narrowAgentContexts(body.filterContexts),
1004
+ filterDecisions: narrowAgentDecisions(body.filterDecisions)
1005
+ });
1006
+ const episodes = buildRoleplayEpisodes(samples);
1007
+ const paths = await exportRoleplayEpisodes(episodes, samples, outputDir);
1008
+ json(
1009
+ res,
1010
+ {
1011
+ samplesGenerated: samples.length,
1012
+ episodesGenerated: episodes.length,
1013
+ outputDir,
1014
+ paths
1015
+ },
1016
+ 201
1017
+ );
1018
+ } catch (err) {
1019
+ error(res, `Roleplay generation failed: ${String(err)}`, 500);
1020
+ }
1021
+ return true;
1022
+ }
1023
+ if (method === "POST" && pathname === "/api/training/roleplay/execute") {
1024
+ const body = await readJsonBody(req, res);
1025
+ if (!body) return true;
1026
+ if (!runtime) {
1027
+ error(res, "Runtime is required to execute roleplay episodes", 503);
1028
+ return true;
1029
+ }
1030
+ const inputPath = body.episodesPath ?? body.manifestPath;
1031
+ if (!inputPath) {
1032
+ error(res, "episodesPath or manifestPath is required", 400);
1033
+ return true;
1034
+ }
1035
+ const {
1036
+ buildRoleplayExecutionReport,
1037
+ executeRoleplayEpisodes,
1038
+ exportRoleplayExecutionResults,
1039
+ loadRoleplayEpisodesFromPath
1040
+ } = await import("../core/roleplay-executor.js");
1041
+ try {
1042
+ const episodes = await loadRoleplayEpisodesFromPath(inputPath);
1043
+ const executions = await executeRoleplayEpisodes(episodes, {
1044
+ runtime,
1045
+ timeoutMs: body.timeoutMs,
1046
+ executeAllParticipantTurns: body.executeAllParticipantTurns ?? false
1047
+ });
1048
+ const outputDir = body.outputDir ?? `.tmp/training-roleplay-execution-${Date.now()}`;
1049
+ const paths = await exportRoleplayExecutionResults(executions, outputDir);
1050
+ const report = buildRoleplayExecutionReport(
1051
+ executions,
1052
+ paths.trajectoryDataset?.summary ?? null
1053
+ );
1054
+ json(
1055
+ res,
1056
+ {
1057
+ episodesExecuted: executions.length,
1058
+ report,
1059
+ outputDir,
1060
+ paths
1061
+ },
1062
+ 201
1063
+ );
1064
+ } catch (err) {
1065
+ error(res, `Roleplay execution failed: ${String(err)}`, 500);
1066
+ }
1067
+ return true;
1068
+ }
1069
+ if (method === "POST" && pathname === "/api/training/trajectories/export") {
1070
+ const body = await readJsonBody(req, res);
1071
+ if (!body) return true;
1072
+ if (body.runId !== void 0 && !normalizeRunId(body.runId)) {
1073
+ error(res, "runId must be a non-empty string", 400);
1074
+ return true;
1075
+ }
1076
+ const outputPath = body.outputPath ?? `.tmp/training-trajectory-export-${Date.now()}.jsonl`;
1077
+ try {
1078
+ const explicitIds = Array.isArray(body.trajectoryIds) ? body.trajectoryIds.filter((id) => typeof id === "string" && id.trim()) : [];
1079
+ const listedTrajectories = explicitIds.length > 0 ? null : await trainingService.listTrajectories({
1080
+ limit: body.limit ?? 100,
1081
+ offset: 0,
1082
+ runId: normalizeRunId(body.runId)
1083
+ });
1084
+ const trajectoryIds = explicitIds.length > 0 ? explicitIds : (listedTrajectories?.trajectories ?? []).map((item) => item.id).filter((id) => id.length > 0);
1085
+ const details = (await Promise.all(
1086
+ trajectoryIds.map(
1087
+ (trajectoryId) => trainingService.getTrajectoryById(trajectoryId)
1088
+ )
1089
+ )).filter((t) => t !== null);
1090
+ if (body.bundle || body.exportBundle) {
1091
+ const requestedRunId = normalizeRunId(body.runId);
1092
+ const bundleTrajectories = requestedRunId ? details.filter(
1093
+ (trajectory) => trajectoryHasRunId(trajectory, requestedRunId)
1094
+ ) : details;
1095
+ const { buildTrajectoryExportBundle } = await import("../core/trajectory-export-bundle.js");
1096
+ const bundle = await buildTrajectoryExportBundle({
1097
+ trajectories: bundleTrajectories,
1098
+ outputDir: body.outputDir ?? `.tmp/training-trajectory-bundle-${Date.now()}`,
1099
+ includeRawJsonl: body.includeRawJsonl === true || body.includeRaw === true,
1100
+ tasks: narrowTrainingTasks(body.tasks),
1101
+ source: {
1102
+ kind: "training-trajectories-export-route",
1103
+ runId: requestedRunId,
1104
+ metadata: {
1105
+ requestedLimit: body.limit ?? 100,
1106
+ requestedRunId: requestedRunId ?? null,
1107
+ explicitTrajectoryIds: explicitIds.length,
1108
+ selectedTrajectoryIds: trajectoryIds.length,
1109
+ loadedTrajectories: details.length,
1110
+ bundledTrajectories: bundleTrajectories.length
1111
+ }
1112
+ }
1113
+ });
1114
+ json(
1115
+ res,
1116
+ {
1117
+ trajectoriesConsidered: trajectoryIds.length,
1118
+ trajectoriesBundled: bundleTrajectories.length,
1119
+ outputDir: bundle.outputDir,
1120
+ manifestPath: bundle.manifestPath,
1121
+ bundle: bundle.manifest
1122
+ },
1123
+ 201
1124
+ );
1125
+ return true;
1126
+ }
1127
+ let exported = 0;
1128
+ let taskDataset;
1129
+ if (body.splitByTask || body.outputDir || body.tasks?.length) {
1130
+ const { exportTrajectoryTaskDatasets } = await import("../core/trajectory-task-datasets.js");
1131
+ const dataset = await exportTrajectoryTaskDatasets(
1132
+ details,
1133
+ body.outputDir ?? `.tmp/training-trajectory-export-${Date.now()}`,
1134
+ narrowTrainingTasks(body.tasks)
1135
+ );
1136
+ exported = dataset.counts.should_respond + dataset.counts.context_routing + dataset.counts.action_planner + dataset.counts.response + dataset.counts.media_description;
1137
+ taskDataset = {
1138
+ counts: dataset.counts,
1139
+ paths: dataset.paths,
1140
+ summary: dataset.summary
1141
+ };
1142
+ } else {
1143
+ const { exportTrajectoriesAsTraining } = await import("../core/dataset-generator.js");
1144
+ exported = await exportTrajectoriesAsTraining(
1145
+ details,
1146
+ body.agentName ?? runtime?.character?.name ?? "Agent",
1147
+ outputPath
1148
+ );
1149
+ }
1150
+ json(
1151
+ res,
1152
+ {
1153
+ exportedExamples: exported,
1154
+ trajectoriesConsidered: trajectoryIds.length,
1155
+ outputPath,
1156
+ taskDataset
1157
+ },
1158
+ 201
1159
+ );
1160
+ } catch (err) {
1161
+ error(res, `Trajectory export failed: ${String(err)}`, 500);
1162
+ }
1163
+ return true;
1164
+ }
1165
+ if (method === "POST" && pathname === "/api/training/trajectories/publish") {
1166
+ const hfConfig = resolveHfUploadConfig();
1167
+ if (!hfConfig) {
1168
+ error(
1169
+ res,
1170
+ "HuggingFace publishing is not configured. Set ELIZA_TRAJECTORY_HF_REPO and an HF token (HF_TOKEN, with HUGGINGFACE_HUB_TOKEN / HUGGING_FACE_HUB_TOKEN accepted as fallbacks).",
1171
+ 409
1172
+ );
1173
+ return true;
1174
+ }
1175
+ const body = await readJsonBody(req, res);
1176
+ if (!body) return true;
1177
+ try {
1178
+ const explicitIds = Array.isArray(body.trajectoryIds) ? body.trajectoryIds.filter((id) => typeof id === "string" && id.trim()) : [];
1179
+ const listed = explicitIds.length > 0 ? null : await trainingService.listTrajectories({
1180
+ limit: body.limit ?? 500,
1181
+ offset: 0
1182
+ });
1183
+ const trajectoryIds = explicitIds.length > 0 ? explicitIds : (listed?.trajectories ?? []).map((item) => item.id).filter((id) => id.length > 0);
1184
+ const details = (await Promise.all(
1185
+ trajectoryIds.map(
1186
+ (trajectoryId) => trainingService.getTrajectoryById(trajectoryId)
1187
+ )
1188
+ )).filter((t) => t !== null);
1189
+ const { buildTrajectoryExportBundle } = await import("../core/trajectory-export-bundle.js");
1190
+ const bundle = await buildTrajectoryExportBundle({
1191
+ trajectories: details,
1192
+ outputDir: body.outputDir ?? `.tmp/training-trajectory-publish-${Date.now()}`,
1193
+ tasks: narrowTrainingTasks(body.tasks),
1194
+ // Privacy filter forced on with the default hash anonymizer.
1195
+ privacy: {
1196
+ apply: true,
1197
+ options: { anonymizer: createHashAnonymizer() }
1198
+ },
1199
+ uploadToHuggingFace: hfConfig,
1200
+ source: {
1201
+ kind: "training-trajectories-publish-route",
1202
+ metadata: {
1203
+ requestedLimit: body.limit ?? 500,
1204
+ explicitTrajectoryIds: explicitIds.length,
1205
+ selectedTrajectoryIds: trajectoryIds.length,
1206
+ loadedTrajectories: details.length
1207
+ }
1208
+ }
1209
+ });
1210
+ if (!bundle.manifest.cloudUpload.uploadedToHuggingFace) {
1211
+ error(
1212
+ res,
1213
+ `HuggingFace upload failed: ${bundle.manifest.cloudUpload.huggingFaceError ?? "unknown error"}`,
1214
+ 502
1215
+ );
1216
+ return true;
1217
+ }
1218
+ json(
1219
+ res,
1220
+ {
1221
+ trajectoriesConsidered: trajectoryIds.length,
1222
+ trajectoriesPublished: bundle.manifest.counts.sanitizedTrajectoryRows,
1223
+ outputDir: bundle.outputDir,
1224
+ manifestPath: bundle.manifestPath,
1225
+ cloudUpload: bundle.manifest.cloudUpload
1226
+ },
1227
+ 201
1228
+ );
1229
+ } catch (err) {
1230
+ error(res, `Trajectory publish failed: ${String(err)}`, 500);
1231
+ }
1232
+ return true;
1233
+ }
1234
+ return false;
1235
+ }
1236
+ export {
1237
+ handleTrainingRoutes
1238
+ };
1239
+ //# sourceMappingURL=training-routes.js.map