@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
package/lib/dist/index.js
DELETED
|
@@ -1,1665 +0,0 @@
|
|
|
1
|
-
// lib/config/defineConfig.ts
|
|
2
|
-
function defineConfig(config) {
|
|
3
|
-
return config;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
// lib/debug.ts
|
|
7
|
-
import fs from "fs";
|
|
8
|
-
import path from "path";
|
|
9
|
-
var isBrowser = typeof window !== "undefined";
|
|
10
|
-
var CONFIG_FILENAME = "agent-health.config.json";
|
|
11
|
-
var serverDebugEnabled = false;
|
|
12
|
-
if (!isBrowser) {
|
|
13
|
-
try {
|
|
14
|
-
const configPath = path.join(process.cwd(), CONFIG_FILENAME);
|
|
15
|
-
if (fs.existsSync(configPath)) {
|
|
16
|
-
const content = fs.readFileSync(configPath, "utf-8");
|
|
17
|
-
const config = JSON.parse(content) || {};
|
|
18
|
-
serverDebugEnabled = config.debug === true;
|
|
19
|
-
} else if (process.env?.DEBUG === "true") {
|
|
20
|
-
serverDebugEnabled = true;
|
|
21
|
-
}
|
|
22
|
-
} catch (err) {
|
|
23
|
-
if (process.env?.DEBUG === "true") {
|
|
24
|
-
serverDebugEnabled = true;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
function isDebugEnabled() {
|
|
29
|
-
if (isBrowser) {
|
|
30
|
-
try {
|
|
31
|
-
return localStorage.getItem("agenteval_debug") === "true";
|
|
32
|
-
} catch {
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return serverDebugEnabled;
|
|
37
|
-
}
|
|
38
|
-
function debug(module, ...args) {
|
|
39
|
-
if (isDebugEnabled()) {
|
|
40
|
-
console.debug(`[${module}]`, ...args);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// services/connectors/base/BaseConnector.ts
|
|
45
|
-
var BaseConnector = class {
|
|
46
|
-
/**
|
|
47
|
-
* Build HTTP headers from auth configuration
|
|
48
|
-
* @param auth Authentication configuration
|
|
49
|
-
* @returns Headers object ready for fetch/axios
|
|
50
|
-
*/
|
|
51
|
-
buildAuthHeaders(auth) {
|
|
52
|
-
const headers = {};
|
|
53
|
-
switch (auth.type) {
|
|
54
|
-
case "basic":
|
|
55
|
-
if (auth.username && auth.password) {
|
|
56
|
-
const credentials = Buffer.from(`${auth.username}:${auth.password}`).toString("base64");
|
|
57
|
-
headers["Authorization"] = `Basic ${credentials}`;
|
|
58
|
-
}
|
|
59
|
-
break;
|
|
60
|
-
case "bearer":
|
|
61
|
-
if (auth.token) {
|
|
62
|
-
headers["Authorization"] = `Bearer ${auth.token}`;
|
|
63
|
-
}
|
|
64
|
-
break;
|
|
65
|
-
case "api-key":
|
|
66
|
-
if (auth.token) {
|
|
67
|
-
headers["X-API-Key"] = auth.token;
|
|
68
|
-
headers["x-api-key"] = auth.token;
|
|
69
|
-
}
|
|
70
|
-
break;
|
|
71
|
-
case "aws-sigv4":
|
|
72
|
-
console.warn("[BaseConnector] AWS SigV4 auth requires runtime signing");
|
|
73
|
-
break;
|
|
74
|
-
case "none":
|
|
75
|
-
default:
|
|
76
|
-
break;
|
|
77
|
-
}
|
|
78
|
-
if (auth.headers) {
|
|
79
|
-
Object.assign(headers, auth.headers);
|
|
80
|
-
}
|
|
81
|
-
return headers;
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Build environment variables from auth configuration
|
|
85
|
-
* Used by subprocess connectors
|
|
86
|
-
*/
|
|
87
|
-
buildAuthEnv(auth) {
|
|
88
|
-
const env = {};
|
|
89
|
-
if (auth.type === "aws-sigv4") {
|
|
90
|
-
if (auth.awsRegion) env["AWS_REGION"] = auth.awsRegion;
|
|
91
|
-
if (auth.awsAccessKeyId) env["AWS_ACCESS_KEY_ID"] = auth.awsAccessKeyId;
|
|
92
|
-
if (auth.awsSecretAccessKey) env["AWS_SECRET_ACCESS_KEY"] = auth.awsSecretAccessKey;
|
|
93
|
-
if (auth.awsSessionToken) env["AWS_SESSION_TOKEN"] = auth.awsSessionToken;
|
|
94
|
-
}
|
|
95
|
-
return env;
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Generate a unique ID for trajectory steps
|
|
99
|
-
*/
|
|
100
|
-
generateId() {
|
|
101
|
-
return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Create a trajectory step with common fields
|
|
105
|
-
*/
|
|
106
|
-
createStep(type, content, extra) {
|
|
107
|
-
return {
|
|
108
|
-
id: this.generateId(),
|
|
109
|
-
timestamp: Date.now(),
|
|
110
|
-
type,
|
|
111
|
-
content,
|
|
112
|
-
...extra
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Default health check implementation
|
|
117
|
-
* Subclasses can override for protocol-specific checks
|
|
118
|
-
*/
|
|
119
|
-
async healthCheck(endpoint, auth) {
|
|
120
|
-
try {
|
|
121
|
-
const headers = this.buildAuthHeaders(auth);
|
|
122
|
-
const response = await fetch(endpoint, {
|
|
123
|
-
method: "HEAD",
|
|
124
|
-
headers
|
|
125
|
-
});
|
|
126
|
-
return response.ok;
|
|
127
|
-
} catch (error) {
|
|
128
|
-
console.error(`[${this.type}] Health check failed:`, error);
|
|
129
|
-
return false;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Log debug message with connector type prefix
|
|
134
|
-
*/
|
|
135
|
-
debug(message, ...args) {
|
|
136
|
-
debug(this.type, message, ...args);
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Log error message with connector type prefix
|
|
140
|
-
*/
|
|
141
|
-
error(message, ...args) {
|
|
142
|
-
console.error(`[${this.type}] ${message}`, ...args);
|
|
143
|
-
}
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
// types/agui.ts
|
|
147
|
-
import { EventType } from "@ag-ui/core";
|
|
148
|
-
var AGUIEventType = EventType;
|
|
149
|
-
|
|
150
|
-
// services/agent/sseStream.ts
|
|
151
|
-
var SSEClient = class {
|
|
152
|
-
constructor() {
|
|
153
|
-
this.abortController = null;
|
|
154
|
-
}
|
|
155
|
-
/**
|
|
156
|
-
* Start consuming SSE stream from the agent endpoint
|
|
157
|
-
*/
|
|
158
|
-
async consume(options) {
|
|
159
|
-
const {
|
|
160
|
-
url,
|
|
161
|
-
method = "POST",
|
|
162
|
-
headers = {},
|
|
163
|
-
body,
|
|
164
|
-
onEvent,
|
|
165
|
-
onError,
|
|
166
|
-
onComplete,
|
|
167
|
-
completeOnRunEnd = false,
|
|
168
|
-
idleTimeoutMs = 12e4
|
|
169
|
-
// 2 minute idle timeout by default (LLM agents can be slow)
|
|
170
|
-
} = options;
|
|
171
|
-
this.abortController = new AbortController();
|
|
172
|
-
debug("SSE", "Connecting to", url);
|
|
173
|
-
debug("SSE", "Method:", method);
|
|
174
|
-
debug("SSE", "Headers:", headers);
|
|
175
|
-
debug("SSE", "Payload:", body ? JSON.stringify(body, null, 2).substring(0, 500) : "none");
|
|
176
|
-
debug("SSE", "Timeout:", idleTimeoutMs, "ms");
|
|
177
|
-
try {
|
|
178
|
-
const requestConfig = {
|
|
179
|
-
method,
|
|
180
|
-
headers: {
|
|
181
|
-
"Content-Type": "application/json",
|
|
182
|
-
Accept: "text/event-stream",
|
|
183
|
-
...headers
|
|
184
|
-
},
|
|
185
|
-
body: body ? JSON.stringify(body) : void 0,
|
|
186
|
-
signal: this.abortController.signal
|
|
187
|
-
};
|
|
188
|
-
debug("SSE", "Request config:", JSON.stringify(requestConfig, null, 2).substring(0, 500));
|
|
189
|
-
const response = await fetch(url, requestConfig);
|
|
190
|
-
debug("SSE", "Response received:", response.status, response.statusText);
|
|
191
|
-
if (!response.ok) {
|
|
192
|
-
let errorBody = "";
|
|
193
|
-
try {
|
|
194
|
-
errorBody = await response.text();
|
|
195
|
-
debug("SSE", "Error response body:", errorBody.substring(0, 500));
|
|
196
|
-
} catch {
|
|
197
|
-
debug("SSE", "Could not read error response body");
|
|
198
|
-
}
|
|
199
|
-
throw new Error(`HTTP ${response.status}: ${response.statusText}${errorBody ? ` - ${errorBody}` : ""}`);
|
|
200
|
-
}
|
|
201
|
-
if (!response.body) {
|
|
202
|
-
throw new Error("Response body is null");
|
|
203
|
-
}
|
|
204
|
-
console.info("[SSE] Connected to agent endpoint, streaming events...");
|
|
205
|
-
debug("SSE", "Response status:", response.status);
|
|
206
|
-
debug("SSE", "Content-Type:", response.headers.get("content-type"));
|
|
207
|
-
const completionReason = await this.processStream(response.body, onEvent, completeOnRunEnd, idleTimeoutMs);
|
|
208
|
-
console.info(`[SSE] Stream completed: ${completionReason}`);
|
|
209
|
-
debug("SSE", `Stream completed: ${completionReason}`);
|
|
210
|
-
onComplete?.();
|
|
211
|
-
} catch (error) {
|
|
212
|
-
if (error instanceof Error) {
|
|
213
|
-
if (error.name === "AbortError") {
|
|
214
|
-
debug("SSE", "Stream aborted (expected after run completion)");
|
|
215
|
-
onComplete?.();
|
|
216
|
-
} else {
|
|
217
|
-
console.error("[SSE] Stream error:", error.message);
|
|
218
|
-
console.error("[SSE] Debug mode is:", isDebugEnabled() ? "ENABLED \u2705" : "DISABLED \u274C");
|
|
219
|
-
const errorDetails = {
|
|
220
|
-
name: error.name,
|
|
221
|
-
message: error.message,
|
|
222
|
-
stack: error.stack,
|
|
223
|
-
cause: error.cause,
|
|
224
|
-
url,
|
|
225
|
-
method,
|
|
226
|
-
headers
|
|
227
|
-
};
|
|
228
|
-
debug("SSE", "Error details:", errorDetails);
|
|
229
|
-
if (error.message.includes("fetch failed")) {
|
|
230
|
-
debug("SSE", '\u{1F4A1} Diagnostic: "fetch failed" typically means:');
|
|
231
|
-
debug("SSE", " - Connection refused (endpoint not running)");
|
|
232
|
-
debug("SSE", " - DNS resolution failed (invalid hostname)");
|
|
233
|
-
debug("SSE", " - Network unreachable (firewall/VPN issues)");
|
|
234
|
-
debug("SSE", " - SSL/TLS certificate issues (self-signed cert)");
|
|
235
|
-
debug("SSE", ` Check if ${url} is accessible`);
|
|
236
|
-
} else if (error.message.includes("timeout")) {
|
|
237
|
-
debug("SSE", "\u{1F4A1} Diagnostic: Request timed out - endpoint may be slow or unresponsive");
|
|
238
|
-
} else if (error.message.includes("ENOTFOUND")) {
|
|
239
|
-
debug("SSE", "\u{1F4A1} Diagnostic: DNS lookup failed - hostname not found");
|
|
240
|
-
} else if (error.message.includes("ECONNREFUSED")) {
|
|
241
|
-
debug("SSE", "\u{1F4A1} Diagnostic: Connection refused - service not listening on this port");
|
|
242
|
-
}
|
|
243
|
-
onError?.(error);
|
|
244
|
-
}
|
|
245
|
-
} else {
|
|
246
|
-
console.error("[SSE] Unknown error:", error);
|
|
247
|
-
debug("SSE", "Unknown error details:", error);
|
|
248
|
-
onError?.(new Error("Unknown error occurred"));
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* Process the ReadableStream and parse SSE events
|
|
254
|
-
* @returns Reason for stream completion
|
|
255
|
-
*/
|
|
256
|
-
async processStream(stream, onEvent, completeOnRunEnd = false, idleTimeoutMs = 12e4) {
|
|
257
|
-
const reader = stream.getReader();
|
|
258
|
-
const decoder = new TextDecoder();
|
|
259
|
-
let buffer = "";
|
|
260
|
-
let lastEventTime = Date.now();
|
|
261
|
-
let eventCount = 0;
|
|
262
|
-
let idleCheckInterval = null;
|
|
263
|
-
const idleTimeoutPromise = new Promise((resolve) => {
|
|
264
|
-
idleCheckInterval = setInterval(() => {
|
|
265
|
-
const idleTime = Date.now() - lastEventTime;
|
|
266
|
-
if (eventCount > 0 && idleTime > idleTimeoutMs) {
|
|
267
|
-
debug("SSE", `Idle timeout: no events for ${idleTime}ms (threshold: ${idleTimeoutMs}ms)`);
|
|
268
|
-
this.abort();
|
|
269
|
-
resolve("idle_timeout");
|
|
270
|
-
}
|
|
271
|
-
}, 1e3);
|
|
272
|
-
});
|
|
273
|
-
try {
|
|
274
|
-
const streamPromise = (async () => {
|
|
275
|
-
while (true) {
|
|
276
|
-
const { done, value } = await reader.read();
|
|
277
|
-
if (done) {
|
|
278
|
-
return "connection_closed";
|
|
279
|
-
}
|
|
280
|
-
lastEventTime = Date.now();
|
|
281
|
-
buffer += decoder.decode(value, { stream: true });
|
|
282
|
-
const lines = buffer.split("\n");
|
|
283
|
-
buffer = lines.pop() || "";
|
|
284
|
-
for (const line of lines) {
|
|
285
|
-
if (line.startsWith("data: ")) {
|
|
286
|
-
const data = line.slice(6);
|
|
287
|
-
if (data.trim()) {
|
|
288
|
-
debug("SSE", "Raw event:", data.substring(0, 200) + (data.length > 200 ? "..." : ""));
|
|
289
|
-
try {
|
|
290
|
-
const event = JSON.parse(data);
|
|
291
|
-
debug("SSE", "Parsed event:", event.type);
|
|
292
|
-
eventCount++;
|
|
293
|
-
if (eventCount % 10 === 0) {
|
|
294
|
-
console.info(`[SSE] Processed ${eventCount} events...`);
|
|
295
|
-
}
|
|
296
|
-
onEvent(event);
|
|
297
|
-
if (completeOnRunEnd && (event.type === AGUIEventType.RUN_FINISHED || event.type === AGUIEventType.RUN_ERROR)) {
|
|
298
|
-
debug("SSE", `Received ${event.type}, completing stream`);
|
|
299
|
-
this.abort();
|
|
300
|
-
return `event:${event.type}`;
|
|
301
|
-
}
|
|
302
|
-
} catch (parseError) {
|
|
303
|
-
console.error("[SSE] Parse error:", parseError);
|
|
304
|
-
debug("SSE", "Failed data:", data);
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
})();
|
|
311
|
-
const reason = await Promise.race([streamPromise, idleTimeoutPromise]);
|
|
312
|
-
return reason;
|
|
313
|
-
} finally {
|
|
314
|
-
if (idleCheckInterval) {
|
|
315
|
-
clearInterval(idleCheckInterval);
|
|
316
|
-
}
|
|
317
|
-
reader.releaseLock();
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
/**
|
|
321
|
-
* Abort the current stream connection
|
|
322
|
-
*/
|
|
323
|
-
abort() {
|
|
324
|
-
this.abortController?.abort();
|
|
325
|
-
}
|
|
326
|
-
};
|
|
327
|
-
async function consumeSSEStream(url, payload, onEvent, headers, options) {
|
|
328
|
-
const client = new SSEClient();
|
|
329
|
-
return new Promise((resolve, reject) => {
|
|
330
|
-
client.consume({
|
|
331
|
-
url,
|
|
332
|
-
method: "POST",
|
|
333
|
-
headers,
|
|
334
|
-
body: payload,
|
|
335
|
-
onEvent,
|
|
336
|
-
onError: (error) => reject(error),
|
|
337
|
-
onComplete: () => resolve(),
|
|
338
|
-
// Enable auto-completion on RUN_FINISHED/RUN_ERROR events
|
|
339
|
-
// This prevents hanging when the agent doesn't close the connection
|
|
340
|
-
completeOnRunEnd: true,
|
|
341
|
-
idleTimeoutMs: options?.idleTimeoutMs
|
|
342
|
-
});
|
|
343
|
-
});
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
// services/agent/payloadBuilder.ts
|
|
347
|
-
var DEFAULT_PPL_TOOL = {
|
|
348
|
-
name: "execute_ppl_query",
|
|
349
|
-
description: "Update the query bar with a PPL query and optionally execute it",
|
|
350
|
-
parameters: {
|
|
351
|
-
type: "object",
|
|
352
|
-
properties: {
|
|
353
|
-
query: {
|
|
354
|
-
type: "string",
|
|
355
|
-
description: "The PPL query to set in the query bar"
|
|
356
|
-
},
|
|
357
|
-
autoExecute: {
|
|
358
|
-
type: "boolean",
|
|
359
|
-
description: "Whether to automatically execute the query (default: true)"
|
|
360
|
-
},
|
|
361
|
-
description: {
|
|
362
|
-
type: "string",
|
|
363
|
-
description: "Optional description of what the query does"
|
|
364
|
-
}
|
|
365
|
-
},
|
|
366
|
-
required: ["query"]
|
|
367
|
-
}
|
|
368
|
-
};
|
|
369
|
-
function generateId(prefix) {
|
|
370
|
-
const timestamp = Date.now();
|
|
371
|
-
const random = Math.random().toString(36).substring(2, 11);
|
|
372
|
-
return `${prefix}-${timestamp}-${random}`;
|
|
373
|
-
}
|
|
374
|
-
function buildAgentPayload(testCase, modelId, threadId, runId) {
|
|
375
|
-
const tools = testCase.tools || [DEFAULT_PPL_TOOL];
|
|
376
|
-
return {
|
|
377
|
-
threadId: threadId || generateId("thread"),
|
|
378
|
-
runId: runId || generateId("run"),
|
|
379
|
-
messages: [
|
|
380
|
-
{
|
|
381
|
-
id: generateId("msg"),
|
|
382
|
-
role: "user",
|
|
383
|
-
content: testCase.initialPrompt
|
|
384
|
-
}
|
|
385
|
-
],
|
|
386
|
-
tools,
|
|
387
|
-
context: testCase.context || [],
|
|
388
|
-
state: {},
|
|
389
|
-
forwardedProps: {}
|
|
390
|
-
};
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
// services/agent/aguiConverter.ts
|
|
394
|
-
import { v4 as uuidv4 } from "uuid";
|
|
395
|
-
var AGUIToTrajectoryConverter = class {
|
|
396
|
-
constructor() {
|
|
397
|
-
this.currentTextMessage = null;
|
|
398
|
-
this.activeTools = /* @__PURE__ */ new Map();
|
|
399
|
-
this.hasEmittedAction = false;
|
|
400
|
-
this.runFinished = false;
|
|
401
|
-
this.pendingTextIsResponse = false;
|
|
402
|
-
this.runId = null;
|
|
403
|
-
this.threadId = null;
|
|
404
|
-
// Thinking state tracking
|
|
405
|
-
this.isThinking = false;
|
|
406
|
-
this.currentThinkingMessage = null;
|
|
407
|
-
}
|
|
408
|
-
/**
|
|
409
|
-
* Process a single AG UI event and convert it to TrajectoryStep(s)
|
|
410
|
-
* Returns an array of steps (usually 0 or 1, sometimes more)
|
|
411
|
-
*/
|
|
412
|
-
processEvent(event) {
|
|
413
|
-
debug("Converter", `Event: ${event.type}`, JSON.stringify(event).substring(0, 300));
|
|
414
|
-
let steps = [];
|
|
415
|
-
switch (event.type) {
|
|
416
|
-
case AGUIEventType.RUN_STARTED:
|
|
417
|
-
steps = this.handleRunStarted(event);
|
|
418
|
-
break;
|
|
419
|
-
case AGUIEventType.RUN_FINISHED:
|
|
420
|
-
steps = this.handleRunFinished(event);
|
|
421
|
-
break;
|
|
422
|
-
case AGUIEventType.RUN_ERROR:
|
|
423
|
-
steps = this.handleRunError(event);
|
|
424
|
-
break;
|
|
425
|
-
case AGUIEventType.TEXT_MESSAGE_START:
|
|
426
|
-
steps = this.handleTextMessageStart(event);
|
|
427
|
-
break;
|
|
428
|
-
case AGUIEventType.TEXT_MESSAGE_CONTENT:
|
|
429
|
-
steps = this.handleTextMessageContent(event);
|
|
430
|
-
break;
|
|
431
|
-
case AGUIEventType.TEXT_MESSAGE_END:
|
|
432
|
-
steps = this.handleTextMessageEnd(event);
|
|
433
|
-
break;
|
|
434
|
-
case AGUIEventType.ACTIVITY_SNAPSHOT:
|
|
435
|
-
steps = this.handleActivitySnapshot(event);
|
|
436
|
-
break;
|
|
437
|
-
case AGUIEventType.ACTIVITY_DELTA:
|
|
438
|
-
steps = this.handleActivityDelta(event);
|
|
439
|
-
break;
|
|
440
|
-
case AGUIEventType.TOOL_CALL_START:
|
|
441
|
-
steps = this.handleToolCallStart(event);
|
|
442
|
-
break;
|
|
443
|
-
case AGUIEventType.TOOL_CALL_ARGS:
|
|
444
|
-
steps = this.handleToolCallArgs(event);
|
|
445
|
-
break;
|
|
446
|
-
case AGUIEventType.TOOL_CALL_END:
|
|
447
|
-
steps = this.handleToolCallEnd(event);
|
|
448
|
-
break;
|
|
449
|
-
case AGUIEventType.TOOL_CALL_RESULT:
|
|
450
|
-
steps = this.handleToolCallResult(event);
|
|
451
|
-
break;
|
|
452
|
-
// Thinking events - extended reasoning from the model
|
|
453
|
-
case AGUIEventType.THINKING_START:
|
|
454
|
-
steps = this.handleThinkingStart(event);
|
|
455
|
-
break;
|
|
456
|
-
case AGUIEventType.THINKING_END:
|
|
457
|
-
steps = this.handleThinkingEnd(event);
|
|
458
|
-
break;
|
|
459
|
-
case AGUIEventType.THINKING_TEXT_MESSAGE_START:
|
|
460
|
-
steps = this.handleThinkingTextMessageStart(event);
|
|
461
|
-
break;
|
|
462
|
-
case AGUIEventType.THINKING_TEXT_MESSAGE_CONTENT:
|
|
463
|
-
steps = this.handleThinkingTextMessageContent(event);
|
|
464
|
-
break;
|
|
465
|
-
case AGUIEventType.THINKING_TEXT_MESSAGE_END:
|
|
466
|
-
steps = this.handleThinkingTextMessageEnd(event);
|
|
467
|
-
break;
|
|
468
|
-
default:
|
|
469
|
-
debug("Converter", `Skipped unhandled event: ${event.type}`);
|
|
470
|
-
break;
|
|
471
|
-
}
|
|
472
|
-
if (steps.length > 0) {
|
|
473
|
-
debug("Converter", `Generated ${steps.length} step(s):`, steps.map((s) => `${s.type}${s.toolName ? `:${s.toolName}` : ""}`).join(", "));
|
|
474
|
-
}
|
|
475
|
-
return steps;
|
|
476
|
-
}
|
|
477
|
-
handleRunStarted(event) {
|
|
478
|
-
this.runId = event.runId;
|
|
479
|
-
this.threadId = event.threadId;
|
|
480
|
-
debug("Converter", `Run started - runId: ${this.runId}, threadId: ${this.threadId}`);
|
|
481
|
-
this.currentTextMessage = null;
|
|
482
|
-
this.activeTools.clear();
|
|
483
|
-
this.hasEmittedAction = false;
|
|
484
|
-
this.runFinished = false;
|
|
485
|
-
this.pendingTextIsResponse = false;
|
|
486
|
-
this.isThinking = false;
|
|
487
|
-
this.currentThinkingMessage = null;
|
|
488
|
-
return [];
|
|
489
|
-
}
|
|
490
|
-
getRunId() {
|
|
491
|
-
return this.runId;
|
|
492
|
-
}
|
|
493
|
-
getThreadId() {
|
|
494
|
-
return this.threadId;
|
|
495
|
-
}
|
|
496
|
-
handleRunFinished(event) {
|
|
497
|
-
this.runFinished = true;
|
|
498
|
-
if (this.currentTextMessage) {
|
|
499
|
-
this.pendingTextIsResponse = true;
|
|
500
|
-
}
|
|
501
|
-
return [];
|
|
502
|
-
}
|
|
503
|
-
handleRunError(event) {
|
|
504
|
-
console.error("[Converter] Run error:", event.message);
|
|
505
|
-
return [{
|
|
506
|
-
id: uuidv4(),
|
|
507
|
-
timestamp: event.timestamp,
|
|
508
|
-
type: "tool_result",
|
|
509
|
-
content: `Error: ${event.message}`,
|
|
510
|
-
status: "FAILURE" /* FAILURE */
|
|
511
|
-
}];
|
|
512
|
-
}
|
|
513
|
-
handleTextMessageStart(event) {
|
|
514
|
-
debug("Converter", `Text message start: ${event.messageId}`);
|
|
515
|
-
this.currentTextMessage = {
|
|
516
|
-
messageId: event.messageId,
|
|
517
|
-
startTime: event.timestamp,
|
|
518
|
-
content: ""
|
|
519
|
-
};
|
|
520
|
-
return [];
|
|
521
|
-
}
|
|
522
|
-
handleTextMessageContent(event) {
|
|
523
|
-
if (this.currentTextMessage && this.currentTextMessage.messageId === event.messageId) {
|
|
524
|
-
this.currentTextMessage.content += event.delta;
|
|
525
|
-
}
|
|
526
|
-
return [];
|
|
527
|
-
}
|
|
528
|
-
handleTextMessageEnd(event) {
|
|
529
|
-
if (!this.currentTextMessage || this.currentTextMessage.messageId !== event.messageId) {
|
|
530
|
-
debug("Converter", `Text end for unknown message: ${event.messageId}`);
|
|
531
|
-
return [];
|
|
532
|
-
}
|
|
533
|
-
const latencyMs = event.timestamp - this.currentTextMessage.startTime;
|
|
534
|
-
const content = this.currentTextMessage.content.trim();
|
|
535
|
-
let stepType;
|
|
536
|
-
if (this.pendingTextIsResponse || this.runFinished) {
|
|
537
|
-
stepType = "response";
|
|
538
|
-
} else {
|
|
539
|
-
stepType = "assistant";
|
|
540
|
-
}
|
|
541
|
-
debug("Converter", `Classification: ${stepType} (runFinished=${this.runFinished}, pendingResponse=${this.pendingTextIsResponse}, hasAction=${this.hasEmittedAction})`);
|
|
542
|
-
if (stepType === "assistant" && content.length === 0) {
|
|
543
|
-
debug("Converter", "Skipping empty assistant message");
|
|
544
|
-
this.currentTextMessage = null;
|
|
545
|
-
return [];
|
|
546
|
-
}
|
|
547
|
-
const step = {
|
|
548
|
-
id: uuidv4(),
|
|
549
|
-
timestamp: event.timestamp,
|
|
550
|
-
type: stepType,
|
|
551
|
-
content,
|
|
552
|
-
latencyMs
|
|
553
|
-
};
|
|
554
|
-
this.currentTextMessage = null;
|
|
555
|
-
return [step];
|
|
556
|
-
}
|
|
557
|
-
handleActivitySnapshot(event) {
|
|
558
|
-
const toolName = this.extractToolName(event.content.title);
|
|
559
|
-
const toolArgs = this.parseToolArgs(event.content.description);
|
|
560
|
-
const actionStepId = uuidv4();
|
|
561
|
-
this.activeTools.set(event.messageId, {
|
|
562
|
-
messageId: event.messageId,
|
|
563
|
-
toolName,
|
|
564
|
-
toolArgs,
|
|
565
|
-
argsAccumulator: "",
|
|
566
|
-
startTime: event.timestamp,
|
|
567
|
-
actionStepId
|
|
568
|
-
});
|
|
569
|
-
this.hasEmittedAction = true;
|
|
570
|
-
debug("Converter", `Tool action: ${toolName}`, toolArgs);
|
|
571
|
-
return [{
|
|
572
|
-
id: actionStepId,
|
|
573
|
-
timestamp: event.timestamp,
|
|
574
|
-
type: "action",
|
|
575
|
-
content: `Calling ${toolName}...`,
|
|
576
|
-
toolName,
|
|
577
|
-
toolArgs
|
|
578
|
-
}];
|
|
579
|
-
}
|
|
580
|
-
handleActivityDelta(event) {
|
|
581
|
-
const toolState = this.activeTools.get(event.messageId);
|
|
582
|
-
if (!toolState) return [];
|
|
583
|
-
const isCompletion = event.patch.some(
|
|
584
|
-
(op) => op.path === "/icon" && (op.value === "CheckCircle" || op.value === "Check")
|
|
585
|
-
);
|
|
586
|
-
if (!isCompletion) return [];
|
|
587
|
-
const descriptionPatch = event.patch.find((op) => op.path === "/description");
|
|
588
|
-
const resultContent = descriptionPatch?.value || "Tool execution completed";
|
|
589
|
-
const latencyMs = event.timestamp - toolState.startTime;
|
|
590
|
-
this.activeTools.delete(event.messageId);
|
|
591
|
-
return [{
|
|
592
|
-
id: uuidv4(),
|
|
593
|
-
timestamp: event.timestamp,
|
|
594
|
-
type: "tool_result",
|
|
595
|
-
content: resultContent,
|
|
596
|
-
status: "SUCCESS" /* SUCCESS */,
|
|
597
|
-
latencyMs
|
|
598
|
-
}];
|
|
599
|
-
}
|
|
600
|
-
handleToolCallStart(event) {
|
|
601
|
-
const actionStepId = uuidv4();
|
|
602
|
-
this.activeTools.set(event.toolCallId, {
|
|
603
|
-
messageId: event.toolCallId,
|
|
604
|
-
toolName: event.toolCallName,
|
|
605
|
-
toolArgs: {},
|
|
606
|
-
argsAccumulator: "",
|
|
607
|
-
// Will accumulate delta strings
|
|
608
|
-
startTime: event.timestamp,
|
|
609
|
-
actionStepId
|
|
610
|
-
});
|
|
611
|
-
this.hasEmittedAction = true;
|
|
612
|
-
debug("Converter", `Tool call started: ${event.toolCallName} (${event.toolCallId})`);
|
|
613
|
-
return [];
|
|
614
|
-
}
|
|
615
|
-
handleToolCallArgs(event) {
|
|
616
|
-
const toolState = this.activeTools.get(event.toolCallId);
|
|
617
|
-
if (toolState) {
|
|
618
|
-
toolState.argsAccumulator += event.delta;
|
|
619
|
-
debug("Converter", `Tool args delta accumulated (${toolState.argsAccumulator.length} chars total)`);
|
|
620
|
-
}
|
|
621
|
-
return [];
|
|
622
|
-
}
|
|
623
|
-
/**
|
|
624
|
-
* Handle TOOL_CALL_END - emits the action step with complete args
|
|
625
|
-
* This is called when the agent is done sending tool call arguments
|
|
626
|
-
* and expects the client to execute the tool
|
|
627
|
-
*/
|
|
628
|
-
handleToolCallEnd(event) {
|
|
629
|
-
const toolState = this.activeTools.get(event.toolCallId);
|
|
630
|
-
if (!toolState) {
|
|
631
|
-
debug("Converter", `Tool call end for unknown tool: ${event.toolCallId}`);
|
|
632
|
-
return [];
|
|
633
|
-
}
|
|
634
|
-
let parsedArgs = {};
|
|
635
|
-
if (toolState.argsAccumulator) {
|
|
636
|
-
try {
|
|
637
|
-
parsedArgs = JSON.parse(toolState.argsAccumulator);
|
|
638
|
-
debug("Converter", `Tool args parsed: ${JSON.stringify(parsedArgs).substring(0, 200)}`);
|
|
639
|
-
} catch {
|
|
640
|
-
parsedArgs = { _raw: toolState.argsAccumulator };
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
toolState.toolArgs = parsedArgs;
|
|
644
|
-
const latencyMs = event.timestamp - toolState.startTime;
|
|
645
|
-
const actionStep = {
|
|
646
|
-
id: toolState.actionStepId,
|
|
647
|
-
timestamp: toolState.startTime,
|
|
648
|
-
type: "action",
|
|
649
|
-
content: `Calling ${toolState.toolName}...`,
|
|
650
|
-
toolName: toolState.toolName,
|
|
651
|
-
toolArgs: parsedArgs,
|
|
652
|
-
latencyMs
|
|
653
|
-
};
|
|
654
|
-
debug("Converter", `Tool call end: ${toolState.toolName} - action step emitted with args`);
|
|
655
|
-
toolState.actionStepId = "";
|
|
656
|
-
return [actionStep];
|
|
657
|
-
}
|
|
658
|
-
handleToolCallResult(event) {
|
|
659
|
-
const toolState = this.activeTools.get(event.toolCallId);
|
|
660
|
-
if (!toolState) return [];
|
|
661
|
-
const latencyMs = event.timestamp - toolState.startTime;
|
|
662
|
-
const steps = [];
|
|
663
|
-
const actionAlreadyEmitted = !toolState.actionStepId;
|
|
664
|
-
if (!actionAlreadyEmitted) {
|
|
665
|
-
let parsedArgs = {};
|
|
666
|
-
if (toolState.argsAccumulator) {
|
|
667
|
-
try {
|
|
668
|
-
parsedArgs = JSON.parse(toolState.argsAccumulator);
|
|
669
|
-
debug("Converter", `Tool args parsed: ${JSON.stringify(parsedArgs).substring(0, 200)}`);
|
|
670
|
-
} catch {
|
|
671
|
-
parsedArgs = { _raw: toolState.argsAccumulator };
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
toolState.toolArgs = parsedArgs;
|
|
675
|
-
steps.push({
|
|
676
|
-
id: toolState.actionStepId,
|
|
677
|
-
timestamp: toolState.startTime,
|
|
678
|
-
type: "action",
|
|
679
|
-
content: `Calling ${toolState.toolName}...`,
|
|
680
|
-
toolName: toolState.toolName,
|
|
681
|
-
toolArgs: parsedArgs
|
|
682
|
-
});
|
|
683
|
-
}
|
|
684
|
-
let resultContent;
|
|
685
|
-
try {
|
|
686
|
-
const parsed = JSON.parse(event.content);
|
|
687
|
-
resultContent = typeof parsed === "string" ? parsed : JSON.stringify(parsed, null, 2);
|
|
688
|
-
} catch (e) {
|
|
689
|
-
resultContent = event.content;
|
|
690
|
-
}
|
|
691
|
-
steps.push({
|
|
692
|
-
id: uuidv4(),
|
|
693
|
-
timestamp: event.timestamp,
|
|
694
|
-
type: "tool_result",
|
|
695
|
-
content: resultContent,
|
|
696
|
-
status: "SUCCESS" /* SUCCESS */,
|
|
697
|
-
latencyMs
|
|
698
|
-
});
|
|
699
|
-
this.activeTools.delete(event.toolCallId);
|
|
700
|
-
debug("Converter", `Tool call result: ${toolState.toolName} -> ${steps.length} steps emitted (action already emitted: ${actionAlreadyEmitted})`);
|
|
701
|
-
return steps;
|
|
702
|
-
}
|
|
703
|
-
// ============ THINKING Event Handlers ============
|
|
704
|
-
handleThinkingStart(event) {
|
|
705
|
-
this.isThinking = true;
|
|
706
|
-
debug("Converter", "Thinking started");
|
|
707
|
-
return [];
|
|
708
|
-
}
|
|
709
|
-
handleThinkingEnd(event) {
|
|
710
|
-
this.isThinking = false;
|
|
711
|
-
debug("Converter", "Thinking ended");
|
|
712
|
-
return [];
|
|
713
|
-
}
|
|
714
|
-
handleThinkingTextMessageStart(event) {
|
|
715
|
-
this.currentThinkingMessage = {
|
|
716
|
-
startTime: event.timestamp || Date.now(),
|
|
717
|
-
content: ""
|
|
718
|
-
};
|
|
719
|
-
debug("Converter", "Thinking text message started");
|
|
720
|
-
return [];
|
|
721
|
-
}
|
|
722
|
-
handleThinkingTextMessageContent(event) {
|
|
723
|
-
if (this.currentThinkingMessage) {
|
|
724
|
-
this.currentThinkingMessage.content += event.delta;
|
|
725
|
-
}
|
|
726
|
-
return [];
|
|
727
|
-
}
|
|
728
|
-
handleThinkingTextMessageEnd(event) {
|
|
729
|
-
if (!this.currentThinkingMessage) {
|
|
730
|
-
debug("Converter", "Thinking text end with no active thinking message");
|
|
731
|
-
return [];
|
|
732
|
-
}
|
|
733
|
-
const content = this.currentThinkingMessage.content.trim();
|
|
734
|
-
if (content.length === 0) {
|
|
735
|
-
debug("Converter", "Skipping empty thinking message");
|
|
736
|
-
this.currentThinkingMessage = null;
|
|
737
|
-
return [];
|
|
738
|
-
}
|
|
739
|
-
const latencyMs = (event.timestamp || Date.now()) - this.currentThinkingMessage.startTime;
|
|
740
|
-
const step = {
|
|
741
|
-
id: uuidv4(),
|
|
742
|
-
timestamp: this.currentThinkingMessage.startTime,
|
|
743
|
-
type: "thinking",
|
|
744
|
-
content,
|
|
745
|
-
latencyMs
|
|
746
|
-
};
|
|
747
|
-
debug("Converter", `Thinking message completed: ${content.length} chars`);
|
|
748
|
-
this.currentThinkingMessage = null;
|
|
749
|
-
return [step];
|
|
750
|
-
}
|
|
751
|
-
extractToolName(title) {
|
|
752
|
-
const runningMatch = title.match(/^Running\s+(.+)$/);
|
|
753
|
-
if (runningMatch) return runningMatch[1];
|
|
754
|
-
const completedMatch = title.match(/^(.+)\s+completed$/i);
|
|
755
|
-
if (completedMatch) return completedMatch[1];
|
|
756
|
-
return title;
|
|
757
|
-
}
|
|
758
|
-
parseToolArgs(description) {
|
|
759
|
-
try {
|
|
760
|
-
const args = {};
|
|
761
|
-
const pairs = description.match(/(\w+):\s*("(?:[^"]|\\")*"|\w+)/g);
|
|
762
|
-
if (pairs) {
|
|
763
|
-
pairs.forEach((pair) => {
|
|
764
|
-
const [key, rawValue] = pair.split(":").map((s) => s.trim());
|
|
765
|
-
let value = rawValue;
|
|
766
|
-
if (rawValue.startsWith('"') && rawValue.endsWith('"')) {
|
|
767
|
-
value = rawValue.slice(1, -1);
|
|
768
|
-
} else if (rawValue === "true") {
|
|
769
|
-
value = true;
|
|
770
|
-
} else if (rawValue === "false") {
|
|
771
|
-
value = false;
|
|
772
|
-
} else if (!isNaN(Number(rawValue))) {
|
|
773
|
-
value = Number(rawValue);
|
|
774
|
-
}
|
|
775
|
-
args[key] = value;
|
|
776
|
-
});
|
|
777
|
-
return args;
|
|
778
|
-
}
|
|
779
|
-
return { description };
|
|
780
|
-
} catch (e) {
|
|
781
|
-
return { description };
|
|
782
|
-
}
|
|
783
|
-
}
|
|
784
|
-
};
|
|
785
|
-
function computeTrajectoryFromRawEvents(rawEvents) {
|
|
786
|
-
const converter = new AGUIToTrajectoryConverter();
|
|
787
|
-
const trajectory = [];
|
|
788
|
-
for (const event of rawEvents) {
|
|
789
|
-
const steps = converter.processEvent(event);
|
|
790
|
-
trajectory.push(...steps);
|
|
791
|
-
}
|
|
792
|
-
trajectory.sort((a, b) => a.timestamp - b.timestamp);
|
|
793
|
-
return trajectory;
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
// services/connectors/agui/AGUIStreamingConnector.ts
|
|
797
|
-
var AGUIStreamingConnector = class extends BaseConnector {
|
|
798
|
-
constructor() {
|
|
799
|
-
super(...arguments);
|
|
800
|
-
this.type = "agui-streaming";
|
|
801
|
-
this.name = "AG-UI Streaming";
|
|
802
|
-
this.supportsStreaming = true;
|
|
803
|
-
}
|
|
804
|
-
/**
|
|
805
|
-
* Build AG-UI payload from standard request
|
|
806
|
-
*/
|
|
807
|
-
buildPayload(request) {
|
|
808
|
-
return buildAgentPayload(
|
|
809
|
-
request.testCase,
|
|
810
|
-
request.modelId,
|
|
811
|
-
request.threadId,
|
|
812
|
-
request.runId
|
|
813
|
-
);
|
|
814
|
-
}
|
|
815
|
-
/**
|
|
816
|
-
* Execute the request using SSE streaming
|
|
817
|
-
*/
|
|
818
|
-
async execute(endpoint, request, auth, onProgress, onRawEvent) {
|
|
819
|
-
const hasPrebuiltPayload = !!request.payload;
|
|
820
|
-
const payload = request.payload || this.buildPayload(request);
|
|
821
|
-
const headers = this.buildAuthHeaders(auth);
|
|
822
|
-
const trajectory = [];
|
|
823
|
-
const rawEvents = [];
|
|
824
|
-
const converter = new AGUIToTrajectoryConverter();
|
|
825
|
-
this.debug("Executing AG-UI streaming request");
|
|
826
|
-
await consumeSSEStream(
|
|
827
|
-
endpoint,
|
|
828
|
-
payload,
|
|
829
|
-
(event) => {
|
|
830
|
-
rawEvents.push(event);
|
|
831
|
-
onRawEvent?.(event);
|
|
832
|
-
const steps = converter.processEvent(event);
|
|
833
|
-
steps.forEach((step) => {
|
|
834
|
-
trajectory.push(step);
|
|
835
|
-
onProgress?.(step);
|
|
836
|
-
});
|
|
837
|
-
},
|
|
838
|
-
headers
|
|
839
|
-
);
|
|
840
|
-
const runId = converter.getRunId();
|
|
841
|
-
this.debug("Stream completed. RunId:", runId, "Steps:", trajectory.length);
|
|
842
|
-
return {
|
|
843
|
-
trajectory,
|
|
844
|
-
runId,
|
|
845
|
-
rawEvents,
|
|
846
|
-
metadata: {
|
|
847
|
-
threadId: converter.getThreadId()
|
|
848
|
-
}
|
|
849
|
-
};
|
|
850
|
-
}
|
|
851
|
-
/**
|
|
852
|
-
* Parse raw AG-UI events into trajectory steps
|
|
853
|
-
* Used for re-processing stored raw events
|
|
854
|
-
*/
|
|
855
|
-
parseResponse(rawEvents) {
|
|
856
|
-
return computeTrajectoryFromRawEvents(rawEvents);
|
|
857
|
-
}
|
|
858
|
-
/**
|
|
859
|
-
* Health check for AG-UI endpoint
|
|
860
|
-
* Tries to connect without sending a full request
|
|
861
|
-
*/
|
|
862
|
-
async healthCheck(endpoint, auth) {
|
|
863
|
-
try {
|
|
864
|
-
const headers = this.buildAuthHeaders(auth);
|
|
865
|
-
const response = await fetch(endpoint, {
|
|
866
|
-
method: "OPTIONS",
|
|
867
|
-
headers
|
|
868
|
-
});
|
|
869
|
-
return true;
|
|
870
|
-
} catch (error) {
|
|
871
|
-
this.error("Health check failed:", error);
|
|
872
|
-
return false;
|
|
873
|
-
}
|
|
874
|
-
}
|
|
875
|
-
};
|
|
876
|
-
var aguiStreamingConnector = new AGUIStreamingConnector();
|
|
877
|
-
|
|
878
|
-
// services/connectors/rest/RESTConnector.ts
|
|
879
|
-
var RESTConnector = class extends BaseConnector {
|
|
880
|
-
constructor() {
|
|
881
|
-
super(...arguments);
|
|
882
|
-
this.type = "rest";
|
|
883
|
-
this.name = "REST API";
|
|
884
|
-
this.supportsStreaming = false;
|
|
885
|
-
}
|
|
886
|
-
/**
|
|
887
|
-
* Build generic REST payload
|
|
888
|
-
* Can be customized via connectorConfig
|
|
889
|
-
*/
|
|
890
|
-
buildPayload(request) {
|
|
891
|
-
return {
|
|
892
|
-
prompt: request.testCase.initialPrompt,
|
|
893
|
-
context: request.testCase.context,
|
|
894
|
-
model: request.modelId,
|
|
895
|
-
tools: request.testCase.tools
|
|
896
|
-
};
|
|
897
|
-
}
|
|
898
|
-
/**
|
|
899
|
-
* Execute REST request
|
|
900
|
-
*/
|
|
901
|
-
async execute(endpoint, request, auth, onProgress, onRawEvent) {
|
|
902
|
-
const payload = request.payload || this.buildPayload(request);
|
|
903
|
-
const headers = this.buildAuthHeaders(auth);
|
|
904
|
-
this.debug("Executing REST request");
|
|
905
|
-
this.debug("Endpoint:", endpoint);
|
|
906
|
-
this.debug("Payload:", JSON.stringify(payload).substring(0, 500));
|
|
907
|
-
const response = await fetch(endpoint, {
|
|
908
|
-
method: "POST",
|
|
909
|
-
headers: {
|
|
910
|
-
"Content-Type": "application/json",
|
|
911
|
-
...headers
|
|
912
|
-
},
|
|
913
|
-
body: JSON.stringify(payload)
|
|
914
|
-
});
|
|
915
|
-
if (!response.ok) {
|
|
916
|
-
const errorText = await response.text();
|
|
917
|
-
throw new Error(`REST request failed: ${response.status} - ${errorText}`);
|
|
918
|
-
}
|
|
919
|
-
const data = await response.json();
|
|
920
|
-
onRawEvent?.(data);
|
|
921
|
-
const trajectory = this.parseResponse(data);
|
|
922
|
-
trajectory.forEach((step) => onProgress?.(step));
|
|
923
|
-
return {
|
|
924
|
-
trajectory,
|
|
925
|
-
runId: data.runId || data.id || null,
|
|
926
|
-
rawEvents: [data],
|
|
927
|
-
metadata: {
|
|
928
|
-
status: response.status,
|
|
929
|
-
responseHeaders: Object.fromEntries(response.headers.entries())
|
|
930
|
-
}
|
|
931
|
-
};
|
|
932
|
-
}
|
|
933
|
-
/**
|
|
934
|
-
* Parse REST response into trajectory steps
|
|
935
|
-
* This is a generic implementation - subclass for specific APIs
|
|
936
|
-
*/
|
|
937
|
-
parseResponse(data) {
|
|
938
|
-
const steps = [];
|
|
939
|
-
if (data.thinking) {
|
|
940
|
-
steps.push(this.createStep("thinking", data.thinking));
|
|
941
|
-
}
|
|
942
|
-
if (data.toolCalls && Array.isArray(data.toolCalls)) {
|
|
943
|
-
for (const call of data.toolCalls) {
|
|
944
|
-
steps.push(this.createStep("action", `Calling ${call.name}...`, {
|
|
945
|
-
toolName: call.name,
|
|
946
|
-
toolArgs: call.args || call.input
|
|
947
|
-
}));
|
|
948
|
-
if (call.result !== void 0) {
|
|
949
|
-
steps.push(this.createStep(
|
|
950
|
-
"tool_result",
|
|
951
|
-
typeof call.result === "string" ? call.result : JSON.stringify(call.result),
|
|
952
|
-
{ status: "SUCCESS" }
|
|
953
|
-
));
|
|
954
|
-
}
|
|
955
|
-
}
|
|
956
|
-
}
|
|
957
|
-
const responseContent = data.response || data.content || data.answer || data.text || data.message;
|
|
958
|
-
if (responseContent) {
|
|
959
|
-
steps.push(this.createStep(
|
|
960
|
-
"response",
|
|
961
|
-
typeof responseContent === "string" ? responseContent : JSON.stringify(responseContent)
|
|
962
|
-
));
|
|
963
|
-
}
|
|
964
|
-
if (data.inference_results) {
|
|
965
|
-
const outputs = data.inference_results[0]?.output || [];
|
|
966
|
-
for (const output of outputs) {
|
|
967
|
-
if (output.name === "response") {
|
|
968
|
-
const content = output.dataAsMap?.response || output.result;
|
|
969
|
-
if (content) {
|
|
970
|
-
steps.push(this.createStep("response", content));
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
|
-
}
|
|
974
|
-
}
|
|
975
|
-
if (steps.length === 0 && data) {
|
|
976
|
-
steps.push(this.createStep("response", JSON.stringify(data, null, 2)));
|
|
977
|
-
}
|
|
978
|
-
return steps;
|
|
979
|
-
}
|
|
980
|
-
};
|
|
981
|
-
var restConnector = new RESTConnector();
|
|
982
|
-
|
|
983
|
-
// services/connectors/subprocess/SubprocessConnector.ts
|
|
984
|
-
import { spawn } from "child_process";
|
|
985
|
-
var DEFAULT_SUBPROCESS_CONFIG = {
|
|
986
|
-
command: "",
|
|
987
|
-
args: [],
|
|
988
|
-
env: {},
|
|
989
|
-
inputMode: "stdin",
|
|
990
|
-
outputParser: "text",
|
|
991
|
-
timeout: 3e5
|
|
992
|
-
// 5 minutes
|
|
993
|
-
};
|
|
994
|
-
var SubprocessConnector = class extends BaseConnector {
|
|
995
|
-
constructor(config) {
|
|
996
|
-
super();
|
|
997
|
-
this.type = "subprocess";
|
|
998
|
-
this.name = "Subprocess (CLI)";
|
|
999
|
-
this.supportsStreaming = true;
|
|
1000
|
-
this.config = { ...DEFAULT_SUBPROCESS_CONFIG, ...config };
|
|
1001
|
-
}
|
|
1002
|
-
/**
|
|
1003
|
-
* Build input for the subprocess
|
|
1004
|
-
*/
|
|
1005
|
-
buildPayload(request) {
|
|
1006
|
-
let prompt = request.testCase.initialPrompt;
|
|
1007
|
-
if (request.testCase.context && request.testCase.context.length > 0) {
|
|
1008
|
-
const contextStr = request.testCase.context.map((c) => `${c.description}: ${c.value}`).join("\n");
|
|
1009
|
-
prompt = `Context:
|
|
1010
|
-
${contextStr}
|
|
1011
|
-
|
|
1012
|
-
Question: ${prompt}`;
|
|
1013
|
-
}
|
|
1014
|
-
return prompt;
|
|
1015
|
-
}
|
|
1016
|
-
/**
|
|
1017
|
-
* Execute subprocess and capture output
|
|
1018
|
-
*/
|
|
1019
|
-
async execute(endpoint, request, auth, onProgress, onRawEvent) {
|
|
1020
|
-
this.debug("========== execute() STARTED ==========");
|
|
1021
|
-
const command = endpoint || this.config.command;
|
|
1022
|
-
const args = this.config.args || [];
|
|
1023
|
-
const input = request.payload || this.buildPayload(request);
|
|
1024
|
-
this.debug("Command:", command);
|
|
1025
|
-
this.debug("Args:", args);
|
|
1026
|
-
this.debug("Input mode:", this.config.inputMode);
|
|
1027
|
-
this.debug("Output parser:", this.config.outputParser);
|
|
1028
|
-
this.debug("Timeout:", this.config.timeout);
|
|
1029
|
-
this.debug("Input (first 500 chars):", input.substring(0, 500));
|
|
1030
|
-
this.debug("Working dir:", this.config.workingDir || process.cwd());
|
|
1031
|
-
const env = {
|
|
1032
|
-
...process.env,
|
|
1033
|
-
...this.buildAuthEnv(auth),
|
|
1034
|
-
...this.config.env
|
|
1035
|
-
};
|
|
1036
|
-
return new Promise((resolve, reject) => {
|
|
1037
|
-
const trajectory = [];
|
|
1038
|
-
const rawOutput = [];
|
|
1039
|
-
let stdout = "";
|
|
1040
|
-
let stderr = "";
|
|
1041
|
-
let settled = false;
|
|
1042
|
-
const finalArgs = this.config.inputMode === "arg" ? [...args, input] : args;
|
|
1043
|
-
this.debug("Spawning process...");
|
|
1044
|
-
this.debug("Full command:", command, finalArgs.join(" "));
|
|
1045
|
-
const proc = spawn(command, finalArgs, {
|
|
1046
|
-
env,
|
|
1047
|
-
cwd: this.config.workingDir,
|
|
1048
|
-
shell: true
|
|
1049
|
-
});
|
|
1050
|
-
this.debug("Process spawned, PID:", proc.pid);
|
|
1051
|
-
const timeoutId = setTimeout(() => {
|
|
1052
|
-
if (settled) return;
|
|
1053
|
-
settled = true;
|
|
1054
|
-
this.debug("TIMEOUT reached, killing process");
|
|
1055
|
-
proc.kill("SIGTERM");
|
|
1056
|
-
reject(new Error(`Subprocess timed out after ${this.config.timeout}ms`));
|
|
1057
|
-
}, this.config.timeout);
|
|
1058
|
-
if (this.config.inputMode === "stdin") {
|
|
1059
|
-
this.debug("Writing input to stdin...");
|
|
1060
|
-
proc.stdin.write(input);
|
|
1061
|
-
proc.stdin.end();
|
|
1062
|
-
this.debug("stdin closed");
|
|
1063
|
-
}
|
|
1064
|
-
proc.stdout.on("data", (data) => {
|
|
1065
|
-
const chunk = data.toString();
|
|
1066
|
-
this.debug("stdout received:", chunk.length, "bytes");
|
|
1067
|
-
this.debug("stdout preview:", chunk.substring(0, 200));
|
|
1068
|
-
stdout += chunk;
|
|
1069
|
-
rawOutput.push({ type: "stdout", data: chunk, timestamp: Date.now() });
|
|
1070
|
-
onRawEvent?.({ type: "stdout", data: chunk });
|
|
1071
|
-
if (this.config.outputParser === "streaming") {
|
|
1072
|
-
this.parseStreamingOutput(chunk, trajectory, onProgress);
|
|
1073
|
-
}
|
|
1074
|
-
});
|
|
1075
|
-
proc.stderr.on("data", (data) => {
|
|
1076
|
-
const chunk = data.toString();
|
|
1077
|
-
this.debug("stderr received:", chunk.length, "bytes");
|
|
1078
|
-
this.debug("stderr:", chunk);
|
|
1079
|
-
stderr += chunk;
|
|
1080
|
-
onRawEvent?.({ type: "stderr", data: chunk });
|
|
1081
|
-
this.debug("stderr:", chunk);
|
|
1082
|
-
});
|
|
1083
|
-
proc.on("close", (code, signal) => {
|
|
1084
|
-
this.debug("Process closed with code:", code, "signal:", signal);
|
|
1085
|
-
clearTimeout(timeoutId);
|
|
1086
|
-
if (settled) return;
|
|
1087
|
-
settled = true;
|
|
1088
|
-
if (code !== 0) {
|
|
1089
|
-
this.debug("Non-zero exit code:", code);
|
|
1090
|
-
this.error(`Process exited with code ${code}`);
|
|
1091
|
-
this.error("stderr:", stderr);
|
|
1092
|
-
}
|
|
1093
|
-
const finalTrajectory = this.config.outputParser === "streaming" ? trajectory : this.parseResponse({ stdout, stderr, exitCode: code });
|
|
1094
|
-
if (this.config.outputParser !== "streaming") {
|
|
1095
|
-
finalTrajectory.forEach((step) => onProgress?.(step));
|
|
1096
|
-
}
|
|
1097
|
-
this.debug("Resolving with trajectory of", finalTrajectory.length, "steps");
|
|
1098
|
-
resolve({
|
|
1099
|
-
trajectory: finalTrajectory,
|
|
1100
|
-
runId: `subprocess-${Date.now()}`,
|
|
1101
|
-
rawEvents: rawOutput,
|
|
1102
|
-
metadata: {
|
|
1103
|
-
command,
|
|
1104
|
-
args: finalArgs,
|
|
1105
|
-
exitCode: code,
|
|
1106
|
-
stderr: stderr || void 0
|
|
1107
|
-
}
|
|
1108
|
-
});
|
|
1109
|
-
});
|
|
1110
|
-
proc.on("error", (error) => {
|
|
1111
|
-
this.debug("ERROR event:", error.message);
|
|
1112
|
-
clearTimeout(timeoutId);
|
|
1113
|
-
if (settled) return;
|
|
1114
|
-
settled = true;
|
|
1115
|
-
let errorMsg = `Failed to spawn subprocess: ${error.message}`;
|
|
1116
|
-
if (error.message.includes("ENOENT")) {
|
|
1117
|
-
errorMsg = `Command '${command}' not found. Is it installed and in PATH?`;
|
|
1118
|
-
console.error(`[Subprocess] ENOENT error - command '${command}' not found in PATH`);
|
|
1119
|
-
} else if (error.message.includes("EACCES")) {
|
|
1120
|
-
errorMsg = `Permission denied executing '${command}'. Check file permissions.`;
|
|
1121
|
-
console.error(`[Subprocess] EACCES error - permission denied for '${command}'`);
|
|
1122
|
-
} else if (error.message.includes("EPERM")) {
|
|
1123
|
-
errorMsg = `Operation not permitted for '${command}'. May require elevated privileges.`;
|
|
1124
|
-
console.error(`[Subprocess] EPERM error - operation not permitted`);
|
|
1125
|
-
}
|
|
1126
|
-
reject(new Error(errorMsg));
|
|
1127
|
-
});
|
|
1128
|
-
});
|
|
1129
|
-
this.debug("========== execute() COMPLETED ==========");
|
|
1130
|
-
}
|
|
1131
|
-
/**
|
|
1132
|
-
* Parse streaming output and emit steps in real-time
|
|
1133
|
-
*/
|
|
1134
|
-
parseStreamingOutput(chunk, trajectory, onProgress) {
|
|
1135
|
-
const lines = chunk.split("\n").filter((line) => line.trim());
|
|
1136
|
-
for (const line of lines) {
|
|
1137
|
-
const step = this.createStep("assistant", line);
|
|
1138
|
-
trajectory.push(step);
|
|
1139
|
-
onProgress?.(step);
|
|
1140
|
-
}
|
|
1141
|
-
}
|
|
1142
|
-
/**
|
|
1143
|
-
* Parse final subprocess output
|
|
1144
|
-
*/
|
|
1145
|
-
parseResponse(data) {
|
|
1146
|
-
const steps = [];
|
|
1147
|
-
if (this.config.outputParser === "json") {
|
|
1148
|
-
try {
|
|
1149
|
-
const parsed = JSON.parse(data.stdout);
|
|
1150
|
-
return this.parseJsonOutput(parsed);
|
|
1151
|
-
} catch {
|
|
1152
|
-
this.debug("Failed to parse JSON output, falling back to text");
|
|
1153
|
-
}
|
|
1154
|
-
}
|
|
1155
|
-
if (data.stdout.trim()) {
|
|
1156
|
-
steps.push(this.createStep("response", data.stdout.trim()));
|
|
1157
|
-
}
|
|
1158
|
-
if (data.exitCode !== 0 && data.stderr.trim()) {
|
|
1159
|
-
steps.push(this.createStep("tool_result", `Error: ${data.stderr.trim()}`, {
|
|
1160
|
-
status: "FAILURE"
|
|
1161
|
-
}));
|
|
1162
|
-
}
|
|
1163
|
-
return steps;
|
|
1164
|
-
}
|
|
1165
|
-
/**
|
|
1166
|
-
* Parse JSON output into trajectory steps
|
|
1167
|
-
*/
|
|
1168
|
-
parseJsonOutput(data) {
|
|
1169
|
-
const steps = [];
|
|
1170
|
-
if (data.thinking) {
|
|
1171
|
-
steps.push(this.createStep("thinking", data.thinking));
|
|
1172
|
-
}
|
|
1173
|
-
if (data.steps && Array.isArray(data.steps)) {
|
|
1174
|
-
for (const step of data.steps) {
|
|
1175
|
-
steps.push(this.createStep(step.type || "assistant", step.content, {
|
|
1176
|
-
toolName: step.toolName,
|
|
1177
|
-
toolArgs: step.toolArgs
|
|
1178
|
-
}));
|
|
1179
|
-
}
|
|
1180
|
-
}
|
|
1181
|
-
if (data.response || data.answer || data.content) {
|
|
1182
|
-
steps.push(this.createStep("response", data.response || data.answer || data.content));
|
|
1183
|
-
}
|
|
1184
|
-
return steps;
|
|
1185
|
-
}
|
|
1186
|
-
/**
|
|
1187
|
-
* Health check - verify command exists
|
|
1188
|
-
*/
|
|
1189
|
-
async healthCheck(endpoint, auth) {
|
|
1190
|
-
const command = endpoint || this.config.command;
|
|
1191
|
-
if (!command) return false;
|
|
1192
|
-
return new Promise((resolve) => {
|
|
1193
|
-
const proc = spawn("which", [command], { shell: true });
|
|
1194
|
-
proc.on("close", (code) => resolve(code === 0));
|
|
1195
|
-
proc.on("error", () => resolve(false));
|
|
1196
|
-
});
|
|
1197
|
-
}
|
|
1198
|
-
};
|
|
1199
|
-
var subprocessConnector = new SubprocessConnector();
|
|
1200
|
-
|
|
1201
|
-
// services/connectors/claude-code/ClaudeCodeConnector.ts
|
|
1202
|
-
var CLAUDE_CODE_DEFAULT_CONFIG = {
|
|
1203
|
-
command: "claude",
|
|
1204
|
-
args: ["--print", "--verbose", "--output-format", "stream-json"],
|
|
1205
|
-
// Structured JSON output (--verbose required with stream-json)
|
|
1206
|
-
env: {
|
|
1207
|
-
// These can be overridden by agent config or environment
|
|
1208
|
-
DISABLE_PROMPT_CACHING: "1",
|
|
1209
|
-
DISABLE_ERROR_REPORTING: "1"
|
|
1210
|
-
// Note: DISABLE_TELEMETRY removed - telemetry enabled by default
|
|
1211
|
-
// Configure OTEL_EXPORTER_OTLP_ENDPOINT in .env to send traces
|
|
1212
|
-
},
|
|
1213
|
-
inputMode: "stdin",
|
|
1214
|
-
outputParser: "streaming",
|
|
1215
|
-
timeout: 6e5
|
|
1216
|
-
// 10 minutes for Claude Code
|
|
1217
|
-
};
|
|
1218
|
-
var ClaudeCodeConnector = class extends SubprocessConnector {
|
|
1219
|
-
constructor(config) {
|
|
1220
|
-
super({ ...CLAUDE_CODE_DEFAULT_CONFIG, ...config });
|
|
1221
|
-
this.type = "claude-code";
|
|
1222
|
-
this.name = "Claude Code CLI";
|
|
1223
|
-
this.outputBuffer = "";
|
|
1224
|
-
this.thinkingBuffer = "";
|
|
1225
|
-
this.isInThinking = false;
|
|
1226
|
-
}
|
|
1227
|
-
/**
|
|
1228
|
-
* Build prompt for Claude Code
|
|
1229
|
-
* Structures the input to get the best RCA results
|
|
1230
|
-
*/
|
|
1231
|
-
buildPayload(request) {
|
|
1232
|
-
const parts = [];
|
|
1233
|
-
if (request.testCase.context && request.testCase.context.length > 0) {
|
|
1234
|
-
parts.push("## Context");
|
|
1235
|
-
for (const ctx of request.testCase.context) {
|
|
1236
|
-
parts.push(`**${ctx.description}:**`);
|
|
1237
|
-
parts.push(ctx.value);
|
|
1238
|
-
parts.push("");
|
|
1239
|
-
}
|
|
1240
|
-
}
|
|
1241
|
-
parts.push("## Task");
|
|
1242
|
-
parts.push(request.testCase.initialPrompt);
|
|
1243
|
-
return parts.join("\n");
|
|
1244
|
-
}
|
|
1245
|
-
/**
|
|
1246
|
-
* Parse Claude Code streaming output (stream-json format)
|
|
1247
|
-
* Each line is a JSON object with type and content
|
|
1248
|
-
*/
|
|
1249
|
-
parseStreamingOutput(chunk, trajectory, onProgress) {
|
|
1250
|
-
this.outputBuffer += chunk;
|
|
1251
|
-
const lines = this.outputBuffer.split("\n");
|
|
1252
|
-
this.outputBuffer = lines.pop() || "";
|
|
1253
|
-
for (const line of lines) {
|
|
1254
|
-
const trimmed = line.trim();
|
|
1255
|
-
if (!trimmed) continue;
|
|
1256
|
-
try {
|
|
1257
|
-
const event = JSON.parse(trimmed);
|
|
1258
|
-
const steps = this.parseJsonEvent(event);
|
|
1259
|
-
for (const step of steps) {
|
|
1260
|
-
trajectory.push(step);
|
|
1261
|
-
onProgress?.(step);
|
|
1262
|
-
}
|
|
1263
|
-
} catch {
|
|
1264
|
-
if (trimmed) {
|
|
1265
|
-
const step = this.createStep("assistant", trimmed);
|
|
1266
|
-
trajectory.push(step);
|
|
1267
|
-
onProgress?.(step);
|
|
1268
|
-
}
|
|
1269
|
-
}
|
|
1270
|
-
}
|
|
1271
|
-
}
|
|
1272
|
-
/**
|
|
1273
|
-
* Parse a single JSON event from stream-json output
|
|
1274
|
-
*/
|
|
1275
|
-
parseJsonEvent(event) {
|
|
1276
|
-
const steps = [];
|
|
1277
|
-
if (event.type === "assistant" && event.message?.content) {
|
|
1278
|
-
for (const block of event.message.content) {
|
|
1279
|
-
if (block.type === "thinking" && block.thinking) {
|
|
1280
|
-
steps.push(this.createStep("thinking", block.thinking));
|
|
1281
|
-
} else if (block.type === "text" && block.text) {
|
|
1282
|
-
steps.push(this.createStep("assistant", block.text));
|
|
1283
|
-
} else if (block.type === "tool_use") {
|
|
1284
|
-
steps.push(this.createStep("action", JSON.stringify(block.input || {}), {
|
|
1285
|
-
toolName: block.name,
|
|
1286
|
-
toolArgs: block.input
|
|
1287
|
-
}));
|
|
1288
|
-
}
|
|
1289
|
-
}
|
|
1290
|
-
} else if (event.type === "content_block_delta") {
|
|
1291
|
-
if (event.delta?.type === "thinking_delta" && event.delta.thinking) {
|
|
1292
|
-
this.thinkingBuffer += event.delta.thinking;
|
|
1293
|
-
} else if (event.delta?.type === "text_delta" && event.delta.text) {
|
|
1294
|
-
steps.push(this.createStep("assistant", event.delta.text));
|
|
1295
|
-
}
|
|
1296
|
-
} else if (event.type === "content_block_stop" && this.thinkingBuffer) {
|
|
1297
|
-
steps.push(this.createStep("thinking", this.thinkingBuffer));
|
|
1298
|
-
this.thinkingBuffer = "";
|
|
1299
|
-
} else if (event.type === "result" && event.result) {
|
|
1300
|
-
steps.push(this.createStep(
|
|
1301
|
-
"response",
|
|
1302
|
-
typeof event.result === "string" ? event.result : JSON.stringify(event.result)
|
|
1303
|
-
));
|
|
1304
|
-
} else if (event.type === "tool_result") {
|
|
1305
|
-
steps.push(this.createStep(
|
|
1306
|
-
"tool_result",
|
|
1307
|
-
typeof event.content === "string" ? event.content : JSON.stringify(event.content),
|
|
1308
|
-
{ status: event.is_error ? "FAILURE" /* FAILURE */ : "SUCCESS" /* SUCCESS */ }
|
|
1309
|
-
));
|
|
1310
|
-
}
|
|
1311
|
-
return steps;
|
|
1312
|
-
}
|
|
1313
|
-
/**
|
|
1314
|
-
* Parse final output for Claude Code
|
|
1315
|
-
*/
|
|
1316
|
-
parseResponse(data) {
|
|
1317
|
-
const steps = [];
|
|
1318
|
-
let content = data.stdout;
|
|
1319
|
-
const thinkingMatches = content.matchAll(/<thinking>([\s\S]*?)<\/thinking>/g);
|
|
1320
|
-
for (const match of thinkingMatches) {
|
|
1321
|
-
const thinking = match[1].trim();
|
|
1322
|
-
if (thinking) {
|
|
1323
|
-
steps.push(this.createStep("thinking", thinking));
|
|
1324
|
-
}
|
|
1325
|
-
content = content.replace(match[0], "");
|
|
1326
|
-
}
|
|
1327
|
-
const response = content.trim();
|
|
1328
|
-
if (response) {
|
|
1329
|
-
steps.push(this.createStep("response", response));
|
|
1330
|
-
}
|
|
1331
|
-
if (data.exitCode !== 0 && data.stderr.trim()) {
|
|
1332
|
-
steps.push(this.createStep("tool_result", `Error: ${data.stderr.trim()}`, {
|
|
1333
|
-
status: "FAILURE" /* FAILURE */
|
|
1334
|
-
}));
|
|
1335
|
-
}
|
|
1336
|
-
return steps;
|
|
1337
|
-
}
|
|
1338
|
-
/**
|
|
1339
|
-
* Reset state for new execution
|
|
1340
|
-
*/
|
|
1341
|
-
resetState() {
|
|
1342
|
-
this.outputBuffer = "";
|
|
1343
|
-
this.thinkingBuffer = "";
|
|
1344
|
-
this.isInThinking = false;
|
|
1345
|
-
}
|
|
1346
|
-
/**
|
|
1347
|
-
* Build CLI args from ClaudeCodeConnectorConfig
|
|
1348
|
-
*/
|
|
1349
|
-
buildConfigArgs(config) {
|
|
1350
|
-
const args = [];
|
|
1351
|
-
if (config.dangerouslySkipPermissions) {
|
|
1352
|
-
args.push("--dangerously-skip-permissions");
|
|
1353
|
-
}
|
|
1354
|
-
if (config.systemPrompt) {
|
|
1355
|
-
args.push("--system-prompt", config.systemPrompt);
|
|
1356
|
-
} else if (config.appendSystemPrompt) {
|
|
1357
|
-
args.push("--append-system-prompt", config.appendSystemPrompt);
|
|
1358
|
-
}
|
|
1359
|
-
if (config.allowedTools?.length) {
|
|
1360
|
-
args.push("--allowed-tools", ...config.allowedTools);
|
|
1361
|
-
}
|
|
1362
|
-
if (config.disallowedTools?.length) {
|
|
1363
|
-
args.push("--disallowed-tools", ...config.disallowedTools);
|
|
1364
|
-
}
|
|
1365
|
-
if (config.mcpConfigPath) {
|
|
1366
|
-
args.push("--mcp-config", config.mcpConfigPath);
|
|
1367
|
-
} else if (config.mcpServers && Object.keys(config.mcpServers).length > 0) {
|
|
1368
|
-
args.push("--mcp-config", JSON.stringify({ mcpServers: config.mcpServers }));
|
|
1369
|
-
}
|
|
1370
|
-
if (config.strictMcpConfig) {
|
|
1371
|
-
args.push("--strict-mcp-config");
|
|
1372
|
-
}
|
|
1373
|
-
if (config.additionalArgs) {
|
|
1374
|
-
args.push(...config.additionalArgs);
|
|
1375
|
-
}
|
|
1376
|
-
return args;
|
|
1377
|
-
}
|
|
1378
|
-
/**
|
|
1379
|
-
* Override execute to reset state and apply connectorConfig
|
|
1380
|
-
*/
|
|
1381
|
-
async execute(endpoint, request, auth, onProgress, onRawEvent) {
|
|
1382
|
-
this.debug("========== execute() STARTED ==========");
|
|
1383
|
-
this.debug("Endpoint:", endpoint);
|
|
1384
|
-
this.debug("Test case:", request.testCase.name);
|
|
1385
|
-
this.debug("Config:", this["config"]);
|
|
1386
|
-
this.resetState();
|
|
1387
|
-
const originalEnv = this.config.env ? structuredClone(this.config.env) : {};
|
|
1388
|
-
const originalArgs = this.config.args ? [...this.config.args] : [];
|
|
1389
|
-
const originalInputMode = this.config.inputMode;
|
|
1390
|
-
const originalTimeout = this.config.timeout;
|
|
1391
|
-
const originalWorkingDir = this.config.workingDir;
|
|
1392
|
-
const ccConfig = request.connectorConfig;
|
|
1393
|
-
if (ccConfig) {
|
|
1394
|
-
this.debug("Applying connectorConfig:", Object.keys(ccConfig));
|
|
1395
|
-
if (ccConfig.env) {
|
|
1396
|
-
this.config.env = { ...this.config.env, ...ccConfig.env };
|
|
1397
|
-
}
|
|
1398
|
-
if (ccConfig.usePromptArg) {
|
|
1399
|
-
this.config.inputMode = "arg";
|
|
1400
|
-
}
|
|
1401
|
-
if (ccConfig.timeout !== void 0) {
|
|
1402
|
-
this.config.timeout = ccConfig.timeout;
|
|
1403
|
-
}
|
|
1404
|
-
if (ccConfig.workingDir) {
|
|
1405
|
-
this.config.workingDir = ccConfig.workingDir;
|
|
1406
|
-
}
|
|
1407
|
-
}
|
|
1408
|
-
if (this.config.env?.CLAUDE_CODE_USE_BEDROCK === "1") {
|
|
1409
|
-
this.config.env = { ...this.config.env, ANTHROPIC_API_KEY: "" };
|
|
1410
|
-
this.debug("Bedrock mode: cleared ANTHROPIC_API_KEY to bypass credit check");
|
|
1411
|
-
}
|
|
1412
|
-
if (request.modelId) {
|
|
1413
|
-
this.config.args = [...this.config.args || [], "--model", request.modelId];
|
|
1414
|
-
this.debug("Model flag added:", request.modelId);
|
|
1415
|
-
}
|
|
1416
|
-
if (ccConfig) {
|
|
1417
|
-
const configArgs = this.buildConfigArgs(ccConfig);
|
|
1418
|
-
if (configArgs.length > 0) {
|
|
1419
|
-
this.config.args = [...this.config.args || [], ...configArgs];
|
|
1420
|
-
this.debug("Config args added:", configArgs);
|
|
1421
|
-
}
|
|
1422
|
-
}
|
|
1423
|
-
try {
|
|
1424
|
-
this.debug("State reset, calling super.execute()...");
|
|
1425
|
-
const result = await super.execute(endpoint, request, auth, onProgress, onRawEvent);
|
|
1426
|
-
this.debug("super.execute() returned with", result.trajectory.length, "steps");
|
|
1427
|
-
this.debug("========== execute() COMPLETED ==========");
|
|
1428
|
-
return result;
|
|
1429
|
-
} finally {
|
|
1430
|
-
this.config.env = originalEnv;
|
|
1431
|
-
this.config.args = originalArgs;
|
|
1432
|
-
this.config.inputMode = originalInputMode;
|
|
1433
|
-
this.config.timeout = originalTimeout;
|
|
1434
|
-
this.config.workingDir = originalWorkingDir;
|
|
1435
|
-
}
|
|
1436
|
-
}
|
|
1437
|
-
/**
|
|
1438
|
-
* Health check - verify claude command exists
|
|
1439
|
-
*/
|
|
1440
|
-
async healthCheck(endpoint, auth) {
|
|
1441
|
-
return super.healthCheck(endpoint || "claude", auth);
|
|
1442
|
-
}
|
|
1443
|
-
};
|
|
1444
|
-
var claudeCodeConnector = new ClaudeCodeConnector();
|
|
1445
|
-
|
|
1446
|
-
// services/connectors/mock/MockConnector.ts
|
|
1447
|
-
var MockConnector = class extends BaseConnector {
|
|
1448
|
-
constructor() {
|
|
1449
|
-
super(...arguments);
|
|
1450
|
-
this.type = "mock";
|
|
1451
|
-
this.name = "Demo Agent (Mock)";
|
|
1452
|
-
this.supportsStreaming = true;
|
|
1453
|
-
}
|
|
1454
|
-
/**
|
|
1455
|
-
* Build payload - not used for mock but required by interface
|
|
1456
|
-
*/
|
|
1457
|
-
buildPayload(request) {
|
|
1458
|
-
return {
|
|
1459
|
-
question: request.testCase.initialPrompt,
|
|
1460
|
-
context: request.testCase.context
|
|
1461
|
-
};
|
|
1462
|
-
}
|
|
1463
|
-
/**
|
|
1464
|
-
* Execute mock request - generates realistic trajectory with delays
|
|
1465
|
-
*/
|
|
1466
|
-
async execute(endpoint, request, auth, onProgress, onRawEvent) {
|
|
1467
|
-
const trajectory = [];
|
|
1468
|
-
const rawEvents = [];
|
|
1469
|
-
const runId = `mock-run-${Date.now()}`;
|
|
1470
|
-
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
1471
|
-
this.debug("Generating mock trajectory for:", request.testCase.name);
|
|
1472
|
-
const emitStep = (step) => {
|
|
1473
|
-
trajectory.push(step);
|
|
1474
|
-
onProgress?.(step);
|
|
1475
|
-
rawEvents.push({ type: "MOCK_STEP", step });
|
|
1476
|
-
onRawEvent?.({ type: "MOCK_STEP", step });
|
|
1477
|
-
};
|
|
1478
|
-
await sleep(100);
|
|
1479
|
-
emitStep(this.createStep(
|
|
1480
|
-
"assistant",
|
|
1481
|
-
"I need to investigate this issue. Let me start by checking the cluster health and then drill down into specific metrics."
|
|
1482
|
-
));
|
|
1483
|
-
await sleep(300);
|
|
1484
|
-
emitStep(this.createStep(
|
|
1485
|
-
"action",
|
|
1486
|
-
"Calling opensearch_cluster_health...",
|
|
1487
|
-
{
|
|
1488
|
-
toolName: "opensearch_cluster_health",
|
|
1489
|
-
toolArgs: { local: true }
|
|
1490
|
-
}
|
|
1491
|
-
));
|
|
1492
|
-
await sleep(500);
|
|
1493
|
-
emitStep(this.createStep(
|
|
1494
|
-
"tool_result",
|
|
1495
|
-
JSON.stringify({ status: "yellow", number_of_nodes: 3, unassigned_shards: 0 }, null, 2),
|
|
1496
|
-
{
|
|
1497
|
-
status: "SUCCESS",
|
|
1498
|
-
latencyMs: 500
|
|
1499
|
-
}
|
|
1500
|
-
));
|
|
1501
|
-
await sleep(300);
|
|
1502
|
-
emitStep(this.createStep(
|
|
1503
|
-
"assistant",
|
|
1504
|
-
"The cluster is in yellow state. Let me check the node stats to identify which node might be causing issues."
|
|
1505
|
-
));
|
|
1506
|
-
await sleep(300);
|
|
1507
|
-
emitStep(this.createStep(
|
|
1508
|
-
"action",
|
|
1509
|
-
"Calling opensearch_nodes_stats...",
|
|
1510
|
-
{
|
|
1511
|
-
toolName: "opensearch_nodes_stats",
|
|
1512
|
-
toolArgs: { metric: "jvm,os" }
|
|
1513
|
-
}
|
|
1514
|
-
));
|
|
1515
|
-
await sleep(600);
|
|
1516
|
-
emitStep(this.createStep(
|
|
1517
|
-
"tool_result",
|
|
1518
|
-
"Node-1: CPU 12%, JVM Heap 45%\nNode-2: CPU 15%, JVM Heap 52%\nNode-3: CPU 98%, JVM Heap 89% (Data Node)",
|
|
1519
|
-
{
|
|
1520
|
-
status: "SUCCESS",
|
|
1521
|
-
latencyMs: 600
|
|
1522
|
-
}
|
|
1523
|
-
));
|
|
1524
|
-
await sleep(400);
|
|
1525
|
-
emitStep(this.createStep(
|
|
1526
|
-
"response",
|
|
1527
|
-
`## Root Cause Analysis Complete
|
|
1528
|
-
|
|
1529
|
-
**Finding:** High CPU utilization detected on Node-3 (98% CPU, 89% JVM Heap)
|
|
1530
|
-
|
|
1531
|
-
**Root Cause:** Node-3 is experiencing resource exhaustion, likely due to:
|
|
1532
|
-
1. Heavy indexing or search operations
|
|
1533
|
-
2. Garbage collection pressure from high heap usage
|
|
1534
|
-
3. Possible hot spot in shard distribution
|
|
1535
|
-
|
|
1536
|
-
**Recommendations:**
|
|
1537
|
-
1. Check hot threads on Node-3 using \`_nodes/Node-3/hot_threads\`
|
|
1538
|
-
2. Review shard distribution and consider rebalancing
|
|
1539
|
-
3. Monitor GC logs for long pauses
|
|
1540
|
-
4. Consider scaling horizontally if load persists`
|
|
1541
|
-
));
|
|
1542
|
-
this.debug("Mock trajectory completed. Steps:", trajectory.length);
|
|
1543
|
-
return {
|
|
1544
|
-
trajectory,
|
|
1545
|
-
runId,
|
|
1546
|
-
rawEvents,
|
|
1547
|
-
metadata: {
|
|
1548
|
-
mock: true,
|
|
1549
|
-
testCaseId: request.testCase.id,
|
|
1550
|
-
testCaseName: request.testCase.name
|
|
1551
|
-
}
|
|
1552
|
-
};
|
|
1553
|
-
}
|
|
1554
|
-
/**
|
|
1555
|
-
* Parse raw events - for mock, just extract steps from our custom format
|
|
1556
|
-
*/
|
|
1557
|
-
parseResponse(rawEvents) {
|
|
1558
|
-
return rawEvents.filter((e) => e.type === "MOCK_STEP" && e.step).map((e) => e.step);
|
|
1559
|
-
}
|
|
1560
|
-
/**
|
|
1561
|
-
* Health check - mock is always "healthy"
|
|
1562
|
-
*/
|
|
1563
|
-
async healthCheck(endpoint, auth) {
|
|
1564
|
-
return true;
|
|
1565
|
-
}
|
|
1566
|
-
};
|
|
1567
|
-
var mockConnector = new MockConnector();
|
|
1568
|
-
|
|
1569
|
-
// services/connectors/registry.ts
|
|
1570
|
-
var DEFAULT_CONNECTOR_TYPE = "agui-streaming";
|
|
1571
|
-
var ConnectorRegistryImpl = class {
|
|
1572
|
-
constructor() {
|
|
1573
|
-
this.connectors = /* @__PURE__ */ new Map();
|
|
1574
|
-
}
|
|
1575
|
-
/**
|
|
1576
|
-
* Register a connector implementation
|
|
1577
|
-
* @throws Error if connector with same type is already registered
|
|
1578
|
-
*/
|
|
1579
|
-
register(connector) {
|
|
1580
|
-
if (this.connectors.has(connector.type)) {
|
|
1581
|
-
console.warn(
|
|
1582
|
-
`[ConnectorRegistry] Overwriting existing connector for type: ${connector.type}`
|
|
1583
|
-
);
|
|
1584
|
-
}
|
|
1585
|
-
this.connectors.set(connector.type, connector);
|
|
1586
|
-
}
|
|
1587
|
-
/**
|
|
1588
|
-
* Get a connector by protocol type
|
|
1589
|
-
*/
|
|
1590
|
-
get(type) {
|
|
1591
|
-
return this.connectors.get(type);
|
|
1592
|
-
}
|
|
1593
|
-
/**
|
|
1594
|
-
* Get all registered connectors
|
|
1595
|
-
*/
|
|
1596
|
-
getAll() {
|
|
1597
|
-
return Array.from(this.connectors.values());
|
|
1598
|
-
}
|
|
1599
|
-
/**
|
|
1600
|
-
* Check if a connector is registered
|
|
1601
|
-
*/
|
|
1602
|
-
has(type) {
|
|
1603
|
-
return this.connectors.has(type);
|
|
1604
|
-
}
|
|
1605
|
-
/**
|
|
1606
|
-
* Get connector for an agent config
|
|
1607
|
-
* Handles backwards compatibility with legacy configs
|
|
1608
|
-
*
|
|
1609
|
-
* Resolution order:
|
|
1610
|
-
* 1. If endpoint starts with 'mock://', use mock connector
|
|
1611
|
-
* 2. If connectorType is specified, use that
|
|
1612
|
-
* 3. Default to 'agui-streaming'
|
|
1613
|
-
*/
|
|
1614
|
-
getForAgent(agent) {
|
|
1615
|
-
if (agent.endpoint.startsWith("mock://")) {
|
|
1616
|
-
const mockConnector2 = this.get("mock");
|
|
1617
|
-
if (mockConnector2) {
|
|
1618
|
-
return mockConnector2;
|
|
1619
|
-
}
|
|
1620
|
-
console.warn("[ConnectorRegistry] Mock connector not registered, falling back to default");
|
|
1621
|
-
}
|
|
1622
|
-
const connectorType = agent.connectorType ?? DEFAULT_CONNECTOR_TYPE;
|
|
1623
|
-
const connector = this.get(connectorType);
|
|
1624
|
-
if (!connector) {
|
|
1625
|
-
console.error(
|
|
1626
|
-
`[ConnectorRegistry] Connector not found for type: ${connectorType}, falling back to ${DEFAULT_CONNECTOR_TYPE}`
|
|
1627
|
-
);
|
|
1628
|
-
const defaultConnector = this.get(DEFAULT_CONNECTOR_TYPE);
|
|
1629
|
-
if (!defaultConnector) {
|
|
1630
|
-
throw new Error(
|
|
1631
|
-
`No connector registered for type '${connectorType}' and no default connector available`
|
|
1632
|
-
);
|
|
1633
|
-
}
|
|
1634
|
-
return defaultConnector;
|
|
1635
|
-
}
|
|
1636
|
-
return connector;
|
|
1637
|
-
}
|
|
1638
|
-
/**
|
|
1639
|
-
* Clear all registered connectors (useful for testing)
|
|
1640
|
-
*/
|
|
1641
|
-
clear() {
|
|
1642
|
-
this.connectors.clear();
|
|
1643
|
-
}
|
|
1644
|
-
/**
|
|
1645
|
-
* Get list of registered connector types
|
|
1646
|
-
*/
|
|
1647
|
-
getRegisteredTypes() {
|
|
1648
|
-
return Array.from(this.connectors.keys());
|
|
1649
|
-
}
|
|
1650
|
-
};
|
|
1651
|
-
var connectorRegistry = new ConnectorRegistryImpl();
|
|
1652
|
-
function registerConnector(connector) {
|
|
1653
|
-
connectorRegistry.register(connector);
|
|
1654
|
-
}
|
|
1655
|
-
export {
|
|
1656
|
-
AGUIStreamingConnector,
|
|
1657
|
-
BaseConnector,
|
|
1658
|
-
ClaudeCodeConnector,
|
|
1659
|
-
MockConnector,
|
|
1660
|
-
RESTConnector,
|
|
1661
|
-
SubprocessConnector,
|
|
1662
|
-
connectorRegistry,
|
|
1663
|
-
defineConfig,
|
|
1664
|
-
registerConnector
|
|
1665
|
-
};
|