@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,762 @@
1
+ # Copyright OpenSearch Contributors
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Agent Health — CloudFormation template for managed observability infrastructure.
5
+ # Deploys an Amazon OpenSearch Service domain and OpenSearch Ingestion (OSIS) pipeline
6
+ # for collecting OpenTelemetry traces from AI agents.
7
+ #
8
+ # Launch Stack URL pattern (replace REGION):
9
+ # https://console.aws.amazon.com/cloudformation/home?region=REGION#/stacks/create/template?stackName=AgentHealthObservability&templateURL=https://agent-health-cfn-REGION.s3.REGION.amazonaws.com/agent-health-observability.yaml
10
+
11
+ AWSTemplateFormatVersion: '2010-09-09'
12
+ Description: >-
13
+ Agent Health Observability Stack — Amazon OpenSearch Service domain with
14
+ OpenSearch Ingestion (OSIS) pipeline for OTLP trace collection from AI agents.
15
+
16
+ # =============================================================================
17
+ # Parameters
18
+ # =============================================================================
19
+ Parameters:
20
+ DomainName:
21
+ Type: String
22
+ Default: ah-traces
23
+ Description: >-
24
+ Name for the OpenSearch Service domain. Keep ≤21 chars because OSIS
25
+ pipeline names are "${DomainName}-traces" with a 28-char max.
26
+ AllowedPattern: '[a-z][a-z0-9\-]+'
27
+ MinLength: 3
28
+ MaxLength: 21
29
+
30
+ InstanceType:
31
+ Type: String
32
+ Default: r8g.large.search
33
+ Description: OpenSearch instance type
34
+ AllowedValues:
35
+ - t3.small.search
36
+ - t3.medium.search
37
+ - r8g.large.search
38
+ - r8g.xlarge.search
39
+ - r8g.2xlarge.search
40
+
41
+ VolumeSize:
42
+ Type: Number
43
+ Default: 100
44
+ Description: EBS volume size in GB per data node
45
+ MinValue: 10
46
+ MaxValue: 1000
47
+
48
+ PipelineMinUnits:
49
+ Type: Number
50
+ Default: 1
51
+ Description: Minimum OSIS pipeline capacity units
52
+ MinValue: 1
53
+ MaxValue: 96
54
+
55
+ PipelineMaxUnits:
56
+ Type: Number
57
+ Default: 4
58
+ Description: Maximum OSIS pipeline capacity units
59
+ MinValue: 1
60
+ MaxValue: 96
61
+
62
+ AdminRoleARN:
63
+ Type: String
64
+ Description: >-
65
+ Optional IAM role ARN to grant OpenSearch all_access (e.g., your Admin role).
66
+ The domain master user is always the internal RoleMappingFunctionRole;
67
+ this parameter adds an additional role with full access via backend role mapping.
68
+ Default: ''
69
+
70
+ # =============================================================================
71
+ # Conditions
72
+ # =============================================================================
73
+ Conditions:
74
+ HasAdminRoleARN: !Not [!Equals [!Ref AdminRoleARN, '']]
75
+ # Note: Domain MasterUserARN is always RoleMappingFunctionRole (not conditional)
76
+
77
+ # =============================================================================
78
+ # Resources
79
+ # =============================================================================
80
+ Resources:
81
+
82
+ # ---------------------------------------------------------------------------
83
+ # IAM Role — FGAC Role Mapping Custom Resource (also used as MasterUserARN)
84
+ # Defined first because the OpenSearch domain references it as master user.
85
+ # ---------------------------------------------------------------------------
86
+ RoleMappingFunctionRole:
87
+ Type: AWS::IAM::Role
88
+ Properties:
89
+ RoleName: !Sub '${DomainName}-${AWS::Region}-role-mapping-cr-role'
90
+ AssumeRolePolicyDocument:
91
+ Version: '2012-10-17'
92
+ Statement:
93
+ - Effect: Allow
94
+ Principal:
95
+ Service: lambda.amazonaws.com
96
+ Action: 'sts:AssumeRole'
97
+ Policies:
98
+ - PolicyName: OpenSearchAccess
99
+ PolicyDocument:
100
+ Version: '2012-10-17'
101
+ Statement:
102
+ - Effect: Allow
103
+ Action:
104
+ - 'es:ESHttp*'
105
+ Resource:
106
+ - !Sub 'arn:aws:es:${AWS::Region}:${AWS::AccountId}:domain/${DomainName}/*'
107
+ - PolicyName: CloudWatchLogs
108
+ PolicyDocument:
109
+ Version: '2012-10-17'
110
+ Statement:
111
+ - Effect: Allow
112
+ Action:
113
+ - 'logs:CreateLogGroup'
114
+ - 'logs:CreateLogStream'
115
+ - 'logs:PutLogEvents'
116
+ Resource: !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:*'
117
+ Tags:
118
+ - Key: agent-health
119
+ Value: observability
120
+ - Key: ManagedBy
121
+ Value: AgentHealthCFN
122
+
123
+ # ---------------------------------------------------------------------------
124
+ # OpenSearch Service Domain
125
+ # ---------------------------------------------------------------------------
126
+ OpenSearchDomain:
127
+ Type: AWS::OpenSearchService::Domain
128
+ DeletionPolicy: Retain
129
+ UpdateReplacePolicy: Retain
130
+ Properties:
131
+ DomainName: !Ref DomainName
132
+ EngineVersion: OpenSearch_3.5
133
+ ClusterConfig:
134
+ InstanceType: !Ref InstanceType
135
+ InstanceCount: 3
136
+ DedicatedMasterEnabled: true
137
+ DedicatedMasterType: !Ref InstanceType
138
+ DedicatedMasterCount: 3
139
+ ZoneAwarenessEnabled: true
140
+ ZoneAwarenessConfig:
141
+ AvailabilityZoneCount: 3
142
+ EBSOptions:
143
+ EBSEnabled: true
144
+ VolumeType: gp3
145
+ VolumeSize: !Ref VolumeSize
146
+ EncryptionAtRestOptions:
147
+ Enabled: true
148
+ NodeToNodeEncryptionOptions:
149
+ Enabled: true
150
+ DomainEndpointOptions:
151
+ EnforceHTTPS: true
152
+ TLSSecurityPolicy: Policy-Min-TLS-1-2-PFS-2023-10
153
+ AdvancedSecurityOptions:
154
+ Enabled: true
155
+ InternalUserDatabaseEnabled: false
156
+ MasterUserOptions:
157
+ MasterUserARN: !GetAtt RoleMappingFunctionRole.Arn
158
+ # "Only use fine-grained access control" — open domain policy,
159
+ # all authorization is handled by the OpenSearch Security plugin (FGAC).
160
+ AccessPolicies:
161
+ Version: '2012-10-17'
162
+ Statement:
163
+ - Effect: Allow
164
+ Principal:
165
+ AWS: '*'
166
+ Action: 'es:*'
167
+ Resource: !Sub 'arn:aws:es:${AWS::Region}:${AWS::AccountId}:domain/${DomainName}/*'
168
+ Tags:
169
+ - Key: agent-health
170
+ Value: observability
171
+ - Key: ManagedBy
172
+ Value: AgentHealthCFN
173
+
174
+ # ---------------------------------------------------------------------------
175
+ # IAM Role — OSIS Pipeline Execution
176
+ # ---------------------------------------------------------------------------
177
+ OSISPipelineRole:
178
+ Type: AWS::IAM::Role
179
+ Properties:
180
+ RoleName: !Sub '${DomainName}-${AWS::Region}-osis-pipeline-role'
181
+ AssumeRolePolicyDocument:
182
+ Version: '2012-10-17'
183
+ Statement:
184
+ - Effect: Allow
185
+ Principal:
186
+ Service: osis-pipelines.amazonaws.com
187
+ Action: 'sts:AssumeRole'
188
+ Policies:
189
+ - PolicyName: OSISToOpenSearch
190
+ PolicyDocument:
191
+ Version: '2012-10-17'
192
+ Statement:
193
+ - Effect: Allow
194
+ Action:
195
+ - 'es:DescribeDomain'
196
+ - 'es:ESHttp*'
197
+ Resource:
198
+ - !Sub 'arn:aws:es:${AWS::Region}:${AWS::AccountId}:domain/${DomainName}'
199
+ - !Sub 'arn:aws:es:${AWS::Region}:${AWS::AccountId}:domain/${DomainName}/*'
200
+ Tags:
201
+ - Key: agent-health
202
+ Value: observability
203
+ - Key: ManagedBy
204
+ Value: AgentHealthCFN
205
+
206
+ # ---------------------------------------------------------------------------
207
+ # IAM Role — Ingestion (for agents pushing telemetry via SigV4)
208
+ # ---------------------------------------------------------------------------
209
+ IngestionRole:
210
+ Type: AWS::IAM::Role
211
+ Properties:
212
+ RoleName: !Sub '${DomainName}-${AWS::Region}-ingestion-role'
213
+ AssumeRolePolicyDocument:
214
+ Version: '2012-10-17'
215
+ Statement:
216
+ - Effect: Allow
217
+ Principal:
218
+ AWS: !Sub 'arn:aws:iam::${AWS::AccountId}:root'
219
+ Action: 'sts:AssumeRole'
220
+ Policies:
221
+ - PolicyName: OSISIngest
222
+ PolicyDocument:
223
+ Version: '2012-10-17'
224
+ Statement:
225
+ - Effect: Allow
226
+ Action:
227
+ - 'osis:Ingest'
228
+ Resource:
229
+ - !Sub 'arn:aws:osis:${AWS::Region}:${AWS::AccountId}:pipeline/${DomainName}-traces'
230
+ - !Sub 'arn:aws:osis:${AWS::Region}:${AWS::AccountId}:pipeline/${DomainName}-logs'
231
+ Tags:
232
+ - Key: agent-health
233
+ Value: observability
234
+ - Key: ManagedBy
235
+ Value: AgentHealthCFN
236
+
237
+ # ---------------------------------------------------------------------------
238
+ # OpenSearch Ingestion (OSIS) Pipeline — OTLP Traces → OpenSearch
239
+ # ---------------------------------------------------------------------------
240
+ OSISTracePipeline:
241
+ Type: AWS::OSIS::Pipeline
242
+ DependsOn: OpenSearchDomain
243
+ Properties:
244
+ PipelineName: !Sub '${DomainName}-traces'
245
+ MinUnits: !Ref PipelineMinUnits
246
+ MaxUnits: !Ref PipelineMaxUnits
247
+ PipelineConfigurationBody: !Sub |
248
+ version: "2"
249
+ otel-traces-entry:
250
+ source:
251
+ otel_trace_source:
252
+ path: "/${DomainName}-traces/v1/traces"
253
+ sink:
254
+ - pipeline:
255
+ name: "otel-traces-raw-pipeline"
256
+ - pipeline:
257
+ name: "otel-service-map-pipeline"
258
+ otel-traces-raw-pipeline:
259
+ source:
260
+ pipeline:
261
+ name: "otel-traces-entry"
262
+ processor:
263
+ - otel_traces:
264
+ sink:
265
+ - opensearch:
266
+ hosts:
267
+ - "https://${OpenSearchDomain.DomainEndpoint}"
268
+ index_type: trace-analytics-plain-raw
269
+ aws:
270
+ sts_role_arn: "${OSISPipelineRole.Arn}"
271
+ region: "${AWS::Region}"
272
+ otel-service-map-pipeline:
273
+ source:
274
+ pipeline:
275
+ name: "otel-traces-entry"
276
+ processor:
277
+ - service_map:
278
+ window_duration: 180
279
+ sink:
280
+ - opensearch:
281
+ hosts:
282
+ - "https://${OpenSearchDomain.DomainEndpoint}"
283
+ index_type: trace-analytics-service-map
284
+ aws:
285
+ sts_role_arn: "${OSISPipelineRole.Arn}"
286
+ region: "${AWS::Region}"
287
+ Tags:
288
+ - Key: agent-health
289
+ Value: observability
290
+ - Key: ManagedBy
291
+ Value: AgentHealthCFN
292
+
293
+ # ---------------------------------------------------------------------------
294
+ # OpenSearch Ingestion (OSIS) Pipeline — OTLP Logs → OpenSearch
295
+ # ---------------------------------------------------------------------------
296
+ OSISLogsPipeline:
297
+ Type: AWS::OSIS::Pipeline
298
+ DependsOn: OpenSearchDomain
299
+ Properties:
300
+ PipelineName: !Sub '${DomainName}-logs'
301
+ MinUnits: !Ref PipelineMinUnits
302
+ MaxUnits: !Ref PipelineMaxUnits
303
+ PipelineConfigurationBody: !Sub |
304
+ version: "2"
305
+ otel-logs-pipeline:
306
+ source:
307
+ otel_logs_source:
308
+ path: "/${DomainName}-logs/v1/logs"
309
+ sink:
310
+ - opensearch:
311
+ hosts:
312
+ - "https://${OpenSearchDomain.DomainEndpoint}"
313
+ index: "otel-logs-%{yyyy.MM.dd}"
314
+ aws:
315
+ sts_role_arn: "${OSISPipelineRole.Arn}"
316
+ region: "${AWS::Region}"
317
+ Tags:
318
+ - Key: agent-health
319
+ Value: observability
320
+ - Key: ManagedBy
321
+ Value: AgentHealthCFN
322
+
323
+ # ---------------------------------------------------------------------------
324
+ # OTLP Ingestion — API Gateway + Lambda → OpenSearch (direct)
325
+ # Provides a public HTTPS endpoint so apps can send OTLP without SigV4 auth.
326
+ # Converts OTLP JSON to trace-analytics format and bulk-indexes into OpenSearch.
327
+ # Also forwards to OSIS pipelines when available for service-map generation.
328
+ # ---------------------------------------------------------------------------
329
+ OTLPIngestLambdaRole:
330
+ Type: AWS::IAM::Role
331
+ Properties:
332
+ RoleName: !Sub '${DomainName}-${AWS::Region}-otlp-ingest-lambda-role'
333
+ AssumeRolePolicyDocument:
334
+ Version: '2012-10-17'
335
+ Statement:
336
+ - Effect: Allow
337
+ Principal:
338
+ Service: lambda.amazonaws.com
339
+ Action: 'sts:AssumeRole'
340
+ Policies:
341
+ - PolicyName: OpenSearchAccess
342
+ PolicyDocument:
343
+ Version: '2012-10-17'
344
+ Statement:
345
+ - Effect: Allow
346
+ Action:
347
+ - 'es:ESHttp*'
348
+ Resource:
349
+ - !Sub 'arn:aws:es:${AWS::Region}:${AWS::AccountId}:domain/${DomainName}/*'
350
+ - PolicyName: OSISIngest
351
+ PolicyDocument:
352
+ Version: '2012-10-17'
353
+ Statement:
354
+ - Effect: Allow
355
+ Action:
356
+ - 'osis:Ingest'
357
+ Resource:
358
+ - !Sub 'arn:aws:osis:${AWS::Region}:${AWS::AccountId}:pipeline/${DomainName}-traces'
359
+ - !Sub 'arn:aws:osis:${AWS::Region}:${AWS::AccountId}:pipeline/${DomainName}-logs'
360
+ - PolicyName: CloudWatchLogs
361
+ PolicyDocument:
362
+ Version: '2012-10-17'
363
+ Statement:
364
+ - Effect: Allow
365
+ Action:
366
+ - 'logs:CreateLogGroup'
367
+ - 'logs:CreateLogStream'
368
+ - 'logs:PutLogEvents'
369
+ Resource: !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:*'
370
+ Tags:
371
+ - Key: agent-health
372
+ Value: observability
373
+ - Key: ManagedBy
374
+ Value: AgentHealthCFN
375
+
376
+ OTLPIngestFunction:
377
+ Type: AWS::Lambda::Function
378
+ DependsOn: OpenSearchDomain
379
+ Properties:
380
+ FunctionName: !Sub '${DomainName}-otlp-ingest'
381
+ Runtime: python3.12
382
+ Handler: index.handler
383
+ Timeout: 30
384
+ MemorySize: 256
385
+ Role: !GetAtt OTLPIngestLambdaRole.Arn
386
+ Environment:
387
+ Variables:
388
+ OPENSEARCH_ENDPOINT: !Sub 'https://${OpenSearchDomain.DomainEndpoint}'
389
+ Code:
390
+ ZipFile: |
391
+ """OTLP Ingestion — converts OTLP JSON to OpenSearch trace-analytics format."""
392
+ import json
393
+ import os
394
+ import urllib.request
395
+ import hashlib
396
+ from datetime import datetime, timezone
397
+ from botocore.auth import SigV4Auth
398
+ from botocore.awsrequest import AWSRequest
399
+ from botocore.session import Session
400
+
401
+ OS_ENDPOINT = os.environ['OPENSEARCH_ENDPOINT']
402
+ REGION = os.environ.get('AWS_REGION', 'us-east-1')
403
+ session = Session()
404
+
405
+ STATUS_MAP = {0: 0, 1: 0, 2: 2} # OTLP Unset/Ok->0, Error->2
406
+ KIND_MAP = {0: 'SPAN_KIND_UNSPECIFIED', 1: 'SPAN_KIND_INTERNAL', 2: 'SPAN_KIND_SERVER',
407
+ 3: 'SPAN_KIND_CLIENT', 4: 'SPAN_KIND_PRODUCER', 5: 'SPAN_KIND_CONSUMER'}
408
+
409
+ def _creds():
410
+ c = session.get_credentials()
411
+ return c.resolve_credentials() if hasattr(c, 'resolve_credentials') else c
412
+
413
+ def _attr_value(v):
414
+ for k in ('stringValue', 'intValue', 'boolValue', 'doubleValue'):
415
+ if k in v:
416
+ return v[k]
417
+ if 'arrayValue' in v:
418
+ return [_attr_value(x) for x in v['arrayValue'].get('values', [])]
419
+ return str(v)
420
+
421
+ def _nano_to_iso(ns):
422
+ """Convert nanosecond timestamp to ISO 8601 with nanosecond precision."""
423
+ try:
424
+ ns = int(ns)
425
+ except (ValueError, TypeError):
426
+ return '1970-01-01T00:00:00.000000000Z'
427
+ secs = ns // 1_000_000_000
428
+ nanos = ns % 1_000_000_000
429
+ dt = datetime.fromtimestamp(secs, tz=timezone.utc)
430
+ return dt.strftime('%Y-%m-%dT%H:%M:%S') + f'.{nanos:09d}Z'
431
+
432
+ def _convert_span(span, resource_attrs, scope_name):
433
+ trace_id = span.get('traceId', '')
434
+ span_id = span.get('spanId', '')
435
+ parent = span.get('parentSpanId', '')
436
+ start_ns = span.get('startTimeUnixNano', '0')
437
+ end_ns = span.get('endTimeUnixNano', '0')
438
+ try:
439
+ duration_nanos = int(end_ns) - int(start_ns)
440
+ if duration_nanos < 0:
441
+ duration_nanos = 0
442
+ except (ValueError, TypeError):
443
+ duration_nanos = 0
444
+ status = span.get('status', {})
445
+ status_code = STATUS_MAP.get(status.get('code', 0), 0)
446
+ kind = KIND_MAP.get(span.get('kind', 0), 'SPAN_KIND_UNSPECIFIED')
447
+ service_name = 'unknown'
448
+ events = []
449
+ for evt in span.get('events', []):
450
+ evt_attrs = {}
451
+ for a in evt.get('attributes', []):
452
+ evt_attrs[a['key']] = _attr_value(a['value'])
453
+ events.append({
454
+ 'name': evt.get('name', ''),
455
+ 'time': _nano_to_iso(evt.get('timeUnixNano', '0')),
456
+ 'attributes': evt_attrs
457
+ })
458
+ doc = {
459
+ 'traceId': trace_id,
460
+ 'spanId': span_id,
461
+ 'parentSpanId': parent,
462
+ 'traceState': span.get('traceState', ''),
463
+ 'name': span.get('name', ''),
464
+ 'kind': kind,
465
+ 'startTime': _nano_to_iso(start_ns),
466
+ 'endTime': _nano_to_iso(end_ns),
467
+ 'durationInNanos': duration_nanos,
468
+ 'serviceName': service_name,
469
+ 'status': {'code': status_code, 'message': status.get('message', '')},
470
+ 'events': events,
471
+ 'links': [],
472
+ 'instrumentationScope': {'name': scope_name},
473
+ }
474
+ if not parent:
475
+ doc['traceGroup'] = span.get('name', '')
476
+ doc['traceGroupFields'] = {
477
+ 'endTime': _nano_to_iso(end_ns),
478
+ 'durationInNanos': duration_nanos,
479
+ 'statusCode': status_code,
480
+ }
481
+ # Resource attributes: nested resource.attributes object, literal
482
+ # dotted keys (Data Prepper trace-analytics-plain-raw / OTEL-faithful).
483
+ resource_attributes = {}
484
+ for a in resource_attrs:
485
+ val = _attr_value(a['value'])
486
+ resource_attributes[a['key']] = val
487
+ if a['key'] == 'service.name':
488
+ doc['serviceName'] = val
489
+ doc['resource'] = {'attributes': resource_attributes}
490
+ # Span attributes: nested attributes object, literal dotted keys.
491
+ span_attributes = {}
492
+ for a in span.get('attributes', []):
493
+ span_attributes[a['key']] = _attr_value(a['value'])
494
+ doc['attributes'] = span_attributes
495
+ doc_id = hashlib.md5(f'{trace_id}{span_id}'.encode()).hexdigest()
496
+ return doc_id, doc
497
+
498
+ def _signed_request(method, path, body):
499
+ url = OS_ENDPOINT + path
500
+ request = AWSRequest(method=method, url=url, data=body,
501
+ headers={'Content-Type': 'application/json'})
502
+ SigV4Auth(_creds(), 'es', REGION).add_auth(request)
503
+ req = urllib.request.Request(url, data=body.encode('utf-8'), method=method,
504
+ headers={k: v for k, v in dict(request.headers).items()})
505
+ try:
506
+ with urllib.request.urlopen(req) as resp:
507
+ return resp.status, resp.read().decode('utf-8', errors='replace')
508
+ except urllib.error.HTTPError as e:
509
+ return e.code, e.read().decode('utf-8', errors='replace')
510
+
511
+ def handler(event, context):
512
+ path = event.get('rawPath', '')
513
+ if '/v1/traces' not in path and '/v1/logs' not in path:
514
+ return {'statusCode': 404, 'body': json.dumps({'error': f'Unknown path: {path}'})}
515
+ body = event.get('body', '')
516
+ is_base64 = event.get('isBase64Encoded', False)
517
+ if is_base64:
518
+ import base64
519
+ body = base64.b64decode(body).decode('utf-8', errors='replace')
520
+ try:
521
+ otlp = json.loads(body) if isinstance(body, str) else body
522
+ except json.JSONDecodeError as e:
523
+ return {'statusCode': 400, 'body': json.dumps({'error': f'Invalid JSON: {e}'})}
524
+ bulk_lines = []
525
+ for rs in otlp.get('resourceSpans', []):
526
+ res_attrs = rs.get('resource', {}).get('attributes', [])
527
+ for ss in rs.get('scopeSpans', []):
528
+ scope_name = ss.get('scope', {}).get('name', '')
529
+ for span in ss.get('spans', []):
530
+ doc_id, doc = _convert_span(span, res_attrs, scope_name)
531
+ bulk_lines.append(json.dumps({'index': {'_index': 'otel-v1-apm-span-000001', '_id': doc_id}}))
532
+ bulk_lines.append(json.dumps(doc, default=str))
533
+ if not bulk_lines:
534
+ return {'statusCode': 200, 'body': json.dumps({'message': 'No spans to index'})}
535
+ bulk_body = '\n'.join(bulk_lines) + '\n'
536
+ status, resp_body = _signed_request('POST', '/otel-v1-apm-span-000001/_bulk', bulk_body)
537
+ return {'statusCode': status, 'body': resp_body}
538
+ Tags:
539
+ - Key: agent-health
540
+ Value: observability
541
+ - Key: ManagedBy
542
+ Value: AgentHealthCFN
543
+
544
+ # ---------------------------------------------------------------------------
545
+ # Custom Resource — Map IAM Roles to OpenSearch FGAC Backend Roles
546
+ # Maps the OSIS pipeline role and Lambda ingest role to 'all_access' so they
547
+ # can write to OpenSearch indices. Runs once during stack create/update.
548
+ # ---------------------------------------------------------------------------
549
+ RoleMappingFunction:
550
+ Type: AWS::Lambda::Function
551
+ DependsOn: OpenSearchDomain
552
+ Properties:
553
+ FunctionName: !Sub '${DomainName}-fgac-role-mapping'
554
+ Runtime: python3.12
555
+ Handler: index.handler
556
+ Timeout: 60
557
+ MemorySize: 128
558
+ Role: !GetAtt RoleMappingFunctionRole.Arn
559
+ Environment:
560
+ Variables:
561
+ OPENSEARCH_ENDPOINT: !Sub 'https://${OpenSearchDomain.DomainEndpoint}'
562
+ OSIS_ROLE_ARN: !GetAtt OSISPipelineRole.Arn
563
+ LAMBDA_ROLE_ARN: !GetAtt OTLPIngestLambdaRole.Arn
564
+ ADMIN_ROLE_ARN: !If
565
+ - HasAdminRoleARN
566
+ - !Ref AdminRoleARN
567
+ - !Sub 'arn:aws:iam::${AWS::AccountId}:root'
568
+ Code:
569
+ ZipFile: |
570
+ """Custom Resource — maps IAM role ARNs to OpenSearch all_access backend role."""
571
+ import json
572
+ import os
573
+ import urllib.request
574
+ from botocore.auth import SigV4Auth
575
+ from botocore.awsrequest import AWSRequest
576
+ from botocore.session import Session
577
+
578
+ OS_ENDPOINT = os.environ['OPENSEARCH_ENDPOINT']
579
+ REGION = os.environ.get('AWS_REGION', 'us-east-1')
580
+ OSIS_ROLE_ARN = os.environ['OSIS_ROLE_ARN']
581
+ LAMBDA_ROLE_ARN = os.environ['LAMBDA_ROLE_ARN']
582
+ ADMIN_ROLE_ARN = os.environ.get('ADMIN_ROLE_ARN', '')
583
+ session = Session()
584
+
585
+ def _creds():
586
+ c = session.get_credentials()
587
+ return c.resolve_credentials() if hasattr(c, 'resolve_credentials') else c
588
+
589
+ def _signed_request(method, path, body=None):
590
+ url = OS_ENDPOINT + path
591
+ headers = {'Content-Type': 'application/json'}
592
+ request = AWSRequest(method=method, url=url, data=body or '', headers=headers)
593
+ SigV4Auth(_creds(), 'es', REGION).add_auth(request)
594
+ req = urllib.request.Request(url, data=(body or '').encode('utf-8'), method=method,
595
+ headers={k: v for k, v in dict(request.headers).items()})
596
+ try:
597
+ with urllib.request.urlopen(req) as resp:
598
+ return resp.status, json.loads(resp.read().decode('utf-8', errors='replace'))
599
+ except urllib.error.HTTPError as e:
600
+ return e.code, json.loads(e.read().decode('utf-8', errors='replace'))
601
+
602
+ def _send_cfn_response(event, context, status, reason=''):
603
+ body = json.dumps({
604
+ 'Status': status,
605
+ 'Reason': reason or f'See CloudWatch Log Stream: {context.log_stream_name}',
606
+ 'PhysicalResourceId': context.log_stream_name,
607
+ 'StackId': event['StackId'],
608
+ 'RequestId': event['RequestId'],
609
+ 'LogicalResourceId': event['LogicalResourceId'],
610
+ })
611
+ req = urllib.request.Request(event['ResponseURL'], data=body.encode('utf-8'),
612
+ method='PUT', headers={'Content-Type': ''})
613
+ urllib.request.urlopen(req)
614
+
615
+ def handler(event, context):
616
+ print(f"Event: {json.dumps(event)}")
617
+ try:
618
+ if event['RequestType'] == 'Delete':
619
+ _send_cfn_response(event, context, 'SUCCESS')
620
+ return
621
+ # Get current mapping for all_access
622
+ status, current = _signed_request('GET', '/_plugins/_security/api/rolesmapping/all_access')
623
+ print(f"Current mapping (status={status}): {json.dumps(current)}")
624
+ if status == 200:
625
+ backend_roles = current.get('all_access', {}).get('backend_roles', [])
626
+ else:
627
+ backend_roles = []
628
+ # Add our roles if not already present
629
+ roles_to_map = [r for r in [OSIS_ROLE_ARN, LAMBDA_ROLE_ARN, ADMIN_ROLE_ARN] if r]
630
+ for role in roles_to_map:
631
+ if role not in backend_roles:
632
+ backend_roles.append(role)
633
+ # PUT the updated mapping
634
+ payload = json.dumps({'backend_roles': backend_roles})
635
+ status, resp = _signed_request('PUT', '/_plugins/_security/api/rolesmapping/all_access', payload)
636
+ print(f"PUT mapping (status={status}): {json.dumps(resp)}")
637
+ if status in (200, 201):
638
+ _send_cfn_response(event, context, 'SUCCESS')
639
+ else:
640
+ _send_cfn_response(event, context, 'FAILED', f'OpenSearch returned {status}: {json.dumps(resp)}')
641
+ except Exception as e:
642
+ print(f"Error: {e}")
643
+ _send_cfn_response(event, context, 'FAILED', str(e))
644
+ Tags:
645
+ - Key: agent-health
646
+ Value: observability
647
+ - Key: ManagedBy
648
+ Value: AgentHealthCFN
649
+
650
+ RoleMappingCustomResource:
651
+ Type: Custom::OpenSearchRoleMapping
652
+ DependsOn:
653
+ - OpenSearchDomain
654
+ - OSISPipelineRole
655
+ - OTLPIngestLambdaRole
656
+ - RoleMappingFunction
657
+ Properties:
658
+ ServiceToken: !GetAtt RoleMappingFunction.Arn
659
+ # Include role ARNs so CFN re-triggers on changes
660
+ OSISRoleArn: !GetAtt OSISPipelineRole.Arn
661
+ LambdaRoleArn: !GetAtt OTLPIngestLambdaRole.Arn
662
+ AdminRoleArn: !If
663
+ - HasAdminRoleARN
664
+ - !Ref AdminRoleARN
665
+ - !Sub 'arn:aws:iam::${AWS::AccountId}:root'
666
+
667
+ OTLPIngestApi:
668
+ Type: AWS::ApiGatewayV2::Api
669
+ Properties:
670
+ Name: !Sub '${DomainName}-otlp-ingest'
671
+ ProtocolType: HTTP
672
+ CorsConfiguration:
673
+ AllowOrigins:
674
+ - '*'
675
+ AllowMethods:
676
+ - POST
677
+ AllowHeaders:
678
+ - content-type
679
+ Tags:
680
+ agent-health: observability
681
+ ManagedBy: AgentHealthCFN
682
+
683
+ OTLPIngestApiIntegration:
684
+ Type: AWS::ApiGatewayV2::Integration
685
+ Properties:
686
+ ApiId: !Ref OTLPIngestApi
687
+ IntegrationType: AWS_PROXY
688
+ IntegrationUri: !GetAtt OTLPIngestFunction.Arn
689
+ PayloadFormatVersion: '2.0'
690
+
691
+ OTLPIngestApiRoute:
692
+ Type: AWS::ApiGatewayV2::Route
693
+ Properties:
694
+ ApiId: !Ref OTLPIngestApi
695
+ RouteKey: 'POST /v1/{signal+}'
696
+ Target: !Sub 'integrations/${OTLPIngestApiIntegration}'
697
+
698
+ OTLPIngestApiStage:
699
+ Type: AWS::ApiGatewayV2::Stage
700
+ Properties:
701
+ ApiId: !Ref OTLPIngestApi
702
+ StageName: '$default'
703
+ AutoDeploy: true
704
+
705
+ OTLPIngestApiPermission:
706
+ Type: AWS::Lambda::Permission
707
+ Properties:
708
+ FunctionName: !Ref OTLPIngestFunction
709
+ Action: 'lambda:InvokeFunction'
710
+ Principal: apigateway.amazonaws.com
711
+ SourceArn: !Sub 'arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${OTLPIngestApi}/*'
712
+
713
+ # =============================================================================
714
+ # Outputs
715
+ # =============================================================================
716
+ Outputs:
717
+ OpenSearchEndpoint:
718
+ Description: OpenSearch domain endpoint URL
719
+ Value: !Sub 'https://${OpenSearchDomain.DomainEndpoint}'
720
+
721
+ OSISTraceIngestEndpoint:
722
+ Description: OSIS trace ingest endpoint (configure as OTEL_EXPORTER_OTLP_TRACES_ENDPOINT in your agent)
723
+ Value: !Join
724
+ - ''
725
+ - - 'https://'
726
+ - !Select [0, !GetAtt OSISTracePipeline.IngestEndpointUrls]
727
+
728
+ OSISLogsIngestEndpoint:
729
+ Description: OSIS logs ingest endpoint (configure as OTEL_EXPORTER_OTLP_LOGS_ENDPOINT in your agent)
730
+ Value: !Join
731
+ - ''
732
+ - - 'https://'
733
+ - !Select [0, !GetAtt OSISLogsPipeline.IngestEndpointUrls]
734
+
735
+ Region:
736
+ Description: AWS Region where the stack was deployed
737
+ Value: !Ref 'AWS::Region'
738
+
739
+ IngestionRoleArn:
740
+ Description: IAM role ARN for agents to assume when pushing telemetry via SigV4
741
+ Value: !GetAtt IngestionRole.Arn
742
+
743
+ OTLPIngestEndpoint:
744
+ Description: >-
745
+ HTTPS endpoint for OTLP trace/log ingestion (no SigV4 needed on client).
746
+ Set OTEL_EXPORTER_OTLP_ENDPOINT to this value in your agent config.
747
+ Value: !Sub 'https://${OTLPIngestApi}.execute-api.${AWS::Region}.amazonaws.com'
748
+
749
+ AgentHealthConfigJSON:
750
+ Description: >-
751
+ Copy this JSON block into your agent-health.config.json file,
752
+ or run: npx @opensearch-project/agent-health configure --from-stack AgentHealthObservability
753
+ Value: !Sub |
754
+ {
755
+ "observability": {
756
+ "endpoint": "https://${OpenSearchDomain.DomainEndpoint}",
757
+ "authType": "sigv4",
758
+ "awsRegion": "${AWS::Region}",
759
+ "awsService": "es",
760
+ "tlsSkipVerify": false
761
+ }
762
+ }