@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,298 @@
1
+ <!--
2
+ * Copyright OpenSearch Contributors
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ -->
5
+
6
+ # Coding Agent Analytics
7
+
8
+ A unified analytics dashboard for AI coding agents. Reads local session data from **Claude Code**, **Kiro**, and **Codex CLI** and provides cross-agent usage metrics, cost estimation, activity patterns, tool analytics, and workspace management — all without sending data anywhere.
9
+
10
+ ## Quick Start
11
+
12
+ ```bash
13
+ # Start the server (includes the analytics dashboard)
14
+ npm run dev:server # Backend on port 4001
15
+ npm run dev # Frontend on port 4000 (separate terminal)
16
+
17
+ # Or production mode (single process)
18
+ npm run server
19
+ ```
20
+
21
+ Open `http://localhost:4000` (dev) or `http://localhost:4001` (prod) and click the **Coding Agents** tab. The dashboard auto-detects installed agents and shows data immediately.
22
+
23
+ ## Supported Agents
24
+
25
+ | Agent | Data Location | What's Parsed | Cost Estimation |
26
+ |-------|--------------|---------------|-----------------|
27
+ | **Claude Code** | `~/.claude/projects/<slug>/*.jsonl` | Messages, tool calls, token usage, cache metrics, MCP usage | Full (input/output/cache tokens) |
28
+ | **Kiro** | `~/.kiro/sessions/cli/*.jsonl` + IDE workspace | Messages, tool calls, partial token counts, session metadata | Partial (Bedrock pricing) |
29
+ | **Codex CLI** | `~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl` | Messages, tool calls, session metadata | None (tokens not persisted) |
30
+
31
+ No configuration required. If the agent's data directory exists, it's detected automatically.
32
+
33
+ ## Dashboard Tabs
34
+
35
+ ### Overview
36
+ Top-level stats across all agents: total sessions, estimated cost, tool success rate, cost per completion, wasted cost (incomplete sessions), and detected agents. Includes daily activity chart, agent distribution pie chart, and auto-generated insights with actionable recommendations.
37
+
38
+ ### Sessions
39
+ Filterable, sortable session list with search. Click any session to open a resizable detail panel showing the full conversation with syntax highlighting. Supports filtering by agent, completion status, and project. Search highlights matches with prev/next navigation.
40
+
41
+ ### Projects
42
+ Per-project analytics cards showing session count, completion rate, cost, and tool errors. Click any project to drill into its sessions.
43
+
44
+ ### Costs
45
+ Cost breakdown by model and project with daily cost trend chart. Includes cache savings calculation. Click chart bars to drill into sessions or projects.
46
+
47
+ ### Activity
48
+ GitHub-style activity heatmap (last 90 days), sessions by hour and day of week, current/longest streaks, and active days. Click any element to explore related sessions.
49
+
50
+ ### Efficiency
51
+ Cross-agent comparison of tool success rate, completion rate, and cost per completion. Per-agent cards with detailed metrics. Click agent cards to view their sessions.
52
+
53
+ ### Tools
54
+ Tool usage analytics with category breakdown (file-io, shell, agent, web, planning, mcp, etc.). Click category bars to filter the tools table. Click tool rows to see sessions using that tool. Includes error rates and success percentages.
55
+
56
+ ### Advanced
57
+ MCP server analytics, hourly effectiveness (completion rate by hour), session duration distribution, conversation depth analysis, and recurring failure patterns. All elements are clickable for drill-down navigation.
58
+
59
+ ### Workspace
60
+ Agent-specific workspace management:
61
+ - **Claude Code**: Active sessions, memory files (view/edit), plans, tasks, and settings
62
+ - **Kiro**: MCP servers, agents, powers, extensions, and settings
63
+
64
+ ## Architecture
65
+
66
+ ```
67
+ Browser (React)
68
+ → Express API (/api/coding-agents/*)
69
+ → SessionCacheManager (in-memory, <1ms responses)
70
+ → ReaderCache (per-agent, directory signature invalidation)
71
+ → [ClaudeCodeReader, KiroReader, CodexReader]
72
+ → Local filesystem (~/.claude/, ~/.kiro/, ~/.codex/)
73
+ ```
74
+
75
+ ### In-Memory Cache
76
+
77
+ Session data is cached in memory with a two-tier invalidation strategy:
78
+
79
+ 1. **Directory signature** — `"latestMtime:fileCount"` fingerprint detects new/deleted sessions without re-parsing
80
+ 2. **Active session refresh** — Background interval (30s) checks file mtime for non-completed sessions only
81
+
82
+ First request after startup: ~30ms (cache warmup). Subsequent requests: <3ms.
83
+
84
+ ### Key Files
85
+
86
+ ```
87
+ server/services/codingAgents/
88
+ ├── index.ts # Barrel exports
89
+ ├── types.ts # Unified type definitions (AgentSession, CombinedStats, etc.)
90
+ ├── registry.ts # Core registry — merges data from all readers
91
+ ├── cache.ts # Two-tier session cache with directory invalidation
92
+ ├── pricing.ts # Multi-vendor pricing (Claude, Bedrock, OpenAI)
93
+ ├── toolCategories.ts # Unified tool categorization across agents
94
+ ├── insights.ts # Auto-generated actionable insights
95
+ └── readers/
96
+ ├── claudeCode.ts # Claude Code JSONL parser
97
+ ├── claudeCodeWorkspace.ts # Claude Code workspace (memory, plans, tasks)
98
+ ├── kiro.ts # Kiro CLI + IDE session parser
99
+ ├── kiroWorkspace.ts # Kiro workspace (MCP, agents, powers)
100
+ └── codex.ts # Codex CLI rollout parser
101
+
102
+ server/routes/
103
+ ├── codingAgents.ts # Analytics API endpoints (12 routes)
104
+ └── claudeCodeWorkspace.ts # Workspace management endpoints (6 routes)
105
+
106
+ components/codingAgents/
107
+ └── CodingAgentsPage.tsx # React dashboard (9 tabs, ~2600 LOC)
108
+ ```
109
+
110
+ ## API Reference
111
+
112
+ All endpoints support optional `from` and `to` query parameters for date range filtering (ISO 8601 format).
113
+
114
+ | Endpoint | Description |
115
+ |----------|-------------|
116
+ | `GET /api/coding-agents/available` | List detected agents |
117
+ | `GET /api/coding-agents/stats` | Combined stats across all agents |
118
+ | `GET /api/coding-agents/sessions` | Paginated session list (supports `agent`, `completed`, `project`, `search`, `limit`, `offset`) |
119
+ | `GET /api/coding-agents/sessions/:agent/:sessionId` | Session detail with full conversation |
120
+ | `GET /api/coding-agents/costs` | Cost breakdown by model and project |
121
+ | `GET /api/coding-agents/activity` | Activity patterns (streaks, hourly, daily, heatmap) |
122
+ | `GET /api/coding-agents/tools` | Tool usage analytics with categories |
123
+ | `GET /api/coding-agents/efficiency` | Per-agent efficiency metrics |
124
+ | `GET /api/coding-agents/projects` | Per-project analytics |
125
+ | `GET /api/coding-agents/advanced` | MCP, duration, conversation depth, hourly effectiveness |
126
+ | `GET /api/coding-agents/failure-patterns` | Recurring tool failure patterns |
127
+ | `GET /api/coding-agents/export` | Export all data as JSON or CSV (`format=json|csv`) |
128
+
129
+ ### Remote Server Endpoints
130
+
131
+ | Endpoint | Description |
132
+ |----------|-------------|
133
+ | `GET /api/remote-servers` | List configured remote servers (API keys masked) |
134
+ | `POST /api/remote-servers` | Add a remote server (`{ name, url, apiKey? }`) |
135
+ | `DELETE /api/remote-servers/:name` | Remove a remote server |
136
+ | `POST /api/remote-servers/:name/test` | Test connectivity to a remote server |
137
+
138
+ ### Workspace Endpoints
139
+
140
+ | Endpoint | Description |
141
+ |----------|-------------|
142
+ | `GET /api/coding-agents/claude-code/memory` | Claude Code memory files by project |
143
+ | `GET /api/coding-agents/claude-code/plans` | Active plans |
144
+ | `GET /api/coding-agents/claude-code/tasks` | Task lists |
145
+ | `GET /api/coding-agents/claude-code/settings` | Claude Code settings |
146
+ | `GET /api/coding-agents/claude-code/active-sessions` | Currently active sessions |
147
+ | `GET /api/coding-agents/kiro/workspace` | Kiro workspace (MCP servers, agents, powers, extensions) |
148
+
149
+ ## Adding a New Agent Reader
150
+
151
+ To add support for a new coding agent:
152
+
153
+ 1. **Create a reader** in `server/services/codingAgents/readers/`:
154
+
155
+ ```typescript
156
+ import type { CodingAgentReader, AgentSession, AgentStats, SessionDetail } from '../types';
157
+
158
+ export class MyAgentReader implements CodingAgentReader {
159
+ readonly agentName = 'my-agent' as const;
160
+ readonly displayName = 'My Agent';
161
+
162
+ async isAvailable(): Promise<boolean> {
163
+ // Check if the agent's data directory exists
164
+ }
165
+
166
+ async getSessions(): Promise<AgentSession[]> {
167
+ // Parse session files and return normalized AgentSession[]
168
+ }
169
+
170
+ async getStats(): Promise<AgentStats> {
171
+ // Aggregate stats from sessions
172
+ }
173
+
174
+ async getSessionDetail(sessionId: string): Promise<SessionDetail | null> {
175
+ // Return full conversation for a session
176
+ }
177
+ }
178
+ ```
179
+
180
+ 2. **Register the reader** in `server/services/codingAgents/registry.ts`:
181
+
182
+ ```typescript
183
+ import { MyAgentReader } from './readers/myAgent';
184
+
185
+ // Add to the readers array
186
+ private readers: CodingAgentReader[] = [
187
+ new ClaudeCodeReader(),
188
+ new KiroReader(),
189
+ new CodexReader(),
190
+ new MyAgentReader(), // ← add here
191
+ ];
192
+ ```
193
+
194
+ 3. **Add pricing** (if available) in `server/services/codingAgents/pricing.ts`
195
+
196
+ 4. **Add tool categories** in `server/services/codingAgents/toolCategories.ts`
197
+
198
+ 5. **Add cache signature** in `server/services/codingAgents/cache.ts` under `DIR_SIGNATURE_FNS`
199
+
200
+ 6. **Add colors/labels** in `components/codingAgents/CodingAgentsPage.tsx`:
201
+ ```typescript
202
+ const AGENT_COLORS = { ..., 'my-agent': '#your-color' };
203
+ const AGENT_LABELS = { ..., 'my-agent': 'My Agent' };
204
+ ```
205
+
206
+ ## Remote Build Server Monitoring
207
+
208
+ Monitor coding agents running on remote EC2 instances, build servers, or cloud dev environments from a single local dashboard.
209
+
210
+ ### How It Works
211
+
212
+ Each remote machine runs `agent-health` in **headless mode** (API only, no frontend). Your local dashboard aggregates data from all remotes transparently — the frontend code is unchanged, always talking to its own local server.
213
+
214
+ ```
215
+ [Remote EC2-A] agent-health serve --headless --api-key sk-abc → :4001
216
+ [Remote EC2-B] agent-health serve --headless --api-key sk-xyz → :4001
217
+
218
+ [Local machine]
219
+ Browser → localhost:4001 → Local server merges local + remote data
220
+ ```
221
+
222
+ ### Setup
223
+
224
+ **On each remote machine:**
225
+
226
+ ```bash
227
+ npx @opensearch-project/agent-health serve --headless --api-key sk-my-secret
228
+ ```
229
+
230
+ **On your local machine:**
231
+
232
+ ```bash
233
+ # Add remote servers
234
+ agent-health remote add --name ec2-build-1 --url http://10.0.1.50:4001 --api-key sk-my-secret
235
+ agent-health remote add --name ec2-build-2 --url http://10.0.1.51:4001 --api-key sk-other
236
+
237
+ # Test connectivity
238
+ agent-health remote test
239
+
240
+ # Start the dashboard — automatically aggregates from all servers
241
+ agent-health
242
+ ```
243
+
244
+ Or use the **Settings UI** — go to Settings > Remote Servers to add, test, and remove servers from the browser.
245
+
246
+ Or configure via `agent-health.config.json`:
247
+
248
+ ```json
249
+ {
250
+ "remoteServers": [
251
+ { "name": "ec2-build-1", "url": "http://10.0.1.50:4001", "apiKey": "sk-my-secret" },
252
+ { "name": "ec2-build-2", "url": "http://10.0.1.51:4001", "apiKey": "sk-other" }
253
+ ]
254
+ }
255
+ ```
256
+
257
+ ### CLI Commands
258
+
259
+ | Command | Description |
260
+ |---------|-------------|
261
+ | `agent-health remote add --name <n> --url <u> [--api-key <k>]` | Add a remote server |
262
+ | `agent-health remote remove <name>` | Remove a remote server |
263
+ | `agent-health remote list` | List configured remotes |
264
+ | `agent-health remote test` | Test connectivity to all remotes |
265
+
266
+ ### Key Behaviors
267
+
268
+ - **Graceful degradation**: If a remote is unreachable, the dashboard still shows data from available sources
269
+ - **30-second cache**: Remote session data is cached locally to avoid excessive network calls
270
+ - **10-second timeout**: Slow remotes don't block the entire dashboard
271
+ - **Server badges**: Sessions from remote servers show a colored badge with the server name
272
+ - **Transparent aggregation**: All analytics (stats, costs, activity, tools, etc.) automatically include remote data
273
+
274
+ ## Feature Toggle
275
+
276
+ Coding Agent Analytics can be disabled entirely without affecting the core evaluation features:
277
+
278
+ ```bash
279
+ # Via environment variable
280
+ AH_DISABLE_CODING_ANALYTICS=true npx @opensearch-project/agent-health
281
+ ```
282
+
283
+ Or in `agent-health.config.json`:
284
+ ```json
285
+ {
286
+ "codingAgentAnalytics": false
287
+ }
288
+ ```
289
+
290
+ When disabled: no routes are mounted, no background timers run, and the "Coding Agents" nav tab is hidden. All evaluation features continue to work normally.
291
+
292
+ ## Privacy
293
+
294
+ All data stays local. The dashboard reads session files directly from your filesystem (`~/.claude/`, `~/.kiro/`, `~/.codex/`). No data is sent to any external service. The `_filePath` internal field used for caching is stripped from all API responses.
295
+
296
+ ## Design Document
297
+
298
+ See [RFC 001: Coding Agent Analytics](rfcs/001-coding-agent-analytics.md) for the full design specification including motivation, architecture decisions, data flow diagrams, and planned future phases.
@@ -0,0 +1,388 @@
1
+ # Configuration Guide
2
+
3
+ Agent Health has **one file you author** plus state the app manages:
4
+
5
+ 1. **`agent-health.config.ts`** — the config you write (agents, connectors, models, judge, reporters, telemetry, and optionally storage/observability). Optional; only for customization.
6
+ 2. **`.agent-health/state.json`** — runtime state the app writes (storage/observability/custom agents/debug). You don't hand-edit this; the Settings UI manages it.
7
+ 3. **Environment variables** — secrets and quick overrides (`process.env` / `.env`).
8
+
9
+ Which is authoritative depends on the mode (below). Zero config also works — file-based storage and built-in demo agents need nothing.
10
+
11
+ ## Quick Start (Zero Config)
12
+
13
+ Most users can start immediately with no configuration:
14
+
15
+ ```bash
16
+ # If you have AWS credentials configured (aws configure)
17
+ npx agent-health run -t demo-tc-1 -a claude-code
18
+ ```
19
+
20
+ This works because:
21
+ - Claude Code uses your `AWS_PROFILE` automatically
22
+ - Travel Planner demo test cases are built-in
23
+ - File-based storage is used by default (no OpenSearch needed)
24
+ - Results shown in terminal
25
+
26
+ ## Two modes: code-first vs UI-first
27
+
28
+ Which file is authoritative depends on whether you author an `agent-health.config.ts`:
29
+
30
+ | Mode | Trigger | Source of truth | Settings UI (data sources) |
31
+ |------|---------|-----------------|----------------------------|
32
+ | **Code-first** | an `agent-health.config.{ts,js,mjs}` exists (project **or** user scope) | the `.ts` + `.env` | read-only — edit the file and restart |
33
+ | **UI-first** | no authored config file anywhere | `.agent-health/state.json` + `.env` | writable — the UI persists here |
34
+
35
+ **The rule:** if an authored config file is present, the runtime state file is
36
+ **ignored entirely** and the `.ts` wins. Otherwise the state file (written by the
37
+ Settings UI) is used. Exactly one plane is active — no merging, no precedence puzzle.
38
+
39
+ `.agent-health/` resolves at both **user** (`~/.agent-health/`) and **project**
40
+ (`<cwd>/.agent-health/`) scope, project overriding user — so you can set clusters
41
+ once globally and override per project.
42
+
43
+ Resolution for storage/observability (each tier overrides the one below):
44
+
45
+ ```
46
+ Code-first: project agent-health.config.ts → user ~/.agent-health/*.ts → OPENSEARCH_* env
47
+ UI-first: project .agent-health/state.json → user ~/.agent-health/state.json → OPENSEARCH_* env → file-storage fallback
48
+ ```
49
+
50
+ A single committed `agent-health.config.ts` (reading secrets from `process.env`)
51
+ is all most projects need — no state file required.
52
+
53
+ ## Runtime state file (`.agent-health/state.json`)
54
+
55
+ In **UI-first** mode (no authored config), configuring storage/observability via
56
+ the **Settings page** writes `.agent-health/state.json` (project scope by
57
+ default; gitignored). Don't hand-edit it — treat it as app-managed state:
58
+
59
+ ```json
60
+ {
61
+ "storage": { "endpoint": "https://...", "authType": "sigv4", "awsRegion": "us-east-1", "awsService": "es", "awsProfile": "default" },
62
+ "observability": { "endpoint": "https://...", "authType": "sigv4", "awsRegion": "us-east-1", "indexes": { "traces": "otel-v1-apm-span-*", "logs": "ml-commons-logs-*" } },
63
+ "debug": false
64
+ }
65
+ ```
66
+
67
+ In **code-first** mode (an `agent-health.config.ts` exists) this file is
68
+ **ignored**, and the Settings data-source panels are read-only — set
69
+ storage/observability in the `.ts` (see [TypeScript Config File](#typescript-config-file-optional)).
70
+
71
+ ### What gets written, and when
72
+
73
+ The app **never writes your `agent-health.config.ts`** — you author it by hand.
74
+ UI writes only ever target `.agent-health/state.json`, and only in ui-first mode:
75
+
76
+ | Action | UI-first (no `.ts`) | Code-first (a `.ts` exists) |
77
+ |--------|---------------------|------------------------------|
78
+ | **Test Connection** | nothing written — connectivity probe only | nothing written — probe only |
79
+ | **Save** (storage / observability / remote server) | writes `.agent-health/state.json` (project scope) | **`409 "managed by agent-health.config.ts"`** — nothing written |
80
+ | **Change a value for real** | Save in the UI | edit `agent-health.config.ts` + restart |
81
+
82
+ So if you edit the endpoint field and hit **Test Connection**, it only probes
83
+ that endpoint (falling back to stored credentials *only* when the endpoint
84
+ matches the configured one); the typed value is **not persisted** until you
85
+ **Save** — and in code-first mode Save is rejected with a `409`. To actually
86
+ switch clusters in code-first mode, edit the `.ts` and restart.
87
+
88
+ ### Auto-migration from legacy files
89
+
90
+ Existing `agent-health.yaml` and `agent-health.config.json` files are migrated
91
+ once to `.agent-health/state.json` on first startup (handled by
92
+ `configMigration.ts`); the originals are renamed to `*.backup`. If you also have
93
+ an `agent-health.config.ts`, the migrated storage/observability are ignored
94
+ (code-first) — a startup warning tells you to move them into the `.ts`.
95
+
96
+ ## Where things live: settings vs data vs your test files
97
+
98
+ Three locations are easy to confuse — they hold different things and have
99
+ different lifecycles:
100
+
101
+ | Location | Plane | Holds | Lifecycle |
102
+ |----------|-------|-------|-----------|
103
+ | `.agent-health/` | **Settings + Data** (control plane + file storage backend) | `state.json` (which storage/observability cluster, custom agents, debug flag — UI-first mode only) and `data/` (`test-cases/`, `benchmarks/`, `runs/`, `analytics/`, `evaluators/`, `traces/`, `skill-evals/` — the records Agent Health produces when no OpenSearch cluster is configured) | app-managed, gitignored, grows with use |
104
+ | `evals/` *(or wherever you keep them)* | **Your source code** | the `.eval.js` / `.eval.ts` test files **you author** with the code SDK | you own it, version-controlled |
105
+
106
+ Rules of thumb:
107
+
108
+ - **`.agent-health/`** answers *"how is Agent Health configured?"* (`state.json`)
109
+ and *"what has Agent Health stored?"* (`data/`). `state.json` is like
110
+ `.vscode/settings.json` and is **ignored entirely** in code-first mode (when an
111
+ `agent-health.config.ts` is present); `data/` is like a local `./data` database
112
+ directory, used only when the storage backend is **file** (set
113
+ `OPENSEARCH_STORAGE_*` or `storage` in your config to use a cluster instead).
114
+ - **`evals/`** is **your test source** — `.eval.js` / `.eval.ts` files you write
115
+ with the [code SDK](./SDK.md) and run with
116
+ `agent-health benchmark -f ./evals/demo.eval.js`. They are **not** stored under
117
+ `.agent-health/data/`; *running* them produces run records that land there (or
118
+ in OpenSearch).
119
+
120
+ `.agent-health/` is **gitignored** — runtime state, not source. Your `evals/` and
121
+ any committed `agent-health.config.ts` are the parts you version-control.
122
+
123
+ ## File-Based Storage (Default)
124
+
125
+ By default, Agent Health uses **file-based storage** that requires no external services. Data is stored as JSON files under the app-managed `.agent-health/data/` directory — combined with `state.json` so there is **one** gitignored, app-managed folder:
126
+
127
+ ```
128
+ .agent-health/
129
+ ├── state.json # config-v2 runtime state (UI-managed)
130
+ └── data/ # generated, disposable
131
+ ├── test-cases/ # Test case definitions
132
+ ├── benchmarks/ # Benchmark configurations
133
+ ├── runs/ # Evaluation run results
134
+ ├── analytics/ # Analytics data
135
+ └── evaluators/ # Evaluator (judge) definitions
136
+ ```
137
+
138
+ This means you can start using Agent Health immediately without setting up OpenSearch. To switch to OpenSearch storage, configure the `OPENSEARCH_STORAGE_*` environment variables (see below).
139
+
140
+ ## Environment Variables
141
+
142
+ ### AWS Credentials
143
+
144
+ Required for Claude Code agent and Bedrock judge.
145
+
146
+ | Variable | Description | Default |
147
+ |----------|-------------|---------|
148
+ | `AWS_PROFILE` | AWS profile to use | `default` |
149
+ | `AWS_REGION` | AWS region | `us-west-2` |
150
+ | `AWS_ACCESS_KEY_ID` | Explicit access key (alternative to profile) | - |
151
+ | `AWS_SECRET_ACCESS_KEY` | Explicit secret key | - |
152
+ | `AWS_SESSION_TOKEN` | Session token (for temporary credentials) | - |
153
+
154
+ **Note:** If you've run `aws configure`, credentials are auto-detected.
155
+
156
+ ### OpenSearch Storage (Optional)
157
+
158
+ Override the default file-based storage with an OpenSearch cluster for shared, production-grade persistence. Without these settings, file-based storage is used automatically.
159
+
160
+ **Basic Auth (username/password):**
161
+
162
+ | Variable | Description | Default |
163
+ |----------|-------------|---------|
164
+ | `OPENSEARCH_STORAGE_ENDPOINT` | Storage cluster URL | - |
165
+ | `OPENSEARCH_STORAGE_USERNAME` | Username | - |
166
+ | `OPENSEARCH_STORAGE_PASSWORD` | Password | - |
167
+ | `OPENSEARCH_STORAGE_TLS_SKIP_VERIFY` | Skip TLS verification | `false` |
168
+
169
+ **AWS SigV4 Auth (instead of username/password):**
170
+
171
+ | Variable | Description | Default |
172
+ |----------|-------------|---------|
173
+ | `OPENSEARCH_STORAGE_ENDPOINT` | Storage cluster URL | - |
174
+ | `OPENSEARCH_STORAGE_AUTH_TYPE` | Auth type: `none` \| `basic` \| `sigv4` (defaults to `basic` when a username/password is set) | - |
175
+ | `OPENSEARCH_STORAGE_AWS_REGION` | AWS region (required for SigV4) | - |
176
+ | `OPENSEARCH_STORAGE_AWS_PROFILE` | AWS profile name (uses default credential chain if omitted) | - |
177
+ | `OPENSEARCH_STORAGE_AWS_SERVICE` | `es` for managed OpenSearch, `aoss` for Serverless | `es` |
178
+ | `OPENSEARCH_STORAGE_TLS_SKIP_VERIFY` | Skip TLS verification | `false` |
179
+
180
+ SigV4 uses the AWS credential chain (`AWS_PROFILE`, `~/.aws/credentials`, IAM role, etc.) — no explicit access keys needed. You can also configure SigV4 via the Settings UI or the `agent-health.config.json` file.
181
+
182
+ ### OpenSearch Observability (Optional)
183
+
184
+ View agent traces and logs. Only needed for ML-Commons agent.
185
+
186
+ **Basic Auth (username/password):**
187
+
188
+ | Variable | Description | Default |
189
+ |----------|-------------|---------|
190
+ | `OPENSEARCH_LOGS_ENDPOINT` | Logs cluster URL | - |
191
+ | `OPENSEARCH_LOGS_USERNAME` | Username | - |
192
+ | `OPENSEARCH_LOGS_PASSWORD` | Password | - |
193
+ | `OPENSEARCH_LOGS_TRACES_INDEX` | Traces index pattern | `otel-v1-apm-span-*` |
194
+ | `OPENSEARCH_LOGS_INDEX` | Logs index pattern | `ml-commons-logs-*` |
195
+
196
+ **AWS SigV4 Auth (instead of username/password):**
197
+
198
+ | Variable | Description | Default |
199
+ |----------|-------------|---------|
200
+ | `OPENSEARCH_LOGS_ENDPOINT` | Logs cluster URL | - |
201
+ | `OPENSEARCH_LOGS_AUTH_TYPE` | Auth type: `none` \| `basic` \| `sigv4` (defaults to `basic` when a username/password is set) | - |
202
+ | `OPENSEARCH_LOGS_AWS_REGION` | AWS region (required for SigV4) | - |
203
+ | `OPENSEARCH_LOGS_AWS_PROFILE` | AWS profile name (uses default credential chain if omitted) | - |
204
+ | `OPENSEARCH_LOGS_AWS_SERVICE` | `es` for managed OpenSearch, `aoss` for Serverless | `es` |
205
+ | `OPENSEARCH_LOGS_TRACES_INDEX` | Traces index pattern | `otel-v1-apm-span-*` |
206
+ | `OPENSEARCH_LOGS_INDEX` | Logs index pattern | `ml-commons-logs-*` |
207
+
208
+ SigV4 authentication is also configurable via the Settings UI (select "AWS SigV4" from the Authentication Type dropdown) or the `agent-health.config.json` file.
209
+
210
+ ### Agent Endpoints (Optional)
211
+
212
+ Override default agent endpoints.
213
+
214
+ | Variable | Description | Default |
215
+ |----------|-------------|---------|
216
+ | `TRAVEL_PLANNER_ENDPOINT` | Travel Planner demo agent URL (requires OTel Demo Docker) | `http://localhost:3000` |
217
+
218
+ To configure additional agents (LangGraph, ML-Commons, HolmesGPT, Claude Code, etc.), use `agent-health.config.ts`. See [TypeScript Config File](#typescript-config-file-optional) below.
219
+
220
+ ### Debug Logging
221
+
222
+ | Variable | Description | Default |
223
+ |----------|-------------|---------|
224
+ | `DEBUG` | Enable verbose debug logging on server startup | `false` |
225
+
226
+ Debug logging can also be toggled at runtime via the Settings page "Verbose Logging" toggle or the `POST /api/debug` endpoint. When enabled, structured debug output appears in both the browser console and server terminal.
227
+
228
+ ### Advanced Settings
229
+
230
+ | Variable | Description | Default |
231
+ |----------|-------------|---------|
232
+ | `VITE_BACKEND_PORT` | Backend server port | `4001` |
233
+ | `BEDROCK_MODEL_ID` | Judge model ID | `us.anthropic.claude-sonnet-4-5-20250929-v1:0` |
234
+
235
+ ## TypeScript Config File (Optional)
236
+
237
+ Create `agent-health.config.ts` for custom agents, models, or connectors.
238
+
239
+ ### When to Use a Config File
240
+
241
+ - Adding custom agents
242
+ - Custom connectors
243
+ - CI/CD (version-controlled config)
244
+ - Custom test case locations
245
+
246
+ ### When NOT to Use a Config File
247
+
248
+ - Just running Claude Code
249
+ - Using default file-based storage (works out of the box)
250
+ - Simple storage setup (use env vars for OpenSearch)
251
+ - Quick testing with Travel Planner demo
252
+
253
+ ### Example Config
254
+
255
+ ```typescript
256
+ // agent-health.config.ts
257
+ import { defineConfig } from '@opensearch-project/agent-health';
258
+
259
+ export default defineConfig({
260
+ // Add custom agents (built-ins still work)
261
+ agents: [
262
+ {
263
+ key: 'my-agent',
264
+ name: 'My Custom Agent',
265
+ connectorType: 'rest', // or 'agui-streaming', 'langgraph', 'strands', 'subprocess'
266
+ endpoint: 'http://localhost:8080/chat',
267
+ useTraces: true,
268
+ },
269
+ ],
270
+
271
+ // Optional: OpenSearch storage for eval results (can also use env vars / the
272
+ // Settings UI). Read secrets from process.env so this file stays committable.
273
+ storage: {
274
+ endpoint: process.env.OPENSEARCH_STORAGE_ENDPOINT!,
275
+ authType: 'sigv4', // 'none' | 'basic' | 'sigv4'
276
+ awsRegion: 'us-east-1',
277
+ awsService: 'es', // 'es' (managed) | 'aoss' (serverless)
278
+ awsProfile: process.env.AWS_PROFILE,
279
+ },
280
+
281
+ // Optional: OpenSearch observability cluster for traces/logs (Traces tab).
282
+ observability: {
283
+ endpoint: process.env.OPENSEARCH_LOGS_ENDPOINT!,
284
+ authType: 'sigv4',
285
+ awsRegion: 'us-east-1',
286
+ indexes: { traces: 'otel-v1-apm-span-*', logs: 'ml-commons-logs-*' },
287
+ },
288
+
289
+ // Custom test cases location
290
+ testCases: './my-tests/*.yaml',
291
+ });
292
+ ```
293
+
294
+ > **Precedence:** an authored `agent-health.config.ts` (above) **wins** and the
295
+ > runtime state file is ignored (code-first). Without a `.ts`, the Settings UI's
296
+ > `.agent-health/state.json` is used, then `OPENSEARCH_*` env, then file-based
297
+ > fallback. See [Two modes: code-first vs UI-first](#two-modes-code-first-vs-ui-first).
298
+
299
+ ### Config File Options
300
+
301
+ | Option | Type | Description |
302
+ |--------|------|-------------|
303
+ | `agents` | `UserAgentConfig[]` | Custom agents (merged with defaults) |
304
+ | `models` | `UserModelConfig[]` | Custom models (merged with defaults) |
305
+ | `connectors` | `AgentConnector[]` | Custom connectors |
306
+ | `storage` | `StorageClusterConfig` | OpenSearch storage cluster (endpoint + auth) |
307
+ | `observability` | `ObservabilityClusterConfig` | OpenSearch traces/logs cluster (endpoint + auth + index patterns) |
308
+ | `testCases` | `string \| string[]` | Test case file patterns |
309
+ | `reporters` | `ReporterConfig[]` | Output reporters |
310
+ | `judge` | `JudgeConfig` | Judge model configuration |
311
+ | `telemetry` | `TelemetryConfig` | OTel evaluation span emission |
312
+ | `extends` | `boolean` | Extend defaults (`true`) or replace (`false`) |
313
+
314
+ ### Agent Config Options
315
+
316
+ ```typescript
317
+ interface UserAgentConfig {
318
+ key: string; // Unique identifier
319
+ name: string; // Display name
320
+ endpoint: string; // URL or command name
321
+ connectorType?: string; // 'agui-streaming', 'rest', 'langgraph', 'strands', 'subprocess', 'claude-code', 'mock'
322
+ headers?: Record<string, string>; // HTTP headers
323
+ useTraces?: boolean; // Enable trace collection
324
+ connectorConfig?: Record<string, any>; // Connector-specific config
325
+ hooks?: AgentHooks; // beforeRequest hook, etc.
326
+ description?: string; // Description
327
+ enabled?: boolean; // Enable/disable agent (default true)
328
+ }
329
+ ```
330
+
331
+ ## Built-in Agents
332
+
333
+ These agents work out of the box:
334
+
335
+ | Agent | Key | Connector | Notes |
336
+ |-------|-----|-----------|-------|
337
+ | Demo Agent | `demo` | `mock` | Simulated responses for testing |
338
+ | Claude Code | `claude-code` | `claude-code` | Requires `claude` CLI installed |
339
+ | Amazon Strands | `strands` | `strands` | Bedrock Agent Runtime (disabled by default) |
340
+ | LangGraph (REST) | `langgraph-rest` | `langgraph` | Direct REST API (disabled by default) |
341
+
342
+ ## Built-in Connectors
343
+
344
+ | Type | Protocol | Use Case |
345
+ |------|----------|----------|
346
+ | `agui-streaming` | AG-UI SSE | ML-Commons and AG-UI compatible agents |
347
+ | `rest` | HTTP POST | Simple REST APIs |
348
+ | `openai-compatible` | OpenAI Chat Completions | LiteLLM, Ollama, vLLM |
349
+ | `langgraph` | LangGraph REST `/invoke` | Non-AG-UI LangGraph instances |
350
+ | `strands` | Bedrock Agent Runtime | Amazon Strands agents (server-only) |
351
+ | `subprocess` | CLI | Generic CLI tools |
352
+ | `claude-code` | CLI | Claude Code CLI specifically |
353
+ | `mock` | In-memory | Testing and demos |
354
+
355
+ ## Configuration Hierarchy
356
+
357
+ Settings are loaded in this order (later overrides earlier):
358
+
359
+ ```
360
+ 1. Built-in defaults (lib/constants.ts)
361
+ ↓
362
+ 2. Environment variables (.env / OPENSEARCH_*)
363
+ ↓
364
+ 3. Runtime state (.agent-health/state.json) — UI-written; used only in ui-first mode
365
+ ↓
366
+ 4. agent-health.config.ts — authored; in code-first mode it WINS and the state file is ignored
367
+ ```
368
+
369
+ **Note:** For **agents/models/connectors/judge/reporters/telemetry**, the
370
+ TypeScript config (`agent-health.config.ts`) is always authoritative. For
371
+ **storage and observability** the order depends on mode — code-first: `.ts` >
372
+ `OPENSEARCH_*` env > file fallback (state ignored); ui-first:
373
+ `.agent-health/state.json` > `OPENSEARCH_*` env > file fallback. See
374
+ [Two modes: code-first vs UI-first](#two-modes-code-first-vs-ui-first).
375
+
376
+ ## Validation
377
+
378
+ Check your configuration:
379
+
380
+ ```bash
381
+ npx agent-health doctor
382
+ ```
383
+
384
+ This shows:
385
+ - Config file status
386
+ - AWS credentials
387
+ - Storage configuration
388
+ - Available agents and connectors