titan-agent 5.4.2 → 5.5.6

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 (302) hide show
  1. package/README.md +1 -1
  2. package/dist/agent/agent.js +9 -5
  3. package/dist/agent/agent.js.map +1 -1
  4. package/dist/agent/agentLoop.js +7 -3
  5. package/dist/agent/agentLoop.js.map +1 -1
  6. package/dist/agent/checkpoint.js +2 -2
  7. package/dist/agent/checkpoint.js.map +1 -1
  8. package/dist/agent/commandPost.js +3 -3
  9. package/dist/agent/commandPost.js.map +1 -1
  10. package/dist/agent/goalProposer.js +2 -2
  11. package/dist/agent/goalProposer.js.map +1 -1
  12. package/dist/agent/goals.js +3 -3
  13. package/dist/agent/goals.js.map +1 -1
  14. package/dist/agent/peerAdvise.js +1 -1
  15. package/dist/agent/peerAdvise.js.map +1 -1
  16. package/dist/agent/planner.js +4 -4
  17. package/dist/agent/planner.js.map +1 -1
  18. package/dist/agent/userProfile.js +2 -2
  19. package/dist/agent/userProfile.js.map +1 -1
  20. package/dist/cli/doctor.js +33 -0
  21. package/dist/cli/doctor.js.map +1 -1
  22. package/dist/cli/onboard.js +4 -4
  23. package/dist/cli/onboard.js.map +1 -1
  24. package/dist/config/config.js +3 -3
  25. package/dist/config/config.js.map +1 -1
  26. package/dist/config/schema.js +8 -1
  27. package/dist/config/schema.js.map +1 -1
  28. package/dist/gateway/routes/adminRouter.js +500 -0
  29. package/dist/gateway/routes/adminRouter.js.map +1 -0
  30. package/dist/gateway/routes/agents.js +231 -0
  31. package/dist/gateway/routes/agents.js.map +1 -0
  32. package/dist/gateway/routes/agentsRouter.js +32 -0
  33. package/dist/gateway/routes/agentsRouter.js.map +1 -0
  34. package/dist/gateway/routes/checkpoints.js +41 -0
  35. package/dist/gateway/routes/checkpoints.js.map +1 -0
  36. package/dist/gateway/routes/commandPost.js +755 -0
  37. package/dist/gateway/routes/commandPost.js.map +1 -0
  38. package/dist/gateway/routes/companies.js +166 -0
  39. package/dist/gateway/routes/companies.js.map +1 -0
  40. package/dist/gateway/routes/files.js +295 -0
  41. package/dist/gateway/routes/files.js.map +1 -0
  42. package/dist/gateway/routes/hardwareRouter.js +151 -0
  43. package/dist/gateway/routes/hardwareRouter.js.map +1 -0
  44. package/dist/gateway/routes/mcpRouter.js +88 -0
  45. package/dist/gateway/routes/mcpRouter.js.map +1 -0
  46. package/dist/gateway/routes/mesh.js +464 -0
  47. package/dist/gateway/routes/mesh.js.map +1 -0
  48. package/dist/gateway/routes/metricsRouter.js +131 -0
  49. package/dist/gateway/routes/metricsRouter.js.map +1 -0
  50. package/dist/gateway/routes/organism.js +82 -0
  51. package/dist/gateway/routes/organism.js.map +1 -0
  52. package/dist/gateway/routes/paperclip.js +101 -0
  53. package/dist/gateway/routes/paperclip.js.map +1 -0
  54. package/dist/gateway/routes/sessions.js +227 -0
  55. package/dist/gateway/routes/sessions.js.map +1 -0
  56. package/dist/gateway/routes/skills.js +295 -0
  57. package/dist/gateway/routes/skills.js.map +1 -0
  58. package/dist/gateway/routes/socialRouter.js +145 -0
  59. package/dist/gateway/routes/socialRouter.js.map +1 -0
  60. package/dist/gateway/routes/systemRouter.js +220 -0
  61. package/dist/gateway/routes/systemRouter.js.map +1 -0
  62. package/dist/gateway/routes/teamsRecipes.js +297 -0
  63. package/dist/gateway/routes/teamsRecipes.js.map +1 -0
  64. package/dist/gateway/routes/tests.js +401 -0
  65. package/dist/gateway/routes/tests.js.map +1 -0
  66. package/dist/gateway/routes/traces.js +33 -0
  67. package/dist/gateway/routes/traces.js.map +1 -0
  68. package/dist/gateway/routes/voiceRouter.js +770 -0
  69. package/dist/gateway/routes/voiceRouter.js.map +1 -0
  70. package/dist/gateway/routes/watchRouter.js +131 -0
  71. package/dist/gateway/routes/watchRouter.js.map +1 -0
  72. package/dist/gateway/server.js +1179 -7379
  73. package/dist/gateway/server.js.map +1 -1
  74. package/dist/mcp/registry.js +2 -2
  75. package/dist/mcp/registry.js.map +1 -1
  76. package/dist/memory/episodic.js +2 -2
  77. package/dist/memory/episodic.js.map +1 -1
  78. package/dist/memory/learning.js +3 -3
  79. package/dist/memory/learning.js.map +1 -1
  80. package/dist/memory/memory.js +3 -3
  81. package/dist/memory/memory.js.map +1 -1
  82. package/dist/organism/drives.js +2 -2
  83. package/dist/organism/drives.js.map +1 -1
  84. package/dist/providers/errorTaxonomy.js +13 -0
  85. package/dist/providers/errorTaxonomy.js.map +1 -1
  86. package/dist/providers/ollama.js +3 -1
  87. package/dist/providers/ollama.js.map +1 -1
  88. package/dist/providers/openai_compat.js +4 -3
  89. package/dist/providers/openai_compat.js.map +1 -1
  90. package/dist/providers/router.js +13 -0
  91. package/dist/providers/router.js.map +1 -1
  92. package/dist/safety/fixOscillation.js +15 -0
  93. package/dist/safety/fixOscillation.js.map +1 -1
  94. package/dist/safety/killSwitch.js +2 -2
  95. package/dist/safety/killSwitch.js.map +1 -1
  96. package/dist/safety/selfRepair.js +7 -3
  97. package/dist/safety/selfRepair.js.map +1 -1
  98. package/dist/skills/builtin/agent_debate.js +2 -2
  99. package/dist/skills/builtin/agent_debate.js.map +1 -1
  100. package/dist/skills/builtin/apply_patch.js +3 -3
  101. package/dist/skills/builtin/apply_patch.js.map +1 -1
  102. package/dist/skills/builtin/shell.js +2 -2
  103. package/dist/skills/builtin/shell.js.map +1 -1
  104. package/dist/skills/builtin/voice_control.js +49 -0
  105. package/dist/skills/builtin/voice_control.js.map +1 -0
  106. package/dist/skills/builtin/widget_gallery.js +6 -1
  107. package/dist/skills/builtin/widget_gallery.js.map +1 -1
  108. package/dist/skills/registry.js +15 -4
  109. package/dist/skills/registry.js.map +1 -1
  110. package/dist/storage/JsonStorage.js +4 -4
  111. package/dist/storage/JsonStorage.js.map +1 -1
  112. package/dist/utils/constants.js +1 -1
  113. package/dist/utils/constants.js.map +1 -1
  114. package/dist/utils/helpers.js +3 -1
  115. package/dist/utils/helpers.js.map +1 -1
  116. package/dist/utils/lifecycle.js +86 -0
  117. package/dist/utils/lifecycle.js.map +1 -0
  118. package/dist/voice/bridge.js +136 -0
  119. package/dist/voice/bridge.js.map +1 -0
  120. package/docs/COO-MASTER-PLAN-2026-05-02.md +474 -0
  121. package/docs/HANDOFF/2026-04-29.md +141 -0
  122. package/docs/HANDOFF-2026-04-30.md +144 -0
  123. package/docs/HANDOFF-2026-05-03.md +114 -0
  124. package/docs/adr/2026-04-29-widget-pipeline-traceability.md +49 -0
  125. package/docs/agent-memory/README.md +45 -0
  126. package/docs/agent-memory/commands.md +100 -0
  127. package/docs/agent-memory/context-tree.md +101 -0
  128. package/docs/agent-memory/current-state.md +54 -0
  129. package/docs/agent-memory/decisions.md +78 -0
  130. package/docs/agent-memory/known-issues.md +76 -0
  131. package/docs/agent-memory/reflections.md +52 -0
  132. package/docs/agent-memory/skills-candidates.md +80 -0
  133. package/docs/superpowers/plans/2026-04-29-comprehensive-audit.md +256 -0
  134. package/docs/superpowers/plans/2026-04-29-comprehensive-test-plan.md +396 -0
  135. package/docs/superpowers/plans/2026-04-29-fix-all-prs.md +251 -0
  136. package/docs/superpowers/plans/2026-04-29-gitnexus-gap-remediation.md +969 -0
  137. package/package.json +5 -2
  138. package/ui/dist/assets/{AuditPanel-CM6Wg9hO.js → AuditPanel-VzSndmDN.js} +2 -2
  139. package/ui/dist/assets/{AutonomyPanel-CESx3ANg.js → AutonomyPanel-BiFouzAV.js} +2 -2
  140. package/ui/dist/assets/AutopilotPanel-fjOfM668.js +1 -0
  141. package/ui/dist/assets/{AutoresearchPanel-DR47NqT5.js → AutoresearchPanel-CVCxzAH3.js} +2 -2
  142. package/ui/dist/assets/BackupPanel-CHVTG--q.js +1 -0
  143. package/ui/dist/assets/{BrowserPanel-C15x9bLn.js → BrowserPanel-D5mvMKFU.js} +2 -2
  144. package/ui/dist/assets/CPActivity-B12mt35m.js +1 -0
  145. package/ui/dist/assets/CPAgentDetail-DsdShc-1.js +1 -0
  146. package/ui/dist/assets/CPAgents-j_7C-oQV.js +1 -0
  147. package/ui/dist/assets/CPApprovals-BShKSX9X.js +1 -0
  148. package/ui/dist/assets/CPCosts-CKPlhBDs.js +1 -0
  149. package/ui/dist/assets/CPDashboard-11c0nkxK.js +1 -0
  150. package/ui/dist/assets/CPFiles-BhLEOnXy.js +1 -0
  151. package/ui/dist/assets/CPGoals-Bi3t1b2P.js +1 -0
  152. package/ui/dist/assets/CPInbox-Bbr7khp6.js +11 -0
  153. package/ui/dist/assets/CPIssueDetail-DSdgNK8r.js +1 -0
  154. package/ui/dist/assets/CPIssues-DDEVKhX6.js +1 -0
  155. package/ui/dist/assets/CPLayout-DgPOfyGv.js +17 -0
  156. package/ui/dist/assets/CPOrg-Df73RrRJ.js +8 -0
  157. package/ui/dist/assets/CPRuns-ByioAz8w.js +1 -0
  158. package/ui/dist/assets/{CPSocial-nb-j7sOE.js → CPSocial-Dlnr_w1X.js} +2 -2
  159. package/ui/dist/assets/ChannelsPanel-DQjQCTK5.js +1 -0
  160. package/ui/dist/assets/CheckpointsPanel-C4vKjlAJ.js +1 -0
  161. package/ui/dist/assets/CommandPostHub-C9pp5Giq.js +24 -0
  162. package/ui/dist/assets/CronPanel-C6bzUfrD.js +1 -0
  163. package/ui/dist/assets/DaemonPanel-BA5Tb_UO.js +1 -0
  164. package/ui/dist/assets/{DataTable-B2Ma8hfi.js → DataTable-CH7IYJJh.js} +1 -1
  165. package/ui/dist/assets/{EmptyState-CcKyk5Yn.js → EmptyState-jU6yNDnF.js} +1 -1
  166. package/ui/dist/assets/{EvalHarnessPanel-BqtMc1ZM.js → EvalHarnessPanel-DnYqredY.js} +2 -2
  167. package/ui/dist/assets/EvalPanel-ChO7CD1r.js +1 -0
  168. package/ui/dist/assets/{FilesPanel-3QKvrWPo.js → FilesPanel-CaUkv2is.js} +2 -2
  169. package/ui/dist/assets/FleetPanel-DC_5uj0N.js +1 -0
  170. package/ui/dist/assets/{HomelabPanel-DhrjTX9m.js → HomelabPanel-CE5PGRpL.js} +2 -2
  171. package/ui/dist/assets/InfraView-C-uSlvb9.js +2 -0
  172. package/ui/dist/assets/InlineEditableField-BMQjiE6-.js +1 -0
  173. package/ui/dist/assets/Input-Bu_b3qmY.js +1 -0
  174. package/ui/dist/assets/IntegrationsPanel-DsYpAq43.js +1 -0
  175. package/ui/dist/assets/IntelligenceView-DUdIO1K7.js +2 -0
  176. package/ui/dist/assets/LearningPanel-UpQZC-mA.js +1 -0
  177. package/ui/dist/assets/LogsPanel-ClXJ4fcr.js +1 -0
  178. package/ui/dist/assets/McpPanel-JKgtIERQ.js +1 -0
  179. package/ui/dist/assets/{MemoryGraphPanel-Bzvjmzvk.js → MemoryGraphPanel-Bo2OrvA6.js} +2 -2
  180. package/ui/dist/assets/MemoryWikiPanel-BqJ1AmYm.js +11 -0
  181. package/ui/dist/assets/{MeshPanel-C3LJSlht.js → MeshPanel-BJVGYvwk.js} +2 -2
  182. package/ui/dist/assets/Modal-CAAooiZU.js +1 -0
  183. package/ui/dist/assets/NvidiaPanel-BtCg3G4w.js +1 -0
  184. package/ui/dist/assets/OrganismPanel-DgrTTzcF.js +1 -0
  185. package/ui/dist/assets/OverviewPanel-rVav1Hox.js +1 -0
  186. package/ui/dist/assets/{PageHeader-BimceqQo.js → PageHeader-CnZtP8ek.js} +1 -1
  187. package/ui/dist/assets/PaperclipPanel-C-FKdhiF.js +1 -0
  188. package/ui/dist/assets/{PersonasPanel-L1j78p6H.js → PersonasPanel-BmlxokfB.js} +1 -1
  189. package/ui/dist/assets/RecipesPanel-BNKKChis.js +1 -0
  190. package/ui/dist/assets/SecurityPanel-I7JRHiNy.js +1 -0
  191. package/ui/dist/assets/SelfImprovePanel-u9h0Lt3p.js +1 -0
  192. package/ui/dist/assets/{SelfProposalsPanel-lNmiDThB.js → SelfProposalsPanel-DKl9iBjM.js} +2 -2
  193. package/ui/dist/assets/SessionsPanel-BhRiWI_g.js +1 -0
  194. package/ui/dist/assets/{SessionsTab-JQbltWww.js → SessionsTab-Bk08wyeY.js} +1 -1
  195. package/ui/dist/assets/SettingsPanel-haLfmG2k.js +1 -0
  196. package/ui/dist/assets/SettingsView--gi3fxI8.js +2 -0
  197. package/ui/dist/assets/{SkeletonLoader-atQtpcF5.js → SkeletonLoader-B5v09EF_.js} +1 -1
  198. package/ui/dist/assets/{SkillsPanel-DlFs2ih7.js → SkillsPanel-BlAHFLcQ.js} +1 -1
  199. package/ui/dist/assets/SomaView-CExtS3zw.js +5 -0
  200. package/ui/dist/assets/{StatCard-DciE_Iqc.js → StatCard-BIsyMybM.js} +1 -1
  201. package/ui/dist/assets/{StatusBadge-BtfSPoW2.js → StatusBadge-D5nU7El8.js} +1 -1
  202. package/ui/dist/assets/Tabs-BBYZrBI8.js +1 -0
  203. package/ui/dist/assets/TeamsPanel-LPXJg823.js +1 -0
  204. package/ui/dist/assets/TelemetryPanel-EqpRBmOI.js +1 -0
  205. package/ui/dist/assets/TitanCanvas-BCbWnLMd.js +985 -0
  206. package/ui/dist/assets/ToolsView-CeP0Zz-N.js +2 -0
  207. package/ui/dist/assets/{Tooltip-70UK0E2I.js → Tooltip-BSO2XVpF.js} +1 -1
  208. package/ui/dist/assets/TraceViewer-BKI7o5B0.js +1 -0
  209. package/ui/dist/assets/TrainingPanel-c-RhjdE1.js +1 -0
  210. package/ui/dist/assets/VoiceOverlay-D-gc58b0.js +27 -0
  211. package/ui/dist/assets/VramPanel-C6xc7zgd.js +1 -0
  212. package/ui/dist/assets/{WatchView-C-sGFpVy.js → WatchView-dqBVCVH0.js} +1 -1
  213. package/ui/dist/assets/WorkTab-CBoLNrTM.js +1 -0
  214. package/ui/dist/assets/{WorkflowsPanel-CvgQU1xI.js → WorkflowsPanel-BAnSTOYe.js} +2 -2
  215. package/ui/dist/assets/approvalHeadline-DB9SgR-9.js +1 -0
  216. package/ui/dist/assets/{arrow-left-DwqHtJiU.js → arrow-left-5chqas7J.js} +1 -1
  217. package/ui/dist/assets/briefcase-D4vLzudp.js +6 -0
  218. package/ui/dist/assets/{chart-column-BtNO6sRy.js → chart-column-CdFlBpoP.js} +1 -1
  219. package/ui/dist/assets/check-Bpm1IONe.js +6 -0
  220. package/ui/dist/assets/chevron-down-D7OLjvuD.js +6 -0
  221. package/ui/dist/assets/chevron-right-aQEw2mUW.js +6 -0
  222. package/ui/dist/assets/chevron-up-C5g6pEj8.js +6 -0
  223. package/ui/dist/assets/{circle-check-big-DZRE_MbN.js → circle-check-big-fPhEdP88.js} +1 -1
  224. package/ui/dist/assets/clock-CTsgP_Sn.js +6 -0
  225. package/ui/dist/assets/{dollar-sign-aVG3a5eL.js → dollar-sign-CudFVYFc.js} +1 -1
  226. package/ui/dist/assets/{download-BxiWJU4G.js → download-DZRxDn67.js} +1 -1
  227. package/ui/dist/assets/external-link-BZ0y_Ahx.js +6 -0
  228. package/ui/dist/assets/{eye-off-CkgfFYhm.js → eye-off-BmJF0YYx.js} +1 -1
  229. package/ui/dist/assets/folder-DA43TRCm.js +11 -0
  230. package/ui/dist/assets/{funnel-PkLdxKyC.js → funnel-J3mULzrz.js} +1 -1
  231. package/ui/dist/assets/{git-branch-BM-Gw95X.js → git-branch-oHibJqDq.js} +1 -1
  232. package/ui/dist/assets/{index-D0RJ8701.css → index-BR0vfkIi.css} +1 -1
  233. package/ui/dist/assets/{index-CahJbWSR.js → index-DzwowwSI.js} +20 -20
  234. package/ui/dist/assets/{layers-BuGf4FIJ.js → layers-DsyEyu7z.js} +1 -1
  235. package/ui/dist/assets/{legacy-CR6o4t-y.js → legacy-8ITl64sV.js} +1 -1
  236. package/ui/dist/assets/{lightbulb-n8gc_XAL.js → lightbulb-C54Ske-p.js} +1 -1
  237. package/ui/dist/assets/list-todo-Cnd4rdoK.js +6 -0
  238. package/ui/dist/assets/loader-circle-1YOBsoQp.js +6 -0
  239. package/ui/dist/assets/network-DbGDAdrn.js +6 -0
  240. package/ui/dist/assets/{pause-DCV52koX.js → pause-CYhO_uQo.js} +1 -1
  241. package/ui/dist/assets/{play-CcJ9BnCh.js → play-DVY9c5Ck.js} +1 -1
  242. package/ui/dist/assets/{plug-CfWBXfCl.js → plug-BcXjlPUL.js} +1 -1
  243. package/ui/dist/assets/plus-Csu2v9GN.js +6 -0
  244. package/ui/dist/assets/{proxy-CzZDfLmm.js → proxy-DxS2_9D7.js} +1 -1
  245. package/ui/dist/assets/rotate-ccw-Co-_W04j.js +6 -0
  246. package/ui/dist/assets/save-Btx-kpoW.js +6 -0
  247. package/ui/dist/assets/search-0hXTwEZR.js +6 -0
  248. package/ui/dist/assets/send-TEpapzQR.js +6 -0
  249. package/ui/dist/assets/shield-check-DjBJXZUr.js +6 -0
  250. package/ui/dist/assets/{square-DJpUhlxi.js → square-OweUvjP-.js} +1 -1
  251. package/ui/dist/assets/{target-DWcmM_9m.js → target-BRW80Xer.js} +1 -1
  252. package/ui/dist/assets/terminal-BtiqJ628.js +16 -0
  253. package/ui/dist/assets/{toggle-right-YusFQ69L.js → toggle-right-CKtSrl28.js} +1 -1
  254. package/ui/dist/assets/{trash-2-CK7yQ55V.js → trash-2-DgWrHVax.js} +1 -1
  255. package/ui/dist/assets/{trending-up-DGjFyubC.js → trending-up-MpIrE4j6.js} +1 -1
  256. package/ui/dist/assets/{trophy-uQv_NgDB.js → trophy-CECuZNhX.js} +1 -1
  257. package/ui/dist/assets/users-dZgv4ePG.js +16 -0
  258. package/ui/dist/assets/wrench-CDz3xYve.js +11 -0
  259. package/ui/dist/index.html +2 -2
  260. package/ui/dist/assets/AutopilotPanel-DtEet1hJ.js +0 -1
  261. package/ui/dist/assets/BackupPanel-BGP8p3l3.js +0 -1
  262. package/ui/dist/assets/CPAgents-DYUtPzSq.js +0 -1
  263. package/ui/dist/assets/CPDashboard-Bf0-SyCh.js +0 -6
  264. package/ui/dist/assets/CPFiles-CxgxjQcO.js +0 -1
  265. package/ui/dist/assets/CPGoals-BsmCMTvT.js +0 -1
  266. package/ui/dist/assets/CPInbox-tMSbmQ9H.js +0 -11
  267. package/ui/dist/assets/ChannelsPanel-DP5C2OKd.js +0 -1
  268. package/ui/dist/assets/CheckpointsPanel-DlranVLZ.js +0 -1
  269. package/ui/dist/assets/CommandPostHub-BgxIa4Ev.js +0 -29
  270. package/ui/dist/assets/CronPanel-LoT5yKwJ.js +0 -1
  271. package/ui/dist/assets/DaemonPanel-DBGMqaE_.js +0 -1
  272. package/ui/dist/assets/EvalPanel-Bc33j0pN.js +0 -1
  273. package/ui/dist/assets/FleetPanel-CSsXuQYj.js +0 -1
  274. package/ui/dist/assets/InfraView-CR6HyrL6.js +0 -2
  275. package/ui/dist/assets/InlineEditableField-CnvF-yFR.js +0 -1
  276. package/ui/dist/assets/Input-GTHp2Rkr.js +0 -1
  277. package/ui/dist/assets/IntegrationsPanel-CymCRE3T.js +0 -1
  278. package/ui/dist/assets/IntelligenceView-C1IHxJRC.js +0 -2
  279. package/ui/dist/assets/LearningPanel-DOCES3lH.js +0 -1
  280. package/ui/dist/assets/LogsPanel-BLnAqEaZ.js +0 -1
  281. package/ui/dist/assets/McpPanel-ChUzmr3z.js +0 -1
  282. package/ui/dist/assets/MemoryWikiPanel-Dwk3Aqwd.js +0 -11
  283. package/ui/dist/assets/NvidiaPanel-CeZK_-CV.js +0 -1
  284. package/ui/dist/assets/OrganismPanel-BB6YOiQV.js +0 -1
  285. package/ui/dist/assets/OverviewPanel-BmtBhQnv.js +0 -1
  286. package/ui/dist/assets/PaperclipPanel-C-brgwA3.js +0 -1
  287. package/ui/dist/assets/RecipesPanel-34lCfynJ.js +0 -1
  288. package/ui/dist/assets/SecurityPanel-CBTPWLj6.js +0 -1
  289. package/ui/dist/assets/SelfImprovePanel-BrPbFHhG.js +0 -1
  290. package/ui/dist/assets/SessionsPanel-DAEYIn83.js +0 -1
  291. package/ui/dist/assets/SettingsPanel-CzRROAYQ.js +0 -1
  292. package/ui/dist/assets/SettingsView-CN7ii2uw.js +0 -2
  293. package/ui/dist/assets/SomaView-Ba642Oqb.js +0 -5
  294. package/ui/dist/assets/TeamsPanel-DKQ5z2Qe.js +0 -1
  295. package/ui/dist/assets/TelemetryPanel-B6KAc55Q.js +0 -1
  296. package/ui/dist/assets/TitanCanvas-C-s0A-lv.js +0 -1092
  297. package/ui/dist/assets/ToolsView-Dei0KMP0.js +0 -2
  298. package/ui/dist/assets/TraceViewer-BniolyBx.js +0 -1
  299. package/ui/dist/assets/TrainingPanel-Bz4CTPGW.js +0 -1
  300. package/ui/dist/assets/VoiceOverlay-CmNCrLcd.js +0 -37
  301. package/ui/dist/assets/VramPanel-Xh_OtRDR.js +0 -1
  302. package/ui/dist/assets/WorkTab-BjLNmgIK.js +0 -1
@@ -0,0 +1,401 @@
1
+ #!/usr/bin/env node
2
+ import { Router } from "express";
3
+ import logger from "../../utils/logger.js";
4
+ import { processMessage } from "../../agent/agent.js";
5
+ import { recordEvalSuiteResult, recordEvalTimeout, recordEvalError } from "../metrics.js";
6
+ const COMPONENT = "TestsRouter";
7
+ function createTestsRouter() {
8
+ const router = Router();
9
+ router.get("/test/health", async (_req, res) => {
10
+ try {
11
+ const { getTestHealthSummary } = await import("../../testing/testHealthMonitor.js");
12
+ const summary = getTestHealthSummary();
13
+ res.json(summary);
14
+ } catch (err) {
15
+ res.status(500).json({ error: err.message });
16
+ }
17
+ });
18
+ router.get("/test/stats", async (_req, res) => {
19
+ try {
20
+ const { getTestHealth } = await import("../../testing/testHealthMonitor.js");
21
+ const stats = getTestHealth();
22
+ res.json(stats);
23
+ } catch (err) {
24
+ res.status(500).json({ error: err.message });
25
+ }
26
+ });
27
+ router.get("/test/failing", async (_req, res) => {
28
+ try {
29
+ const { getFailingTests } = await import("../../testing/testHealthMonitor.js");
30
+ const failing = getFailingTests();
31
+ res.json(failing);
32
+ } catch (err) {
33
+ res.status(500).json({ error: err.message });
34
+ }
35
+ });
36
+ router.get("/test/flaky", async (_req, res) => {
37
+ try {
38
+ const { getFlakyTests } = await import("../../testing/testHealthMonitor.js");
39
+ const threshold = _req.query.threshold ? parseFloat(_req.query.threshold) : 0.4;
40
+ const flaky = getFlakyTests(threshold);
41
+ res.json(flaky);
42
+ } catch (err) {
43
+ res.status(500).json({ error: err.message });
44
+ }
45
+ });
46
+ router.get("/test/runs", async (_req, res) => {
47
+ try {
48
+ const { getRecentTestRuns } = await import("../../testing/testHealthMonitor.js");
49
+ const limit = _req.query.limit ? parseInt(_req.query.limit, 10) : 10;
50
+ const runs = getRecentTestRuns(limit);
51
+ res.json(runs);
52
+ } catch (err) {
53
+ res.status(500).json({ error: err.message });
54
+ }
55
+ });
56
+ router.post("/test/run", async (_req, res) => {
57
+ try {
58
+ const { runTestsDetailed } = await import("../../testing/testHealthMonitor.js");
59
+ const { pattern, watch, coverage, timeout } = _req.body;
60
+ const result = await runTestsDetailed({ pattern, watch, coverage, timeout });
61
+ res.json(result);
62
+ } catch (err) {
63
+ res.status(500).json({ error: err.message });
64
+ }
65
+ });
66
+ router.get("/test/repair-history", async (_req, res) => {
67
+ try {
68
+ const { getRepairHistory } = await import("../../testing/repairValidator.js");
69
+ const repairId = _req.query.repairId;
70
+ const history = getRepairHistory(repairId);
71
+ res.json(history);
72
+ } catch (err) {
73
+ res.status(500).json({ error: err.message });
74
+ }
75
+ });
76
+ router.get("/tests/health", async (_req, res) => {
77
+ try {
78
+ const { getTestHealthSummary } = await import("../../testing/testHealthMonitor.js");
79
+ const summary = getTestHealthSummary();
80
+ res.json(summary);
81
+ } catch (e) {
82
+ logger.error(COMPONENT, `Endpoint error: ${e.message}`);
83
+ res.status(500).json({ error: "Something went wrong on our end. Please try again in a moment." });
84
+ }
85
+ });
86
+ router.get("/tests/failing", async (_req, res) => {
87
+ try {
88
+ const { getFailingTests } = await import("../../testing/testHealthMonitor.js");
89
+ const failing = getFailingTests();
90
+ res.json({ tests: failing, count: failing.length });
91
+ } catch (e) {
92
+ logger.error(COMPONENT, `Endpoint error: ${e.message}`);
93
+ res.status(500).json({ error: "Something went wrong on our end. Please try again in a moment." });
94
+ }
95
+ });
96
+ router.get("/tests/flaky", async (_req, res) => {
97
+ try {
98
+ const { getFlakyTests } = await import("../../testing/testHealthMonitor.js");
99
+ const threshold = _req.query.threshold ? parseFloat(_req.query.threshold) : 0.4;
100
+ const flaky = getFlakyTests(threshold);
101
+ res.json({ tests: flaky, count: flaky.length, threshold });
102
+ } catch (e) {
103
+ logger.error(COMPONENT, `Endpoint error: ${e.message}`);
104
+ res.status(500).json({ error: "Something went wrong on our end. Please try again in a moment." });
105
+ }
106
+ });
107
+ router.get("/tests/history", async (_req, res) => {
108
+ try {
109
+ const { getRecentTestRuns } = await import("../../testing/testHealthMonitor.js");
110
+ const limit = _req.query.limit ? parseInt(_req.query.limit, 10) : 10;
111
+ const runs = getRecentTestRuns(limit);
112
+ res.json({ runs, count: runs.length });
113
+ } catch (e) {
114
+ logger.error(COMPONENT, `Endpoint error: ${e.message}`);
115
+ res.status(500).json({ error: "Something went wrong on our end. Please try again in a moment." });
116
+ }
117
+ });
118
+ router.post("/tests/run", async (req, res) => {
119
+ try {
120
+ const { runTests } = await import("../../testing/testRunner.js");
121
+ const { pattern, timeout } = req.body;
122
+ const result = await runTests({ pattern, timeout });
123
+ res.json(result);
124
+ } catch (e) {
125
+ logger.error(COMPONENT, `Endpoint error: ${e.message}`);
126
+ res.status(500).json({ error: "Something went wrong on our end. Please try again in a moment." });
127
+ }
128
+ });
129
+ router.post("/tests/validate-repair", async (req, res) => {
130
+ try {
131
+ const { validateRepair } = await import("../../testing/repairValidator.js");
132
+ const { repairId, finding, affectedFiles } = req.body;
133
+ if (!repairId || !finding) {
134
+ res.status(400).json({ error: "Missing required fields: repairId, finding" });
135
+ return;
136
+ }
137
+ const result = await validateRepair({ repairId, finding, affectedFiles });
138
+ res.json(result);
139
+ } catch (e) {
140
+ logger.error(COMPONENT, `Endpoint error: ${e.message}`);
141
+ res.status(500).json({ error: "Something went wrong on our end. Please try again in a moment." });
142
+ }
143
+ });
144
+ router.get("/tests/repair-history", async (req, res) => {
145
+ try {
146
+ const { getRepairHistory } = await import("../../testing/repairValidator.js");
147
+ const { repairId } = req.query;
148
+ const history = getRepairHistory(repairId);
149
+ res.json({ history, count: history.length });
150
+ } catch (e) {
151
+ logger.error(COMPONENT, `Endpoint error: ${e.message}`);
152
+ res.status(500).json({ error: "Something went wrong on our end. Please try again in a moment." });
153
+ }
154
+ });
155
+ router.post("/tests/validate-system-repair", async (req, res) => {
156
+ try {
157
+ const { validateSystemRepair } = await import("../../testing/repairValidator.js");
158
+ const { repairType, target } = req.body;
159
+ if (!repairType || !target) {
160
+ res.status(400).json({ error: "Missing required fields: repairType, target" });
161
+ return;
162
+ }
163
+ const result = await validateSystemRepair({ repairType, target });
164
+ res.json({ success: result.valid ?? false, repairType, target, ...result });
165
+ } catch (e) {
166
+ logger.error(COMPONENT, `Endpoint error: ${e.message}`);
167
+ res.status(500).json({ error: "Something went wrong on our end. Please try again in a moment." });
168
+ }
169
+ });
170
+ router.get("/test-health/summary", async (_req, res) => {
171
+ try {
172
+ const { getTestHealthSummary, getFlakyTests } = await import("../../testing/testHealthMonitor.js");
173
+ const raw = getTestHealthSummary();
174
+ const flaky = getFlakyTests().length;
175
+ res.json({
176
+ total: raw.total,
177
+ passing: raw.passing,
178
+ failing: raw.failing,
179
+ flaky,
180
+ coverage: raw.coveragePct
181
+ });
182
+ } catch (e) {
183
+ logger.error(COMPONENT, `Endpoint error: ${e.message}`);
184
+ res.status(500).json({ error: "Something went wrong on our end. Please try again in a moment." });
185
+ }
186
+ });
187
+ router.get("/test-health/failing", async (_req, res) => {
188
+ try {
189
+ const { getFailingTests } = await import("../../testing/testHealthMonitor.js");
190
+ const limit = _req.query.limit ? parseInt(_req.query.limit, 10) : 10;
191
+ const names = getFailingTests().slice(0, limit);
192
+ const tests = names.map((name) => ({ name, suite: "", error: "", lastFailed: "", attempts: 0 }));
193
+ res.json({ count: tests.length, tests });
194
+ } catch (e) {
195
+ res.status(500).json({ error: e.message, tests: [] });
196
+ }
197
+ });
198
+ router.get("/test-health/flaky", async (_req, res) => {
199
+ try {
200
+ const { getFlakyTests } = await import("../../testing/testHealthMonitor.js");
201
+ const threshold = _req.query.threshold ? parseFloat(_req.query.threshold) : 0.4;
202
+ const limit = _req.query.limit ? parseInt(_req.query.limit, 10) : 10;
203
+ const names = getFlakyTests(threshold).slice(0, limit);
204
+ const tests = names.map((name) => ({ name, suite: "", passRate: 0, runs: 0 }));
205
+ res.json({ count: tests.length, threshold, tests });
206
+ } catch (e) {
207
+ res.status(500).json({ error: e.message, tests: [] });
208
+ }
209
+ });
210
+ router.get("/test-health/history", async (_req, res) => {
211
+ try {
212
+ const { getRecentTestRuns } = await import("../../testing/testHealthMonitor.js");
213
+ const limit = _req.query.limit ? parseInt(_req.query.limit, 10) : 5;
214
+ const runs = getRecentTestRuns(limit);
215
+ res.json({ count: runs.length, runs });
216
+ } catch (e) {
217
+ res.status(500).json({ error: e.message, runs: [] });
218
+ }
219
+ });
220
+ router.post("/test-health/run", async (req, res) => {
221
+ try {
222
+ const { runTests } = await import("../../testing/testRunner.js");
223
+ const { pattern, coverage, timeout } = req.body;
224
+ const result = await runTests({ pattern, coverage, timeout });
225
+ res.json(result);
226
+ } catch (e) {
227
+ res.status(500).json({ error: e.message, success: false });
228
+ }
229
+ });
230
+ router.post("/eval/run", async (req, res) => {
231
+ const requestedSuite = req.body?.suite ?? "";
232
+ const timeoutMs = (() => {
233
+ const raw = req.query?.timeoutMs;
234
+ if (typeof raw !== "string") return 6e5;
235
+ const n = Number(raw);
236
+ if (!Number.isFinite(n) || n <= 0) return 6e5;
237
+ return Math.max(1e4, Math.min(36e5, Math.round(n)));
238
+ })();
239
+ if (requestedSuite) {
240
+ res.setHeader("X-Eval-Suite", requestedSuite);
241
+ }
242
+ const tStart = Date.now();
243
+ logger.info(COMPONENT, `/api/eval/run START suite=${requestedSuite || "(none)"} timeoutMs=${timeoutMs}`);
244
+ try {
245
+ const {
246
+ runEvalSuite,
247
+ WIDGET_CREATION_SUITE,
248
+ SAFETY_SUITE,
249
+ TOOL_ROUTING_SUITE,
250
+ GATE_FORMAT_SUITE,
251
+ PIPELINE_SUITE,
252
+ ADVERSARIAL_SUITE,
253
+ TOOL_ROUTING_V2_SUITE,
254
+ SESSION_SUITE,
255
+ WIDGET_V2_SUITE,
256
+ GATE_FORMAT_V2_SUITE,
257
+ CONTENT_SUITE
258
+ } = await import("../../eval/harness.js");
259
+ const systemWidgetShortcuts = [
260
+ { pattern: /\b(?:backups?|snapshots?|archives?)\b/i, source: "system:backup", name: "Backup Manager", w: 6, h: 6 },
261
+ { pattern: /\b(?:training|train|specialists?|models?)\b/i, source: "system:training", name: "Training Dashboard", w: 6, h: 6 },
262
+ { pattern: /\b(?:recipes?|playbooks?|workflows?|jarvis)\b/i, source: "system:recipes", name: "Recipe Kitchen", w: 6, h: 6 },
263
+ { pattern: /\b(?:vram|gpu|memory|nvidia)\b/i, source: "system:vram", name: "VRAM Monitor", w: 6, h: 6 },
264
+ { pattern: /\b(?:teams?|members?|roles?|permissions?|rbac)\b/i, source: "system:teams", name: "Team Hub", w: 6, h: 6 },
265
+ { pattern: /\b(?:cron|schedules?|jobs?|timers?)\b/i, source: "system:cron", name: "Cron Scheduler", w: 6, h: 6 },
266
+ { pattern: /\b(?:checkpoints?|restores?|save state)\b/i, source: "system:checkpoints", name: "Checkpoints", w: 6, h: 5 },
267
+ { pattern: /\b(?:organism|drives?|safety|alerts?|guardrails?)\b/i, source: "system:organism", name: "Organism Monitor", w: 6, h: 6 },
268
+ { pattern: /\b(?:fleet|nodes?|routes?|mesh)\b/i, source: "system:fleet", name: "Fleet Router", w: 6, h: 5 },
269
+ { pattern: /\b(?:captcha|browsers?|form fill|web automation)\b/i, source: "system:browser", name: "Browser Tools", w: 6, h: 5 },
270
+ { pattern: /\b(?:paperclip|sidecars?|helpers?)\b/i, source: "system:paperclip", name: "Paperclip", w: 6, h: 5 },
271
+ { pattern: /\b(?:tests?|flaky|failing|coverage|eval)\b/i, source: "system:eval", name: "Test Lab", w: 6, h: 6 }
272
+ ];
273
+ const agentCall = async (input, testName) => {
274
+ const shortcut = systemWidgetShortcuts.find((s) => s.pattern.test(input));
275
+ if (shortcut) {
276
+ return {
277
+ content: `Added the **${shortcut.name}** widget to your canvas.
278
+
279
+ _____widget
280
+ { "name": "${shortcut.name}", "format": "system", "source": "${shortcut.source}", "w": ${shortcut.w}, "h": ${shortcut.h} }`,
281
+ toolsUsed: []
282
+ };
283
+ }
284
+ const userId = testName ? `eval-${testName.replace(/\s+/g, "-").toLowerCase()}` : "eval-harness";
285
+ const result2 = await processMessage(input, "eval", userId, {});
286
+ return {
287
+ content: result2.content || "",
288
+ toolsUsed: result2.toolsUsed ?? []
289
+ };
290
+ };
291
+ let cases;
292
+ const suite = requestedSuite;
293
+ switch (suite) {
294
+ case "widget-creation":
295
+ cases = WIDGET_CREATION_SUITE;
296
+ break;
297
+ case "safety":
298
+ cases = SAFETY_SUITE;
299
+ break;
300
+ case "tool-routing":
301
+ cases = TOOL_ROUTING_SUITE;
302
+ break;
303
+ case "gate-format":
304
+ cases = GATE_FORMAT_SUITE;
305
+ break;
306
+ case "pipeline":
307
+ cases = PIPELINE_SUITE;
308
+ break;
309
+ case "adversarial":
310
+ cases = ADVERSARIAL_SUITE;
311
+ break;
312
+ case "tool-routing-v2":
313
+ cases = TOOL_ROUTING_V2_SUITE;
314
+ break;
315
+ case "session":
316
+ cases = SESSION_SUITE;
317
+ break;
318
+ case "widget-v2":
319
+ cases = WIDGET_V2_SUITE;
320
+ break;
321
+ case "gate-format-v2":
322
+ cases = GATE_FORMAT_V2_SUITE;
323
+ break;
324
+ case "content":
325
+ cases = CONTENT_SUITE;
326
+ break;
327
+ default:
328
+ res.status(404).json({
329
+ error: `Unknown suite: ${suite || "(empty)"}. Choose: widget-creation, safety, tool-routing, gate-format, pipeline, adversarial, tool-routing-v2, session, widget-v2, gate-format-v2, content.`
330
+ });
331
+ return;
332
+ }
333
+ const TIMEOUT = /* @__PURE__ */ Symbol("eval-timeout");
334
+ const result = await Promise.race([
335
+ runEvalSuite(suite, cases, agentCall),
336
+ new Promise((resolve) => {
337
+ setTimeout(() => resolve(TIMEOUT), timeoutMs);
338
+ })
339
+ ]);
340
+ if (result === TIMEOUT) {
341
+ const elapsed2 = Date.now() - tStart;
342
+ logger.warn(COMPONENT, `/api/eval/run TIMEOUT suite=${suite} elapsedMs=${elapsed2} timeoutMs=${timeoutMs}`);
343
+ try {
344
+ recordEvalTimeout(suite);
345
+ } catch {
346
+ }
347
+ res.status(504).json({
348
+ suite,
349
+ passed: 0,
350
+ total: 0,
351
+ results: [],
352
+ timedOut: true,
353
+ timeoutMs,
354
+ elapsedMs: elapsed2,
355
+ error: `Eval suite '${suite}' timed out after ${timeoutMs}ms`
356
+ });
357
+ return;
358
+ }
359
+ try {
360
+ recordEvalSuiteResult(suite, result.passed, result.total);
361
+ } catch {
362
+ }
363
+ const elapsed = Date.now() - tStart;
364
+ logger.info(COMPONENT, `/api/eval/run DONE suite=${suite} passed=${result.passed}/${result.total} elapsedMs=${elapsed}`);
365
+ res.json(result);
366
+ } catch (e) {
367
+ const err = e;
368
+ const elapsed = Date.now() - tStart;
369
+ logger.warn(COMPONENT, `/api/eval/run ERROR suite=${requestedSuite || "(none)"} elapsedMs=${elapsed} message=${err.message}`);
370
+ try {
371
+ recordEvalError(requestedSuite || "unknown", err.name || "unknown");
372
+ } catch {
373
+ }
374
+ res.status(500).json({
375
+ suite: requestedSuite || void 0,
376
+ error: err.message || "Eval run failed",
377
+ errorClass: err.name || "Error"
378
+ });
379
+ }
380
+ });
381
+ router.get("/eval/suites", async (_req, res) => {
382
+ res.json({ suites: [
383
+ "widget-creation",
384
+ "safety",
385
+ "tool-routing",
386
+ "gate-format",
387
+ "pipeline",
388
+ "adversarial",
389
+ "tool-routing-v2",
390
+ "session",
391
+ "widget-v2",
392
+ "gate-format-v2",
393
+ "content"
394
+ ] });
395
+ });
396
+ return router;
397
+ }
398
+ export {
399
+ createTestsRouter
400
+ };
401
+ //# sourceMappingURL=tests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/gateway/routes/tests.ts"],"sourcesContent":["/**\n * Tests Router\n *\n * Extracted from gateway/server.ts.\n * Consolidates all /api/test/*, /api/tests/*, /api/test-health/*, and /api/eval/* routes.\n */\n\nimport { Router, type Request, type Response } from 'express';\nimport logger from '../../utils/logger.js';\nimport { processMessage } from '../../agent/agent.js';\nimport { recordEvalSuiteResult, recordEvalTimeout, recordEvalError } from '../metrics.js';\n\nconst COMPONENT = 'TestsRouter';\n\nexport function createTestsRouter(): Router {\n const router = Router();\n\n // ── Test routes (/api/test/*) ───────────────────────────────────\n router.get('/test/health', async (_req, res) => {\n try {\n const { getTestHealthSummary } = await import('../../testing/testHealthMonitor.js');\n const summary = getTestHealthSummary();\n res.json(summary);\n } catch (err) {\n res.status(500).json({ error: (err as Error).message });\n }\n });\n\n router.get('/test/stats', async (_req, res) => {\n try {\n const { getTestHealth } = await import('../../testing/testHealthMonitor.js');\n const stats = getTestHealth();\n res.json(stats);\n } catch (err) {\n res.status(500).json({ error: (err as Error).message });\n }\n });\n\n router.get('/test/failing', async (_req, res) => {\n try {\n const { getFailingTests } = await import('../../testing/testHealthMonitor.js');\n const failing = getFailingTests();\n res.json(failing);\n } catch (err) {\n res.status(500).json({ error: (err as Error).message });\n }\n });\n\n router.get('/test/flaky', async (_req, res) => {\n try {\n const { getFlakyTests } = await import('../../testing/testHealthMonitor.js');\n const threshold = _req.query.threshold ? parseFloat(_req.query.threshold as string) : 0.4;\n const flaky = getFlakyTests(threshold);\n res.json(flaky);\n } catch (err) {\n res.status(500).json({ error: (err as Error).message });\n }\n });\n\n router.get('/test/runs', async (_req, res) => {\n try {\n const { getRecentTestRuns } = await import('../../testing/testHealthMonitor.js');\n const limit = _req.query.limit ? parseInt(_req.query.limit as string, 10) : 10;\n const runs = getRecentTestRuns(limit);\n res.json(runs);\n } catch (err) {\n res.status(500).json({ error: (err as Error).message });\n }\n });\n\n router.post('/test/run', async (_req, res) => {\n try {\n const { runTestsDetailed } = await import('../../testing/testHealthMonitor.js');\n const { pattern, watch, coverage, timeout } = _req.body;\n const result = await runTestsDetailed({ pattern, watch, coverage, timeout });\n res.json(result);\n } catch (err) {\n res.status(500).json({ error: (err as Error).message });\n }\n });\n\n router.get('/test/repair-history', async (_req, res) => {\n try {\n const { getRepairHistory } = await import('../../testing/repairValidator.js');\n const repairId = _req.query.repairId as string | undefined;\n const history = getRepairHistory(repairId);\n res.json(history);\n } catch (err) {\n res.status(500).json({ error: (err as Error).message });\n }\n });\n\n // ── Tests routes (/api/tests/*) ─────────────────────────────────\n router.get('/tests/health', async (_req, res) => {\n try {\n const { getTestHealthSummary } = await import('../../testing/testHealthMonitor.js');\n const summary = getTestHealthSummary();\n res.json(summary);\n } catch (e) {\n logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' });\n }\n });\n\n router.get('/tests/failing', async (_req, res) => {\n try {\n const { getFailingTests } = await import('../../testing/testHealthMonitor.js');\n const failing = getFailingTests();\n res.json({ tests: failing, count: failing.length });\n } catch (e) {\n logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' });\n }\n });\n\n router.get('/tests/flaky', async (_req, res) => {\n try {\n const { getFlakyTests } = await import('../../testing/testHealthMonitor.js');\n const threshold = _req.query.threshold ? parseFloat(_req.query.threshold as string) : 0.4;\n const flaky = getFlakyTests(threshold);\n res.json({ tests: flaky, count: flaky.length, threshold });\n } catch (e) {\n logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' });\n }\n });\n\n router.get('/tests/history', async (_req, res) => {\n try {\n const { getRecentTestRuns } = await import('../../testing/testHealthMonitor.js');\n const limit = _req.query.limit ? parseInt(_req.query.limit as string, 10) : 10;\n const runs = getRecentTestRuns(limit);\n res.json({ runs, count: runs.length });\n } catch (e) {\n logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' });\n }\n });\n\n router.post('/tests/run', async (req, res) => {\n try {\n const { runTests } = await import('../../testing/testRunner.js');\n const { pattern, timeout } = req.body;\n const result = await runTests({ pattern, timeout });\n res.json(result);\n } catch (e) {\n logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' });\n }\n });\n\n router.post('/tests/validate-repair', async (req, res) => {\n try {\n const { validateRepair } = await import('../../testing/repairValidator.js');\n const { repairId, finding, affectedFiles } = req.body;\n\n if (!repairId || !finding) {\n res.status(400).json({ error: 'Missing required fields: repairId, finding' });\n return;\n }\n\n const result = await validateRepair({ repairId, finding, affectedFiles });\n res.json(result);\n } catch (e) {\n logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' });\n }\n });\n\n router.get('/tests/repair-history', async (req, res) => {\n try {\n const { getRepairHistory } = await import('../../testing/repairValidator.js');\n const { repairId } = req.query;\n const history = getRepairHistory(repairId as string | undefined);\n res.json({ history, count: history.length });\n } catch (e) {\n logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' });\n }\n });\n\n router.post('/tests/validate-system-repair', async (req, res) => {\n try {\n const { validateSystemRepair } = await import('../../testing/repairValidator.js');\n const { repairType, target } = req.body;\n\n if (!repairType || !target) {\n res.status(400).json({ error: 'Missing required fields: repairType, target' });\n return;\n }\n\n const result = await validateSystemRepair({ repairType, target });\n res.json({ success: result.valid ?? false, repairType, target, ...result });\n } catch (e) {\n logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' });\n }\n });\n\n // ── Test-Health routes (/api/test-health/*) ─────────────────────\n router.get('/test-health/summary', async (_req, res) => {\n try {\n const { getTestHealthSummary, getFlakyTests } = await import('../../testing/testHealthMonitor.js');\n const raw = getTestHealthSummary();\n const flaky = getFlakyTests().length;\n res.json({\n total: raw.total as number,\n passing: raw.passing as number,\n failing: raw.failing as number,\n flaky,\n coverage: raw.coveragePct as number,\n });\n } catch (e) {\n logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' });\n }\n });\n\n router.get('/test-health/failing', async (_req, res) => {\n try {\n const { getFailingTests } = await import('../../testing/testHealthMonitor.js');\n const limit = _req.query.limit ? parseInt(_req.query.limit as string, 10) : 10;\n const names = getFailingTests().slice(0, limit);\n const tests = names.map(name => ({ name, suite: '', error: '', lastFailed: '', attempts: 0 }));\n res.json({ count: tests.length, tests });\n } catch (e) {\n res.status(500).json({ error: (e as Error).message, tests: [] });\n }\n });\n\n router.get('/test-health/flaky', async (_req, res) => {\n try {\n const { getFlakyTests } = await import('../../testing/testHealthMonitor.js');\n const threshold = _req.query.threshold ? parseFloat(_req.query.threshold as string) : 0.4;\n const limit = _req.query.limit ? parseInt(_req.query.limit as string, 10) : 10;\n const names = getFlakyTests(threshold).slice(0, limit);\n const tests = names.map(name => ({ name, suite: '', passRate: 0, runs: 0 }));\n res.json({ count: tests.length, threshold, tests });\n } catch (e) {\n res.status(500).json({ error: (e as Error).message, tests: [] });\n }\n });\n\n router.get('/test-health/history', async (_req, res) => {\n try {\n const { getRecentTestRuns } = await import('../../testing/testHealthMonitor.js');\n const limit = _req.query.limit ? parseInt(_req.query.limit as string, 10) : 5;\n const runs = getRecentTestRuns(limit);\n res.json({ count: runs.length, runs });\n } catch (e) {\n res.status(500).json({ error: (e as Error).message, runs: [] });\n }\n });\n\n router.post('/test-health/run', async (req, res) => {\n try {\n const { runTests } = await import('../../testing/testRunner.js');\n const { pattern, coverage, timeout } = req.body;\n const result = await runTests({ pattern, coverage, timeout });\n res.json(result);\n } catch (e) {\n res.status(500).json({ error: (e as Error).message, success: false });\n }\n });\n\n // ── Eval routes (/api/eval/*) ──────────────────────────────────\n // v5.3.1 hardening:\n // - Promise.race with configurable timeout (?timeoutMs=, default 10 min)\n // - 504 on timeout with {timedOut:true} so the CI gate sees an explicit\n // signal instead of a hung connection\n // - 500 on unhandled exception (gateway must not crash on a bad case)\n // - 404 (was 400) on unknown suite — semantically right, easier on CI\n // scripts that branch on resource-not-found vs validation\n // - X-Eval-Suite response header so /var/log filtering is one grep\n // - Prometheus counters: timeout_total + error_total updated on the\n // respective failure paths so the Trends tab can chart drift.\n router.post('/eval/run', async (req, res) => {\n const requestedSuite = (req.body as { suite?: string } | undefined)?.suite ?? '';\n const timeoutMs = (() => {\n const raw = req.query?.timeoutMs;\n if (typeof raw !== 'string') return 600_000; // 10 min default\n const n = Number(raw);\n // Guard against ridiculous values: clamp to [10s, 1hr].\n if (!Number.isFinite(n) || n <= 0) return 600_000;\n return Math.max(10_000, Math.min(3_600_000, Math.round(n)));\n })();\n if (requestedSuite) {\n res.setHeader('X-Eval-Suite', requestedSuite);\n }\n const tStart = Date.now();\n logger.info(COMPONENT, `/api/eval/run START suite=${requestedSuite || '(none)'} timeoutMs=${timeoutMs}`);\n\n try {\n const {\n runEvalSuite,\n WIDGET_CREATION_SUITE,\n SAFETY_SUITE,\n TOOL_ROUTING_SUITE,\n GATE_FORMAT_SUITE,\n PIPELINE_SUITE,\n ADVERSARIAL_SUITE,\n TOOL_ROUTING_V2_SUITE,\n SESSION_SUITE,\n WIDGET_V2_SUITE,\n GATE_FORMAT_V2_SUITE,\n CONTENT_SUITE,\n } = await import('../../eval/harness.js');\n\n // Local agent call — replicates the system-widget shortcut inline\n // so eval tests exercise the same fast-path users get via HTTP.\n const systemWidgetShortcuts: Array<{ pattern: RegExp; source: string; name: string; w: number; h: number }> = [\n { pattern: /\\b(?:backups?|snapshots?|archives?)\\b/i, source: 'system:backup', name: 'Backup Manager', w: 6, h: 6 },\n { pattern: /\\b(?:training|train|specialists?|models?)\\b/i, source: 'system:training', name: 'Training Dashboard', w: 6, h: 6 },\n { pattern: /\\b(?:recipes?|playbooks?|workflows?|jarvis)\\b/i, source: 'system:recipes', name: 'Recipe Kitchen', w: 6, h: 6 },\n { pattern: /\\b(?:vram|gpu|memory|nvidia)\\b/i, source: 'system:vram', name: 'VRAM Monitor', w: 6, h: 6 },\n { pattern: /\\b(?:teams?|members?|roles?|permissions?|rbac)\\b/i, source: 'system:teams', name: 'Team Hub', w: 6, h: 6 },\n { pattern: /\\b(?:cron|schedules?|jobs?|timers?)\\b/i, source: 'system:cron', name: 'Cron Scheduler', w: 6, h: 6 },\n { pattern: /\\b(?:checkpoints?|restores?|save state)\\b/i, source: 'system:checkpoints', name: 'Checkpoints', w: 6, h: 5 },\n { pattern: /\\b(?:organism|drives?|safety|alerts?|guardrails?)\\b/i, source: 'system:organism', name: 'Organism Monitor', w: 6, h: 6 },\n { pattern: /\\b(?:fleet|nodes?|routes?|mesh)\\b/i, source: 'system:fleet', name: 'Fleet Router', w: 6, h: 5 },\n { pattern: /\\b(?:captcha|browsers?|form fill|web automation)\\b/i, source: 'system:browser', name: 'Browser Tools', w: 6, h: 5 },\n { pattern: /\\b(?:paperclip|sidecars?|helpers?)\\b/i, source: 'system:paperclip', name: 'Paperclip', w: 6, h: 5 },\n { pattern: /\\b(?:tests?|flaky|failing|coverage|eval)\\b/i, source: 'system:eval', name: 'Test Lab', w: 6, h: 6 },\n ];\n const agentCall = async (input: string, testName?: string) => {\n const shortcut = systemWidgetShortcuts.find(s => s.pattern.test(input));\n if (shortcut) {\n return {\n content: `Added the **${shortcut.name}** widget to your canvas.\\n\\n_____widget\\n{ \"name\": \"${shortcut.name}\", \"format\": \"system\", \"source\": \"${shortcut.source}\", \"w\": ${shortcut.w}, \"h\": ${shortcut.h} }`,\n toolsUsed: [],\n };\n }\n // Use a unique userId per test case so each test gets a fresh session\n // with its own token budget. Prevents budget bleed across tests.\n const userId = testName ? `eval-${testName.replace(/\\s+/g, '-').toLowerCase()}` : 'eval-harness';\n const result = await processMessage(input, 'eval', userId, {});\n return {\n content: result.content || '',\n toolsUsed: (result.toolsUsed as string[]) ?? [],\n };\n };\n\n let cases;\n const suite = requestedSuite;\n switch (suite) {\n case 'widget-creation': cases = WIDGET_CREATION_SUITE; break;\n case 'safety': cases = SAFETY_SUITE; break;\n case 'tool-routing': cases = TOOL_ROUTING_SUITE; break;\n case 'gate-format': cases = GATE_FORMAT_SUITE; break;\n case 'pipeline': cases = PIPELINE_SUITE; break;\n case 'adversarial': cases = ADVERSARIAL_SUITE; break;\n case 'tool-routing-v2': cases = TOOL_ROUTING_V2_SUITE; break;\n case 'session': cases = SESSION_SUITE; break;\n case 'widget-v2': cases = WIDGET_V2_SUITE; break;\n case 'gate-format-v2': cases = GATE_FORMAT_V2_SUITE; break;\n case 'content': cases = CONTENT_SUITE; break;\n default:\n // 404 (was 400 in v5.3.0) — \"this suite resource doesn't exist\"\n // is semantically more accurate than \"your request was malformed\",\n // and lets CI scripts branch on resource-not-found.\n res.status(404).json({\n error: `Unknown suite: ${suite || '(empty)'}. Choose: widget-creation, safety, tool-routing, gate-format, pipeline, adversarial, tool-routing-v2, session, widget-v2, gate-format-v2, content.`,\n });\n return;\n }\n\n // Promise.race: whichever finishes first wins. The timeout branch\n // resolves with a sentinel object so we don't have to reach into\n // the AbortController plumbing of every downstream tool.\n const TIMEOUT = Symbol('eval-timeout');\n const result = await Promise.race([\n runEvalSuite(suite, cases, agentCall),\n new Promise<typeof TIMEOUT>(resolve => {\n setTimeout(() => resolve(TIMEOUT), timeoutMs);\n }),\n ]);\n\n if (result === TIMEOUT) {\n const elapsed = Date.now() - tStart;\n logger.warn(COMPONENT, `/api/eval/run TIMEOUT suite=${suite} elapsedMs=${elapsed} timeoutMs=${timeoutMs}`);\n try { recordEvalTimeout(suite); } catch { /* metrics best-effort */ }\n res.status(504).json({\n suite,\n passed: 0,\n total: 0,\n results: [],\n timedOut: true,\n timeoutMs,\n elapsedMs: elapsed,\n error: `Eval suite '${suite}' timed out after ${timeoutMs}ms`,\n });\n return;\n }\n\n // Publish to Prometheus so suite regressions surface in /metrics over time.\n try { recordEvalSuiteResult(suite, result.passed, result.total); } catch { /* metrics best-effort */ }\n const elapsed = Date.now() - tStart;\n logger.info(COMPONENT, `/api/eval/run DONE suite=${suite} passed=${result.passed}/${result.total} elapsedMs=${elapsed}`);\n res.json(result);\n } catch (e) {\n const err = e as Error;\n const elapsed = Date.now() - tStart;\n logger.warn(COMPONENT, `/api/eval/run ERROR suite=${requestedSuite || '(none)'} elapsedMs=${elapsed} message=${err.message}`);\n try { recordEvalError(requestedSuite || 'unknown', err.name || 'unknown'); } catch { /* metrics best-effort */ }\n // Return the actual message — eval is an internal/admin endpoint, not\n // user-facing chat. Generic \"something went wrong\" hid real bugs from\n // the CI gate.\n res.status(500).json({\n suite: requestedSuite || undefined,\n error: err.message || 'Eval run failed',\n errorClass: err.name || 'Error',\n });\n }\n });\n\n router.get('/eval/suites', async (_req, res) => {\n res.json({ suites: [\n 'widget-creation', 'safety', 'tool-routing', 'gate-format',\n 'pipeline', 'adversarial', 'tool-routing-v2', 'session',\n 'widget-v2', 'gate-format-v2', 'content',\n ] });\n });\n\n return router;\n}\n"],"mappings":"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","names":["result","elapsed"]}
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+ import { Router } from "express";
3
+ function createTracesRouter() {
4
+ const router = Router();
5
+ router.get("/", async (_req, res) => {
6
+ try {
7
+ const { listTraces, getTraceStats } = await import("../../agent/tracer.js");
8
+ const limit = parseInt(_req.query.limit || "50", 10);
9
+ const session = _req.query.session;
10
+ res.json({ traces: listTraces(limit, session), stats: getTraceStats() });
11
+ } catch {
12
+ res.json({ traces: [], stats: {} });
13
+ }
14
+ });
15
+ router.get("/:traceId", async (req, res) => {
16
+ try {
17
+ const { getTrace } = await import("../../agent/tracer.js");
18
+ const trace = getTrace(req.params.traceId);
19
+ if (!trace) {
20
+ res.status(404).json({ error: "Trace not found" });
21
+ return;
22
+ }
23
+ res.json(trace);
24
+ } catch {
25
+ res.status(500).json({ error: "Tracer unavailable" });
26
+ }
27
+ });
28
+ return router;
29
+ }
30
+ export {
31
+ createTracesRouter
32
+ };
33
+ //# sourceMappingURL=traces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/gateway/routes/traces.ts"],"sourcesContent":["import { Router } from 'express';\n\nexport function createTracesRouter(): Router {\n const router = Router();\n\n router.get('/', async (_req, res) => {\n try {\n const { listTraces, getTraceStats } = await import('../../agent/tracer.js');\n const limit = parseInt(_req.query.limit as string || '50', 10);\n const session = _req.query.session as string | undefined;\n res.json({ traces: listTraces(limit, session), stats: getTraceStats() });\n } catch { res.json({ traces: [], stats: {} }); }\n });\n\n router.get('/:traceId', async (req, res) => {\n try {\n const { getTrace } = await import('../../agent/tracer.js');\n const trace = getTrace(req.params.traceId);\n if (!trace) { res.status(404).json({ error: 'Trace not found' }); return; }\n res.json(trace);\n } catch { res.status(500).json({ error: 'Tracer unavailable' }); }\n });\n\n return router;\n}\n"],"mappings":";AAAA,SAAS,cAAc;AAEhB,SAAS,qBAA6B;AAC3C,QAAM,SAAS,OAAO;AAEtB,SAAO,IAAI,KAAK,OAAO,MAAM,QAAQ;AACnC,QAAI;AACF,YAAM,EAAE,YAAY,cAAc,IAAI,MAAM,OAAO,uBAAuB;AAC1E,YAAM,QAAQ,SAAS,KAAK,MAAM,SAAmB,MAAM,EAAE;AAC7D,YAAM,UAAU,KAAK,MAAM;AAC3B,UAAI,KAAK,EAAE,QAAQ,WAAW,OAAO,OAAO,GAAG,OAAO,cAAc,EAAE,CAAC;AAAA,IACzE,QAAQ;AAAE,UAAI,KAAK,EAAE,QAAQ,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC;AAAA,IAAG;AAAA,EACjD,CAAC;AAED,SAAO,IAAI,aAAa,OAAO,KAAK,QAAQ;AAC1C,QAAI;AACF,YAAM,EAAE,SAAS,IAAI,MAAM,OAAO,uBAAuB;AACzD,YAAM,QAAQ,SAAS,IAAI,OAAO,OAAO;AACzC,UAAI,CAAC,OAAO;AAAE,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,kBAAkB,CAAC;AAAG;AAAA,MAAQ;AAC1E,UAAI,KAAK,KAAK;AAAA,IAChB,QAAQ;AAAE,UAAI,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,qBAAqB,CAAC;AAAA,IAAG;AAAA,EACnE,CAAC;AAED,SAAO;AACT;","names":[]}