@opensearch-project/agent-health 0.3.0 → 0.5.2

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 (518) hide show
  1. package/README.md +77 -6
  2. package/cli/dist/index.js +10072 -4502
  3. package/deployment/cloudformation/agent-health-observability.yaml +762 -0
  4. package/dist/assets/index-CCQRDlO0.js +243 -0
  5. package/dist/assets/index-CNHQVbcj.css +1 -0
  6. package/dist/index.html +2 -2
  7. package/docs/ARCHITECTURE.md +450 -0
  8. package/docs/BACKEND_JOB_QUEUE.md +405 -0
  9. package/docs/CLAUDE_CODE_TELEMETRY.md +283 -0
  10. package/docs/CLI.md +431 -0
  11. package/docs/CODING_AGENT_ANALYTICS.md +298 -0
  12. package/docs/CONFIGURATION.md +388 -0
  13. package/docs/CONNECTORS.md +536 -0
  14. package/docs/INSTRUMENT_WITH_OTEL.md +390 -0
  15. package/docs/ML-COMMONS-SETUP.md +289 -0
  16. package/docs/NPX_PACKAGING.md +195 -0
  17. package/docs/PERFORMANCE-MONITORING.md +200 -0
  18. package/docs/PERFORMANCE.md +390 -0
  19. package/docs/PI_PROFILING.md +169 -0
  20. package/docs/PLAN-non-agui-agent-support.md +525 -0
  21. package/docs/SDK.md +577 -0
  22. package/docs/SKILLS.md +264 -0
  23. package/docs/blogs/2026-02-28-opensearch-agent-health.md +200 -0
  24. package/docs/blogs/getting-started-blog.md +608 -0
  25. package/docs/diagrams/Agent-health.excalidraw +5656 -0
  26. package/docs/diagrams/architecture.png +0 -0
  27. package/docs/plans/field-redesign.md +468 -0
  28. package/docs/rfcs/001-coding-agent-analytics.md +374 -0
  29. package/docs/rfcs/002-enterprise-leaderboard.md +267 -0
  30. package/docs/rfcs/003-remote-aggregation.md +146 -0
  31. package/docs/rfcs/004-test-sdk-v2.md +599 -0
  32. package/docs/skills/AGENT_HEALTH.md +598 -0
  33. package/docs/skills/AGENT_PROFILE.md +191 -0
  34. package/docs/skills/add-connector/SKILL.md +68 -0
  35. package/docs/skills/agent-health-profile/SKILL.md +40 -0
  36. package/docs/skills/config-auth/SKILL.md +194 -0
  37. package/docs/skills/config-auth/evals/evals.json +35 -0
  38. package/docs/skills/create-pr/SKILL.md +73 -0
  39. package/docs/skills/instrument-otel/SKILL.md +84 -0
  40. package/docs/skills/write-test/SKILL.md +124 -0
  41. package/docs/ui prd.md +376 -0
  42. package/examples/README.md +53 -0
  43. package/examples/config/agent-health.config.example.ts +155 -0
  44. package/examples/connectors/echo-connector.ts +131 -0
  45. package/examples/eval-files/demo.eval.js +128 -0
  46. package/examples/eval-files/sdk-hooks-demo.eval.js +99 -0
  47. package/examples/pi-profiling/README.md +77 -0
  48. package/examples/pi-profiling/agent-health-profile.ts +417 -0
  49. package/lib/dist/lib/agentUtils.d.ts +29 -0
  50. package/lib/dist/lib/agentUtils.d.ts.map +1 -0
  51. package/lib/dist/lib/agentUtils.js +43 -0
  52. package/lib/dist/lib/agentUtils.js.map +1 -0
  53. package/lib/dist/lib/benchmarkExport.d.ts +14 -0
  54. package/lib/dist/lib/benchmarkExport.d.ts.map +1 -0
  55. package/lib/dist/lib/benchmarkExport.js +41 -0
  56. package/lib/dist/lib/benchmarkExport.js.map +1 -0
  57. package/lib/dist/lib/benchmarkVersionUtils.d.ts +37 -0
  58. package/lib/dist/lib/benchmarkVersionUtils.d.ts.map +1 -0
  59. package/lib/dist/lib/benchmarkVersionUtils.js +68 -0
  60. package/lib/dist/lib/benchmarkVersionUtils.js.map +1 -0
  61. package/lib/dist/lib/config/defineConfig.d.ts +27 -0
  62. package/lib/dist/lib/config/defineConfig.d.ts.map +1 -0
  63. package/lib/dist/lib/config/defineConfig.js +28 -0
  64. package/lib/dist/lib/config/defineConfig.js.map +1 -0
  65. package/lib/dist/lib/config/index.d.ts +9 -0
  66. package/lib/dist/lib/config/index.d.ts.map +1 -0
  67. package/lib/dist/lib/config/index.js +8 -0
  68. package/lib/dist/lib/config/index.js.map +1 -0
  69. package/lib/dist/lib/config/loader.d.ts +39 -0
  70. package/lib/dist/lib/config/loader.d.ts.map +1 -0
  71. package/lib/dist/lib/config/loader.js +258 -0
  72. package/lib/dist/lib/config/loader.js.map +1 -0
  73. package/lib/dist/lib/config/statePaths.d.ts +61 -0
  74. package/lib/dist/lib/config/statePaths.d.ts.map +1 -0
  75. package/lib/dist/lib/config/statePaths.js +188 -0
  76. package/lib/dist/lib/config/statePaths.js.map +1 -0
  77. package/lib/dist/lib/config/types.d.ts +231 -0
  78. package/lib/dist/lib/config/types.d.ts.map +1 -0
  79. package/lib/dist/lib/config/types.js +6 -0
  80. package/lib/dist/lib/config/types.js.map +1 -0
  81. package/lib/dist/lib/config.d.ts +39 -0
  82. package/lib/dist/lib/config.d.ts.map +1 -0
  83. package/lib/dist/lib/config.js +118 -0
  84. package/lib/dist/lib/config.js.map +1 -0
  85. package/lib/dist/lib/constants.d.ts +70 -0
  86. package/lib/dist/lib/constants.d.ts.map +1 -0
  87. package/lib/dist/lib/constants.js +365 -0
  88. package/lib/dist/lib/constants.js.map +1 -0
  89. package/lib/dist/lib/contextUtilization.d.ts +23 -0
  90. package/lib/dist/lib/contextUtilization.d.ts.map +1 -0
  91. package/lib/dist/lib/contextUtilization.js +72 -0
  92. package/lib/dist/lib/contextUtilization.js.map +1 -0
  93. package/lib/dist/lib/dashboardMetrics.d.ts +87 -0
  94. package/lib/dist/lib/dashboardMetrics.d.ts.map +1 -0
  95. package/lib/dist/lib/dashboardMetrics.js +242 -0
  96. package/lib/dist/lib/dashboardMetrics.js.map +1 -0
  97. package/lib/dist/lib/dataSourceConfig.d.ts +108 -0
  98. package/lib/dist/lib/dataSourceConfig.d.ts.map +1 -0
  99. package/lib/dist/lib/dataSourceConfig.js +166 -0
  100. package/lib/dist/lib/dataSourceConfig.js.map +1 -0
  101. package/lib/dist/lib/debug.d.ts +26 -0
  102. package/lib/dist/lib/debug.d.ts.map +1 -0
  103. package/lib/dist/lib/debug.js +132 -0
  104. package/lib/dist/lib/debug.js.map +1 -0
  105. package/lib/dist/lib/diagnostics.d.ts +28 -0
  106. package/lib/dist/lib/diagnostics.d.ts.map +1 -0
  107. package/lib/dist/lib/diagnostics.js +65 -0
  108. package/lib/dist/lib/diagnostics.js.map +1 -0
  109. package/lib/dist/lib/envCompat.d.ts +27 -0
  110. package/lib/dist/lib/envCompat.d.ts.map +1 -0
  111. package/lib/dist/lib/envCompat.js +73 -0
  112. package/lib/dist/lib/envCompat.js.map +1 -0
  113. package/lib/dist/lib/findPackageRoot.d.ts +7 -0
  114. package/lib/dist/lib/findPackageRoot.d.ts.map +1 -0
  115. package/lib/dist/lib/findPackageRoot.js +57 -0
  116. package/lib/dist/lib/findPackageRoot.js.map +1 -0
  117. package/lib/dist/lib/hooks.d.ts +36 -0
  118. package/lib/dist/lib/hooks.d.ts.map +1 -0
  119. package/lib/dist/lib/hooks.js +112 -0
  120. package/lib/dist/lib/hooks.js.map +1 -0
  121. package/lib/dist/lib/index.d.ts +47 -0
  122. package/lib/dist/lib/index.d.ts.map +1 -0
  123. package/lib/dist/lib/index.js +62 -0
  124. package/lib/dist/lib/index.js.map +1 -0
  125. package/lib/dist/lib/labels.d.ts +90 -0
  126. package/lib/dist/lib/labels.d.ts.map +1 -0
  127. package/lib/dist/lib/labels.js +158 -0
  128. package/lib/dist/lib/labels.js.map +1 -0
  129. package/lib/dist/lib/markdown.d.ts +16 -0
  130. package/lib/dist/lib/markdown.d.ts.map +1 -0
  131. package/lib/dist/lib/markdown.js +42 -0
  132. package/lib/dist/lib/markdown.js.map +1 -0
  133. package/lib/dist/lib/matchers/expect.d.ts +3 -0
  134. package/lib/dist/lib/matchers/expect.d.ts.map +1 -0
  135. package/lib/dist/lib/matchers/expect.js +225 -0
  136. package/lib/dist/lib/matchers/expect.js.map +1 -0
  137. package/lib/dist/lib/matchers/index.d.ts +8 -0
  138. package/lib/dist/lib/matchers/index.d.ts.map +1 -0
  139. package/lib/dist/lib/matchers/index.js +9 -0
  140. package/lib/dist/lib/matchers/index.js.map +1 -0
  141. package/lib/dist/lib/matchers/judgeAccessor.d.ts +113 -0
  142. package/lib/dist/lib/matchers/judgeAccessor.d.ts.map +1 -0
  143. package/lib/dist/lib/matchers/judgeAccessor.js +183 -0
  144. package/lib/dist/lib/matchers/judgeAccessor.js.map +1 -0
  145. package/lib/dist/lib/matchers/session.d.ts +39 -0
  146. package/lib/dist/lib/matchers/session.d.ts.map +1 -0
  147. package/lib/dist/lib/matchers/session.js +116 -0
  148. package/lib/dist/lib/matchers/session.js.map +1 -0
  149. package/lib/dist/lib/matchers/traces.d.ts +55 -0
  150. package/lib/dist/lib/matchers/traces.d.ts.map +1 -0
  151. package/lib/dist/lib/matchers/traces.js +116 -0
  152. package/lib/dist/lib/matchers/traces.js.map +1 -0
  153. package/lib/dist/lib/matchers/types.d.ts +75 -0
  154. package/lib/dist/lib/matchers/types.d.ts.map +1 -0
  155. package/lib/dist/lib/matchers/types.js +6 -0
  156. package/lib/dist/lib/matchers/types.js.map +1 -0
  157. package/lib/dist/lib/packagePaths.d.ts +29 -0
  158. package/lib/dist/lib/packagePaths.d.ts.map +1 -0
  159. package/lib/dist/lib/packagePaths.js +63 -0
  160. package/lib/dist/lib/packagePaths.js.map +1 -0
  161. package/lib/dist/lib/performance.d.ts +51 -0
  162. package/lib/dist/lib/performance.d.ts.map +1 -0
  163. package/lib/dist/lib/performance.js +159 -0
  164. package/lib/dist/lib/performance.js.map +1 -0
  165. package/lib/dist/lib/portConfig.d.ts +29 -0
  166. package/lib/dist/lib/portConfig.d.ts.map +1 -0
  167. package/lib/dist/lib/portConfig.js +64 -0
  168. package/lib/dist/lib/portConfig.js.map +1 -0
  169. package/lib/dist/lib/preferences.d.ts +63 -0
  170. package/lib/dist/lib/preferences.d.ts.map +1 -0
  171. package/lib/dist/lib/preferences.js +117 -0
  172. package/lib/dist/lib/preferences.js.map +1 -0
  173. package/lib/dist/lib/resolveAgentModel.d.ts +22 -0
  174. package/lib/dist/lib/resolveAgentModel.d.ts.map +1 -0
  175. package/lib/dist/lib/resolveAgentModel.js +37 -0
  176. package/lib/dist/lib/resolveAgentModel.js.map +1 -0
  177. package/lib/dist/lib/runStats.d.ts +92 -0
  178. package/lib/dist/lib/runStats.d.ts.map +1 -0
  179. package/lib/dist/lib/runStats.js +160 -0
  180. package/lib/dist/lib/runStats.js.map +1 -0
  181. package/lib/dist/lib/telemetry/constants.d.ts +60 -0
  182. package/lib/dist/lib/telemetry/constants.d.ts.map +1 -0
  183. package/lib/dist/lib/telemetry/constants.js +87 -0
  184. package/lib/dist/lib/telemetry/constants.js.map +1 -0
  185. package/lib/dist/lib/telemetry/evalSpans.d.ts +61 -0
  186. package/lib/dist/lib/telemetry/evalSpans.d.ts.map +1 -0
  187. package/lib/dist/lib/telemetry/evalSpans.js +254 -0
  188. package/lib/dist/lib/telemetry/evalSpans.js.map +1 -0
  189. package/lib/dist/lib/telemetry/index.d.ts +11 -0
  190. package/lib/dist/lib/telemetry/index.d.ts.map +1 -0
  191. package/lib/dist/lib/telemetry/index.js +15 -0
  192. package/lib/dist/lib/telemetry/index.js.map +1 -0
  193. package/lib/dist/lib/telemetry/opensearchExporter.d.ts +43 -0
  194. package/lib/dist/lib/telemetry/opensearchExporter.d.ts.map +1 -0
  195. package/lib/dist/lib/telemetry/opensearchExporter.js +217 -0
  196. package/lib/dist/lib/telemetry/opensearchExporter.js.map +1 -0
  197. package/lib/dist/lib/telemetry/provider.d.ts +55 -0
  198. package/lib/dist/lib/telemetry/provider.d.ts.map +1 -0
  199. package/lib/dist/lib/telemetry/provider.js +140 -0
  200. package/lib/dist/lib/telemetry/provider.js.map +1 -0
  201. package/lib/dist/lib/testCaseLabels.d.ts +34 -0
  202. package/lib/dist/lib/testCaseLabels.d.ts.map +1 -0
  203. package/lib/dist/lib/testCaseLabels.js +88 -0
  204. package/lib/dist/lib/testCaseLabels.js.map +1 -0
  205. package/lib/dist/lib/testCaseValidation.d.ts +140 -0
  206. package/lib/dist/lib/testCaseValidation.d.ts.map +1 -0
  207. package/lib/dist/lib/testCaseValidation.js +162 -0
  208. package/lib/dist/lib/testCaseValidation.js.map +1 -0
  209. package/lib/dist/lib/testCases/agentFixture.d.ts +80 -0
  210. package/lib/dist/lib/testCases/agentFixture.d.ts.map +1 -0
  211. package/lib/dist/lib/testCases/agentFixture.js +43 -0
  212. package/lib/dist/lib/testCases/agentFixture.js.map +1 -0
  213. package/lib/dist/lib/testCases/authoringSurface.d.ts +10 -0
  214. package/lib/dist/lib/testCases/authoringSurface.d.ts.map +1 -0
  215. package/lib/dist/lib/testCases/authoringSurface.js +54 -0
  216. package/lib/dist/lib/testCases/authoringSurface.js.map +1 -0
  217. package/lib/dist/lib/testCases/codemod.d.ts +13 -0
  218. package/lib/dist/lib/testCases/codemod.d.ts.map +1 -0
  219. package/lib/dist/lib/testCases/codemod.js +169 -0
  220. package/lib/dist/lib/testCases/codemod.js.map +1 -0
  221. package/lib/dist/lib/testCases/define.d.ts +114 -0
  222. package/lib/dist/lib/testCases/define.d.ts.map +1 -0
  223. package/lib/dist/lib/testCases/define.js +253 -0
  224. package/lib/dist/lib/testCases/define.js.map +1 -0
  225. package/lib/dist/lib/testCases/evaluators.d.ts +80 -0
  226. package/lib/dist/lib/testCases/evaluators.d.ts.map +1 -0
  227. package/lib/dist/lib/testCases/evaluators.js +105 -0
  228. package/lib/dist/lib/testCases/evaluators.js.map +1 -0
  229. package/lib/dist/lib/testCases/index.d.ts +14 -0
  230. package/lib/dist/lib/testCases/index.d.ts.map +1 -0
  231. package/lib/dist/lib/testCases/index.js +12 -0
  232. package/lib/dist/lib/testCases/index.js.map +1 -0
  233. package/lib/dist/lib/testCases/judge.d.ts +165 -0
  234. package/lib/dist/lib/testCases/judge.d.ts.map +1 -0
  235. package/lib/dist/lib/testCases/judge.js +359 -0
  236. package/lib/dist/lib/testCases/judge.js.map +1 -0
  237. package/lib/dist/lib/testCases/loader.d.ts +26 -0
  238. package/lib/dist/lib/testCases/loader.d.ts.map +1 -0
  239. package/lib/dist/lib/testCases/loader.js +149 -0
  240. package/lib/dist/lib/testCases/loader.js.map +1 -0
  241. package/lib/dist/lib/testCases/types.d.ts +242 -0
  242. package/lib/dist/lib/testCases/types.d.ts.map +1 -0
  243. package/lib/dist/lib/testCases/types.js +6 -0
  244. package/lib/dist/lib/testCases/types.js.map +1 -0
  245. package/lib/dist/lib/theme.d.ts +6 -0
  246. package/lib/dist/lib/theme.d.ts.map +1 -0
  247. package/lib/dist/lib/theme.js +36 -0
  248. package/lib/dist/lib/theme.js.map +1 -0
  249. package/lib/dist/lib/uiTelemetry.d.ts +7 -0
  250. package/lib/dist/lib/uiTelemetry.d.ts.map +1 -0
  251. package/lib/dist/lib/uiTelemetry.js +25 -0
  252. package/lib/dist/lib/uiTelemetry.js.map +1 -0
  253. package/lib/dist/lib/utils.d.ts +96 -0
  254. package/lib/dist/lib/utils.d.ts.map +1 -0
  255. package/lib/dist/lib/utils.js +232 -0
  256. package/lib/dist/lib/utils.js.map +1 -0
  257. package/lib/dist/lib/workflow/consolidate.d.ts +12 -0
  258. package/lib/dist/lib/workflow/consolidate.d.ts.map +1 -0
  259. package/lib/dist/lib/workflow/consolidate.js +33 -0
  260. package/lib/dist/lib/workflow/consolidate.js.map +1 -0
  261. package/lib/dist/lib/workflow/index.d.ts +13 -0
  262. package/lib/dist/lib/workflow/index.d.ts.map +1 -0
  263. package/lib/dist/lib/workflow/index.js +12 -0
  264. package/lib/dist/lib/workflow/index.js.map +1 -0
  265. package/lib/dist/lib/workflow/ledger.d.ts +30 -0
  266. package/lib/dist/lib/workflow/ledger.d.ts.map +1 -0
  267. package/lib/dist/lib/workflow/ledger.js +41 -0
  268. package/lib/dist/lib/workflow/ledger.js.map +1 -0
  269. package/lib/dist/lib/workflow/pool.d.ts +13 -0
  270. package/lib/dist/lib/workflow/pool.d.ts.map +1 -0
  271. package/lib/dist/lib/workflow/pool.js +44 -0
  272. package/lib/dist/lib/workflow/pool.js.map +1 -0
  273. package/lib/dist/lib/workflow/source.d.ts +22 -0
  274. package/lib/dist/lib/workflow/source.d.ts.map +1 -0
  275. package/lib/dist/lib/workflow/source.js +29 -0
  276. package/lib/dist/lib/workflow/source.js.map +1 -0
  277. package/lib/dist/lib/workflow/stepB.d.ts +71 -0
  278. package/lib/dist/lib/workflow/stepB.d.ts.map +1 -0
  279. package/lib/dist/lib/workflow/stepB.js +99 -0
  280. package/lib/dist/lib/workflow/stepB.js.map +1 -0
  281. package/lib/dist/lib/workflow/types.d.ts +86 -0
  282. package/lib/dist/lib/workflow/types.d.ts.map +1 -0
  283. package/lib/dist/lib/workflow/types.js +6 -0
  284. package/lib/dist/lib/workflow/types.js.map +1 -0
  285. package/lib/dist/lib/workflow/workflow.d.ts +119 -0
  286. package/lib/dist/lib/workflow/workflow.d.ts.map +1 -0
  287. package/lib/dist/lib/workflow/workflow.js +195 -0
  288. package/lib/dist/lib/workflow/workflow.js.map +1 -0
  289. package/lib/dist/services/agent/aguiConverter.d.ts +50 -0
  290. package/lib/dist/services/agent/aguiConverter.d.ts.map +1 -0
  291. package/lib/dist/services/agent/aguiConverter.js +449 -0
  292. package/lib/dist/services/agent/aguiConverter.js.map +1 -0
  293. package/lib/dist/services/agent/index.d.ts +10 -0
  294. package/lib/dist/services/agent/index.d.ts.map +1 -0
  295. package/lib/dist/services/agent/index.js +12 -0
  296. package/lib/dist/services/agent/index.js.map +1 -0
  297. package/lib/dist/services/agent/payloadBuilder.d.ts +33 -0
  298. package/lib/dist/services/agent/payloadBuilder.d.ts.map +1 -0
  299. package/lib/dist/services/agent/payloadBuilder.js +75 -0
  300. package/lib/dist/services/agent/payloadBuilder.js.map +1 -0
  301. package/lib/dist/services/agent/sseStream.d.ts +43 -0
  302. package/lib/dist/services/agent/sseStream.d.ts.map +1 -0
  303. package/lib/dist/services/agent/sseStream.js +223 -0
  304. package/lib/dist/services/agent/sseStream.js.map +1 -0
  305. package/lib/dist/services/connectors/agui/AGUIStreamingConnector.d.ts +44 -0
  306. package/lib/dist/services/connectors/agui/AGUIStreamingConnector.d.ts.map +1 -0
  307. package/lib/dist/services/connectors/agui/AGUIStreamingConnector.js +95 -0
  308. package/lib/dist/services/connectors/agui/AGUIStreamingConnector.js.map +1 -0
  309. package/lib/dist/services/connectors/base/BaseConnector.d.ts +81 -0
  310. package/lib/dist/services/connectors/base/BaseConnector.d.ts.map +1 -0
  311. package/lib/dist/services/connectors/base/BaseConnector.js +170 -0
  312. package/lib/dist/services/connectors/base/BaseConnector.js.map +1 -0
  313. package/lib/dist/services/connectors/claude-code/ClaudeCodeConnector.d.ts +116 -0
  314. package/lib/dist/services/connectors/claude-code/ClaudeCodeConnector.d.ts.map +1 -0
  315. package/lib/dist/services/connectors/claude-code/ClaudeCodeConnector.js +403 -0
  316. package/lib/dist/services/connectors/claude-code/ClaudeCodeConnector.js.map +1 -0
  317. package/lib/dist/services/connectors/index.d.ts +13 -0
  318. package/lib/dist/services/connectors/index.d.ts.map +1 -0
  319. package/lib/dist/services/connectors/index.js +32 -0
  320. package/lib/dist/services/connectors/index.js.map +1 -0
  321. package/lib/dist/services/connectors/kiro/KiroConnector.d.ts +48 -0
  322. package/lib/dist/services/connectors/kiro/KiroConnector.d.ts.map +1 -0
  323. package/lib/dist/services/connectors/kiro/KiroConnector.js +158 -0
  324. package/lib/dist/services/connectors/kiro/KiroConnector.js.map +1 -0
  325. package/lib/dist/services/connectors/langgraph/LangGraphConnector.d.ts +36 -0
  326. package/lib/dist/services/connectors/langgraph/LangGraphConnector.d.ts.map +1 -0
  327. package/lib/dist/services/connectors/langgraph/LangGraphConnector.js +175 -0
  328. package/lib/dist/services/connectors/langgraph/LangGraphConnector.js.map +1 -0
  329. package/lib/dist/services/connectors/mock/MockConnector.d.ts +37 -0
  330. package/lib/dist/services/connectors/mock/MockConnector.d.ts.map +1 -0
  331. package/lib/dist/services/connectors/mock/MockConnector.js +120 -0
  332. package/lib/dist/services/connectors/mock/MockConnector.js.map +1 -0
  333. package/lib/dist/services/connectors/openai-compatible/OpenAICompatibleConnector.d.ts +42 -0
  334. package/lib/dist/services/connectors/openai-compatible/OpenAICompatibleConnector.d.ts.map +1 -0
  335. package/lib/dist/services/connectors/openai-compatible/OpenAICompatibleConnector.js +133 -0
  336. package/lib/dist/services/connectors/openai-compatible/OpenAICompatibleConnector.js.map +1 -0
  337. package/lib/dist/services/connectors/pi/PiConnector.d.ts +87 -0
  338. package/lib/dist/services/connectors/pi/PiConnector.d.ts.map +1 -0
  339. package/lib/dist/services/connectors/pi/PiConnector.js +274 -0
  340. package/lib/dist/services/connectors/pi/PiConnector.js.map +1 -0
  341. package/lib/dist/services/connectors/registry.d.ts +57 -0
  342. package/lib/dist/services/connectors/registry.d.ts.map +1 -0
  343. package/lib/dist/services/connectors/registry.js +106 -0
  344. package/lib/dist/services/connectors/registry.js.map +1 -0
  345. package/lib/dist/services/connectors/rest/RESTConnector.d.ts +38 -0
  346. package/lib/dist/services/connectors/rest/RESTConnector.d.ts.map +1 -0
  347. package/lib/dist/services/connectors/rest/RESTConnector.js +117 -0
  348. package/lib/dist/services/connectors/rest/RESTConnector.js.map +1 -0
  349. package/lib/dist/services/connectors/server.d.ts +13 -0
  350. package/lib/dist/services/connectors/server.d.ts.map +1 -0
  351. package/lib/dist/services/connectors/server.js +34 -0
  352. package/lib/dist/services/connectors/server.js.map +1 -0
  353. package/lib/dist/services/connectors/strands/StrandsConnector.d.ts +48 -0
  354. package/lib/dist/services/connectors/strands/StrandsConnector.d.ts.map +1 -0
  355. package/lib/dist/services/connectors/strands/StrandsConnector.js +221 -0
  356. package/lib/dist/services/connectors/strands/StrandsConnector.js.map +1 -0
  357. package/lib/dist/services/connectors/subprocess/SubprocessConnector.d.ts +88 -0
  358. package/lib/dist/services/connectors/subprocess/SubprocessConnector.d.ts.map +1 -0
  359. package/lib/dist/services/connectors/subprocess/SubprocessConnector.js +418 -0
  360. package/lib/dist/services/connectors/subprocess/SubprocessConnector.js.map +1 -0
  361. package/lib/dist/services/connectors/types.d.ts +213 -0
  362. package/lib/dist/services/connectors/types.d.ts.map +1 -0
  363. package/lib/dist/services/connectors/types.js +6 -0
  364. package/lib/dist/services/connectors/types.js.map +1 -0
  365. package/lib/dist/services/evaluation/bedrockJudge.d.ts +64 -0
  366. package/lib/dist/services/evaluation/bedrockJudge.d.ts.map +1 -0
  367. package/lib/dist/services/evaluation/bedrockJudge.js +167 -0
  368. package/lib/dist/services/evaluation/bedrockJudge.js.map +1 -0
  369. package/lib/dist/services/evaluation/evaluatorError.d.ts +56 -0
  370. package/lib/dist/services/evaluation/evaluatorError.d.ts.map +1 -0
  371. package/lib/dist/services/evaluation/evaluatorError.js +56 -0
  372. package/lib/dist/services/evaluation/evaluatorError.js.map +1 -0
  373. package/lib/dist/services/evaluation/index.d.ts +106 -0
  374. package/lib/dist/services/evaluation/index.d.ts.map +1 -0
  375. package/lib/dist/services/evaluation/index.js +684 -0
  376. package/lib/dist/services/evaluation/index.js.map +1 -0
  377. package/lib/dist/services/evaluation/mockTrajectory.d.ts +3 -0
  378. package/lib/dist/services/evaluation/mockTrajectory.d.ts.map +1 -0
  379. package/lib/dist/services/evaluation/mockTrajectory.js +72 -0
  380. package/lib/dist/services/evaluation/mockTrajectory.js.map +1 -0
  381. package/lib/dist/services/opensearch/client.d.ts +26 -0
  382. package/lib/dist/services/opensearch/client.d.ts.map +1 -0
  383. package/lib/dist/services/opensearch/client.js +131 -0
  384. package/lib/dist/services/opensearch/client.js.map +1 -0
  385. package/lib/dist/services/opensearch/index.d.ts +16 -0
  386. package/lib/dist/services/opensearch/index.d.ts.map +1 -0
  387. package/lib/dist/services/opensearch/index.js +25 -0
  388. package/lib/dist/services/opensearch/index.js.map +1 -0
  389. package/lib/dist/services/storage/asyncBenchmarkStorage.d.ts +123 -0
  390. package/lib/dist/services/storage/asyncBenchmarkStorage.d.ts.map +1 -0
  391. package/lib/dist/services/storage/asyncBenchmarkStorage.js +429 -0
  392. package/lib/dist/services/storage/asyncBenchmarkStorage.js.map +1 -0
  393. package/lib/dist/services/storage/asyncRunStorage.d.ts +127 -0
  394. package/lib/dist/services/storage/asyncRunStorage.d.ts.map +1 -0
  395. package/lib/dist/services/storage/asyncRunStorage.js +448 -0
  396. package/lib/dist/services/storage/asyncRunStorage.js.map +1 -0
  397. package/lib/dist/services/storage/asyncTestCaseStorage.d.ts +156 -0
  398. package/lib/dist/services/storage/asyncTestCaseStorage.d.ts.map +1 -0
  399. package/lib/dist/services/storage/asyncTestCaseStorage.js +285 -0
  400. package/lib/dist/services/storage/asyncTestCaseStorage.js.map +1 -0
  401. package/lib/dist/services/storage/index.d.ts +17 -0
  402. package/lib/dist/services/storage/index.d.ts.map +1 -0
  403. package/lib/dist/services/storage/index.js +20 -0
  404. package/lib/dist/services/storage/index.js.map +1 -0
  405. package/lib/dist/services/storage/migration.d.ts +54 -0
  406. package/lib/dist/services/storage/migration.d.ts.map +1 -0
  407. package/lib/dist/services/storage/migration.js +296 -0
  408. package/lib/dist/services/storage/migration.js.map +1 -0
  409. package/lib/dist/services/storage/opensearchClient.d.ts +924 -0
  410. package/lib/dist/services/storage/opensearchClient.d.ts.map +1 -0
  411. package/lib/dist/services/storage/opensearchClient.js +435 -0
  412. package/lib/dist/services/storage/opensearchClient.js.map +1 -0
  413. package/lib/dist/services/traces/browserRecovery.d.ts +26 -0
  414. package/lib/dist/services/traces/browserRecovery.d.ts.map +1 -0
  415. package/lib/dist/services/traces/browserRecovery.js +81 -0
  416. package/lib/dist/services/traces/browserRecovery.js.map +1 -0
  417. package/lib/dist/services/traces/categoryStyles.d.ts +21 -0
  418. package/lib/dist/services/traces/categoryStyles.d.ts.map +1 -0
  419. package/lib/dist/services/traces/categoryStyles.js +56 -0
  420. package/lib/dist/services/traces/categoryStyles.js.map +1 -0
  421. package/lib/dist/services/traces/executionOrderTransform.d.ts +35 -0
  422. package/lib/dist/services/traces/executionOrderTransform.d.ts.map +1 -0
  423. package/lib/dist/services/traces/executionOrderTransform.js +313 -0
  424. package/lib/dist/services/traces/executionOrderTransform.js.map +1 -0
  425. package/lib/dist/services/traces/fetchSpansForRun.d.ts +86 -0
  426. package/lib/dist/services/traces/fetchSpansForRun.d.ts.map +1 -0
  427. package/lib/dist/services/traces/fetchSpansForRun.js +69 -0
  428. package/lib/dist/services/traces/fetchSpansForRun.js.map +1 -0
  429. package/lib/dist/services/traces/flowTransform.d.ts +24 -0
  430. package/lib/dist/services/traces/flowTransform.d.ts.map +1 -0
  431. package/lib/dist/services/traces/flowTransform.js +228 -0
  432. package/lib/dist/services/traces/flowTransform.js.map +1 -0
  433. package/lib/dist/services/traces/index.d.ts +121 -0
  434. package/lib/dist/services/traces/index.d.ts.map +1 -0
  435. package/lib/dist/services/traces/index.js +255 -0
  436. package/lib/dist/services/traces/index.js.map +1 -0
  437. package/lib/dist/services/traces/intentTransform.d.ts +20 -0
  438. package/lib/dist/services/traces/intentTransform.d.ts.map +1 -0
  439. package/lib/dist/services/traces/intentTransform.js +131 -0
  440. package/lib/dist/services/traces/intentTransform.js.map +1 -0
  441. package/lib/dist/services/traces/judgeAgentsHints.d.ts +63 -0
  442. package/lib/dist/services/traces/judgeAgentsHints.d.ts.map +1 -0
  443. package/lib/dist/services/traces/judgeAgentsHints.js +89 -0
  444. package/lib/dist/services/traces/judgeAgentsHints.js.map +1 -0
  445. package/lib/dist/services/traces/messageExtraction.d.ts +15 -0
  446. package/lib/dist/services/traces/messageExtraction.d.ts.map +1 -0
  447. package/lib/dist/services/traces/messageExtraction.js +251 -0
  448. package/lib/dist/services/traces/messageExtraction.js.map +1 -0
  449. package/lib/dist/services/traces/spanCategorization.d.ts +63 -0
  450. package/lib/dist/services/traces/spanCategorization.d.ts.map +1 -0
  451. package/lib/dist/services/traces/spanCategorization.js +276 -0
  452. package/lib/dist/services/traces/spanCategorization.js.map +1 -0
  453. package/lib/dist/services/traces/spanPreprocessing.d.ts +37 -0
  454. package/lib/dist/services/traces/spanPreprocessing.d.ts.map +1 -0
  455. package/lib/dist/services/traces/spanPreprocessing.js +102 -0
  456. package/lib/dist/services/traces/spanPreprocessing.js.map +1 -0
  457. package/lib/dist/services/traces/spansToTrajectory.d.ts +36 -0
  458. package/lib/dist/services/traces/spansToTrajectory.d.ts.map +1 -0
  459. package/lib/dist/services/traces/spansToTrajectory.js +387 -0
  460. package/lib/dist/services/traces/spansToTrajectory.js.map +1 -0
  461. package/lib/dist/services/traces/toolSimilarity.d.ts +35 -0
  462. package/lib/dist/services/traces/toolSimilarity.d.ts.map +1 -0
  463. package/lib/dist/services/traces/toolSimilarity.js +203 -0
  464. package/lib/dist/services/traces/toolSimilarity.js.map +1 -0
  465. package/lib/dist/services/traces/traceComparison.d.ts +31 -0
  466. package/lib/dist/services/traces/traceComparison.d.ts.map +1 -0
  467. package/lib/dist/services/traces/traceComparison.js +318 -0
  468. package/lib/dist/services/traces/traceComparison.js.map +1 -0
  469. package/lib/dist/services/traces/traceGrouping.d.ts +19 -0
  470. package/lib/dist/services/traces/traceGrouping.d.ts.map +1 -0
  471. package/lib/dist/services/traces/traceGrouping.js +107 -0
  472. package/lib/dist/services/traces/traceGrouping.js.map +1 -0
  473. package/lib/dist/services/traces/tracePoller.d.ts +84 -0
  474. package/lib/dist/services/traces/tracePoller.d.ts.map +1 -0
  475. package/lib/dist/services/traces/tracePoller.js +309 -0
  476. package/lib/dist/services/traces/tracePoller.js.map +1 -0
  477. package/lib/dist/services/traces/traceStats.d.ts +45 -0
  478. package/lib/dist/services/traces/traceStats.d.ts.map +1 -0
  479. package/lib/dist/services/traces/traceStats.js +114 -0
  480. package/lib/dist/services/traces/traceStats.js.map +1 -0
  481. package/lib/dist/services/traces/traceSummary.d.ts +47 -0
  482. package/lib/dist/services/traces/traceSummary.d.ts.map +1 -0
  483. package/lib/dist/services/traces/traceSummary.js +68 -0
  484. package/lib/dist/services/traces/traceSummary.js.map +1 -0
  485. package/lib/dist/services/traces/utils.d.ts +33 -0
  486. package/lib/dist/services/traces/utils.d.ts.map +1 -0
  487. package/lib/dist/services/traces/utils.js +114 -0
  488. package/lib/dist/services/traces/utils.js.map +1 -0
  489. package/lib/dist/types/agui.d.ts +13 -0
  490. package/lib/dist/types/agui.d.ts.map +1 -0
  491. package/lib/dist/types/agui.js +16 -0
  492. package/lib/dist/types/agui.js.map +1 -0
  493. package/lib/dist/types/index.d.ts +1175 -0
  494. package/lib/dist/types/index.d.ts.map +1 -0
  495. package/lib/dist/types/index.js +12 -0
  496. package/lib/dist/types/index.js.map +1 -0
  497. package/lib/dist/types/skills.d.ts +146 -0
  498. package/lib/dist/types/skills.d.ts.map +1 -0
  499. package/lib/dist/types/skills.js +6 -0
  500. package/lib/dist/types/skills.js.map +1 -0
  501. package/observio-sample-agent/pi-package/README.md +112 -0
  502. package/observio-sample-agent/pi-package/extensions/agent-health.ts +373 -0
  503. package/observio-sample-agent/pi-package/package.json +17 -0
  504. package/observio-sample-agent/pi-package/prompts/agent-health.md +37 -0
  505. package/observio-sample-agent/pi-package/skills/create-pr/SKILL.md +88 -0
  506. package/observio-sample-agent/pi-package/skills/fix-bug/SKILL.md +71 -0
  507. package/observio-sample-agent/pi-package/skills/implement-feature/SKILL.md +156 -0
  508. package/observio-sample-agent/pi-package/skills/instrument-otel/SKILL.md +208 -0
  509. package/observio-sample-agent/pi-package/skills/setup-collector/SKILL.md +146 -0
  510. package/observio-sample-agent/pi-package/skills/write-test/SKILL.md +115 -0
  511. package/package.json +64 -13
  512. package/server/dist/app.js +32651 -17637
  513. package/server/dist/index.js +29875 -14638
  514. package/tsconfig.lib.json +71 -0
  515. package/dist/assets/index-EvPLSTAS.js +0 -267
  516. package/dist/assets/index-RXasQKUs.css +0 -1
  517. package/lib/dist/config/index.js +0 -404
  518. package/lib/dist/index.js +0 -1665
@@ -0,0 +1,405 @@
1
+ # Backend Job Queue for Experiment Runs
2
+
3
+ ## Overview
4
+
5
+ Move experiment evaluation from browser to backend with a persistent job queue.
6
+
7
+ **Goal**: Close browser, experiments keep running. Monitor progress anytime.
8
+
9
+ **Features**:
10
+ - Queue experiments to run in background
11
+ - Start, stop, pause (between use cases), resume
12
+ - Real-time SSE streaming of trajectory steps
13
+ - File-based persistence (survives server restarts)
14
+
15
+ ---
16
+
17
+ ## Milestone Breakdown
18
+
19
+ ### Milestone 1: Backend Can Run a Single Evaluation
20
+
21
+ **Scope**: Prove backend can call agent, convert events, call judge - same as browser does today.
22
+
23
+ #### Tasks
24
+
25
+ - [ ] **A1**: Copy `aguiConverter.ts` to `server/services/` (replace debug import with console)
26
+ - [ ] **A2**: Copy `payloadBuilder.ts` to `server/services/` (just copy, no changes)
27
+ - [ ] **A3**: Create `server/services/nodeSSEClient.ts` (adapt browser SSE client for Node)
28
+ - [ ] **A4**: Create `server/services/evaluationService.ts` (port runEvaluation logic)
29
+ - [ ] **A6-partial**: Create test endpoint `POST /api/eval/test` in `server/routes/eval.ts`
30
+
31
+ #### How to Verify
32
+
33
+ ```bash
34
+ # 1. Start the server
35
+ npm run dev:server
36
+
37
+ # 2. Call the test endpoint with a test case ID
38
+ curl -X POST http://localhost:4001/api/eval/test \
39
+ -H "Content-Type: application/json" \
40
+ -d '{"testCaseId": "YOUR_TEST_CASE_ID", "agentKey": "YOUR_AGENT", "modelId": "YOUR_MODEL"}'
41
+
42
+ # 3. Check the response has:
43
+ # - trajectory array with steps
44
+ # - metrics with accuracy score
45
+ # - status: "completed" or "failed"
46
+ # - runId captured from agent
47
+ ```
48
+
49
+ #### Success Criteria
50
+
51
+ - [ ] Response contains trajectory steps (action, tool_result, assistant, response)
52
+ - [ ] Response contains metrics from judge
53
+ - [ ] runId is captured (check server logs: `[EvalService] Agent completed, runId: xxx`)
54
+ - [ ] Report is saved to OpenSearch
55
+
56
+ ---
57
+
58
+ ### Milestone 2: File-Based Job Queue (No SSE Yet)
59
+
60
+ **Scope**: Jobs can be submitted, started, and persist to file. Poll for status.
61
+
62
+ #### Tasks
63
+
64
+ - [ ] **C1**: Create `types/jobs.ts` with job types
65
+ - [ ] **C2**: Create `server/services/jobStorage.ts` for file persistence
66
+ - [ ] **A5**: Create `server/services/jobQueue.ts` (without SSE broadcasting)
67
+ - [ ] **A6**: Create `/api/jobs/*` routes in `server/routes/jobs.ts`
68
+ - [ ] Mount routes in `server/routes/index.ts`
69
+ - [ ] Initialize job queue in `server/index.ts`
70
+
71
+ #### How to Verify
72
+
73
+ ```bash
74
+ # 1. Submit a job
75
+ curl -X POST http://localhost:4001/api/jobs \
76
+ -H "Content-Type: application/json" \
77
+ -d '{"experimentId": "YOUR_EXP_ID", "runConfig": {"name": "Test Run", "agentKey": "xxx", "modelId": "yyy"}}'
78
+ # → Returns job with status: "queued"
79
+
80
+ # 2. Check file was created
81
+ cat server/data/jobs/queue.json
82
+ # → Should show job in jobs array
83
+
84
+ # 3. List jobs via API
85
+ curl http://localhost:4001/api/jobs
86
+ # → Returns { jobs: [...] }
87
+
88
+ # 4. Start the job
89
+ curl -X POST http://localhost:4001/api/jobs/JOB_ID/start
90
+ # → Returns { success: true }
91
+
92
+ # 5. Poll for status (repeat until completed)
93
+ curl http://localhost:4001/api/jobs/JOB_ID
94
+ # → Watch status change: queued → running → completed
95
+
96
+ # 6. Restart server mid-job, check recovery
97
+ # Kill server (Ctrl+C), restart, check queue.json - job should be "paused"
98
+
99
+ # 7. Cancel a running job
100
+ curl -X POST http://localhost:4001/api/jobs/JOB_ID/cancel
101
+ ```
102
+
103
+ #### Success Criteria
104
+
105
+ - [ ] Jobs persist in `server/data/jobs/queue.json`
106
+ - [ ] Job transitions: queued → running → completed
107
+ - [ ] Use cases execute sequentially (check server logs)
108
+ - [ ] Reports are saved for each completed use case
109
+ - [ ] Server restart marks running job as paused
110
+ - [ ] Cancel stops job after current use case
111
+
112
+ ---
113
+
114
+ ### Milestone 3: SSE Streaming for Real-Time Progress
115
+
116
+ **Scope**: Clients can subscribe to job events, see trajectory steps live.
117
+
118
+ #### Tasks
119
+
120
+ - [ ] **C3**: Create `server/services/sseManager.ts`
121
+ - [ ] **A5-update**: Add SSE broadcasting to job queue service
122
+ - [ ] **A6-update**: Add `/api/jobs/:id/stream` endpoint
123
+
124
+ #### How to Verify
125
+
126
+ ```bash
127
+ # 1. In terminal 1: Subscribe to job stream
128
+ curl -N http://localhost:4001/api/jobs/JOB_ID/stream
129
+ # → Should see: data: {"type":"connected"}
130
+
131
+ # 2. In terminal 2: Start the job
132
+ curl -X POST http://localhost:4001/api/jobs/JOB_ID/start
133
+
134
+ # 3. Watch terminal 1 - should see streaming events:
135
+ # data: {"type":"job:status","data":{"status":"running"}}
136
+ # data: {"type":"job:progress","data":{"useCaseId":"xxx","status":"running"}}
137
+ # data: {"type":"job:trajectory","data":{"step":{"type":"action",...}}}
138
+ # data: {"type":"job:trajectory","data":{"step":{"type":"tool_result",...}}}
139
+ # ... more trajectory steps ...
140
+ # data: {"type":"job:progress","data":{"useCaseId":"xxx","status":"completed"}}
141
+ # data: {"type":"job:complete","data":{...}}
142
+
143
+ # 4. Open multiple terminals with curl -N, verify all receive same events
144
+ ```
145
+
146
+ #### Success Criteria
147
+
148
+ - [ ] SSE connection stays open
149
+ - [ ] Trajectory steps stream in real-time (as agent executes)
150
+ - [ ] Multiple clients receive same events
151
+ - [ ] Keep-alive pings prevent timeout
152
+ - [ ] Client disconnect doesn't crash server
153
+
154
+ ---
155
+
156
+ ### Milestone 4: Pause/Resume Works
157
+
158
+ **Scope**: Pause a running job between use cases, resume later.
159
+
160
+ #### Tasks
161
+
162
+ - [ ] **A5-update**: Add pause/resume logic to job queue service
163
+
164
+ #### How to Verify
165
+
166
+ ```bash
167
+ # 1. Start a job with multiple use cases
168
+ curl -X POST http://localhost:4001/api/jobs/JOB_ID/start
169
+
170
+ # 2. Wait for first use case to complete (watch logs or SSE)
171
+ # Server log: "[JobQueue] Use case 0 completed"
172
+
173
+ # 3. Pause the job
174
+ curl -X POST http://localhost:4001/api/jobs/JOB_ID/pause
175
+
176
+ # 4. Check status - should be "paused"
177
+ curl http://localhost:4001/api/jobs/JOB_ID
178
+ # → status: "paused", currentUseCaseIndex: 1
179
+
180
+ # 5. Check queue.json - should persist paused state
181
+ cat server/data/jobs/queue.json
182
+
183
+ # 6. Resume the job
184
+ curl -X POST http://localhost:4001/api/jobs/JOB_ID/resume
185
+
186
+ # 7. Watch it continue from where it left off
187
+ # Server log: "[JobQueue] Resuming job at index 1"
188
+ ```
189
+
190
+ #### Success Criteria
191
+
192
+ - [ ] Pause takes effect after current use case completes
193
+ - [ ] Paused state persists in file
194
+ - [ ] Resume continues from next use case (not from beginning)
195
+ - [ ] All results preserved (use cases 0-N completed before pause)
196
+
197
+ ---
198
+
199
+ ### Milestone 5: Frontend Integration
200
+
201
+ **Scope**: UI uses job queue instead of browser-based execution.
202
+
203
+ #### Tasks
204
+
205
+ - [ ] **B1**: Create `services/api/jobsApi.ts` client
206
+ - [ ] **B2**: Create `hooks/useJobStream.ts` hook
207
+ - [ ] **B3**: Create `components/JobProgressPanel.tsx` component
208
+ - [ ] **B4**: Update `components/ExperimentRunsPage.tsx` with feature flag
209
+
210
+ #### How to Verify
211
+
212
+ 1. Open the app in browser, go to an experiment
213
+ 2. Click "Add Run", configure, click "Start"
214
+ 3. Verify: Job is submitted (check Network tab: POST /api/jobs)
215
+ 4. Verify: Progress panel shows live updates
216
+ 5. Verify: Trajectory steps appear as they stream
217
+ 6. Close browser tab
218
+ 7. Reopen browser, go back to experiment
219
+ 8. Verify: Job is still running (or completed)
220
+ 9. Verify: Results appear correctly
221
+
222
+ #### Success Criteria
223
+
224
+ - [ ] UI submits job instead of running in browser
225
+ - [ ] Live progress updates via SSE
226
+ - [ ] Can close browser, job continues
227
+ - [ ] Pause/Resume buttons work
228
+ - [ ] Final results match what old system produced
229
+
230
+ ---
231
+
232
+ ### Milestone 6: Cleanup & Polish
233
+
234
+ **Scope**: Remove feature flag, clean up old code, handle edge cases.
235
+
236
+ #### Tasks
237
+
238
+ - [ ] Remove feature flag, make job queue the default
239
+ - [ ] Handle edge cases (network errors, agent timeouts)
240
+ - [ ] Add job history cleanup (delete old completed jobs)
241
+ - [ ] Update documentation
242
+
243
+ ---
244
+
245
+ ## Implementation Timeline
246
+
247
+ ```
248
+ Week 1: Milestone 1 (Backend Eval)
249
+ ├── Copy aguiConverter to server
250
+ ├── Copy payloadBuilder to server
251
+ ├── Create nodeSSEClient
252
+ ├── Create evaluationService
253
+ └── Add test endpoint
254
+ └── VERIFY: curl test works ✓
255
+
256
+ Week 2: Milestone 2 (Job Queue)
257
+ ├── Create job types
258
+ ├── Create jobStorage
259
+ ├── Create jobQueue
260
+ └── Create job routes
261
+ └── VERIFY: Job lifecycle via curl ✓
262
+
263
+ Week 3: Milestone 3 + 4 (SSE + Pause/Resume)
264
+ ├── Create sseManager
265
+ ├── Add broadcasting to queue
266
+ ├── Add stream endpoint
267
+ └── Add pause/resume logic
268
+ └── VERIFY: SSE stream + pause works ✓
269
+
270
+ Week 4: Milestone 5 (Frontend)
271
+ ├── Create jobsApi
272
+ ├── Create useJobStream hook
273
+ ├── Create JobProgressPanel
274
+ └── Update ExperimentRunsPage
275
+ └── VERIFY: Full flow in browser ✓
276
+ ```
277
+
278
+ ---
279
+
280
+ ## Files to Create
281
+
282
+ | File | Milestone | Description |
283
+ |------|-----------|-------------|
284
+ | `types/jobs.ts` | M2 | Job types |
285
+ | `server/services/aguiConverter.ts` | M1 | Copy from frontend |
286
+ | `server/services/payloadBuilder.ts` | M1 | Copy from frontend |
287
+ | `server/services/nodeSSEClient.ts` | M1 | Node SSE consumer |
288
+ | `server/services/evaluationService.ts` | M1 | Backend eval logic |
289
+ | `server/services/jobStorage.ts` | M2 | File persistence |
290
+ | `server/services/jobQueue.ts` | M2 | Queue orchestrator |
291
+ | `server/services/sseManager.ts` | M3 | Client broadcasting |
292
+ | `server/routes/jobs.ts` | M2 | API endpoints |
293
+ | `services/api/jobsApi.ts` | M5 | Frontend API client |
294
+ | `hooks/useJobStream.ts` | M5 | SSE subscription |
295
+ | `components/JobProgressPanel.tsx` | M5 | Progress UI |
296
+
297
+ ## Files to Modify
298
+
299
+ | File | Milestone | Change |
300
+ |------|-----------|--------|
301
+ | `server/routes/index.ts` | M2 | Mount job routes |
302
+ | `server/index.ts` | M2 | Initialize job queue on startup |
303
+ | `components/ExperimentRunsPage.tsx` | M5 | Add feature flag + job integration |
304
+
305
+ ---
306
+
307
+ ## Backward Compatibility
308
+
309
+ During Milestone 5, use a feature flag:
310
+
311
+ ```typescript
312
+ // In ExperimentRunsPage.tsx
313
+ const USE_BACKEND_JOBS = true; // Toggle to test
314
+
315
+ const handleStartRun = async () => {
316
+ if (USE_BACKEND_JOBS) {
317
+ // New: Submit to backend job queue
318
+ const job = await jobsApi.submit(experimentId, runConfigValues);
319
+ await jobsApi.start(job.id);
320
+ setActiveJobId(job.id);
321
+ } else {
322
+ // Old: Run in browser (existing code, unchanged)
323
+ await runExperiment(experiment, runConfigValues, onProgress);
324
+ }
325
+ };
326
+ ```
327
+
328
+ This enables:
329
+ - **A/B testing**: Run same test case both ways, compare results
330
+ - **Quick rollback**: Set flag to false if issues found
331
+ - **Gradual rollout**: Enable for some users first
332
+
333
+ ---
334
+
335
+ ## Technical Details
336
+
337
+ ### Job Types (`types/jobs.ts`)
338
+
339
+ ```typescript
340
+ export type JobStatus = 'queued' | 'running' | 'paused' | 'completed' | 'failed' | 'cancelled';
341
+
342
+ export interface ExperimentJob {
343
+ id: string;
344
+ experimentId: string;
345
+ experimentName: string;
346
+ runConfig: RunConfigInput;
347
+ status: JobStatus;
348
+ useCaseIds: string[];
349
+ currentUseCaseIndex: number;
350
+ currentUseCaseId: string | null;
351
+ results: Record<string, { reportId: string; status: RunResultStatus }>;
352
+ createdAt: string;
353
+ startedAt: string | null;
354
+ pausedAt: string | null;
355
+ completedAt: string | null;
356
+ error: string | null;
357
+ experimentRunId: string | null;
358
+ }
359
+
360
+ export type JobEventType = 'job:status' | 'job:progress' | 'job:trajectory' | 'job:complete' | 'job:error';
361
+
362
+ export interface JobEvent {
363
+ type: JobEventType;
364
+ jobId: string;
365
+ timestamp: number;
366
+ data: unknown;
367
+ }
368
+ ```
369
+
370
+ ### API Endpoints
371
+
372
+ | Method | Endpoint | Description |
373
+ |--------|----------|-------------|
374
+ | `POST` | `/api/jobs` | Submit new job |
375
+ | `GET` | `/api/jobs` | List all jobs |
376
+ | `GET` | `/api/jobs/:id` | Get job details |
377
+ | `POST` | `/api/jobs/:id/start` | Start queued job |
378
+ | `POST` | `/api/jobs/:id/pause` | Pause running job |
379
+ | `POST` | `/api/jobs/:id/resume` | Resume paused job |
380
+ | `POST` | `/api/jobs/:id/cancel` | Cancel job |
381
+ | `DELETE` | `/api/jobs/:id` | Delete from history |
382
+ | `GET` | `/api/jobs/:id/stream` | SSE stream for progress |
383
+
384
+ ### File Storage Structure
385
+
386
+ ```
387
+ server/
388
+ data/
389
+ jobs/
390
+ queue.json # Active jobs
391
+ history/
392
+ {jobId}.json # Archived completed/failed jobs
393
+ ```
394
+
395
+ ### Key Implementation Notes
396
+
397
+ 1. **AG UI Converter** (`services/agent/aguiConverter.ts`) is already Node.js compatible - just needs debug import changed
398
+
399
+ 2. **Payload Builder** (`services/agent/payloadBuilder.ts`) is 100% portable - pure functions, no browser APIs
400
+
401
+ 3. **SSE in Node.js** - Use native `fetch` (Node 18+) with `ReadableStream.getReader()` - same as browser
402
+
403
+ 4. **Pause Logic** - Set a flag, checked between use cases. Current use case always completes.
404
+
405
+ 5. **Server Restart Recovery** - On startup, scan queue for `status: 'running'`, mark as `'paused'`
@@ -0,0 +1,283 @@
1
+ <!--
2
+ * Copyright OpenSearch Contributors
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ -->
5
+
6
+ # Claude Code Telemetry → Agent Health
7
+
8
+ Route Claude Code's native OpenTelemetry telemetry (traces, logs, metrics) into the same OpenSearch cluster used by Agent Health, so you can view Claude Code sessions alongside your other agent traces.
9
+
10
+ ## Quick Setup (Recommended)
11
+
12
+ If you deployed the Agent Health Observability CloudFormation stack, it includes an API Gateway with a Lambda SigV4 proxy. Claude Code can send telemetry directly to it — no Docker or local collector needed.
13
+
14
+ ### 1. Get Your API Gateway URL
15
+
16
+ From CloudFormation stack outputs:
17
+
18
+ ```bash
19
+ aws cloudformation describe-stacks \
20
+ --stack-name AgentHealthObservability \
21
+ --query "Stacks[0].Outputs[?OutputKey=='OTLPIngestEndpoint'].OutputValue" \
22
+ --output text
23
+ ```
24
+
25
+ ### 2. Configure Claude Code
26
+
27
+ Add to your `~/.zshrc` (or `~/.bashrc`):
28
+
29
+ ```bash
30
+ # --- Claude Code OpenTelemetry ---
31
+ export CLAUDE_CODE_ENABLE_TELEMETRY=1
32
+
33
+ # Exporters (all three signals)
34
+ export OTEL_METRICS_EXPORTER=otlp
35
+ export OTEL_LOGS_EXPORTER=otlp
36
+ export OTEL_TRACES_EXPORTER=otlp
37
+
38
+ # Point at API Gateway (Lambda proxies to OSIS with SigV4)
39
+ export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
40
+ export OTEL_EXPORTER_OTLP_ENDPOINT=https://<YOUR-API-GATEWAY-URL>
41
+ ```
42
+
43
+ Then reload and start a new Claude Code session:
44
+
45
+ ```bash
46
+ source ~/.zshrc
47
+ claude
48
+ ```
49
+
50
+ Telemetry begins flowing automatically. No restart of the API Gateway or OSIS needed.
51
+
52
+ ### 3. View in Agent Health
53
+
54
+ Open Agent Health → **Agent Traces** tab. Claude Code appears as service `claude-code`. Expand the time range filter if recent sessions don't appear immediately (OSIS ingestion has a short delay).
55
+
56
+ Each Claude Code conversation becomes a trace with spans for:
57
+ - `interaction` — top-level user turn
58
+ - `llm_request` — model API calls (with token counts and cost)
59
+ - `tool` / `tool.execution` — tool invocations and results
60
+
61
+ ## Privacy Note
62
+
63
+ Even with default settings (no opt-in flags), Claude Code telemetry includes `session.id`, `user.account_uuid`, and `organization.id` in every span. These are account-level identifiers, not conversation content.
64
+
65
+ To include prompt and tool content in spans (useful for debugging, but sends conversation data to OpenSearch):
66
+
67
+ ```bash
68
+ # Optional — has privacy implications
69
+ export OTEL_LOG_USER_PROMPTS=1
70
+ export OTEL_LOG_TOOL_DETAILS=1
71
+ export OTEL_LOG_TOOL_CONTENT=1
72
+ ```
73
+
74
+ ## What Data Lands in OpenSearch
75
+
76
+ | Signal | Data | Index Pattern |
77
+ |--------|------|---------------|
78
+ | **Traces** | Span hierarchy: `interaction` → `llm_request` / `tool` → `tool.execution` | `otel-v1-apm-span-*` |
79
+ | **Logs/Events** | `user_prompt`, `api_request`, `tool_result`, `tool_decision`, `compaction` events | `otel-logs-*` |
80
+ | **Metrics** | `claude_code.cost.usage`, `claude_code.token.usage`, `claude_code.session.count`, etc. | Not supported by OSIS (no OTLP metrics receiver) |
81
+
82
+ ### Key Span Attributes
83
+
84
+ Every span includes `service.name: claude-code`, `session.id`, `user.account_uuid`, and `organization.id`. LLM request spans add `model`, `input_tokens`, `output_tokens`, `cost_usd`, `duration_ms`. Tool spans add `tool_name`, `result_tokens`.
85
+
86
+ > **Run correlation (Strategy D).** Because Claude Code stamps a stable
87
+ > `session.id` on *every* span of a run — and emits neither our
88
+ > `agent_health.run.id` nor a W3C `traceparent` we control — Agent Health
89
+ > correlates its spans by that `session.id`. `ClaudeCodeConnector` captures the
90
+ > `session_id` from the stream-json output, persists it as `report.sessionId`,
91
+ > and the run-report Traces tab / trace judge query `attributes.session.id`
92
+ > (unioned with the service-name + time-window fallback). See
93
+ > [AGENTS.md → Trace correlation conventions](../AGENTS.md).
94
+
95
+ See the [Claude Code monitoring docs](https://code.claude.com/docs/en/monitoring-usage) for the full attribute reference.
96
+
97
+ ## Verification
98
+
99
+ ### Check OpenSearch for Claude Code spans
100
+
101
+ ```bash
102
+ curl -s "https://<opensearch-endpoint>/otel-v1-apm-span-*/_search" \
103
+ -H 'Content-Type: application/json' \
104
+ -d '{
105
+ "size": 5,
106
+ "query": { "match": { "serviceName": "claude-code" } },
107
+ "sort": [{ "startTime": "desc" }]
108
+ }' | jq '.hits.hits[]._source.spanId'
109
+ ```
110
+
111
+ Or open Agent Health → Agent Traces and filter by service name `claude-code`.
112
+
113
+ ## Troubleshooting
114
+
115
+ | Symptom | Cause | Fix |
116
+ |---------|-------|-----|
117
+ | No spans in Agent Traces | Time range too narrow | Expand to "Last 7d"; OSIS ingestion can have a short delay |
118
+ | `HTTP 403` from API Gateway | IAM credentials expired or wrong account | Refresh credentials; Lambda assumes a role in the stack's account |
119
+ | Traces arrive but no logs | OSIS has no logs pipeline | Deploy the full CFN stack which includes `otel_logs_source` pipeline |
120
+ | Spans arrive but no service map | Service map processor not in OSIS | The Agent Health CFN template includes `otel-service-map-pipeline` by default |
121
+
122
+ ## Advanced: Local ADOT Collector
123
+
124
+ If you can't use the API Gateway (e.g., air-gapped environment, custom processing), you can run a local ADOT collector that signs requests with SigV4 and forwards to OSIS directly.
125
+
126
+ <details>
127
+ <summary>ADOT Collector setup</summary>
128
+
129
+ ### Architecture
130
+
131
+ ```
132
+ Claude Code ──OTLP (gRPC, localhost)──▶ ADOT Collector (Docker)
133
+ │
134
+ SigV4-signed HTTPS
135
+ │
136
+ ┌─────────────────┼─────────────────┐
137
+ ▼ ▼ ▼
138
+ OSIS Traces OSIS Logs (metrics via
139
+ Pipeline Pipeline logs pipeline)
140
+ │ │
141
+ ▼ ▼
142
+ OpenSearch (otel-v1-apm-span-* / otel-logs-*)
143
+ ```
144
+
145
+ ### Prerequisites
146
+
147
+ - Docker installed and running
148
+ - AWS credentials with `osis:Ingest` permission on your pipelines
149
+
150
+ ### Get Your OSIS Endpoints
151
+
152
+ ```bash
153
+ # Traces endpoint
154
+ aws cloudformation describe-stacks \
155
+ --stack-name AgentHealthObservability \
156
+ --query "Stacks[0].Outputs[?OutputKey=='OSISTraceIngestEndpoint'].OutputValue" \
157
+ --output text
158
+
159
+ # Logs endpoint
160
+ aws cloudformation describe-stacks \
161
+ --stack-name AgentHealthObservability \
162
+ --query "Stacks[0].Outputs[?OutputKey=='OSISLogsIngestEndpoint'].OutputValue" \
163
+ --output text
164
+ ```
165
+
166
+ ### Collector Config
167
+
168
+ Create `~/.claude/otel-collector-config.yaml`:
169
+
170
+ ```yaml
171
+ receivers:
172
+ otlp:
173
+ protocols:
174
+ grpc:
175
+ endpoint: 0.0.0.0:4317
176
+ http:
177
+ endpoint: 0.0.0.0:4318
178
+
179
+ processors:
180
+ batch:
181
+ timeout: 10s
182
+ send_batch_size: 512
183
+
184
+ exporters:
185
+ otlphttp/traces:
186
+ endpoint: "https://<YOUR-OSIS-TRACES-ENDPOINT>"
187
+ encoding: json # REQUIRED: OSIS rejects protobuf with HTTP 500
188
+ compression: none # Avoid gzip issues with SigV4 body signing
189
+ auth:
190
+ authenticator: sigv4auth
191
+
192
+ otlphttp/logs:
193
+ endpoint: "https://<YOUR-OSIS-LOGS-ENDPOINT>"
194
+ encoding: json
195
+ compression: none
196
+ auth:
197
+ authenticator: sigv4auth
198
+
199
+ extensions:
200
+ sigv4auth:
201
+ region: "us-west-2" # ← your OSIS pipeline region
202
+ service: "osis"
203
+
204
+ service:
205
+ extensions: [sigv4auth]
206
+ pipelines:
207
+ traces:
208
+ receivers: [otlp]
209
+ processors: [batch]
210
+ exporters: [otlphttp/traces]
211
+ logs:
212
+ receivers: [otlp]
213
+ processors: [batch]
214
+ exporters: [otlphttp/logs]
215
+ ```
216
+
217
+ > **Important:** `encoding: json` and `compression: none` are **required**. OSIS rejects OTLP protobuf payloads with HTTP 500.
218
+
219
+ ### Docker Compose
220
+
221
+ Create `~/.claude/docker-compose-otel.yaml`:
222
+
223
+ ```yaml
224
+ services:
225
+ adot-collector:
226
+ image: public.ecr.aws/aws-observability/aws-otel-collector:latest
227
+ command: ["--config", "/opt/config.yaml"]
228
+ ports:
229
+ - "4317:4317"
230
+ - "4318:4318"
231
+ volumes:
232
+ - ./otel-collector-config.yaml:/opt/config.yaml:ro
233
+ env_file:
234
+ - .adot.env # AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN
235
+ environment:
236
+ - AWS_REGION=${AWS_REGION:-us-west-2}
237
+ restart: unless-stopped
238
+ ```
239
+
240
+ Create `~/.claude/.adot.env` with your AWS credentials:
241
+
242
+ ```bash
243
+ AWS_ACCESS_KEY_ID=AKIA...
244
+ AWS_SECRET_ACCESS_KEY=...
245
+ AWS_SESSION_TOKEN=... # if using temporary credentials
246
+ ```
247
+
248
+ ### Start / Stop
249
+
250
+ ```bash
251
+ cd ~/.claude
252
+ docker compose -f docker-compose-otel.yaml up -d
253
+ docker compose -f docker-compose-otel.yaml logs --tail 20
254
+ # Look for: "Everything is ready. Begin running and processing data."
255
+ ```
256
+
257
+ When using the ADOT path, configure Claude Code with gRPC instead of HTTP:
258
+
259
+ ```bash
260
+ export OTEL_EXPORTER_OTLP_PROTOCOL=grpc
261
+ export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
262
+ ```
263
+
264
+ To stop:
265
+
266
+ ```bash
267
+ docker compose -f ~/.claude/docker-compose-otel.yaml down
268
+ ```
269
+
270
+ ### ADOT-Specific Troubleshooting
271
+
272
+ | Symptom | Cause | Fix |
273
+ |---------|-------|-----|
274
+ | `HTTP 500` from OSIS | Protobuf encoding (default) | Add `encoding: json` and `compression: none` to all `otlphttp` exporters |
275
+ | `HTTP 401` / "Missing Authentication Token" | SigV4 credentials expired | Refresh `.adot.env` with fresh credentials |
276
+ | `EOF` or connection drops | OSIS pipeline cold-start | Stop and start the OSIS pipeline |
277
+ | `connection refused` | ADOT not listening on 4317 | Check `docker ps`; ensure ports aren't taken |
278
+
279
+ </details>
280
+
281
+ ## Disabling Telemetry
282
+
283
+ Unset `CLAUDE_CODE_ENABLE_TELEMETRY` or set it to `0`. No other changes needed.