@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.
- package/README.md +77 -6
- package/cli/dist/index.js +10072 -4502
- package/deployment/cloudformation/agent-health-observability.yaml +762 -0
- package/dist/assets/index-CCQRDlO0.js +243 -0
- package/dist/assets/index-CNHQVbcj.css +1 -0
- package/dist/index.html +2 -2
- package/docs/ARCHITECTURE.md +450 -0
- package/docs/BACKEND_JOB_QUEUE.md +405 -0
- package/docs/CLAUDE_CODE_TELEMETRY.md +283 -0
- package/docs/CLI.md +431 -0
- package/docs/CODING_AGENT_ANALYTICS.md +298 -0
- package/docs/CONFIGURATION.md +388 -0
- package/docs/CONNECTORS.md +536 -0
- package/docs/INSTRUMENT_WITH_OTEL.md +390 -0
- package/docs/ML-COMMONS-SETUP.md +289 -0
- package/docs/NPX_PACKAGING.md +195 -0
- package/docs/PERFORMANCE-MONITORING.md +200 -0
- package/docs/PERFORMANCE.md +390 -0
- package/docs/PI_PROFILING.md +169 -0
- package/docs/PLAN-non-agui-agent-support.md +525 -0
- package/docs/SDK.md +577 -0
- package/docs/SKILLS.md +264 -0
- package/docs/blogs/2026-02-28-opensearch-agent-health.md +200 -0
- package/docs/blogs/getting-started-blog.md +608 -0
- package/docs/diagrams/Agent-health.excalidraw +5656 -0
- package/docs/diagrams/architecture.png +0 -0
- package/docs/plans/field-redesign.md +468 -0
- package/docs/rfcs/001-coding-agent-analytics.md +374 -0
- package/docs/rfcs/002-enterprise-leaderboard.md +267 -0
- package/docs/rfcs/003-remote-aggregation.md +146 -0
- package/docs/rfcs/004-test-sdk-v2.md +599 -0
- package/docs/skills/AGENT_HEALTH.md +598 -0
- package/docs/skills/AGENT_PROFILE.md +191 -0
- package/docs/skills/add-connector/SKILL.md +68 -0
- package/docs/skills/agent-health-profile/SKILL.md +40 -0
- package/docs/skills/config-auth/SKILL.md +194 -0
- package/docs/skills/config-auth/evals/evals.json +35 -0
- package/docs/skills/create-pr/SKILL.md +73 -0
- package/docs/skills/instrument-otel/SKILL.md +84 -0
- package/docs/skills/write-test/SKILL.md +124 -0
- package/docs/ui prd.md +376 -0
- package/examples/README.md +53 -0
- package/examples/config/agent-health.config.example.ts +155 -0
- package/examples/connectors/echo-connector.ts +131 -0
- package/examples/eval-files/demo.eval.js +128 -0
- package/examples/eval-files/sdk-hooks-demo.eval.js +99 -0
- package/examples/pi-profiling/README.md +77 -0
- package/examples/pi-profiling/agent-health-profile.ts +417 -0
- package/lib/dist/lib/agentUtils.d.ts +29 -0
- package/lib/dist/lib/agentUtils.d.ts.map +1 -0
- package/lib/dist/lib/agentUtils.js +43 -0
- package/lib/dist/lib/agentUtils.js.map +1 -0
- package/lib/dist/lib/benchmarkExport.d.ts +14 -0
- package/lib/dist/lib/benchmarkExport.d.ts.map +1 -0
- package/lib/dist/lib/benchmarkExport.js +41 -0
- package/lib/dist/lib/benchmarkExport.js.map +1 -0
- package/lib/dist/lib/benchmarkVersionUtils.d.ts +37 -0
- package/lib/dist/lib/benchmarkVersionUtils.d.ts.map +1 -0
- package/lib/dist/lib/benchmarkVersionUtils.js +68 -0
- package/lib/dist/lib/benchmarkVersionUtils.js.map +1 -0
- package/lib/dist/lib/config/defineConfig.d.ts +27 -0
- package/lib/dist/lib/config/defineConfig.d.ts.map +1 -0
- package/lib/dist/lib/config/defineConfig.js +28 -0
- package/lib/dist/lib/config/defineConfig.js.map +1 -0
- package/lib/dist/lib/config/index.d.ts +9 -0
- package/lib/dist/lib/config/index.d.ts.map +1 -0
- package/lib/dist/lib/config/index.js +8 -0
- package/lib/dist/lib/config/index.js.map +1 -0
- package/lib/dist/lib/config/loader.d.ts +39 -0
- package/lib/dist/lib/config/loader.d.ts.map +1 -0
- package/lib/dist/lib/config/loader.js +258 -0
- package/lib/dist/lib/config/loader.js.map +1 -0
- package/lib/dist/lib/config/statePaths.d.ts +61 -0
- package/lib/dist/lib/config/statePaths.d.ts.map +1 -0
- package/lib/dist/lib/config/statePaths.js +188 -0
- package/lib/dist/lib/config/statePaths.js.map +1 -0
- package/lib/dist/lib/config/types.d.ts +231 -0
- package/lib/dist/lib/config/types.d.ts.map +1 -0
- package/lib/dist/lib/config/types.js +6 -0
- package/lib/dist/lib/config/types.js.map +1 -0
- package/lib/dist/lib/config.d.ts +39 -0
- package/lib/dist/lib/config.d.ts.map +1 -0
- package/lib/dist/lib/config.js +118 -0
- package/lib/dist/lib/config.js.map +1 -0
- package/lib/dist/lib/constants.d.ts +70 -0
- package/lib/dist/lib/constants.d.ts.map +1 -0
- package/lib/dist/lib/constants.js +365 -0
- package/lib/dist/lib/constants.js.map +1 -0
- package/lib/dist/lib/contextUtilization.d.ts +23 -0
- package/lib/dist/lib/contextUtilization.d.ts.map +1 -0
- package/lib/dist/lib/contextUtilization.js +72 -0
- package/lib/dist/lib/contextUtilization.js.map +1 -0
- package/lib/dist/lib/dashboardMetrics.d.ts +87 -0
- package/lib/dist/lib/dashboardMetrics.d.ts.map +1 -0
- package/lib/dist/lib/dashboardMetrics.js +242 -0
- package/lib/dist/lib/dashboardMetrics.js.map +1 -0
- package/lib/dist/lib/dataSourceConfig.d.ts +108 -0
- package/lib/dist/lib/dataSourceConfig.d.ts.map +1 -0
- package/lib/dist/lib/dataSourceConfig.js +166 -0
- package/lib/dist/lib/dataSourceConfig.js.map +1 -0
- package/lib/dist/lib/debug.d.ts +26 -0
- package/lib/dist/lib/debug.d.ts.map +1 -0
- package/lib/dist/lib/debug.js +132 -0
- package/lib/dist/lib/debug.js.map +1 -0
- package/lib/dist/lib/diagnostics.d.ts +28 -0
- package/lib/dist/lib/diagnostics.d.ts.map +1 -0
- package/lib/dist/lib/diagnostics.js +65 -0
- package/lib/dist/lib/diagnostics.js.map +1 -0
- package/lib/dist/lib/envCompat.d.ts +27 -0
- package/lib/dist/lib/envCompat.d.ts.map +1 -0
- package/lib/dist/lib/envCompat.js +73 -0
- package/lib/dist/lib/envCompat.js.map +1 -0
- package/lib/dist/lib/findPackageRoot.d.ts +7 -0
- package/lib/dist/lib/findPackageRoot.d.ts.map +1 -0
- package/lib/dist/lib/findPackageRoot.js +57 -0
- package/lib/dist/lib/findPackageRoot.js.map +1 -0
- package/lib/dist/lib/hooks.d.ts +36 -0
- package/lib/dist/lib/hooks.d.ts.map +1 -0
- package/lib/dist/lib/hooks.js +112 -0
- package/lib/dist/lib/hooks.js.map +1 -0
- package/lib/dist/lib/index.d.ts +47 -0
- package/lib/dist/lib/index.d.ts.map +1 -0
- package/lib/dist/lib/index.js +62 -0
- package/lib/dist/lib/index.js.map +1 -0
- package/lib/dist/lib/labels.d.ts +90 -0
- package/lib/dist/lib/labels.d.ts.map +1 -0
- package/lib/dist/lib/labels.js +158 -0
- package/lib/dist/lib/labels.js.map +1 -0
- package/lib/dist/lib/markdown.d.ts +16 -0
- package/lib/dist/lib/markdown.d.ts.map +1 -0
- package/lib/dist/lib/markdown.js +42 -0
- package/lib/dist/lib/markdown.js.map +1 -0
- package/lib/dist/lib/matchers/expect.d.ts +3 -0
- package/lib/dist/lib/matchers/expect.d.ts.map +1 -0
- package/lib/dist/lib/matchers/expect.js +225 -0
- package/lib/dist/lib/matchers/expect.js.map +1 -0
- package/lib/dist/lib/matchers/index.d.ts +8 -0
- package/lib/dist/lib/matchers/index.d.ts.map +1 -0
- package/lib/dist/lib/matchers/index.js +9 -0
- package/lib/dist/lib/matchers/index.js.map +1 -0
- package/lib/dist/lib/matchers/judgeAccessor.d.ts +113 -0
- package/lib/dist/lib/matchers/judgeAccessor.d.ts.map +1 -0
- package/lib/dist/lib/matchers/judgeAccessor.js +183 -0
- package/lib/dist/lib/matchers/judgeAccessor.js.map +1 -0
- package/lib/dist/lib/matchers/session.d.ts +39 -0
- package/lib/dist/lib/matchers/session.d.ts.map +1 -0
- package/lib/dist/lib/matchers/session.js +116 -0
- package/lib/dist/lib/matchers/session.js.map +1 -0
- package/lib/dist/lib/matchers/traces.d.ts +55 -0
- package/lib/dist/lib/matchers/traces.d.ts.map +1 -0
- package/lib/dist/lib/matchers/traces.js +116 -0
- package/lib/dist/lib/matchers/traces.js.map +1 -0
- package/lib/dist/lib/matchers/types.d.ts +75 -0
- package/lib/dist/lib/matchers/types.d.ts.map +1 -0
- package/lib/dist/lib/matchers/types.js +6 -0
- package/lib/dist/lib/matchers/types.js.map +1 -0
- package/lib/dist/lib/packagePaths.d.ts +29 -0
- package/lib/dist/lib/packagePaths.d.ts.map +1 -0
- package/lib/dist/lib/packagePaths.js +63 -0
- package/lib/dist/lib/packagePaths.js.map +1 -0
- package/lib/dist/lib/performance.d.ts +51 -0
- package/lib/dist/lib/performance.d.ts.map +1 -0
- package/lib/dist/lib/performance.js +159 -0
- package/lib/dist/lib/performance.js.map +1 -0
- package/lib/dist/lib/portConfig.d.ts +29 -0
- package/lib/dist/lib/portConfig.d.ts.map +1 -0
- package/lib/dist/lib/portConfig.js +64 -0
- package/lib/dist/lib/portConfig.js.map +1 -0
- package/lib/dist/lib/preferences.d.ts +63 -0
- package/lib/dist/lib/preferences.d.ts.map +1 -0
- package/lib/dist/lib/preferences.js +117 -0
- package/lib/dist/lib/preferences.js.map +1 -0
- package/lib/dist/lib/resolveAgentModel.d.ts +22 -0
- package/lib/dist/lib/resolveAgentModel.d.ts.map +1 -0
- package/lib/dist/lib/resolveAgentModel.js +37 -0
- package/lib/dist/lib/resolveAgentModel.js.map +1 -0
- package/lib/dist/lib/runStats.d.ts +92 -0
- package/lib/dist/lib/runStats.d.ts.map +1 -0
- package/lib/dist/lib/runStats.js +160 -0
- package/lib/dist/lib/runStats.js.map +1 -0
- package/lib/dist/lib/telemetry/constants.d.ts +60 -0
- package/lib/dist/lib/telemetry/constants.d.ts.map +1 -0
- package/lib/dist/lib/telemetry/constants.js +87 -0
- package/lib/dist/lib/telemetry/constants.js.map +1 -0
- package/lib/dist/lib/telemetry/evalSpans.d.ts +61 -0
- package/lib/dist/lib/telemetry/evalSpans.d.ts.map +1 -0
- package/lib/dist/lib/telemetry/evalSpans.js +254 -0
- package/lib/dist/lib/telemetry/evalSpans.js.map +1 -0
- package/lib/dist/lib/telemetry/index.d.ts +11 -0
- package/lib/dist/lib/telemetry/index.d.ts.map +1 -0
- package/lib/dist/lib/telemetry/index.js +15 -0
- package/lib/dist/lib/telemetry/index.js.map +1 -0
- package/lib/dist/lib/telemetry/opensearchExporter.d.ts +43 -0
- package/lib/dist/lib/telemetry/opensearchExporter.d.ts.map +1 -0
- package/lib/dist/lib/telemetry/opensearchExporter.js +217 -0
- package/lib/dist/lib/telemetry/opensearchExporter.js.map +1 -0
- package/lib/dist/lib/telemetry/provider.d.ts +55 -0
- package/lib/dist/lib/telemetry/provider.d.ts.map +1 -0
- package/lib/dist/lib/telemetry/provider.js +140 -0
- package/lib/dist/lib/telemetry/provider.js.map +1 -0
- package/lib/dist/lib/testCaseLabels.d.ts +34 -0
- package/lib/dist/lib/testCaseLabels.d.ts.map +1 -0
- package/lib/dist/lib/testCaseLabels.js +88 -0
- package/lib/dist/lib/testCaseLabels.js.map +1 -0
- package/lib/dist/lib/testCaseValidation.d.ts +140 -0
- package/lib/dist/lib/testCaseValidation.d.ts.map +1 -0
- package/lib/dist/lib/testCaseValidation.js +162 -0
- package/lib/dist/lib/testCaseValidation.js.map +1 -0
- package/lib/dist/lib/testCases/agentFixture.d.ts +80 -0
- package/lib/dist/lib/testCases/agentFixture.d.ts.map +1 -0
- package/lib/dist/lib/testCases/agentFixture.js +43 -0
- package/lib/dist/lib/testCases/agentFixture.js.map +1 -0
- package/lib/dist/lib/testCases/authoringSurface.d.ts +10 -0
- package/lib/dist/lib/testCases/authoringSurface.d.ts.map +1 -0
- package/lib/dist/lib/testCases/authoringSurface.js +54 -0
- package/lib/dist/lib/testCases/authoringSurface.js.map +1 -0
- package/lib/dist/lib/testCases/codemod.d.ts +13 -0
- package/lib/dist/lib/testCases/codemod.d.ts.map +1 -0
- package/lib/dist/lib/testCases/codemod.js +169 -0
- package/lib/dist/lib/testCases/codemod.js.map +1 -0
- package/lib/dist/lib/testCases/define.d.ts +114 -0
- package/lib/dist/lib/testCases/define.d.ts.map +1 -0
- package/lib/dist/lib/testCases/define.js +253 -0
- package/lib/dist/lib/testCases/define.js.map +1 -0
- package/lib/dist/lib/testCases/evaluators.d.ts +80 -0
- package/lib/dist/lib/testCases/evaluators.d.ts.map +1 -0
- package/lib/dist/lib/testCases/evaluators.js +105 -0
- package/lib/dist/lib/testCases/evaluators.js.map +1 -0
- package/lib/dist/lib/testCases/index.d.ts +14 -0
- package/lib/dist/lib/testCases/index.d.ts.map +1 -0
- package/lib/dist/lib/testCases/index.js +12 -0
- package/lib/dist/lib/testCases/index.js.map +1 -0
- package/lib/dist/lib/testCases/judge.d.ts +165 -0
- package/lib/dist/lib/testCases/judge.d.ts.map +1 -0
- package/lib/dist/lib/testCases/judge.js +359 -0
- package/lib/dist/lib/testCases/judge.js.map +1 -0
- package/lib/dist/lib/testCases/loader.d.ts +26 -0
- package/lib/dist/lib/testCases/loader.d.ts.map +1 -0
- package/lib/dist/lib/testCases/loader.js +149 -0
- package/lib/dist/lib/testCases/loader.js.map +1 -0
- package/lib/dist/lib/testCases/types.d.ts +242 -0
- package/lib/dist/lib/testCases/types.d.ts.map +1 -0
- package/lib/dist/lib/testCases/types.js +6 -0
- package/lib/dist/lib/testCases/types.js.map +1 -0
- package/lib/dist/lib/theme.d.ts +6 -0
- package/lib/dist/lib/theme.d.ts.map +1 -0
- package/lib/dist/lib/theme.js +36 -0
- package/lib/dist/lib/theme.js.map +1 -0
- package/lib/dist/lib/uiTelemetry.d.ts +7 -0
- package/lib/dist/lib/uiTelemetry.d.ts.map +1 -0
- package/lib/dist/lib/uiTelemetry.js +25 -0
- package/lib/dist/lib/uiTelemetry.js.map +1 -0
- package/lib/dist/lib/utils.d.ts +96 -0
- package/lib/dist/lib/utils.d.ts.map +1 -0
- package/lib/dist/lib/utils.js +232 -0
- package/lib/dist/lib/utils.js.map +1 -0
- package/lib/dist/lib/workflow/consolidate.d.ts +12 -0
- package/lib/dist/lib/workflow/consolidate.d.ts.map +1 -0
- package/lib/dist/lib/workflow/consolidate.js +33 -0
- package/lib/dist/lib/workflow/consolidate.js.map +1 -0
- package/lib/dist/lib/workflow/index.d.ts +13 -0
- package/lib/dist/lib/workflow/index.d.ts.map +1 -0
- package/lib/dist/lib/workflow/index.js +12 -0
- package/lib/dist/lib/workflow/index.js.map +1 -0
- package/lib/dist/lib/workflow/ledger.d.ts +30 -0
- package/lib/dist/lib/workflow/ledger.d.ts.map +1 -0
- package/lib/dist/lib/workflow/ledger.js +41 -0
- package/lib/dist/lib/workflow/ledger.js.map +1 -0
- package/lib/dist/lib/workflow/pool.d.ts +13 -0
- package/lib/dist/lib/workflow/pool.d.ts.map +1 -0
- package/lib/dist/lib/workflow/pool.js +44 -0
- package/lib/dist/lib/workflow/pool.js.map +1 -0
- package/lib/dist/lib/workflow/source.d.ts +22 -0
- package/lib/dist/lib/workflow/source.d.ts.map +1 -0
- package/lib/dist/lib/workflow/source.js +29 -0
- package/lib/dist/lib/workflow/source.js.map +1 -0
- package/lib/dist/lib/workflow/stepB.d.ts +71 -0
- package/lib/dist/lib/workflow/stepB.d.ts.map +1 -0
- package/lib/dist/lib/workflow/stepB.js +99 -0
- package/lib/dist/lib/workflow/stepB.js.map +1 -0
- package/lib/dist/lib/workflow/types.d.ts +86 -0
- package/lib/dist/lib/workflow/types.d.ts.map +1 -0
- package/lib/dist/lib/workflow/types.js +6 -0
- package/lib/dist/lib/workflow/types.js.map +1 -0
- package/lib/dist/lib/workflow/workflow.d.ts +119 -0
- package/lib/dist/lib/workflow/workflow.d.ts.map +1 -0
- package/lib/dist/lib/workflow/workflow.js +195 -0
- package/lib/dist/lib/workflow/workflow.js.map +1 -0
- package/lib/dist/services/agent/aguiConverter.d.ts +50 -0
- package/lib/dist/services/agent/aguiConverter.d.ts.map +1 -0
- package/lib/dist/services/agent/aguiConverter.js +449 -0
- package/lib/dist/services/agent/aguiConverter.js.map +1 -0
- package/lib/dist/services/agent/index.d.ts +10 -0
- package/lib/dist/services/agent/index.d.ts.map +1 -0
- package/lib/dist/services/agent/index.js +12 -0
- package/lib/dist/services/agent/index.js.map +1 -0
- package/lib/dist/services/agent/payloadBuilder.d.ts +33 -0
- package/lib/dist/services/agent/payloadBuilder.d.ts.map +1 -0
- package/lib/dist/services/agent/payloadBuilder.js +75 -0
- package/lib/dist/services/agent/payloadBuilder.js.map +1 -0
- package/lib/dist/services/agent/sseStream.d.ts +43 -0
- package/lib/dist/services/agent/sseStream.d.ts.map +1 -0
- package/lib/dist/services/agent/sseStream.js +223 -0
- package/lib/dist/services/agent/sseStream.js.map +1 -0
- package/lib/dist/services/connectors/agui/AGUIStreamingConnector.d.ts +44 -0
- package/lib/dist/services/connectors/agui/AGUIStreamingConnector.d.ts.map +1 -0
- package/lib/dist/services/connectors/agui/AGUIStreamingConnector.js +95 -0
- package/lib/dist/services/connectors/agui/AGUIStreamingConnector.js.map +1 -0
- package/lib/dist/services/connectors/base/BaseConnector.d.ts +81 -0
- package/lib/dist/services/connectors/base/BaseConnector.d.ts.map +1 -0
- package/lib/dist/services/connectors/base/BaseConnector.js +170 -0
- package/lib/dist/services/connectors/base/BaseConnector.js.map +1 -0
- package/lib/dist/services/connectors/claude-code/ClaudeCodeConnector.d.ts +116 -0
- package/lib/dist/services/connectors/claude-code/ClaudeCodeConnector.d.ts.map +1 -0
- package/lib/dist/services/connectors/claude-code/ClaudeCodeConnector.js +403 -0
- package/lib/dist/services/connectors/claude-code/ClaudeCodeConnector.js.map +1 -0
- package/lib/dist/services/connectors/index.d.ts +13 -0
- package/lib/dist/services/connectors/index.d.ts.map +1 -0
- package/lib/dist/services/connectors/index.js +32 -0
- package/lib/dist/services/connectors/index.js.map +1 -0
- package/lib/dist/services/connectors/kiro/KiroConnector.d.ts +48 -0
- package/lib/dist/services/connectors/kiro/KiroConnector.d.ts.map +1 -0
- package/lib/dist/services/connectors/kiro/KiroConnector.js +158 -0
- package/lib/dist/services/connectors/kiro/KiroConnector.js.map +1 -0
- package/lib/dist/services/connectors/langgraph/LangGraphConnector.d.ts +36 -0
- package/lib/dist/services/connectors/langgraph/LangGraphConnector.d.ts.map +1 -0
- package/lib/dist/services/connectors/langgraph/LangGraphConnector.js +175 -0
- package/lib/dist/services/connectors/langgraph/LangGraphConnector.js.map +1 -0
- package/lib/dist/services/connectors/mock/MockConnector.d.ts +37 -0
- package/lib/dist/services/connectors/mock/MockConnector.d.ts.map +1 -0
- package/lib/dist/services/connectors/mock/MockConnector.js +120 -0
- package/lib/dist/services/connectors/mock/MockConnector.js.map +1 -0
- package/lib/dist/services/connectors/openai-compatible/OpenAICompatibleConnector.d.ts +42 -0
- package/lib/dist/services/connectors/openai-compatible/OpenAICompatibleConnector.d.ts.map +1 -0
- package/lib/dist/services/connectors/openai-compatible/OpenAICompatibleConnector.js +133 -0
- package/lib/dist/services/connectors/openai-compatible/OpenAICompatibleConnector.js.map +1 -0
- package/lib/dist/services/connectors/pi/PiConnector.d.ts +87 -0
- package/lib/dist/services/connectors/pi/PiConnector.d.ts.map +1 -0
- package/lib/dist/services/connectors/pi/PiConnector.js +274 -0
- package/lib/dist/services/connectors/pi/PiConnector.js.map +1 -0
- package/lib/dist/services/connectors/registry.d.ts +57 -0
- package/lib/dist/services/connectors/registry.d.ts.map +1 -0
- package/lib/dist/services/connectors/registry.js +106 -0
- package/lib/dist/services/connectors/registry.js.map +1 -0
- package/lib/dist/services/connectors/rest/RESTConnector.d.ts +38 -0
- package/lib/dist/services/connectors/rest/RESTConnector.d.ts.map +1 -0
- package/lib/dist/services/connectors/rest/RESTConnector.js +117 -0
- package/lib/dist/services/connectors/rest/RESTConnector.js.map +1 -0
- package/lib/dist/services/connectors/server.d.ts +13 -0
- package/lib/dist/services/connectors/server.d.ts.map +1 -0
- package/lib/dist/services/connectors/server.js +34 -0
- package/lib/dist/services/connectors/server.js.map +1 -0
- package/lib/dist/services/connectors/strands/StrandsConnector.d.ts +48 -0
- package/lib/dist/services/connectors/strands/StrandsConnector.d.ts.map +1 -0
- package/lib/dist/services/connectors/strands/StrandsConnector.js +221 -0
- package/lib/dist/services/connectors/strands/StrandsConnector.js.map +1 -0
- package/lib/dist/services/connectors/subprocess/SubprocessConnector.d.ts +88 -0
- package/lib/dist/services/connectors/subprocess/SubprocessConnector.d.ts.map +1 -0
- package/lib/dist/services/connectors/subprocess/SubprocessConnector.js +418 -0
- package/lib/dist/services/connectors/subprocess/SubprocessConnector.js.map +1 -0
- package/lib/dist/services/connectors/types.d.ts +213 -0
- package/lib/dist/services/connectors/types.d.ts.map +1 -0
- package/lib/dist/services/connectors/types.js +6 -0
- package/lib/dist/services/connectors/types.js.map +1 -0
- package/lib/dist/services/evaluation/bedrockJudge.d.ts +64 -0
- package/lib/dist/services/evaluation/bedrockJudge.d.ts.map +1 -0
- package/lib/dist/services/evaluation/bedrockJudge.js +167 -0
- package/lib/dist/services/evaluation/bedrockJudge.js.map +1 -0
- package/lib/dist/services/evaluation/evaluatorError.d.ts +56 -0
- package/lib/dist/services/evaluation/evaluatorError.d.ts.map +1 -0
- package/lib/dist/services/evaluation/evaluatorError.js +56 -0
- package/lib/dist/services/evaluation/evaluatorError.js.map +1 -0
- package/lib/dist/services/evaluation/index.d.ts +106 -0
- package/lib/dist/services/evaluation/index.d.ts.map +1 -0
- package/lib/dist/services/evaluation/index.js +684 -0
- package/lib/dist/services/evaluation/index.js.map +1 -0
- package/lib/dist/services/evaluation/mockTrajectory.d.ts +3 -0
- package/lib/dist/services/evaluation/mockTrajectory.d.ts.map +1 -0
- package/lib/dist/services/evaluation/mockTrajectory.js +72 -0
- package/lib/dist/services/evaluation/mockTrajectory.js.map +1 -0
- package/lib/dist/services/opensearch/client.d.ts +26 -0
- package/lib/dist/services/opensearch/client.d.ts.map +1 -0
- package/lib/dist/services/opensearch/client.js +131 -0
- package/lib/dist/services/opensearch/client.js.map +1 -0
- package/lib/dist/services/opensearch/index.d.ts +16 -0
- package/lib/dist/services/opensearch/index.d.ts.map +1 -0
- package/lib/dist/services/opensearch/index.js +25 -0
- package/lib/dist/services/opensearch/index.js.map +1 -0
- package/lib/dist/services/storage/asyncBenchmarkStorage.d.ts +123 -0
- package/lib/dist/services/storage/asyncBenchmarkStorage.d.ts.map +1 -0
- package/lib/dist/services/storage/asyncBenchmarkStorage.js +429 -0
- package/lib/dist/services/storage/asyncBenchmarkStorage.js.map +1 -0
- package/lib/dist/services/storage/asyncRunStorage.d.ts +127 -0
- package/lib/dist/services/storage/asyncRunStorage.d.ts.map +1 -0
- package/lib/dist/services/storage/asyncRunStorage.js +448 -0
- package/lib/dist/services/storage/asyncRunStorage.js.map +1 -0
- package/lib/dist/services/storage/asyncTestCaseStorage.d.ts +156 -0
- package/lib/dist/services/storage/asyncTestCaseStorage.d.ts.map +1 -0
- package/lib/dist/services/storage/asyncTestCaseStorage.js +285 -0
- package/lib/dist/services/storage/asyncTestCaseStorage.js.map +1 -0
- package/lib/dist/services/storage/index.d.ts +17 -0
- package/lib/dist/services/storage/index.d.ts.map +1 -0
- package/lib/dist/services/storage/index.js +20 -0
- package/lib/dist/services/storage/index.js.map +1 -0
- package/lib/dist/services/storage/migration.d.ts +54 -0
- package/lib/dist/services/storage/migration.d.ts.map +1 -0
- package/lib/dist/services/storage/migration.js +296 -0
- package/lib/dist/services/storage/migration.js.map +1 -0
- package/lib/dist/services/storage/opensearchClient.d.ts +924 -0
- package/lib/dist/services/storage/opensearchClient.d.ts.map +1 -0
- package/lib/dist/services/storage/opensearchClient.js +435 -0
- package/lib/dist/services/storage/opensearchClient.js.map +1 -0
- package/lib/dist/services/traces/browserRecovery.d.ts +26 -0
- package/lib/dist/services/traces/browserRecovery.d.ts.map +1 -0
- package/lib/dist/services/traces/browserRecovery.js +81 -0
- package/lib/dist/services/traces/browserRecovery.js.map +1 -0
- package/lib/dist/services/traces/categoryStyles.d.ts +21 -0
- package/lib/dist/services/traces/categoryStyles.d.ts.map +1 -0
- package/lib/dist/services/traces/categoryStyles.js +56 -0
- package/lib/dist/services/traces/categoryStyles.js.map +1 -0
- package/lib/dist/services/traces/executionOrderTransform.d.ts +35 -0
- package/lib/dist/services/traces/executionOrderTransform.d.ts.map +1 -0
- package/lib/dist/services/traces/executionOrderTransform.js +313 -0
- package/lib/dist/services/traces/executionOrderTransform.js.map +1 -0
- package/lib/dist/services/traces/fetchSpansForRun.d.ts +86 -0
- package/lib/dist/services/traces/fetchSpansForRun.d.ts.map +1 -0
- package/lib/dist/services/traces/fetchSpansForRun.js +69 -0
- package/lib/dist/services/traces/fetchSpansForRun.js.map +1 -0
- package/lib/dist/services/traces/flowTransform.d.ts +24 -0
- package/lib/dist/services/traces/flowTransform.d.ts.map +1 -0
- package/lib/dist/services/traces/flowTransform.js +228 -0
- package/lib/dist/services/traces/flowTransform.js.map +1 -0
- package/lib/dist/services/traces/index.d.ts +121 -0
- package/lib/dist/services/traces/index.d.ts.map +1 -0
- package/lib/dist/services/traces/index.js +255 -0
- package/lib/dist/services/traces/index.js.map +1 -0
- package/lib/dist/services/traces/intentTransform.d.ts +20 -0
- package/lib/dist/services/traces/intentTransform.d.ts.map +1 -0
- package/lib/dist/services/traces/intentTransform.js +131 -0
- package/lib/dist/services/traces/intentTransform.js.map +1 -0
- package/lib/dist/services/traces/judgeAgentsHints.d.ts +63 -0
- package/lib/dist/services/traces/judgeAgentsHints.d.ts.map +1 -0
- package/lib/dist/services/traces/judgeAgentsHints.js +89 -0
- package/lib/dist/services/traces/judgeAgentsHints.js.map +1 -0
- package/lib/dist/services/traces/messageExtraction.d.ts +15 -0
- package/lib/dist/services/traces/messageExtraction.d.ts.map +1 -0
- package/lib/dist/services/traces/messageExtraction.js +251 -0
- package/lib/dist/services/traces/messageExtraction.js.map +1 -0
- package/lib/dist/services/traces/spanCategorization.d.ts +63 -0
- package/lib/dist/services/traces/spanCategorization.d.ts.map +1 -0
- package/lib/dist/services/traces/spanCategorization.js +276 -0
- package/lib/dist/services/traces/spanCategorization.js.map +1 -0
- package/lib/dist/services/traces/spanPreprocessing.d.ts +37 -0
- package/lib/dist/services/traces/spanPreprocessing.d.ts.map +1 -0
- package/lib/dist/services/traces/spanPreprocessing.js +102 -0
- package/lib/dist/services/traces/spanPreprocessing.js.map +1 -0
- package/lib/dist/services/traces/spansToTrajectory.d.ts +36 -0
- package/lib/dist/services/traces/spansToTrajectory.d.ts.map +1 -0
- package/lib/dist/services/traces/spansToTrajectory.js +387 -0
- package/lib/dist/services/traces/spansToTrajectory.js.map +1 -0
- package/lib/dist/services/traces/toolSimilarity.d.ts +35 -0
- package/lib/dist/services/traces/toolSimilarity.d.ts.map +1 -0
- package/lib/dist/services/traces/toolSimilarity.js +203 -0
- package/lib/dist/services/traces/toolSimilarity.js.map +1 -0
- package/lib/dist/services/traces/traceComparison.d.ts +31 -0
- package/lib/dist/services/traces/traceComparison.d.ts.map +1 -0
- package/lib/dist/services/traces/traceComparison.js +318 -0
- package/lib/dist/services/traces/traceComparison.js.map +1 -0
- package/lib/dist/services/traces/traceGrouping.d.ts +19 -0
- package/lib/dist/services/traces/traceGrouping.d.ts.map +1 -0
- package/lib/dist/services/traces/traceGrouping.js +107 -0
- package/lib/dist/services/traces/traceGrouping.js.map +1 -0
- package/lib/dist/services/traces/tracePoller.d.ts +84 -0
- package/lib/dist/services/traces/tracePoller.d.ts.map +1 -0
- package/lib/dist/services/traces/tracePoller.js +309 -0
- package/lib/dist/services/traces/tracePoller.js.map +1 -0
- package/lib/dist/services/traces/traceStats.d.ts +45 -0
- package/lib/dist/services/traces/traceStats.d.ts.map +1 -0
- package/lib/dist/services/traces/traceStats.js +114 -0
- package/lib/dist/services/traces/traceStats.js.map +1 -0
- package/lib/dist/services/traces/traceSummary.d.ts +47 -0
- package/lib/dist/services/traces/traceSummary.d.ts.map +1 -0
- package/lib/dist/services/traces/traceSummary.js +68 -0
- package/lib/dist/services/traces/traceSummary.js.map +1 -0
- package/lib/dist/services/traces/utils.d.ts +33 -0
- package/lib/dist/services/traces/utils.d.ts.map +1 -0
- package/lib/dist/services/traces/utils.js +114 -0
- package/lib/dist/services/traces/utils.js.map +1 -0
- package/lib/dist/types/agui.d.ts +13 -0
- package/lib/dist/types/agui.d.ts.map +1 -0
- package/lib/dist/types/agui.js +16 -0
- package/lib/dist/types/agui.js.map +1 -0
- package/lib/dist/types/index.d.ts +1175 -0
- package/lib/dist/types/index.d.ts.map +1 -0
- package/lib/dist/types/index.js +12 -0
- package/lib/dist/types/index.js.map +1 -0
- package/lib/dist/types/skills.d.ts +146 -0
- package/lib/dist/types/skills.d.ts.map +1 -0
- package/lib/dist/types/skills.js +6 -0
- package/lib/dist/types/skills.js.map +1 -0
- package/observio-sample-agent/pi-package/README.md +112 -0
- package/observio-sample-agent/pi-package/extensions/agent-health.ts +373 -0
- package/observio-sample-agent/pi-package/package.json +17 -0
- package/observio-sample-agent/pi-package/prompts/agent-health.md +37 -0
- package/observio-sample-agent/pi-package/skills/create-pr/SKILL.md +88 -0
- package/observio-sample-agent/pi-package/skills/fix-bug/SKILL.md +71 -0
- package/observio-sample-agent/pi-package/skills/implement-feature/SKILL.md +156 -0
- package/observio-sample-agent/pi-package/skills/instrument-otel/SKILL.md +208 -0
- package/observio-sample-agent/pi-package/skills/setup-collector/SKILL.md +146 -0
- package/observio-sample-agent/pi-package/skills/write-test/SKILL.md +115 -0
- package/package.json +64 -13
- package/server/dist/app.js +32651 -17637
- package/server/dist/index.js +29875 -14638
- package/tsconfig.lib.json +71 -0
- package/dist/assets/index-EvPLSTAS.js +0 -267
- package/dist/assets/index-RXasQKUs.css +0 -1
- package/lib/dist/config/index.js +0 -404
- package/lib/dist/index.js +0 -1665
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: implement-feature
|
|
3
|
+
description: >
|
|
4
|
+
Guided feature implementation for Agent Health. Use when a user wants to add a new
|
|
5
|
+
capability, endpoint, CLI command, or UI component to the Agent Health project.
|
|
6
|
+
Ensures correct architecture layer, coding conventions, test coverage, and PR readiness.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Implement Feature in Agent Health
|
|
10
|
+
|
|
11
|
+
You are helping the user implement a feature in the Agent Health project. Follow the project's architecture and conventions strictly.
|
|
12
|
+
|
|
13
|
+
## Step 1: Understand the Request
|
|
14
|
+
|
|
15
|
+
Clarify:
|
|
16
|
+
1. What does the feature do? (user-facing behavior)
|
|
17
|
+
2. Who triggers it? (UI, CLI, API, background process)
|
|
18
|
+
3. What data does it read/write? (OpenSearch indexes, config, files)
|
|
19
|
+
|
|
20
|
+
## Step 2: Identify the Architecture Layer
|
|
21
|
+
|
|
22
|
+
Use the `find_architecture` tool to locate where this feature belongs. The layers are:
|
|
23
|
+
|
|
24
|
+
| Trigger | Implementation Layer | Key Pattern |
|
|
25
|
+
|---------|---------------------|-------------|
|
|
26
|
+
| HTTP API | `server/routes/` | Route validation, early return 404, `{ error }` responses |
|
|
27
|
+
| CLI command | `cli/commands/` | Uses `apiClient.ts` to call server, `ensureServer()` for lifecycle |
|
|
28
|
+
| Background work | `services/` | SSE streaming, cancellation tokens, persist state immediately |
|
|
29
|
+
| UI interaction | `components/` + `hooks/` | React, shadcn/ui, client service calls |
|
|
30
|
+
| Data persistence | `services/storage/` | `asyncXStorage` with `toAppFormat()`/`toStorageFormat()` |
|
|
31
|
+
| Agent protocol | `services/connectors/` | ConnectorType, streaming adapter |
|
|
32
|
+
|
|
33
|
+
**Critical rule**: All clients access OpenSearch through the server HTTP API. Never bypass the server.
|
|
34
|
+
|
|
35
|
+
## Step 3: Plan the Implementation
|
|
36
|
+
|
|
37
|
+
Before writing code, identify:
|
|
38
|
+
- **Files to create**: New routes, services, types, tests
|
|
39
|
+
- **Files to modify**: Existing types, route registrations, CLI command list
|
|
40
|
+
- **Types needed**: Add to `types/index.ts` — use string unions (not enums), discriminated unions with `type` field
|
|
41
|
+
|
|
42
|
+
### Coding Conventions to Follow
|
|
43
|
+
|
|
44
|
+
- **Route validation**: `validateX(): string | null`, return 400 early
|
|
45
|
+
- **Storage wrappers**: `toAppFormat()`/`toStorageFormat()` conversion
|
|
46
|
+
- **SSE streaming**: Set event-stream headers, `res.flushHeaders()`, structured events
|
|
47
|
+
- **Cancellation**: `{ isCancelled, cancel() }` token in a Map, check before each iteration
|
|
48
|
+
- **Run status**: `pending` → `running` → `completed` | `failed` | `cancelled`
|
|
49
|
+
- **Exports**: Barrel exports via `index.ts` with named functions
|
|
50
|
+
- **Path alias**: Use `@/` prefix for all imports (maps to project root)
|
|
51
|
+
- **Types**: `RunConfigInput` (user fields) vs full entity. String unions not enums.
|
|
52
|
+
|
|
53
|
+
### What NOT to Do
|
|
54
|
+
|
|
55
|
+
- Don't add unnecessary error handling for internal code paths
|
|
56
|
+
- Don't add docstrings/comments to code you didn't change
|
|
57
|
+
- Don't create helpers/abstractions for one-time operations
|
|
58
|
+
- Don't add feature flags or backwards-compatibility shims
|
|
59
|
+
- Don't modify `package.json` name or version fields
|
|
60
|
+
|
|
61
|
+
## Step 4: Implement
|
|
62
|
+
|
|
63
|
+
Write the code following the plan. For each file:
|
|
64
|
+
|
|
65
|
+
1. Add SPDX header: `/* Copyright OpenSearch Contributors\n SPDX-License-Identifier: Apache-2.0 */`
|
|
66
|
+
2. Use `@/` path alias for imports
|
|
67
|
+
3. Follow existing patterns in the same directory
|
|
68
|
+
|
|
69
|
+
### If Adding a Route
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
// server/routes/myFeature.ts
|
|
73
|
+
import { Router } from 'express';
|
|
74
|
+
|
|
75
|
+
const router = Router();
|
|
76
|
+
|
|
77
|
+
function validateInput(body: any): string | null {
|
|
78
|
+
if (!body.requiredField) return 'requiredField is required';
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
router.post('/api/my-feature', async (req, res) => {
|
|
83
|
+
const error = validateInput(req.body);
|
|
84
|
+
if (error) return res.status(400).json({ error });
|
|
85
|
+
// ...implementation
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
export default router;
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### If Adding a CLI Command
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
// cli/commands/myCommand.ts
|
|
95
|
+
// Uses apiClient — NEVER calls OpenSearch directly
|
|
96
|
+
import { apiClient } from '../utils/apiClient';
|
|
97
|
+
import { ensureServer } from '../utils/serverLifecycle';
|
|
98
|
+
|
|
99
|
+
export async function myCommand(args: any) {
|
|
100
|
+
await ensureServer();
|
|
101
|
+
const result = await apiClient.get('/api/my-feature');
|
|
102
|
+
// ...
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### If Adding a Storage Entity
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
// services/storage/asyncMyStorage.ts
|
|
110
|
+
// Follow the asyncTestCaseStorage.ts pattern exactly
|
|
111
|
+
export const asyncMyStorage = {
|
|
112
|
+
async create(entity: MyType): Promise<MyType> { /* ... */ },
|
|
113
|
+
async get(id: string): Promise<MyType | null> { /* ... */ },
|
|
114
|
+
async update(id: string, updates: Partial<MyType>): Promise<MyType> {
|
|
115
|
+
// MUST throw if entity doesn't exist (no upsert)
|
|
116
|
+
},
|
|
117
|
+
async delete(id: string): Promise<void> { /* ... */ },
|
|
118
|
+
async list(): Promise<MyType[]> { /* ... */ },
|
|
119
|
+
};
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Step 5: Write Tests
|
|
123
|
+
|
|
124
|
+
Use the `/write-test` skill or follow these rules:
|
|
125
|
+
- Place tests in `tests/` mirroring source structure
|
|
126
|
+
- Use `@/` path alias, never relative imports
|
|
127
|
+
- Coverage thresholds: 90% lines/statements, 80% functions/branches
|
|
128
|
+
- Mock external services (OpenSearch, Bedrock), not internal modules
|
|
129
|
+
- Integration tests that create data MUST clean up in `afterEach`/`afterAll`
|
|
130
|
+
|
|
131
|
+
## Step 6: Validate
|
|
132
|
+
|
|
133
|
+
Run `run_validation` tool with scope "all" to verify:
|
|
134
|
+
- TypeScript compiles cleanly (`npm run build:all`)
|
|
135
|
+
- All tests pass (`npm run test:all`)
|
|
136
|
+
- No coverage regression
|
|
137
|
+
|
|
138
|
+
## Step 7: Prepare PR
|
|
139
|
+
|
|
140
|
+
Use `check_compliance` tool to verify:
|
|
141
|
+
- [ ] SPDX headers on all new files
|
|
142
|
+
- [ ] CHANGELOG.md updated
|
|
143
|
+
- [ ] All commits have DCO signoff (`git commit -s`)
|
|
144
|
+
- [ ] Build passes, tests pass
|
|
145
|
+
- [ ] No `--no-verify` bypasses
|
|
146
|
+
|
|
147
|
+
Then create the PR following the project template:
|
|
148
|
+
```
|
|
149
|
+
## Summary
|
|
150
|
+
- <1-3 bullet points of what changed>
|
|
151
|
+
|
|
152
|
+
## Test plan
|
|
153
|
+
- [ ] Unit tests added/updated
|
|
154
|
+
- [ ] Integration tests pass
|
|
155
|
+
- [ ] Manual verification steps
|
|
156
|
+
```
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: instrument-otel
|
|
3
|
+
description: >
|
|
4
|
+
Add OpenTelemetry instrumentation to an AI agent for Agent Health observability.
|
|
5
|
+
Use when a user wants to make their agent's traces visible in Agent Health dashboards,
|
|
6
|
+
or when debugging why traces aren't appearing. Covers span structure, Gen AI semantic
|
|
7
|
+
conventions, required attributes, and OTLP exporter setup.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Instrument Agent with OpenTelemetry
|
|
11
|
+
|
|
12
|
+
You are helping the user add OpenTelemetry instrumentation to their AI agent so it produces traces that Agent Health can consume and visualize.
|
|
13
|
+
|
|
14
|
+
## What Agent Health Expects
|
|
15
|
+
|
|
16
|
+
Agent Health categorizes spans by reading `gen_ai.operation.name`:
|
|
17
|
+
- `invoke_agent` → AGENT span (root)
|
|
18
|
+
- `chat` → LLM span (model calls)
|
|
19
|
+
- `execute_tool` → TOOL span (tool invocations)
|
|
20
|
+
|
|
21
|
+
All other spans are categorized as FRAMEWORK.
|
|
22
|
+
|
|
23
|
+
## Step 1: Determine the User's Stack
|
|
24
|
+
|
|
25
|
+
Ask the user:
|
|
26
|
+
1. What language/runtime? (Node.js, Python, Java, Go)
|
|
27
|
+
2. What LLM provider? (Bedrock, OpenAI, Anthropic, etc.)
|
|
28
|
+
3. What framework? (LangChain, LangGraph, Strands, custom)
|
|
29
|
+
4. Where should traces export to? (OSIS pipeline, local collector, direct to OpenSearch)
|
|
30
|
+
|
|
31
|
+
## Step 2: Set Up the Tracer Provider
|
|
32
|
+
|
|
33
|
+
Generate a telemetry provider module. Requirements:
|
|
34
|
+
- Use `BatchSpanProcessor` (not Simple) for production
|
|
35
|
+
- Set `service.name` resource attribute to identify the agent
|
|
36
|
+
- Export via OTLP/HTTP to the configured endpoint
|
|
37
|
+
- Make it opt-in via environment variable
|
|
38
|
+
|
|
39
|
+
### Reference Pattern (Node.js/TypeScript)
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
import { NodeTracerProvider, BatchSpanProcessor } from '@opentelemetry/sdk-trace-node';
|
|
43
|
+
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
|
|
44
|
+
import { resourceFromAttributes } from '@opentelemetry/resources';
|
|
45
|
+
|
|
46
|
+
const resource = resourceFromAttributes({
|
|
47
|
+
'service.name': process.env.OTEL_SERVICE_NAME || 'my-agent',
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const provider = new NodeTracerProvider({
|
|
51
|
+
resource,
|
|
52
|
+
spanProcessors: [
|
|
53
|
+
new BatchSpanProcessor(
|
|
54
|
+
new OTLPTraceExporter({ url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT })
|
|
55
|
+
),
|
|
56
|
+
],
|
|
57
|
+
});
|
|
58
|
+
provider.register();
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Python Equivalent
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
from opentelemetry import trace
|
|
65
|
+
from opentelemetry.sdk.trace import TracerProvider
|
|
66
|
+
from opentelemetry.sdk.trace.export import BatchSpanExporter
|
|
67
|
+
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
|
|
68
|
+
from opentelemetry.sdk.resources import Resource
|
|
69
|
+
|
|
70
|
+
resource = Resource.create({"service.name": "my-agent"})
|
|
71
|
+
provider = TracerProvider(resource=resource)
|
|
72
|
+
provider.add_span_processor(BatchSpanExporter(OTLPSpanExporter()))
|
|
73
|
+
trace.set_tracer_provider(provider)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Step 3: Create Span Helpers
|
|
77
|
+
|
|
78
|
+
Generate helper functions for each span type. These MUST follow the naming and attribute conventions exactly.
|
|
79
|
+
|
|
80
|
+
### Root Agent Span
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
function startAgentSpan(runId: string) {
|
|
84
|
+
const span = tracer.startSpan('invoke_agent <agent-name>', {
|
|
85
|
+
kind: SpanKind.SERVER,
|
|
86
|
+
attributes: {
|
|
87
|
+
'gen_ai.operation.name': 'invoke_agent',
|
|
88
|
+
'gen_ai.system': '<provider>', // e.g. 'aws.bedrock'
|
|
89
|
+
'gen_ai.agent.name': '<agent-name>',
|
|
90
|
+
'gen_ai.conversation.id': runId, // links the trace to an Agent Health run (also accepted as agent_health.run.id)
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
return { span, ctx: trace.setSpan(context.active(), span) };
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### LLM Call Span (child of agent)
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
function startLLMSpan(parentCtx: Context, opts: { modelId: string; temperature?: number; maxTokens?: number }) {
|
|
101
|
+
const span = tracer.startSpan('chat <system>', {
|
|
102
|
+
kind: SpanKind.CLIENT,
|
|
103
|
+
attributes: {
|
|
104
|
+
'gen_ai.operation.name': 'chat',
|
|
105
|
+
'gen_ai.system': '<provider>',
|
|
106
|
+
'gen_ai.request.model': opts.modelId,
|
|
107
|
+
'gen_ai.request.temperature': opts.temperature,
|
|
108
|
+
'gen_ai.request.max_tokens': opts.maxTokens,
|
|
109
|
+
},
|
|
110
|
+
}, parentCtx);
|
|
111
|
+
return { span, ctx: trace.setSpan(parentCtx, span) };
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function endLLMSpan(span: Span, opts: { inputTokens?: number; outputTokens?: number; stopReason?: string }) {
|
|
115
|
+
if (opts.inputTokens) span.setAttribute('gen_ai.usage.input_tokens', opts.inputTokens);
|
|
116
|
+
if (opts.outputTokens) span.setAttribute('gen_ai.usage.output_tokens', opts.outputTokens);
|
|
117
|
+
if (opts.stopReason) span.setAttribute('gen_ai.response.finish_reason', opts.stopReason);
|
|
118
|
+
|
|
119
|
+
// Add content events
|
|
120
|
+
span.addEvent('gen_ai.content.prompt', { 'gen_ai.prompt': '...' });
|
|
121
|
+
span.addEvent('gen_ai.content.completion', { 'gen_ai.completion': '...' });
|
|
122
|
+
span.end();
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Tool Execution Span (child of agent)
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
function startToolSpan(parentCtx: Context, toolName: string, toolInput?: any) {
|
|
130
|
+
const span = tracer.startSpan(`execute_tool ${toolName}`, {
|
|
131
|
+
kind: SpanKind.CLIENT,
|
|
132
|
+
attributes: {
|
|
133
|
+
'gen_ai.operation.name': 'execute_tool',
|
|
134
|
+
'gen_ai.tool.name': toolName,
|
|
135
|
+
},
|
|
136
|
+
}, parentCtx);
|
|
137
|
+
|
|
138
|
+
if (toolInput) {
|
|
139
|
+
span.addEvent('gen_ai.tool.input', {
|
|
140
|
+
'gen_ai.tool.input': JSON.stringify(toolInput).slice(0, 3000),
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
return { span, ctx: trace.setSpan(parentCtx, span) };
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function endToolSpan(span: Span, result?: any, error?: Error) {
|
|
147
|
+
if (result) {
|
|
148
|
+
span.addEvent('gen_ai.tool.output', {
|
|
149
|
+
'gen_ai.tool.output': JSON.stringify(result).slice(0, 3000),
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
if (error) span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
|
|
153
|
+
span.end();
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Step 4: Wire Into the Agent Loop
|
|
158
|
+
|
|
159
|
+
Show the user where to place span calls in their agent's execution flow:
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
┌─────────────────────────────────────────────┐
|
|
163
|
+
│ startAgentSpan(runId) │ ← Root span
|
|
164
|
+
│ │
|
|
165
|
+
│ ┌─── Loop ───────────────────────────┐ │
|
|
166
|
+
│ │ startLLMSpan(agentCtx, {...}) │ │ ← Each model call
|
|
167
|
+
│ │ → call LLM │ │
|
|
168
|
+
│ │ endLLMSpan(span, {tokens, reason}) │ │
|
|
169
|
+
│ │ │ │
|
|
170
|
+
│ │ if tool_calls: │ │
|
|
171
|
+
│ │ startToolSpan(agentCtx, name) │ │ ← Each tool execution
|
|
172
|
+
│ │ → execute tool │ │
|
|
173
|
+
│ │ endToolSpan(span, result) │ │
|
|
174
|
+
│ └─────────────────────────────────────┘ │
|
|
175
|
+
│ │
|
|
176
|
+
│ agentSpan.end() │ ← End root span
|
|
177
|
+
└─────────────────────────────────────────────┘
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Step 5: Verify
|
|
181
|
+
|
|
182
|
+
After instrumentation, help the user verify:
|
|
183
|
+
|
|
184
|
+
1. **Exporter connectivity**: Check OTLP endpoint is reachable
|
|
185
|
+
2. **Span hierarchy**: Root agent span has LLM + tool children
|
|
186
|
+
3. **Required attributes**: All `gen_ai.*` attributes present
|
|
187
|
+
4. **Events**: Prompt/completion events on LLM spans, input/output on tool spans
|
|
188
|
+
5. **Agent Health visibility**: Traces appear in the Traces tab with correct categorization
|
|
189
|
+
|
|
190
|
+
Use the `validate_spans` tool to check their code automatically.
|
|
191
|
+
|
|
192
|
+
## Common Issues
|
|
193
|
+
|
|
194
|
+
| Symptom | Cause | Fix |
|
|
195
|
+
|---------|-------|-----|
|
|
196
|
+
| No traces in Agent Health | Exporter endpoint wrong or unreachable | Check `OTEL_EXPORTER_OTLP_ENDPOINT` |
|
|
197
|
+
| Spans show as FRAMEWORK | Missing `gen_ai.operation.name` attribute | Add the attribute to every span |
|
|
198
|
+
| No token metrics | Missing `gen_ai.usage.*` attributes | Set on LLM span end |
|
|
199
|
+
| Flat span list (no tree) | Not passing parent context | Use `parentCtx` in startSpan |
|
|
200
|
+
| Traces appear but no cost data | Missing model attribute | Set `gen_ai.request.model` |
|
|
201
|
+
|
|
202
|
+
## Environment Variables
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
OTEL_EXPORTER_OTLP_ENDPOINT=https://your-osis-pipeline/v1/traces
|
|
206
|
+
OTEL_SERVICE_NAME=my-agent
|
|
207
|
+
OTEL_ENABLED=true # optional, default true
|
|
208
|
+
```
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: setup-collector
|
|
3
|
+
description: >
|
|
4
|
+
Set up an OpenTelemetry collector or OSIS pipeline to route traces from an agent
|
|
5
|
+
to OpenSearch for Agent Health consumption. Covers OSIS, OTel Collector, and
|
|
6
|
+
direct export configurations.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Set Up Trace Collection Pipeline
|
|
10
|
+
|
|
11
|
+
You are helping the user configure a pipeline to get their agent's OTel traces into OpenSearch where Agent Health can read them.
|
|
12
|
+
|
|
13
|
+
## Architecture Options
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
Agent → OTLP/HTTP → [Pipeline] → OpenSearch
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Three pipeline options:
|
|
20
|
+
|
|
21
|
+
| Option | Best For | Complexity |
|
|
22
|
+
|--------|----------|------------|
|
|
23
|
+
| OSIS (OpenSearch Ingestion) | AWS-managed, production | Low (managed) |
|
|
24
|
+
| OTel Collector | Self-hosted, flexible routing | Medium |
|
|
25
|
+
| Direct export | Dev/testing only | Lowest |
|
|
26
|
+
|
|
27
|
+
## Option 1: OSIS Pipeline (Recommended for AWS)
|
|
28
|
+
|
|
29
|
+
### Prerequisites
|
|
30
|
+
- AWS account with OSIS access
|
|
31
|
+
- OpenSearch domain (managed or serverless)
|
|
32
|
+
|
|
33
|
+
### Pipeline Configuration
|
|
34
|
+
|
|
35
|
+
```yaml
|
|
36
|
+
version: "2"
|
|
37
|
+
otel-trace-pipeline:
|
|
38
|
+
source:
|
|
39
|
+
otel_trace_source:
|
|
40
|
+
path: "/v1/traces"
|
|
41
|
+
processor:
|
|
42
|
+
- otel_trace_raw:
|
|
43
|
+
sink:
|
|
44
|
+
- opensearch:
|
|
45
|
+
hosts: ["https://your-opensearch-domain.us-west-2.es.amazonaws.com"]
|
|
46
|
+
index: "otel-v1-apm-span-*"
|
|
47
|
+
aws:
|
|
48
|
+
sts_role_arn: "arn:aws:iam::ACCOUNT:role/osis-role"
|
|
49
|
+
region: "us-west-2"
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Agent Configuration
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
OTEL_EXPORTER_OTLP_ENDPOINT=https://your-osis-pipeline.us-west-2.osis.amazonaws.com/v1/traces
|
|
56
|
+
OTEL_SERVICE_NAME=my-agent
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Option 2: OTel Collector (Self-hosted)
|
|
60
|
+
|
|
61
|
+
### docker-compose.yml
|
|
62
|
+
|
|
63
|
+
```yaml
|
|
64
|
+
services:
|
|
65
|
+
otel-collector:
|
|
66
|
+
image: otel/opentelemetry-collector-contrib:latest
|
|
67
|
+
ports:
|
|
68
|
+
- "4318:4318" # OTLP HTTP
|
|
69
|
+
volumes:
|
|
70
|
+
- ./otel-config.yaml:/etc/otelcol-contrib/config.yaml
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### otel-config.yaml
|
|
74
|
+
|
|
75
|
+
```yaml
|
|
76
|
+
receivers:
|
|
77
|
+
otlp:
|
|
78
|
+
protocols:
|
|
79
|
+
http:
|
|
80
|
+
endpoint: 0.0.0.0:4318
|
|
81
|
+
|
|
82
|
+
processors:
|
|
83
|
+
batch:
|
|
84
|
+
timeout: 5s
|
|
85
|
+
send_batch_size: 100
|
|
86
|
+
|
|
87
|
+
exporters:
|
|
88
|
+
opensearch:
|
|
89
|
+
http:
|
|
90
|
+
endpoint: "https://your-opensearch:9200"
|
|
91
|
+
tls:
|
|
92
|
+
insecure: false
|
|
93
|
+
dataset: "traces"
|
|
94
|
+
|
|
95
|
+
service:
|
|
96
|
+
pipelines:
|
|
97
|
+
traces:
|
|
98
|
+
receivers: [otlp]
|
|
99
|
+
processors: [batch]
|
|
100
|
+
exporters: [opensearch]
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Agent Configuration
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318/v1/traces
|
|
107
|
+
OTEL_SERVICE_NAME=my-agent
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Option 3: Direct Export (Dev Only)
|
|
111
|
+
|
|
112
|
+
Export directly to OpenSearch Data Prepper format. Not recommended for production (no batching, no retry).
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
OTEL_EXPORTER_OTLP_ENDPOINT=https://your-opensearch:9200/_plugins/_trace_analytics/v1/traces
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Agent Health Configuration
|
|
119
|
+
|
|
120
|
+
Once traces are flowing to OpenSearch, configure Agent Health to read them:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# In your Agent Health .env
|
|
124
|
+
OPENSEARCH_LOGS_ENDPOINT=https://your-opensearch:9200
|
|
125
|
+
OPENSEARCH_LOGS_USERNAME=admin
|
|
126
|
+
OPENSEARCH_LOGS_PASSWORD=admin
|
|
127
|
+
# Or for AWS SigV4:
|
|
128
|
+
# OPENSEARCH_LOGS_AUTH_TYPE=sigv4
|
|
129
|
+
# OPENSEARCH_LOGS_AWS_REGION=us-west-2
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Verification Checklist
|
|
133
|
+
|
|
134
|
+
1. **Agent sends spans**: Check agent logs for "telemetry enabled" message
|
|
135
|
+
2. **Pipeline receives**: Check OSIS/Collector metrics for incoming spans
|
|
136
|
+
3. **OpenSearch has data**: Query `otel-v1-apm-span-*` index
|
|
137
|
+
4. **Agent Health sees traces**: Open Traces tab, verify spans appear with correct categorization
|
|
138
|
+
|
|
139
|
+
## Troubleshooting
|
|
140
|
+
|
|
141
|
+
| Issue | Check |
|
|
142
|
+
|-------|-------|
|
|
143
|
+
| No spans arriving | Is `OTEL_EXPORTER_OTLP_ENDPOINT` correct? Is the agent calling `provider.register()`? |
|
|
144
|
+
| Spans in OS but not in Agent Health | Check index pattern matches what Agent Health queries (`otel-v1-apm-span-*`) |
|
|
145
|
+
| Auth errors | Check IAM role for OSIS, or username/password for basic auth |
|
|
146
|
+
| Spans arrive but incomplete | Ensure `provider.shutdown()` is called on agent exit (flushes batch) |
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: write-test
|
|
3
|
+
description: >
|
|
4
|
+
Write tests for Agent Health following project conventions. Use when adding tests
|
|
5
|
+
for new features, bug fixes, or improving coverage. Covers Jest setup, mocking
|
|
6
|
+
patterns, path aliases, and coverage thresholds.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Write Tests for Agent Health
|
|
10
|
+
|
|
11
|
+
You are helping the user write tests following Agent Health's conventions.
|
|
12
|
+
|
|
13
|
+
## Test Structure
|
|
14
|
+
|
|
15
|
+
- Tests live in `tests/` mirroring the source directory structure
|
|
16
|
+
- Jest config: `jest.config.cjs`
|
|
17
|
+
- **Always use `@/` path alias** — never relative imports
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
// ✅ Correct
|
|
21
|
+
import { myFunction } from '@/services/myService';
|
|
22
|
+
|
|
23
|
+
// ❌ Wrong
|
|
24
|
+
import { myFunction } from '../../services/myService';
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Test File Template
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
/* Copyright OpenSearch Contributors
|
|
31
|
+
SPDX-License-Identifier: Apache-2.0 */
|
|
32
|
+
|
|
33
|
+
import { functionUnderTest } from '@/path/to/module';
|
|
34
|
+
|
|
35
|
+
describe('functionUnderTest', () => {
|
|
36
|
+
beforeEach(() => {
|
|
37
|
+
jest.clearAllMocks();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('should handle the happy path', () => {
|
|
41
|
+
const result = functionUnderTest(validInput);
|
|
42
|
+
expect(result).toEqual(expectedOutput);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('should handle edge case', () => {
|
|
46
|
+
// ...
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Mocking Patterns
|
|
52
|
+
|
|
53
|
+
### Mock External Services (OpenSearch, Bedrock)
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
jest.mock('@/server/adapters/opensearch/StorageModule', () => ({
|
|
57
|
+
getStorageModule: () => ({
|
|
58
|
+
testCases: {
|
|
59
|
+
create: jest.fn().mockResolvedValue({ id: 'test-1', name: 'Test' }),
|
|
60
|
+
get: jest.fn().mockResolvedValue(null),
|
|
61
|
+
},
|
|
62
|
+
}),
|
|
63
|
+
}));
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Mock Fetch/HTTP
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
const mockFetch = jest.fn().mockResolvedValue({
|
|
70
|
+
ok: true,
|
|
71
|
+
json: () => Promise.resolve({ data: 'result' }),
|
|
72
|
+
});
|
|
73
|
+
global.fetch = mockFetch;
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Don't Mock Internal Modules
|
|
77
|
+
|
|
78
|
+
Test through the public API. Only mock at system boundaries.
|
|
79
|
+
|
|
80
|
+
## Integration Tests
|
|
81
|
+
|
|
82
|
+
If the test creates data in OpenSearch or starts a server:
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
afterEach(async () => {
|
|
86
|
+
// Clean up created resources
|
|
87
|
+
await storage.delete(createdId);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
afterAll(async () => {
|
|
91
|
+
// Close connections
|
|
92
|
+
await server.close();
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Coverage Thresholds
|
|
97
|
+
|
|
98
|
+
| Metric | Minimum |
|
|
99
|
+
|--------|---------|
|
|
100
|
+
| Lines | 90% |
|
|
101
|
+
| Statements | 90% |
|
|
102
|
+
| Functions | 80% |
|
|
103
|
+
| Branches | 80% |
|
|
104
|
+
|
|
105
|
+
Run coverage: `npm test -- --coverage`
|
|
106
|
+
|
|
107
|
+
## Running Tests
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
npm test # All tests
|
|
111
|
+
npm run test:unit # Unit only
|
|
112
|
+
npm run test:integration # Integration only
|
|
113
|
+
npm test -- path/to/file.test.ts # Single file
|
|
114
|
+
npm test -- --watch # Watch mode
|
|
115
|
+
```
|