@opensearch-project/agent-health 0.4.0 → 0.6.0
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 +36 -5
- package/cli/dist/index.js +8292 -2938
- package/deployment/cloudformation/agent-health-observability.yaml +223 -32
- package/dist/assets/index-BfxtxmKc.css +1 -0
- package/dist/assets/index-CrjAfDHu.js +243 -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 +474 -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 +397 -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 +626 -0
- package/docs/SKILLS.md +264 -0
- package/docs/STORAGE_INDEX_FIELD_LIMITS.md +216 -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 +652 -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/ops-rca-classification.eval.js +71 -0
- package/examples/eval-files/ops-rca-evaluator.json +15 -0
- package/examples/eval-files/sdk-demo.eval.js +72 -0
- package/examples/eval-files/sdk-describe-demo.eval.js +50 -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/bedrockCompat.d.ts +27 -0
- package/lib/dist/lib/bedrockCompat.d.ts.map +1 -0
- package/lib/dist/lib/bedrockCompat.js +83 -0
- package/lib/dist/lib/bedrockCompat.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/benchmarkImage.d.ts +52 -0
- package/lib/dist/lib/benchmarkImage.d.ts.map +1 -0
- package/lib/dist/lib/benchmarkImage.js +113 -0
- package/lib/dist/lib/benchmarkImage.js.map +1 -0
- package/lib/dist/lib/benchmarkVersionUtils.d.ts +50 -0
- package/lib/dist/lib/benchmarkVersionUtils.d.ts.map +1 -0
- package/lib/dist/lib/benchmarkVersionUtils.js +89 -0
- package/lib/dist/lib/benchmarkVersionUtils.js.map +1 -0
- package/lib/dist/lib/chunkedFetch.d.ts +18 -0
- package/lib/dist/lib/chunkedFetch.d.ts.map +1 -0
- package/lib/dist/lib/chunkedFetch.js +40 -0
- package/lib/dist/lib/chunkedFetch.js.map +1 -0
- package/lib/dist/lib/comparisonInsights.d.ts +104 -0
- package/lib/dist/lib/comparisonInsights.d.ts.map +1 -0
- package/lib/dist/lib/comparisonInsights.js +212 -0
- package/lib/dist/lib/comparisonInsights.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 +263 -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 +245 -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 +81 -0
- package/lib/dist/lib/constants.d.ts.map +1 -0
- package/lib/dist/lib/constants.js +374 -0
- package/lib/dist/lib/constants.js.map +1 -0
- package/lib/dist/lib/contextFormat.d.ts +26 -0
- package/lib/dist/lib/contextFormat.d.ts.map +1 -0
- package/lib/dist/lib/contextFormat.js +28 -0
- package/lib/dist/lib/contextFormat.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 +82 -0
- package/lib/dist/lib/envCompat.js.map +1 -0
- package/lib/dist/lib/evaluationRerun.d.ts +63 -0
- package/lib/dist/lib/evaluationRerun.d.ts.map +1 -0
- package/lib/dist/lib/evaluationRerun.js +85 -0
- package/lib/dist/lib/evaluationRerun.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 +70 -0
- package/lib/dist/lib/matchers/traces.d.ts.map +1 -0
- package/lib/dist/lib/matchers/traces.js +236 -0
- package/lib/dist/lib/matchers/traces.js.map +1 -0
- package/lib/dist/lib/matchers/tracesPricing.d.ts +38 -0
- package/lib/dist/lib/matchers/tracesPricing.d.ts.map +1 -0
- package/lib/dist/lib/matchers/tracesPricing.js +64 -0
- package/lib/dist/lib/matchers/tracesPricing.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 +116 -0
- package/lib/dist/lib/runStats.d.ts.map +1 -0
- package/lib/dist/lib/runStats.js +192 -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 +36 -0
- package/lib/dist/lib/testCases/loader.d.ts.map +1 -0
- package/lib/dist/lib/testCases/loader.js +179 -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 +111 -0
- package/lib/dist/lib/utils.d.ts.map +1 -0
- package/lib/dist/lib/utils.js +254 -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 +126 -0
- package/lib/dist/services/connectors/claude-code/ClaudeCodeConnector.d.ts.map +1 -0
- package/lib/dist/services/connectors/claude-code/ClaudeCodeConnector.js +417 -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 +426 -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 +71 -0
- package/lib/dist/services/evaluation/bedrockJudge.d.ts.map +1 -0
- package/lib/dist/services/evaluation/bedrockJudge.js +169 -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 +440 -0
- package/lib/dist/services/storage/asyncBenchmarkStorage.js.map +1 -0
- package/lib/dist/services/storage/asyncRunStorage.d.ts +135 -0
- package/lib/dist/services/storage/asyncRunStorage.d.ts.map +1 -0
- package/lib/dist/services/storage/asyncRunStorage.js +524 -0
- package/lib/dist/services/storage/asyncRunStorage.js.map +1 -0
- package/lib/dist/services/storage/asyncTestCaseStorage.d.ts +170 -0
- package/lib/dist/services/storage/asyncTestCaseStorage.d.ts.map +1 -0
- package/lib/dist/services/storage/asyncTestCaseStorage.js +301 -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 +947 -0
- package/lib/dist/services/storage/opensearchClient.d.ts.map +1 -0
- package/lib/dist/services/storage/opensearchClient.js +442 -0
- package/lib/dist/services/storage/opensearchClient.js.map +1 -0
- package/lib/dist/services/traces/browserRecovery.d.ts +37 -0
- package/lib/dist/services/traces/browserRecovery.d.ts.map +1 -0
- package/lib/dist/services/traces/browserRecovery.js +108 -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 +313 -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 +425 -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 +108 -0
- package/lib/dist/services/traces/tracePoller.d.ts.map +1 -0
- package/lib/dist/services/traces/tracePoller.js +475 -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 +1229 -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 +45 -9
- package/server/dist/app.js +34031 -18731
- package/server/dist/index.js +30737 -15338
- package/tsconfig.lib.json +71 -0
- package/dist/assets/index-BOIP5L7h.js +0 -246
- package/dist/assets/index-CU9YKpAL.css +0 -1
- package/lib/dist/config/index.js +0 -452
- package/lib/dist/index.js +0 -1725
package/docs/SKILLS.md
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
* Copyright OpenSearch Contributors
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
-->
|
|
5
|
+
|
|
6
|
+
# Skills Evaluator — Authoring Guide
|
|
7
|
+
|
|
8
|
+
The Skills Evaluator runs an A/B benchmark on an [AgentSkills](https://agentskills.io/) /
|
|
9
|
+
[Claude Code skill](https://docs.claude.com/en/docs/claude-code/skills): one set of
|
|
10
|
+
agent runs **with** the skill injected, one set **without**, then grades the same
|
|
11
|
+
assertions on both trajectories and reports the delta in pass-rate, latency, and
|
|
12
|
+
tokens. Optionally, an LLM proposes an improved `SKILL.md` body from the failure
|
|
13
|
+
evidence and (with `auto`) applies it.
|
|
14
|
+
|
|
15
|
+
This guide tells you **how to write a skill that the evaluator can score
|
|
16
|
+
fairly** — and what every warning / status the UI shows actually means.
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
┌──────────┐ ┌──────────────┐ ┌──────────────┐ ┌────────────┐
|
|
20
|
+
│ SKILL.md │→ │ parseSkill │→ │ runSkillEval │→ │ benchmark │
|
|
21
|
+
└──────────┘ │ validate + │ │ with vs │ │ + diff + │
|
|
22
|
+
│ warn │ │ without │ │ improve │
|
|
23
|
+
└──────────────┘ └──────────────┘ └────────────┘
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 1. Anatomy of a skill folder
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
my-skill/
|
|
32
|
+
├── SKILL.md # required — frontmatter + body
|
|
33
|
+
└── evals/
|
|
34
|
+
└── evals.json # optional — auto-generated if absent
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`SKILL.md` is a markdown file with a YAML frontmatter block delimited by `---`
|
|
38
|
+
on lines by themselves:
|
|
39
|
+
|
|
40
|
+
```markdown
|
|
41
|
+
---
|
|
42
|
+
name: rca-log-analysis
|
|
43
|
+
description: Use when the user asks why a service is failing or wants to find
|
|
44
|
+
the root cause from log lines. Triggers on terms like "why is X failing",
|
|
45
|
+
"RCA", "root cause", "error spike".
|
|
46
|
+
allowed-tools:
|
|
47
|
+
- Read
|
|
48
|
+
- Bash(git:*)
|
|
49
|
+
license: Apache-2.0
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
# Root-cause analysis from logs
|
|
53
|
+
|
|
54
|
+
When the user asks why a service is failing:
|
|
55
|
+
|
|
56
|
+
1. Pull the last 5 minutes of logs from the suspect service.
|
|
57
|
+
2. Group by error code; the dominant code is your starting hypothesis.
|
|
58
|
+
3. ...
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Frontmatter rules (enforced by `parseSkill`)
|
|
62
|
+
|
|
63
|
+
| Field | Required | Constraint |
|
|
64
|
+
| --------------- | -------- | ----------------------------------------------------------------------- |
|
|
65
|
+
| `name` | yes | lowercase kebab-case, ≤ 64 chars |
|
|
66
|
+
| `description` | yes | ≤ 1024 chars; **should describe trigger conditions** (see §2) |
|
|
67
|
+
| `allowed-tools` | no | YAML list **or** whitespace-separated string (`Bash(git:*)` patterns ok) |
|
|
68
|
+
| `license` | no | free-form string |
|
|
69
|
+
| `compatibility` | no | free-form string |
|
|
70
|
+
| `metadata` | no | arbitrary YAML mapping |
|
|
71
|
+
|
|
72
|
+
The closing `---` must be on its own line. CRLF line endings are normalised
|
|
73
|
+
before matching.
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## 2. Why your `description` is the most important field
|
|
78
|
+
|
|
79
|
+
In Claude Code's skill loader the `description` is what the matcher
|
|
80
|
+
**actually reads** when deciding whether to inject the skill into a given
|
|
81
|
+
turn. The body is only loaded after the description has matched. A
|
|
82
|
+
description that reads like a tagline ("A helper for log analysis") will
|
|
83
|
+
silently fail to fire.
|
|
84
|
+
|
|
85
|
+
The parser surfaces two warnings for this:
|
|
86
|
+
|
|
87
|
+
| Warning text | What to do |
|
|
88
|
+
| ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
89
|
+
| `description is only N characters … aim for ≥ 30 chars and explicitly state trigger conditions` | The description is too short to discriminate from peers. Expand it. |
|
|
90
|
+
| `description does not appear to state when the skill should be used` | Add a phrase like **`Use when …`**, **`For requests about …`**, **`Trigger on …`**, **`Invoke when the user asks …`**. The matcher looks for these. |
|
|
91
|
+
|
|
92
|
+
Good descriptions:
|
|
93
|
+
|
|
94
|
+
> ✅ "Use when the user asks why a service is failing or wants RCA from logs.
|
|
95
|
+
> Triggers on phrases like 'why is X erroring', 'root cause', 'error spike'."
|
|
96
|
+
|
|
97
|
+
> ✅ "For requests about diffing two trajectories — invoke when the user
|
|
98
|
+
> mentions 'compare runs', 'why did the agent behave differently', or pastes
|
|
99
|
+
> two run IDs."
|
|
100
|
+
|
|
101
|
+
Bad descriptions (parser will warn):
|
|
102
|
+
|
|
103
|
+
> ❌ "Helper for logs."
|
|
104
|
+
> ❌ "Skill for trace analysis."
|
|
105
|
+
> ❌ "Improves debugging."
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## 3. Authoring `evals/evals.json`
|
|
110
|
+
|
|
111
|
+
Each eval case is a triple **prompt → expected_output → assertions**. The
|
|
112
|
+
evaluator runs the prompt twice (with and without the skill), then asks the
|
|
113
|
+
LLM judge whether **each** assertion holds against the resulting trajectory.
|
|
114
|
+
|
|
115
|
+
```json
|
|
116
|
+
{
|
|
117
|
+
"skill_name": "rca-log-analysis",
|
|
118
|
+
"evals": [
|
|
119
|
+
{
|
|
120
|
+
"id": 1,
|
|
121
|
+
"prompt": "The checkout service started returning 503s 10 minutes ago. Why?",
|
|
122
|
+
"expected_output": "Identifies a downstream dependency or resource exhaustion as the cause.",
|
|
123
|
+
"assertions": [
|
|
124
|
+
"The agent searches logs for the affected service before guessing",
|
|
125
|
+
"The agent groups errors by error code or status",
|
|
126
|
+
"The agent's final answer names a specific suspect (service / resource / config)"
|
|
127
|
+
]
|
|
128
|
+
}
|
|
129
|
+
]
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Tips:
|
|
134
|
+
|
|
135
|
+
- **Make assertions discriminating.** A good assertion is one a *baseline*
|
|
136
|
+
agent (without the skill) would plausibly fail — that's the only way the
|
|
137
|
+
A/B delta surfaces real value. Trivial assertions like "the response is in
|
|
138
|
+
English" don't move the needle.
|
|
139
|
+
- **2–3 assertions per eval is plenty.** Each assertion costs one judge call.
|
|
140
|
+
- **`expected_output` is free-form** — it's used as judge context, not as a
|
|
141
|
+
string-match target.
|
|
142
|
+
- **Auto-generation** runs only if `evals/evals.json` is missing. If it
|
|
143
|
+
fails to parse a JSON eval set from the model response, the evaluator
|
|
144
|
+
**throws with the exact JSON shape** rather than substituting a generic
|
|
145
|
+
placeholder. Hand-author the file in that case.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## 4. Reading the validation panel
|
|
150
|
+
|
|
151
|
+
After you select a skill in the UI, the validation panel shows:
|
|
152
|
+
|
|
153
|
+
| Symbol | Meaning |
|
|
154
|
+
| ------ | ---------------------------------------------------------------------------------------------------- |
|
|
155
|
+
| ✅ | `valid: true` — frontmatter parsed, required fields present |
|
|
156
|
+
| ❌ | `valid: false` — at least one hard error; the **Run Evaluation** button stays disabled |
|
|
157
|
+
| ⚠ | Warning, listed below the description. Skill still runs, but you should fix before publishing. |
|
|
158
|
+
|
|
159
|
+
Common warnings (and what they mean):
|
|
160
|
+
|
|
161
|
+
| Warning | Cause / Fix |
|
|
162
|
+
| -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
|
|
163
|
+
| `description does not appear to state when the skill should be used` | Add a "Use when …" trigger phrase (§2) |
|
|
164
|
+
| `Instructions are ~N tokens (recommended <5000)` | Skill body too long. Split into multiple skills or move examples to bundled reference files. |
|
|
165
|
+
| `evals/evals.json present but invalid: …` | The file exists but parsing failed. The reason follows the colon (e.g. `invalid JSON`, `missing skill_name`). |
|
|
166
|
+
| `No evals/evals.json found — skill cannot be evaluated …` | Auto-generation will run on Evaluate. Provide your own to control what's tested. |
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## 5. Reading the run progress
|
|
171
|
+
|
|
172
|
+
While a run is in flight, the progress bar shows three counters:
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
N passed N failed ⚠ N errored
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
The distinction is intentional and matters:
|
|
179
|
+
|
|
180
|
+
| Status | Meaning | Improver behaviour |
|
|
181
|
+
| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
|
182
|
+
| `passed` | Agent ran cleanly **and** every assertion graded true. | Treated as a positive example. |
|
|
183
|
+
| `failed` | Agent ran cleanly but **at least one assertion graded false**. | This is the signal the improver learns from — the skill is the suspect. |
|
|
184
|
+
| `errored` | The **agent itself** crashed / endpoint unreachable / timed out — assertions were skipped because grading them would (a) waste a judge call and (b) wrongly blame the skill. | **Excluded** from improvement-proposal evidence. Fix the agent (endpoint, auth, network) before drawing skill conclusions. |
|
|
185
|
+
|
|
186
|
+
If you see all `errored`, the skill is **unknowable** — the evaluator is
|
|
187
|
+
telling you to debug the agent, not the skill.
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## 6. Auto-applying improvement proposals (`auto: true`)
|
|
192
|
+
|
|
193
|
+
When the LLM proposes an improved `SKILL.md` body, you can ship it
|
|
194
|
+
automatically with the **Apply & Re-run** button (UI) or `--auto` (CLI).
|
|
195
|
+
|
|
196
|
+
The server applies the change **non-destructively**:
|
|
197
|
+
|
|
198
|
+
1. Snapshots the current `SKILL.md` to `SKILL.md.bak` next to it.
|
|
199
|
+
2. Refuses to apply (with an explanatory error pointing to
|
|
200
|
+
`iteration-N/improvement-proposal.json`) if the original instructions
|
|
201
|
+
snapshot doesn't appear verbatim in the file — this prevents the silent
|
|
202
|
+
no-op case where `String.replace` matched nothing but the API still
|
|
203
|
+
claimed `applied: true`.
|
|
204
|
+
|
|
205
|
+
To roll back: `mv SKILL.md.bak SKILL.md`.
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## 7. Where skills are discovered
|
|
210
|
+
|
|
211
|
+
The discover endpoint scans both **user scope** and **project scope**, in
|
|
212
|
+
this order:
|
|
213
|
+
|
|
214
|
+
| Path | Source label | Notes |
|
|
215
|
+
| -------------------------- | ------------------------ | -------------------------------------- |
|
|
216
|
+
| `~/.claude/skills/` | `Claude Code (user)` | Per Claude Code spec — user-global. |
|
|
217
|
+
| `<cwd>/.claude/skills/` | `Claude Code` | Project scope. |
|
|
218
|
+
| `<cwd>/.kiro/skills/` | `Kiro` | |
|
|
219
|
+
| `<cwd>/.kiro/steering/` | `Kiro` | |
|
|
220
|
+
| `<cwd>/.codex/` | `Codex` | |
|
|
221
|
+
| `<cwd>/.cursor/rules/` | `Cursor` | |
|
|
222
|
+
| `<cwd>/.github/copilot/` | `Copilot` | |
|
|
223
|
+
| `<cwd>/.continue/skills/` | `Continue` | |
|
|
224
|
+
| `<cwd>/skills/` | `Project` | |
|
|
225
|
+
|
|
226
|
+
Duplicate skill folders (same absolute path) appear once. Home-relative
|
|
227
|
+
paths render as `~/…` in the dropdown. You can also paste a path manually
|
|
228
|
+
or upload a single `SKILL.md` from the UI.
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## 8. CLI
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
# Run on a specific skill folder
|
|
236
|
+
agent-health skill ./my-skill --agent claude-code --model claude-sonnet
|
|
237
|
+
|
|
238
|
+
# Auto-apply the proposed improvement and re-run
|
|
239
|
+
agent-health skill ./my-skill --auto
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
The CLI emits the same SSE event stream the UI consumes; `evalStatus` per
|
|
243
|
+
case is logged with the same tri-state semantics described in §5.
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## 9. Troubleshooting
|
|
248
|
+
|
|
249
|
+
| Symptom | Likely cause |
|
|
250
|
+
| ------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
251
|
+
| Skill validates but A/B delta is ~0% | Assertions aren't discriminating — a baseline agent passes them too. Rewrite assertions to require knowledge the skill uniquely provides. |
|
|
252
|
+
| All evals graded `errored` | Agent endpoint unreachable, auth failed, or model timed out. Check the agent's settings page first; the skill is unknowable until then. |
|
|
253
|
+
| `Cannot auto-apply: original instructions snapshot does not match …` | The `SKILL.md` was edited between proposal generation and apply. Open `iteration-N/improvement-proposal.json`, review, and merge by hand. |
|
|
254
|
+
| `description does not appear to state when the skill should be used` | Add a "Use when …" trigger phrase. The matcher needs it (§2). |
|
|
255
|
+
| `allowed-tools` parsed wrong (e.g. `["Read,Write"]`) | Pre-PR-206 behaviour — upgrade. The current parser accepts both YAML lists and whitespace-separated strings. |
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## See also
|
|
260
|
+
|
|
261
|
+
- [AgentSkills open standard](https://agentskills.io/)
|
|
262
|
+
- [Claude Code skills documentation](https://docs.claude.com/en/docs/claude-code/skills)
|
|
263
|
+
- [`docs/SDK.md`](./SDK.md) — code-based test SDK (different surface; complementary)
|
|
264
|
+
- Source: [`services/skills/`](../services/skills/), [`server/routes/skills.ts`](../server/routes/skills.ts), [`components/skills/SkillsPage.tsx`](../components/skills/SkillsPage.tsx)
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# Storage: OpenSearch index field-limit growth (`evals_runs`)
|
|
2
|
+
|
|
3
|
+
## Incident
|
|
4
|
+
|
|
5
|
+
Owner-hit while running code-QA benchmarks: report/run persistence on the
|
|
6
|
+
shared cluster's `evals_runs` index failed with
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
illegal_argument_exception: Limit of total fields [5000] has been exceeded
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Run **execution** succeeded — only the **write** errored out, i.e. data loss
|
|
13
|
+
(the completed report was never persisted).
|
|
14
|
+
|
|
15
|
+
This is the same *class* of bug PR #418 fixed for `evals_experiments`
|
|
16
|
+
(`EvaluationRun.results` / `testCaseSnapshots`): OpenSearch's default dynamic
|
|
17
|
+
mapping mints a new mapped field for every previously-unseen key under a
|
|
18
|
+
free-form object, and the field-count budget (`index.mapping.total_fields.limit`)
|
|
19
|
+
is **shared across every document in the index**, not per-document. #418 did
|
|
20
|
+
not cover `evals_runs` (the report/`TestCaseRun` index used by the code-SDK
|
|
21
|
+
path) — this fix does.
|
|
22
|
+
|
|
23
|
+
## Root cause: two unprotected growth vectors in `evals_runs`
|
|
24
|
+
|
|
25
|
+
Both are driven by the same source: `EvaluationMetrics`
|
|
26
|
+
(`types/index.ts`) is an open index signature (`[key: string]: number |
|
|
27
|
+
undefined`) by design — custom/system evaluators declare arbitrary metric
|
|
28
|
+
dimension names via `evaluator.scoringConfig.metrics`
|
|
29
|
+
(`server/services/judgeResponseParser.ts`'s `extractMetrics()`,
|
|
30
|
+
`services/storage/asyncRunStorage.ts`'s `storedMetricsToApp()` /
|
|
31
|
+
`toStorageFormat()` — see the comments in both, which explicitly call out
|
|
32
|
+
"preserve every metric the judge emitted, not just the four legacy keys").
|
|
33
|
+
Every *distinct* custom metric name, across every run/matcher ever written,
|
|
34
|
+
used to mint a brand-new mapped field, shared index-wide, forever.
|
|
35
|
+
|
|
36
|
+
| Field (in `evals_runs`) | Shape | Growth vector |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| `metrics` (report-level) | `Record<string, number>` | One set of dynamic names per run — one custom evaluator with N metric names adds ≤N new fields **the first time it's seen**, but a code-QA benchmark suite iterating on many custom evaluators over time accumulates without bound. |
|
|
39
|
+
| `matcherResults[].judgeMetrics` | `Record<string, number>`, nested inside a `nested`-typed array | Same growth, but **per SDK `judge()` call** — a single code-QA test case with many `expect`/`judge()` claims × many custom judge dimensions multiplies fast. This is the "code-SDK path" referenced in the incident — `matcherResults` is populated exclusively by the code-based test SDK (`docs/SDK.md`), not the legacy UI-driven runner. |
|
|
40
|
+
|
|
41
|
+
Everything else already flagged in the original bug report — matcher
|
|
42
|
+
`actual`/`expected`, `trajectory`, `logs`, `rawEvents`, `improvementStrategies`,
|
|
43
|
+
`spans` (span attributes) — was **already** `{ type: 'object', enabled: false
|
|
44
|
+
}` in `server/constants/indexMappings.ts` before this change (audited, not
|
|
45
|
+
touched). `llmJudgeResponse` (which itself has an open `extraFields`/
|
|
46
|
+
`parsedMetrics` shape) is **never persisted** to `evals_runs` at all
|
|
47
|
+
(`toStorageFormat()` doesn't include it) — confirmed via `git grep
|
|
48
|
+
llmJudgeResponse services/storage server/adapters`, no hits — so it isn't a
|
|
49
|
+
growth vector for this index either.
|
|
50
|
+
|
|
51
|
+
## Fix (mirrors #418's pattern)
|
|
52
|
+
|
|
53
|
+
`server/constants/indexMappings.ts`, `evals_runs` index:
|
|
54
|
+
|
|
55
|
+
```diff
|
|
56
|
+
metrics: {
|
|
57
|
+
+ dynamic: false,
|
|
58
|
+
properties: {
|
|
59
|
+
accuracy: { type: 'float' },
|
|
60
|
+
faithfulness: { type: 'float' },
|
|
61
|
+
latency_score: { type: 'float' },
|
|
62
|
+
trajectory_alignment_score: { type: 'float' },
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
...
|
|
66
|
+
matcherResults: {
|
|
67
|
+
type: 'nested',
|
|
68
|
+
properties: {
|
|
69
|
+
...
|
|
70
|
+
judgeMetrics: {
|
|
71
|
+
+ dynamic: false,
|
|
72
|
+
properties: {
|
|
73
|
+
accuracy: { type: 'float' },
|
|
74
|
+
faithfulness: { type: 'float' },
|
|
75
|
+
latency_score: { type: 'float' },
|
|
76
|
+
trajectory_alignment_score: { type: 'float' },
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Unlike #418's `results`/`testCaseSnapshots` (`enabled: false`, fully opaque),
|
|
84
|
+
this uses `dynamic: false` **with explicit typed sub-properties** for the
|
|
85
|
+
four legacy metric names — they stay real, typed, queryable fields (nothing
|
|
86
|
+
queries them today — see the audit below — but it's free to keep them typed),
|
|
87
|
+
while every *other* metric/dimension name is stored in `_source` (readable,
|
|
88
|
+
unaffected) but never added to the mapping. `_source` is unaffected either
|
|
89
|
+
way — the choice between `enabled:false` and `dynamic:false` only changes
|
|
90
|
+
what OpenSearch can filter/sort/aggregate on, never what's persisted or
|
|
91
|
+
returned.
|
|
92
|
+
|
|
93
|
+
## Query audit — nothing queried becomes unsearchable
|
|
94
|
+
|
|
95
|
+
Every OpenSearch-level query/filter/sort/aggregation against `evals_runs`
|
|
96
|
+
(`server/adapters/opensearch/StorageModule.ts`'s `OpenSearchRunOperations`)
|
|
97
|
+
was enumerated. None touch `metrics.*` or `matcherResults[].judgeMetrics.*`
|
|
98
|
+
beyond the four legacy names, which stay mapped:
|
|
99
|
+
|
|
100
|
+
| Consumer | Query | Fields used | Affected by this fix? |
|
|
101
|
+
|---|---|---|---|
|
|
102
|
+
| `OpenSearchRunOperations.search()` | `term` filters | `experimentId`, `experimentRunId`, `testCaseId`, `agentId`, `modelId`, `status`, `passFailStatus` | No — untouched, still explicit `keyword` fields |
|
|
103
|
+
| `OpenSearchRunOperations.search()` | `range` filter | `createdAt` | No — untouched, still `date` |
|
|
104
|
+
| `OpenSearchRunOperations.getAll()` / `.search()` | `sort` | `createdAt` | No |
|
|
105
|
+
| `OpenSearchRunOperations.countsByTestCase()` | `terms` agg | `testCaseId` | No |
|
|
106
|
+
| `asyncRunStorage.ts` `SearchQuery.minAccuracy` | **application-level** `Array.filter()`, not an OpenSearch query (`reports.filter(r => r.metrics.accuracy >= ...)`) | `metrics.accuracy` (read from `_source` in JS) | No — reads the value out of `_source`, which is unaffected by `dynamic: false`. If this were ever converted to a server-side `range` query, it would still work: `accuracy` stays an explicitly mapped, queryable field. |
|
|
107
|
+
| UI (`MatcherResultsPanel.tsx`, `JudgeSection.tsx`, `RunDetailsContent.tsx`) | none — reads `matcherResults`/`judgeMetrics` out of the fetched JSON document, never issues its own OpenSearch query | n/a | No |
|
|
108
|
+
| `services/evaluation/index.ts`, `services/benchmarkRunner.ts`, `services/hookOrchestrator.ts` | none — same, in-process consumption of the already-fetched report | n/a | No |
|
|
109
|
+
|
|
110
|
+
Conclusion: **no consumer anywhere issues an OpenSearch-side query against a
|
|
111
|
+
non-legacy `metrics.*` or `judgeMetrics.*` name.** Both are read back via
|
|
112
|
+
`_source` wherever consumed (search, list, comparison, UI). This mirrors
|
|
113
|
+
exactly the trade-off #418 already made and documented for
|
|
114
|
+
`EvaluationRun.results`.
|
|
115
|
+
|
|
116
|
+
## Migration story — what to run, exactly
|
|
117
|
+
|
|
118
|
+
**Nothing runs automatically against the live cluster from this PR.**
|
|
119
|
+
|
|
120
|
+
### New / fresh indexes
|
|
121
|
+
|
|
122
|
+
No action needed. `ensureIndexes()` (`server/services/indexInitializer.ts`,
|
|
123
|
+
called on every server boot and on "attach new cluster") creates any missing
|
|
124
|
+
index straight from the updated `INDEX_MAPPINGS` — new deployments and any
|
|
125
|
+
environment that doesn't have `evals_runs` yet get the fix immediately.
|
|
126
|
+
|
|
127
|
+
### Existing, NOT-YET-poisoned `evals_runs` (most environments)
|
|
128
|
+
|
|
129
|
+
Also no action needed, but not immediate — `ensureIndexes()` also calls
|
|
130
|
+
`client.indices.putMapping()` on every boot for existing indexes, which is
|
|
131
|
+
how the `dynamic: false` fix reaches an already-existing-but-clean index: it
|
|
132
|
+
succeeds silently and the index is protected from the next write onward.
|
|
133
|
+
|
|
134
|
+
### The shared cluster's `evals_runs`, if already poisoned
|
|
135
|
+
|
|
136
|
+
If any code-QA benchmark run already wrote a custom evaluator metric name to
|
|
137
|
+
the shared cluster before this fix ships, `evals_runs.metrics` (and/or
|
|
138
|
+
`matcherResults.judgeMetrics`) already has real, dynamically-inferred
|
|
139
|
+
sub-properties. OpenSearch's `putMapping` **rejects** an `enabled`/`dynamic`
|
|
140
|
+
change on a field that already has sub-properties
|
|
141
|
+
(`mapper_exception: the [dynamic] parameter can't be updated for the object
|
|
142
|
+
mapping [metrics]`) — `ensureIndexes()` catches this, logs a warning, and
|
|
143
|
+
otherwise no-ops (no crash, no data loss, same as #418's documented
|
|
144
|
+
`mapper_exception` handling for `results`). **The index keeps growing** until
|
|
145
|
+
an explicit reindex is run.
|
|
146
|
+
|
|
147
|
+
**This is not new migration code** — the existing generic reindex mechanism
|
|
148
|
+
(`reindexSingleIndex()`, `server/services/mappingFixer.ts`, already shipped
|
|
149
|
+
and already exposed at `POST /api/storage/reindex`, `server/routes/storage/admin.ts`)
|
|
150
|
+
already recreates any `INDEX_MAPPINGS`-registered index from scratch and
|
|
151
|
+
copies every document across, which sheds a poisoned mapping's dynamically-
|
|
152
|
+
inferred sub-fields while preserving 100% of the underlying `_source` data
|
|
153
|
+
(proven in `tests/integration/services/storage/evalsRunsMappingMigrationRecipe.integration.test.ts`,
|
|
154
|
+
run against a real OpenSearch container with a deliberately-poisoned index).
|
|
155
|
+
|
|
156
|
+
**The owner's exact recipe, when ready to run it against the shared cluster:**
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
# 1. Confirm the target index actually needs it (optional sanity check):
|
|
160
|
+
curl -s -X GET "$OPENSEARCH_STORAGE_ENDPOINT/evals_runs/_mapping" \
|
|
161
|
+
-u "$OPENSEARCH_STORAGE_USERNAME:$OPENSEARCH_STORAGE_PASSWORD" \
|
|
162
|
+
| jq '.evals_runs.mappings.properties.metrics'
|
|
163
|
+
# If this prints a `dynamic` key, it's already fixed. If it prints only
|
|
164
|
+
# `properties` with more than the 4 legacy metric names, it's poisoned.
|
|
165
|
+
|
|
166
|
+
# 2. Run the reindex via the running server's admin API (recreates the
|
|
167
|
+
# index from the current INDEX_MAPPINGS and copies every document
|
|
168
|
+
# across; the same doc-count-validated, recovery-safe path
|
|
169
|
+
# reindexSingleIndex() has always used for keyword-type mismatch fixes):
|
|
170
|
+
curl -s -X POST "http://localhost:4001/api/storage/reindex" \
|
|
171
|
+
-H 'Content-Type: application/json' \
|
|
172
|
+
-d '{"index": "evals_runs"}'
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Caveats to read before running this against the shared cluster:
|
|
176
|
+
|
|
177
|
+
- **No write lock during a manual `/api/storage/reindex` call.** The
|
|
178
|
+
auto-fix boot path (`fixIndexMappings()`) acquires a process-local
|
|
179
|
+
migration lock around the reindex; the manual admin route calls
|
|
180
|
+
`reindexSingleIndex()` directly and does **not** (pre-existing gap in
|
|
181
|
+
`server/routes/storage/admin.ts`, not introduced by this PR — flagged here,
|
|
182
|
+
not fixed, since it's out of scope for this change). Run it during a quiet
|
|
183
|
+
window (no in-flight evaluation runs writing reports) to avoid a write
|
|
184
|
+
racing the index delete/recreate step.
|
|
185
|
+
- It touches only `evals_runs`. The already-known-poisoned `evals_experiments`
|
|
186
|
+
(800+ stale `results.*` fields, per the incident notes) uses the identical
|
|
187
|
+
recipe (`{"index": "evals_experiments"}`) — that cleanup is separately
|
|
188
|
+
planned by ops; this PR does not touch or schedule it.
|
|
189
|
+
- Document count is validated before the temporary index is deleted; if the
|
|
190
|
+
copy-back count doesn't match, the error message names the surviving temp
|
|
191
|
+
index (`evals_runs_reindex_temp`) for manual recovery — nothing is deleted
|
|
192
|
+
until the counts are confirmed equal.
|
|
193
|
+
|
|
194
|
+
## Tests
|
|
195
|
+
|
|
196
|
+
- Unit (`tests/unit/server/constants/indexMappings.test.ts`): mapping-shape
|
|
197
|
+
assertions — `dynamic: false` + typed legacy properties on both `metrics`
|
|
198
|
+
and `matcherResults.judgeMetrics`; pre-existing `enabled:false` fields stay
|
|
199
|
+
disabled; every field `OpenSearchRunOperations.search()` queries stays
|
|
200
|
+
explicitly mapped.
|
|
201
|
+
- Integration, real OpenSearch
|
|
202
|
+
(`tests/integration/services/storage/testCaseRunMetricsMappingGrowth.integration.test.ts`):
|
|
203
|
+
writes one report with 1000+ distinct custom `metrics`/`judgeMetrics` names
|
|
204
|
+
(500 report-level + 125 `judge()` calls × 4 dimensions), asserts it
|
|
205
|
+
round-trips correctly and the index's total mapped-field count does not
|
|
206
|
+
grow; asserts the query-audit fields stay queryable.
|
|
207
|
+
- Integration, real OpenSearch, migration recipe
|
|
208
|
+
(`tests/integration/services/storage/evalsRunsMappingMigrationRecipe.integration.test.ts`):
|
|
209
|
+
deliberately poisons a throwaway index the old way, runs the *existing*
|
|
210
|
+
`reindexSingleIndex()`, asserts the mapping resets to `dynamic: false` and
|
|
211
|
+
all document data survives byte-for-byte.
|
|
212
|
+
|
|
213
|
+
Both integration suites skip gracefully (with a console warning) if no
|
|
214
|
+
OpenSearch cluster is reachable at `TEST_OPENSEARCH_ENDPOINT` (default
|
|
215
|
+
`http://localhost:9200`) — the unit suite covers the mapping-shape assertions
|
|
216
|
+
unconditionally.
|