@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
|
Binary file
|
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
# Plan: Code-Based Test Case SDK — Field Redesign (v2)
|
|
2
|
+
|
|
3
|
+
## Status (as of 2026-05-16)
|
|
4
|
+
|
|
5
|
+
### Completed (in working tree, not yet committed)
|
|
6
|
+
- [x] `lib/testCases/types.ts` — Rewritten with `TestOptions` (prompt required), `CodeTestCase`, `EvalResult`
|
|
7
|
+
- [x] `lib/testCases/define.ts` — Rewritten with `test()` API, file-scoped registries, `defineTestCases()` compat wrapper
|
|
8
|
+
- [x] `lib/testCases/judge.ts` — Rewritten with runtime `wasJudgeCalled()`/`resetJudgeFlag()` flags
|
|
9
|
+
- [x] `lib/testCases/loader.ts` — Rewritten with per-test-case `computeTestCaseHash()`, file-scoped loading via registry
|
|
10
|
+
- [x] `lib/testCases/index.ts` — Updated barrel exports for new API
|
|
11
|
+
- [x] `lib/index.ts` — Added SDK exports (`test`, `defineTestCases`, `judge`, `expect`)
|
|
12
|
+
- [x] `services/sourceResolver.ts` — Added `EvaluateFn` type, `evaluateFnMap` to `ResolvedSources`, `code-import` case in switch (partial — needs unification to `import` type)
|
|
13
|
+
|
|
14
|
+
### Not Started
|
|
15
|
+
- [ ] Unified `import` source type (replace `file-import` + `code-import` + `directory-import`)
|
|
16
|
+
- [ ] `services/evaluationRunner.ts` — Deterministic eval path with `resetJudgeFlag`/`wasJudgeCalled` inference
|
|
17
|
+
- [ ] `types/index.ts` — `sourceFile` replaces `sourceUri`, `evaluationType` on TestCaseVersion, unified source type
|
|
18
|
+
- [ ] `server/constants/indexMappings.ts` — `sourceFile` field
|
|
19
|
+
- [ ] `server/adapters/file/StorageModule.ts` — `bulkUpsert` match on `sourceFile`
|
|
20
|
+
- [ ] `server/adapters/opensearch/StorageModule.ts` — same
|
|
21
|
+
- [ ] `cli/commands/benchmark.ts` — `-f` accepts dirs, exit codes, `--reporter`
|
|
22
|
+
- [ ] `cli/reporters/` — `summary.ts`, `junit.ts`, `json.ts`
|
|
23
|
+
- [ ] `components/RunDetailsContent.tsx` — Read evaluationType from version
|
|
24
|
+
- [ ] `components/evals3/TestCasesPage.tsx` — Badge on `sourceFile`
|
|
25
|
+
- [ ] All test updates (see step 11)
|
|
26
|
+
|
|
27
|
+
### Key Context for Handoff
|
|
28
|
+
- Branch: `feat/test-case-sdk` (local only, working tree has uncommitted changes)
|
|
29
|
+
- The v1 implementation (committed on remote `feat/test-case-sdk`) uses `sourceUri`, `defineTestCases()`, per-file hash, and `evaluationType` on TestCaseRun. All of that is being replaced.
|
|
30
|
+
- `evaluationRunner.ts` already has `runWithConcurrencyLimit()` — no need for `p-limit` dep.
|
|
31
|
+
- The plan file was pushed to `fork/docs/sdk-field-redesign-plan` branch.
|
|
32
|
+
- Existing tests reference old field names (`sourceUri`, old `defineTestCases` API) and will need updating.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Context
|
|
37
|
+
|
|
38
|
+
The initial SDK implementation (steps 1-11) is complete and passing. This redesign incorporates principal engineer review feedback to make the SDK actually production-ready — not just a working API, but something teams adopt over alternatives (Promptfoo, Braintrust, Langsmith).
|
|
39
|
+
|
|
40
|
+
**Core insight:** The previous plan focused on internal field placement. This revision prioritizes the **customer-facing contract** — the API signature, CI exit codes, parallelism, and cost visibility — and defers internal storage plumbing where it doesn't block adoption.
|
|
41
|
+
|
|
42
|
+
**Key changes from v1:**
|
|
43
|
+
1. **Kill `agentic: boolean`** — infer evaluation type at runtime from whether `judge()` was called. No customer-facing field.
|
|
44
|
+
2. **Add explicit `prompt` field** — test name is a description, prompt is what gets sent to the agent.
|
|
45
|
+
3. **Add `--concurrency N`** — parallel test execution with semaphore.
|
|
46
|
+
4. **Define CI contract** — exit codes, `--reporter junit|json`, pass/fail gate.
|
|
47
|
+
5. **File-scoped isolation** — each file gets its own registry (no global mutable state).
|
|
48
|
+
6. **Unify source types** — merge `file-import`, `code-import`, `directory-import` into a single `import` type that auto-detects by extension. `-f` accepts files and dirs.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Implementation Steps
|
|
53
|
+
|
|
54
|
+
### 1. Redesign SDK API: `test()` with explicit prompt
|
|
55
|
+
|
|
56
|
+
**Files:** `lib/testCases/types.ts`, `lib/testCases/define.ts`
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
// lib/testCases/types.ts
|
|
60
|
+
export interface TestOptions {
|
|
61
|
+
prompt: string; // REQUIRED — what gets sent to the agent
|
|
62
|
+
category: string;
|
|
63
|
+
difficulty: 'Easy' | 'Medium' | 'Hard';
|
|
64
|
+
description?: string;
|
|
65
|
+
context?: { description: string; value: string }[];
|
|
66
|
+
labels?: string[];
|
|
67
|
+
timeout?: number; // ms, default 120000 (2 min)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface CodeTestCase {
|
|
71
|
+
name: string;
|
|
72
|
+
options: TestOptions;
|
|
73
|
+
evaluate: (result: EvalResult) => Promise<void> | void;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface EvalResult {
|
|
77
|
+
trajectory: TrajectoryStep[];
|
|
78
|
+
agentOutput: string;
|
|
79
|
+
rawEvents: any[];
|
|
80
|
+
runId?: string;
|
|
81
|
+
durationMs: number;
|
|
82
|
+
tokenUsage?: { prompt: number; completion: number; total: number };
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
// lib/testCases/define.ts
|
|
88
|
+
export interface FileRegistry {
|
|
89
|
+
tests: CodeTestCase[];
|
|
90
|
+
filePath?: string;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Per-file registries (keyed by absolute file path)
|
|
94
|
+
const registries = new Map<string, FileRegistry>();
|
|
95
|
+
let activeFile: string | null = null;
|
|
96
|
+
|
|
97
|
+
export function setActiveFile(filePath: string): void {
|
|
98
|
+
activeFile = filePath;
|
|
99
|
+
if (!registries.has(filePath)) {
|
|
100
|
+
registries.set(filePath, { tests: [], filePath });
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function test(
|
|
105
|
+
name: string,
|
|
106
|
+
options: TestOptions,
|
|
107
|
+
evaluate: (result: EvalResult) => Promise<void> | void
|
|
108
|
+
): void {
|
|
109
|
+
if (!name || typeof name !== 'string') throw new Error('test() requires a name');
|
|
110
|
+
if (!options.prompt) throw new Error('test() requires options.prompt');
|
|
111
|
+
if (!options.category) throw new Error('test() requires options.category');
|
|
112
|
+
if (!options.difficulty) throw new Error('test() requires options.difficulty');
|
|
113
|
+
if (typeof evaluate !== 'function') throw new Error('test() requires an evaluate function');
|
|
114
|
+
|
|
115
|
+
const registry = activeFile ? registries.get(activeFile)! : getDefaultRegistry();
|
|
116
|
+
registry.tests.push({ name, options, evaluate });
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export function getRegisteredTests(filePath?: string): CodeTestCase[] {
|
|
120
|
+
if (filePath) return [...(registries.get(filePath)?.tests ?? [])];
|
|
121
|
+
// Return all tests across all files
|
|
122
|
+
return [...registries.values()].flatMap(r => [...r.tests]);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export function clearRegistry(filePath?: string): void {
|
|
126
|
+
if (filePath) registries.delete(filePath);
|
|
127
|
+
else registries.clear();
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Customer usage:**
|
|
132
|
+
```typescript
|
|
133
|
+
// evals/cybergym.eval.ts
|
|
134
|
+
import { test, expect } from '@opensearch-project/agent-health';
|
|
135
|
+
|
|
136
|
+
test('CyberGym Task 42', {
|
|
137
|
+
prompt: 'Analyze the vulnerability in the authentication module and provide a proof of concept exploit',
|
|
138
|
+
category: 'Security',
|
|
139
|
+
difficulty: 'Hard',
|
|
140
|
+
}, async (result) => {
|
|
141
|
+
const poc = extractPoc(result.agentOutput);
|
|
142
|
+
const res = await submitToCyberGym(poc, 'task-42');
|
|
143
|
+
expect(res.exit_code).to.not.equal(0);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
test('RCA Log Analysis', {
|
|
147
|
+
prompt: 'Investigate the spike in 5xx errors starting at 14:30 UTC. Identify the root cause.',
|
|
148
|
+
category: 'RCA',
|
|
149
|
+
difficulty: 'Medium',
|
|
150
|
+
}, async (result) => {
|
|
151
|
+
// Use LLM judge for semantic evaluation
|
|
152
|
+
await judge(result.trajectory, ['Identifies root cause', 'Suggests remediation']);
|
|
153
|
+
// Can also add deterministic checks
|
|
154
|
+
expect(result.durationMs).to.be.lessThan(60000);
|
|
155
|
+
});
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### 2. Infer `evaluationType` at runtime (kill `agentic` field)
|
|
159
|
+
|
|
160
|
+
**No customer-facing field.** Instead, detect at runtime:
|
|
161
|
+
|
|
162
|
+
**File:** `lib/testCases/judge.ts`
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
// Thread-local flag set when judge() is called during evaluate()
|
|
166
|
+
let judgeCalledInCurrentEval = false;
|
|
167
|
+
|
|
168
|
+
export function wasJudgeCalled(): boolean {
|
|
169
|
+
return judgeCalledInCurrentEval;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export function resetJudgeFlag(): void {
|
|
173
|
+
judgeCalledInCurrentEval = false;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export async function judge(trajectory: TrajectoryStep[], criteria: string[]): Promise<JudgeVerdict> {
|
|
177
|
+
judgeCalledInCurrentEval = true;
|
|
178
|
+
// Call LLM judge, return verdict
|
|
179
|
+
// ...
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**File:** `services/evaluationRunner.ts` — after calling evaluate():
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
resetJudgeFlag();
|
|
187
|
+
try {
|
|
188
|
+
await evalFn({ trajectory, agentOutput, rawEvents, durationMs });
|
|
189
|
+
const usedJudge = wasJudgeCalled();
|
|
190
|
+
report.passFailStatus = 'passed';
|
|
191
|
+
// evaluationType is inferred, stored on version after first run
|
|
192
|
+
} catch (evalError: any) {
|
|
193
|
+
const usedJudge = wasJudgeCalled();
|
|
194
|
+
report.passFailStatus = 'failed';
|
|
195
|
+
report.assertionError = evalError.message;
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
**On TestCaseVersion:** `evaluationType` is set after the first execution:
|
|
200
|
+
- If `judge()` was called → `'agentic'`
|
|
201
|
+
- If only assertions → `'deterministic'`
|
|
202
|
+
- If both → `'hybrid'` (new value)
|
|
203
|
+
|
|
204
|
+
This means version gets its `evaluationType` lazily on first run, not at import time.
|
|
205
|
+
|
|
206
|
+
### 3. Replace `sourceUri` with `sourceFile` + per-test-case hash
|
|
207
|
+
|
|
208
|
+
**File:** `types/index.ts` — on TestCase:
|
|
209
|
+
```typescript
|
|
210
|
+
sourceFile?: string; // Relative path: "evals/cybergym.eval.ts"
|
|
211
|
+
sourceHash?: string; // SHA-256 of per-test-case content (not the whole file)
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**Per-test-case hash** (`lib/testCases/loader.ts`):
|
|
215
|
+
```typescript
|
|
216
|
+
export function computeTestCaseHash(tc: CodeTestCase): string {
|
|
217
|
+
const content = JSON.stringify({
|
|
218
|
+
name: tc.name,
|
|
219
|
+
prompt: tc.options.prompt,
|
|
220
|
+
category: tc.options.category,
|
|
221
|
+
difficulty: tc.options.difficulty,
|
|
222
|
+
context: tc.options.context,
|
|
223
|
+
labels: tc.options.labels,
|
|
224
|
+
description: tc.options.description,
|
|
225
|
+
});
|
|
226
|
+
return crypto.createHash('sha256').update(content).digest('hex');
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
**Match key for upsert:** `name + sourceFile`
|
|
231
|
+
|
|
232
|
+
### 4. Add `--concurrency N` to benchmark runner
|
|
233
|
+
|
|
234
|
+
**File:** `cli/commands/benchmark.ts` — add option:
|
|
235
|
+
```typescript
|
|
236
|
+
.option('-c, --concurrency <number>', 'Number of parallel test executions', '3')
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
**File:** `services/evaluationRunner.ts` — parallel execution with semaphore:
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
import pLimit from 'p-limit';
|
|
243
|
+
|
|
244
|
+
export async function executeEvaluationRun(run, testCases, options) {
|
|
245
|
+
const concurrency = options.concurrency ?? 3;
|
|
246
|
+
const limit = pLimit(concurrency);
|
|
247
|
+
|
|
248
|
+
const tasks = testCases.map(tc =>
|
|
249
|
+
limit(() => executeSingleTestCase(run, tc, options))
|
|
250
|
+
);
|
|
251
|
+
|
|
252
|
+
await Promise.allSettled(tasks);
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
**New dependency:** `p-limit` (tiny, zero-dep semaphore).
|
|
257
|
+
|
|
258
|
+
### 5. Define CI contract: exit codes + reporters
|
|
259
|
+
|
|
260
|
+
**File:** `cli/commands/benchmark.ts`:
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
.option('--reporter <type>', 'Output format: summary (default), junit, json, tap', 'summary')
|
|
264
|
+
.option('--fail-fast', 'Stop on first failure')
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
**Exit codes:**
|
|
268
|
+
- `0` — all tests passed
|
|
269
|
+
- `1` — one or more tests failed
|
|
270
|
+
- `2` — configuration error (bad file, missing agent, etc.)
|
|
271
|
+
|
|
272
|
+
**File:** `cli/reporters/` (new directory):
|
|
273
|
+
|
|
274
|
+
| File | Purpose |
|
|
275
|
+
|------|---------|
|
|
276
|
+
| `summary.ts` | Default terminal output (pass/fail counts, duration, cost) |
|
|
277
|
+
| `junit.ts` | JUnit XML for CI integration (GitHub Actions, Jenkins) |
|
|
278
|
+
| `json.ts` | Machine-readable JSON (for programmatic consumption) |
|
|
279
|
+
|
|
280
|
+
**JUnit output** enables:
|
|
281
|
+
```yaml
|
|
282
|
+
# .github/workflows/eval.yml
|
|
283
|
+
- run: npx agent-health benchmark -f evals/ -a my-agent --reporter junit > results.xml
|
|
284
|
+
- uses: dorny/test-reporter@v1
|
|
285
|
+
with:
|
|
286
|
+
reporter: java-junit
|
|
287
|
+
path: results.xml
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### 6. Add timeout + cost visibility
|
|
291
|
+
|
|
292
|
+
**Timeout per test case** (from `TestOptions.timeout`, default 120s):
|
|
293
|
+
```typescript
|
|
294
|
+
const result = await Promise.race([
|
|
295
|
+
runAgentAndEvaluate(tc),
|
|
296
|
+
timeout(tc.options.timeout ?? 120000),
|
|
297
|
+
]);
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
**Cost summary** in reporter output:
|
|
301
|
+
```
|
|
302
|
+
Results: 48 passed, 2 failed (50 total)
|
|
303
|
+
Duration: 4m 32s
|
|
304
|
+
Tokens: 1.2M prompt / 340K completion
|
|
305
|
+
Est. cost: $4.82 (agent) + $1.20 (judge) = $6.02
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
**File:** `cli/reporters/summary.ts` — aggregate token usage from all runs and compute cost based on model pricing from config.
|
|
309
|
+
|
|
310
|
+
### 7. Move `evaluationType` to TestCaseVersion
|
|
311
|
+
|
|
312
|
+
**File:** `types/index.ts`
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
export interface TestCaseVersion {
|
|
316
|
+
// ... existing fields ...
|
|
317
|
+
evaluationType?: 'agentic' | 'deterministic' | 'hybrid';
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Remove from `TestCaseRun`. Keep `assertionError` on run (execution-time data).
|
|
322
|
+
|
|
323
|
+
**Lazy population:** On first execution of a code-imported test case, update the version's `evaluationType` based on runtime inference (step 2). Subsequent runs don't change it (immutable once set).
|
|
324
|
+
|
|
325
|
+
### 8. Update storage: `sourceFile` + match logic
|
|
326
|
+
|
|
327
|
+
**File:** `server/constants/indexMappings.ts`:
|
|
328
|
+
```diff
|
|
329
|
+
- sourceUri: { type: 'keyword' },
|
|
330
|
+
+ sourceFile: { type: 'keyword' },
|
|
331
|
+
sourceHash: { type: 'keyword' },
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
**File:** `server/adapters/file/StorageModule.ts` + `opensearch/StorageModule.ts`:
|
|
335
|
+
- `bulkUpsert` matches on `name + sourceFile`
|
|
336
|
+
- On hash change → new version (with `evaluationType` if known)
|
|
337
|
+
|
|
338
|
+
### 9. Unified `import` source type in source resolver
|
|
339
|
+
|
|
340
|
+
**File:** `services/sourceResolver.ts`
|
|
341
|
+
|
|
342
|
+
Replace the three separate source types (`file-import`, `code-import`, `directory-import`) with a single `import` type:
|
|
343
|
+
|
|
344
|
+
```typescript
|
|
345
|
+
case 'import': {
|
|
346
|
+
const { testCases, fnMap } = await resolveImport(source.paths, storage);
|
|
347
|
+
// ...
|
|
348
|
+
}
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
**`resolveImport(paths, storage)`** handles the unified logic:
|
|
352
|
+
1. For each path, check if it's a file or directory
|
|
353
|
+
2. If directory → scan for `*.eval.ts`, `*.eval.js`, `*.json` recursively
|
|
354
|
+
3. For each file, route by extension:
|
|
355
|
+
- `.json` → existing JSON import path (parse + `bulkCreate`)
|
|
356
|
+
- `.ts` / `.js` / `.mjs` → code import path (load module + `bulkUpsert`)
|
|
357
|
+
4. Code files produce `evaluateFnMap` entries; JSON files don't
|
|
358
|
+
5. Return combined test cases + fnMap
|
|
359
|
+
|
|
360
|
+
**CLI `-f` flag** accepts both files and directories:
|
|
361
|
+
```bash
|
|
362
|
+
npx agent-health benchmark -f evals/ # scans dir
|
|
363
|
+
npx agent-health benchmark -f evals/rca.eval.ts # single code file
|
|
364
|
+
npx agent-health benchmark -f test-cases.json # single JSON file
|
|
365
|
+
npx agent-health benchmark -f evals/ -f extra.json # mixed
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
**`TestCaseSource` type** simplification:
|
|
369
|
+
```typescript
|
|
370
|
+
// Before: 3 source types
|
|
371
|
+
| { type: 'file-import'; filenames: string[]; testCaseIds: string[] }
|
|
372
|
+
| { type: 'code-import'; filenames: string[]; testCaseIds: string[] }
|
|
373
|
+
| { type: 'directory-import'; dirPaths: string[]; testCaseIds: string[] }
|
|
374
|
+
|
|
375
|
+
// After: 1 unified type
|
|
376
|
+
| { type: 'import'; paths: string[]; testCaseIds: string[] }
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
Keep old types as aliases for backward compat (existing benchmarks may have these in storage).
|
|
380
|
+
|
|
381
|
+
### 10. Update UI
|
|
382
|
+
|
|
383
|
+
**File:** `components/evals3/TestCasesPage.tsx`:
|
|
384
|
+
- "Code" badge on `testCase.sourceFile` (not `sourceUri`)
|
|
385
|
+
- Disable edit for code-sourced test cases
|
|
386
|
+
|
|
387
|
+
**File:** `components/RunDetailsContent.tsx`:
|
|
388
|
+
- Read `evaluationType` from test case version (not report)
|
|
389
|
+
- Show "Hybrid" badge when both judge and assertions were used
|
|
390
|
+
- Show assertion error for deterministic/hybrid failures
|
|
391
|
+
|
|
392
|
+
### 11. Update existing tests
|
|
393
|
+
|
|
394
|
+
| Test File | Change |
|
|
395
|
+
|-----------|--------|
|
|
396
|
+
| `tests/unit/lib/testCases/define.test.ts` | Rewrite for `test()` API with `prompt` field, file-scoped registry |
|
|
397
|
+
| `tests/unit/services/evaluationRunner.deterministic.test.ts` | Remove `evaluationType` from report assertions |
|
|
398
|
+
| `tests/unit/services/sourceResolver.codeImport.test.ts` | `sourceFile` instead of `sourceUri`, prompt field |
|
|
399
|
+
| `tests/unit/server/adapters/bulkUpsert.test.ts` | Match on `sourceFile` |
|
|
400
|
+
| `tests/integration/services/sourceResolver.codeImport.integration.test.ts` | Update for new API |
|
|
401
|
+
| `tests/integration/services/codeSdkObservio.integration.test.ts` | Update field references |
|
|
402
|
+
| `tests/unit/cli/reporters/` (new) | Test junit, json, summary output |
|
|
403
|
+
|
|
404
|
+
### 12. Package exports
|
|
405
|
+
|
|
406
|
+
**File:** `lib/testCases/index.ts`:
|
|
407
|
+
```typescript
|
|
408
|
+
export { test, getRegisteredTests, clearRegistry } from './define.js';
|
|
409
|
+
export { judge } from './judge.js';
|
|
410
|
+
export { defineTestCases } from './compat.js'; // Deprecated
|
|
411
|
+
export type { TestOptions, CodeTestCase, EvalResult } from './types.js';
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
**File:** `lib/index.ts`:
|
|
415
|
+
```typescript
|
|
416
|
+
export { test, defineTestCases, judge } from './testCases/index.js';
|
|
417
|
+
export { expect } from 'chai';
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
**New dependency:** `p-limit` (production — for concurrency control).
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
424
|
+
## Critical Files to Modify
|
|
425
|
+
|
|
426
|
+
| File | Change |
|
|
427
|
+
|------|--------|
|
|
428
|
+
| `lib/testCases/types.ts` | `TestOptions` with `prompt` (required), `timeout`; drop `agentic` |
|
|
429
|
+
| `lib/testCases/define.ts` | File-scoped registries, `test()` with prompt validation |
|
|
430
|
+
| `lib/testCases/loader.ts` | Per-test-case hash, file-scoped loading |
|
|
431
|
+
| `lib/testCases/judge.ts` | Runtime flag for `judge()` calls |
|
|
432
|
+
| `services/evaluationRunner.ts` | Parallel execution (`p-limit`), timeout, infer evaluationType |
|
|
433
|
+
| `services/sourceResolver.ts` | Unified `import` source type, `sourceFile` (relative), per-test-case hash |
|
|
434
|
+
| `types/index.ts` | Replace 3 source types with unified `import` type |
|
|
435
|
+
| `cli/commands/benchmark.ts` | `-f` accepts files+dirs, `--reporter`, `--fail-fast`, exit codes |
|
|
436
|
+
| `cli/reporters/` (new) | `summary.ts`, `junit.ts`, `json.ts` |
|
|
437
|
+
| `types/index.ts` | `evaluationType` on TestCaseVersion (lazy), `sourceFile` on TestCase |
|
|
438
|
+
| `server/constants/indexMappings.ts` | `sourceFile` replaces `sourceUri` |
|
|
439
|
+
| `server/adapters/file/StorageModule.ts` | Match on `sourceFile` in bulkUpsert |
|
|
440
|
+
| `components/RunDetailsContent.tsx` | Read evaluationType from version |
|
|
441
|
+
| `components/evals3/TestCasesPage.tsx` | Badge on `sourceFile` |
|
|
442
|
+
|
|
443
|
+
---
|
|
444
|
+
|
|
445
|
+
## Implementation Order (prioritized by customer impact)
|
|
446
|
+
|
|
447
|
+
1. **SDK API** (steps 1-2) — `test()` with prompt, file-scoped registry, runtime inference
|
|
448
|
+
2. **CI contract** (step 5) — exit codes, reporters
|
|
449
|
+
3. **Parallelism + timeout** (steps 4, 6) — `--concurrency`, per-test timeout
|
|
450
|
+
4. **Storage redesign** (steps 3, 7, 8, 9) — sourceFile, per-test hash, version-level evaluationType
|
|
451
|
+
5. **UI** (step 10) — badges, version-aware rendering
|
|
452
|
+
6. **Tests** (step 11) — update all affected tests
|
|
453
|
+
7. **Exports** (step 12) — package API surface
|
|
454
|
+
|
|
455
|
+
---
|
|
456
|
+
|
|
457
|
+
## Verification Plan
|
|
458
|
+
|
|
459
|
+
1. **Build:** `npm run build:all` passes
|
|
460
|
+
2. **Unit tests:** `npm run test:unit` — all pass
|
|
461
|
+
3. **CI contract test:** `npx agent-health benchmark -f tests/fixtures/sample.eval.ts -a observio --reporter json` returns exit 0/1 correctly
|
|
462
|
+
4. **Parallel test:** 10 test cases with `--concurrency 5` complete in ~2x single-case time (not 10x)
|
|
463
|
+
5. **JUnit output:** Valid XML parseable by `dorny/test-reporter`
|
|
464
|
+
6. **Cost summary:** Token counts + estimated cost displayed in summary reporter
|
|
465
|
+
7. **Per-test hash:** Modify one test in a multi-test file → only that test gets new version
|
|
466
|
+
8. **Runtime inference:** Test with `judge()` → version gets `evaluationType: 'agentic'`; test without → `'deterministic'`; test with both → `'hybrid'`
|
|
467
|
+
9. **Timeout:** Test case exceeding timeout fails with clear error message
|
|
468
|
+
10. **Backward compat:** `defineTestCases([...])` still works, old test cases render correctly
|