@crownpeak/dqm-react-component-dev-mcp 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +138 -0
- package/data/.env.example +22 -0
- package/data/.gitattributes +47 -0
- package/data/.glfrc.json +7 -0
- package/data/.husky/pre-commit +5 -0
- package/data/.nvmrc +1 -0
- package/data/CHANGELOG.md +75 -0
- package/data/CODE_OF_CONDUCT.md +129 -0
- package/data/CONTRIBUTING.md +203 -0
- package/data/DOCS-STRUCTURE.md +307 -0
- package/data/I18N.md +292 -0
- package/data/LICENSE +22 -0
- package/data/README.md +315 -0
- package/data/SECURITY.md +125 -0
- package/data/WIKI-DEPLOYMENT.md +348 -0
- package/data/docs/AI-FEATURES.md +610 -0
- package/data/docs/API-REFERENCE.md +1022 -0
- package/data/docs/AUTHENTICATION.md +301 -0
- package/data/docs/BACKEND-API.md +468 -0
- package/data/docs/DEVELOPMENT.md +375 -0
- package/data/docs/EXAMPLES.md +622 -0
- package/data/docs/MCP-SERVER.md +307 -0
- package/data/docs/MIGRATION-GUIDE.md +367 -0
- package/data/docs/NPM-PUBLISH.md +193 -0
- package/data/docs/QUICKSTART.md +206 -0
- package/data/docs/REDIS-SETUP.md +162 -0
- package/data/docs/SERVER.md +228 -0
- package/data/docs/TROUBLESHOOTING.md +657 -0
- package/data/docs/WIDGET-GUIDE.md +638 -0
- package/data/docs/WIKI-HOME.md +58 -0
- package/data/docs/WIKI-SIDEBAR.md +39 -0
- package/data/package.json +171 -0
- package/data/playwright.config.ts +64 -0
- package/data/probe/.cargo/config.toml +10 -0
- package/data/probe/.claude/commands/performance-review.md +15 -0
- package/data/probe/.clinerules +288 -0
- package/data/probe/.dockerignore +57 -0
- package/data/probe/.githooks/post-commit +11 -0
- package/data/probe/.githooks/pre-commit +99 -0
- package/data/probe/.githooks/pre-commit-vow +9 -0
- package/data/probe/.prompts/engineer.md +41 -0
- package/data/probe/.roomodes +28 -0
- package/data/probe/.windsurfrules +0 -0
- package/data/probe/BASH_TOOL_SUMMARY.md +148 -0
- package/data/probe/BENCHMARKING.md +256 -0
- package/data/probe/CLAUDE.md +226 -0
- package/data/probe/CODE_OF_CONDUCT.md +128 -0
- package/data/probe/CONTRIBUTING.md +193 -0
- package/data/probe/Cargo.toml +120 -0
- package/data/probe/Cross.toml +10 -0
- package/data/probe/DOCKER-README.md +224 -0
- package/data/probe/Dockerfile +32 -0
- package/data/probe/ENHANCED_DEBUG_TELEMETRY.md +188 -0
- package/data/probe/LICENSE +201 -0
- package/data/probe/Makefile +210 -0
- package/data/probe/README.md +824 -0
- package/data/probe/SECURITY.md +67 -0
- package/data/probe/WINDOWS-GUIDE.md +294 -0
- package/data/probe/benches/parsing_benchmarks.rs +370 -0
- package/data/probe/benches/search_benchmarks.rs +599 -0
- package/data/probe/benches/simd_benchmarks.rs +372 -0
- package/data/probe/benches/timing_benchmarks.rs +287 -0
- package/data/probe/build-windows.bat +229 -0
- package/data/probe/codex-config/config.toml +6 -0
- package/data/probe/docs/PERFORMANCE_OPTIMIZATION.md +161 -0
- package/data/probe/examples/cache_demo.rs +46 -0
- package/data/probe/examples/chat/.dockerignore +37 -0
- package/data/probe/examples/chat/ChatSessionManager.js +295 -0
- package/data/probe/examples/chat/Dockerfile +98 -0
- package/data/probe/examples/chat/LICENSE +201 -0
- package/data/probe/examples/chat/LOCAL_IMAGE_SUPPORT.md +195 -0
- package/data/probe/examples/chat/MCP_INTEGRATION.md +400 -0
- package/data/probe/examples/chat/README.md +338 -0
- package/data/probe/examples/chat/TRACING.md +226 -0
- package/data/probe/examples/chat/appTracer.js +968 -0
- package/data/probe/examples/chat/auth.js +76 -0
- package/data/probe/examples/chat/bin/probe-chat.js +13 -0
- package/data/probe/examples/chat/build.js +104 -0
- package/data/probe/examples/chat/cancelRequest.js +84 -0
- package/data/probe/examples/chat/demo-agentic-image-flow.js +88 -0
- package/data/probe/examples/chat/demo-local-images.js +128 -0
- package/data/probe/examples/chat/fileSpanExporter.js +181 -0
- package/data/probe/examples/chat/implement/README.md +228 -0
- package/data/probe/examples/chat/implement/backends/AiderBackend.js +750 -0
- package/data/probe/examples/chat/implement/backends/BaseBackend.js +276 -0
- package/data/probe/examples/chat/implement/backends/ClaudeCodeBackend.js +767 -0
- package/data/probe/examples/chat/implement/backends/MockBackend.js +237 -0
- package/data/probe/examples/chat/implement/backends/registry.js +85 -0
- package/data/probe/examples/chat/implement/core/BackendManager.js +567 -0
- package/data/probe/examples/chat/implement/core/ImplementTool.js +354 -0
- package/data/probe/examples/chat/implement/core/config.js +428 -0
- package/data/probe/examples/chat/implement/core/timeouts.js +58 -0
- package/data/probe/examples/chat/implement/core/utils.js +496 -0
- package/data/probe/examples/chat/implement/types/BackendTypes.js +126 -0
- package/data/probe/examples/chat/index.js +669 -0
- package/data/probe/examples/chat/mcpServer.js +341 -0
- package/data/probe/examples/chat/npm/LICENSE +15 -0
- package/data/probe/examples/chat/npm/README.md +168 -0
- package/data/probe/examples/chat/npm/bin/probe-chat.js +156 -0
- package/data/probe/examples/chat/npm/index.js +259 -0
- package/data/probe/examples/chat/npm/package.json +54 -0
- package/data/probe/examples/chat/package.json +102 -0
- package/data/probe/examples/chat/probeChat.js +456 -0
- package/data/probe/examples/chat/probeTool.js +491 -0
- package/data/probe/examples/chat/storage/JsonChatStorage.js +476 -0
- package/data/probe/examples/chat/telemetry.js +281 -0
- package/data/probe/examples/chat/test/integration/chatFlows.test.js +320 -0
- package/data/probe/examples/chat/test/integration/toolCalling.test.js +471 -0
- package/data/probe/examples/chat/test/mocks/mockLLMProvider.js +269 -0
- package/data/probe/examples/chat/test/test-backends.js +90 -0
- package/data/probe/examples/chat/test/testUtils.js +530 -0
- package/data/probe/examples/chat/test/unit/backendTimeout.test.js +161 -0
- package/data/probe/examples/chat/test/unit/packageFiles.test.js +120 -0
- package/data/probe/examples/chat/test/verify-tests.js +118 -0
- package/data/probe/examples/chat/test-agentic-image-loading.js +294 -0
- package/data/probe/examples/chat/test-ai-sdk-telemetry.js +204 -0
- package/data/probe/examples/chat/test-chat-tracing.js +38 -0
- package/data/probe/examples/chat/test-direct-function.js +49 -0
- package/data/probe/examples/chat/test-file-size-validation.js +103 -0
- package/data/probe/examples/chat/test-full-mcp-integration.js +258 -0
- package/data/probe/examples/chat/test-github-context.txt +12 -0
- package/data/probe/examples/chat/test-hierarchy.js +203 -0
- package/data/probe/examples/chat/test-image-spans.js +37 -0
- package/data/probe/examples/chat/test-local-image-reading.js +176 -0
- package/data/probe/examples/chat/test-mcp-integration.js +136 -0
- package/data/probe/examples/chat/test-mcp-probe-server.js +161 -0
- package/data/probe/examples/chat/test-mcp-with-ai.js +279 -0
- package/data/probe/examples/chat/test-multiple-allowed-dirs.js +111 -0
- package/data/probe/examples/chat/test-probe-mcp-server.js +110 -0
- package/data/probe/examples/chat/test-security-validation.js +145 -0
- package/data/probe/examples/chat/test-simple-tracing.js +32 -0
- package/data/probe/examples/chat/test-trace-verification.js +235 -0
- package/data/probe/examples/chat/test-tracing.js +114 -0
- package/data/probe/examples/chat/tokenCounter.js +419 -0
- package/data/probe/examples/chat/tokenUsageDisplay.js +134 -0
- package/data/probe/examples/chat/webServer.js +1103 -0
- package/data/probe/examples/reranker/Cargo.toml +33 -0
- package/data/probe/examples/reranker/DEBUG_OUTPUT_ANALYSIS.md +71 -0
- package/data/probe/examples/reranker/MODELS.md +66 -0
- package/data/probe/examples/reranker/MODEL_COMPARISON.md +60 -0
- package/data/probe/examples/reranker/MULTI_MODEL_ANALYSIS.md +176 -0
- package/data/probe/examples/reranker/PERFORMANCE_SUMMARY.md +156 -0
- package/data/probe/examples/reranker/README.md +347 -0
- package/data/probe/examples/reranker/RUST_BERT_COMPARISON.md +82 -0
- package/data/probe/examples/reranker/TOKENIZATION_GUIDE.md +120 -0
- package/data/probe/examples/reranker/check_rust_tokenizer.py +108 -0
- package/data/probe/examples/reranker/convert_to_torchscript.py +109 -0
- package/data/probe/examples/reranker/debug_scoring.py +189 -0
- package/data/probe/examples/reranker/debug_tokenization.py +154 -0
- package/data/probe/examples/reranker/download_models.sh +73 -0
- package/data/probe/examples/reranker/requirements.txt +13 -0
- package/data/probe/examples/reranker/run_comprehensive_benchmark.sh +83 -0
- package/data/probe/examples/reranker/rust_bert_test/Cargo.toml +12 -0
- package/data/probe/examples/reranker/rust_bert_test/README.md +54 -0
- package/data/probe/examples/reranker/simple_test.py +50 -0
- package/data/probe/examples/reranker/test_all_models.sh +63 -0
- package/data/probe/examples/reranker/test_bert_results.sh +44 -0
- package/data/probe/examples/reranker/test_cross_encoder.py +334 -0
- package/data/probe/examples/reranker/test_cross_encoder.sh +80 -0
- package/data/probe/examples/reranker/test_exact_comparison.py +151 -0
- package/data/probe/examples/reranker/test_parallel_performance.sh +56 -0
- package/data/probe/examples/reranker/test_scores.py +132 -0
- package/data/probe/install.ps1 +508 -0
- package/data/probe/install.sh +460 -0
- package/data/probe/npm/CLONE_METHOD_EXAMPLES.md +596 -0
- package/data/probe/npm/CONTEXT_COMPACTION.md +303 -0
- package/data/probe/npm/DELEGATE_TOOL_README.md +166 -0
- package/data/probe/npm/MAID_INTEGRATION.md +313 -0
- package/data/probe/npm/MCP_INTEGRATION_SUMMARY.md +241 -0
- package/data/probe/npm/README.md +824 -0
- package/data/probe/npm/bin/.gitignore +7 -0
- package/data/probe/npm/bin/.gitkeep +0 -0
- package/data/probe/npm/bin/README.md +12 -0
- package/data/probe/npm/bin/probe +167 -0
- package/data/probe/npm/docs/CLAUDE_CODE_INTEGRATION.md +414 -0
- package/data/probe/npm/docs/CODEX_INTEGRATION.md +502 -0
- package/data/probe/npm/docs/EDIT_CREATE_TOOLS.md +233 -0
- package/data/probe/npm/docs/RETRY_AND_FALLBACK.md +674 -0
- package/data/probe/npm/example-usage.js +335 -0
- package/data/probe/npm/examples/multi-engine-demo.js +117 -0
- package/data/probe/npm/examples/probe-agent-cli.js +113 -0
- package/data/probe/npm/examples/test-agent-edit.js +114 -0
- package/data/probe/npm/examples/test-edit-create.js +120 -0
- package/data/probe/npm/examples/test-edit-direct.js +114 -0
- package/data/probe/npm/index.d.ts +744 -0
- package/data/probe/npm/jest.config.js +52 -0
- package/data/probe/npm/package.json +117 -0
- package/data/probe/npm/scripts/build-agent.cjs +75 -0
- package/data/probe/npm/scripts/build-cjs.js +124 -0
- package/data/probe/npm/scripts/build-mcp.cjs +36 -0
- package/data/probe/npm/scripts/postinstall.js +216 -0
- package/data/probe/npm/test-codex-e2e.js +78 -0
- package/data/probe/npm/test-download-lock.js +109 -0
- package/data/probe/npm/test-grep-security.js +94 -0
- package/data/probe/npm/test-grep-simplified.js +63 -0
- package/data/probe/npm/test-grep.js +51 -0
- package/data/probe/npm/tests/README.md +96 -0
- package/data/probe/npm/tests/agent-compact-history.test.js +174 -0
- package/data/probe/npm/tests/allow-tests-default.test.js +151 -0
- package/data/probe/npm/tests/contextCompactor.test.js +498 -0
- package/data/probe/npm/tests/delegate-config.test.js +353 -0
- package/data/probe/npm/tests/delegate-integration.test.js +348 -0
- package/data/probe/npm/tests/extractor-integration.test.js +162 -0
- package/data/probe/npm/tests/extractor.test.js +317 -0
- package/data/probe/npm/tests/fixtures/sampleDiagrams.js +267 -0
- package/data/probe/npm/tests/integration/claude-code-auto-fallback.spec.js +148 -0
- package/data/probe/npm/tests/integration/claude-code-multi-step.spec.js +127 -0
- package/data/probe/npm/tests/integration/claude-code-tool-events.spec.js +163 -0
- package/data/probe/npm/tests/integration/codex-auto-fallback.spec.js +191 -0
- package/data/probe/npm/tests/integration/codex-tool-events.spec.js +147 -0
- package/data/probe/npm/tests/integration/examplesChatMcp.test.js +402 -0
- package/data/probe/npm/tests/integration/mcpDotenvSupport.test.js +174 -0
- package/data/probe/npm/tests/integration/mcpErrorHandling.test.js +566 -0
- package/data/probe/npm/tests/integration/mcpRobustness.test.js +564 -0
- package/data/probe/npm/tests/integration/mcpStdoutPurity.test.js +355 -0
- package/data/probe/npm/tests/integration/probeAgentMcp.test.js +398 -0
- package/data/probe/npm/tests/integration/retryFallback.test.js +368 -0
- package/data/probe/npm/tests/integration/schema-in-initial-message.test.js +318 -0
- package/data/probe/npm/tests/integration/schema-validation-loop-prevention.test.js +244 -0
- package/data/probe/npm/tests/integration/schemaRetryLogic.test.js +94 -0
- package/data/probe/npm/tests/integration/validationFlow.test.js +329 -0
- package/data/probe/npm/tests/manual/test-codex-basic.js +110 -0
- package/data/probe/npm/tests/mcp/mcpClientManager.test.js +614 -0
- package/data/probe/npm/tests/mcp/mcpConfig.test.js +359 -0
- package/data/probe/npm/tests/mcp/mcpXmlBridge.test.js +436 -0
- package/data/probe/npm/tests/mcp/mockMcpServer.js +510 -0
- package/data/probe/npm/tests/mcp-strict-syntax.test.js +319 -0
- package/data/probe/npm/tests/mermaidQuoteEscaping.test.js +214 -0
- package/data/probe/npm/tests/nestedQuoteFix.test.js +40 -0
- package/data/probe/npm/tests/setup.js +46 -0
- package/data/probe/npm/tests/unit/allowed-tools.test.js +513 -0
- package/data/probe/npm/tests/unit/attempt-completion-closing-tag-in-content.test.js +188 -0
- package/data/probe/npm/tests/unit/attemptCompletionJsonFix.test.js +238 -0
- package/data/probe/npm/tests/unit/attemptCompletionJsonIssue.test.js +128 -0
- package/data/probe/npm/tests/unit/backtickAutoFix.test.js +35 -0
- package/data/probe/npm/tests/unit/bash-probe-agent-integration.test.js +389 -0
- package/data/probe/npm/tests/unit/bash-simple-commands.test.js +324 -0
- package/data/probe/npm/tests/unit/bash-tool-comprehensive.test.js +371 -0
- package/data/probe/npm/tests/unit/bash-tool-integration.test.js +310 -0
- package/data/probe/npm/tests/unit/bash-tool.test.js +341 -0
- package/data/probe/npm/tests/unit/completion-prompt.test.js +379 -0
- package/data/probe/npm/tests/unit/cwd-path-options.test.js +287 -0
- package/data/probe/npm/tests/unit/delegate-limits.test.js +422 -0
- package/data/probe/npm/tests/unit/direct-content-attempt-completion.test.js +235 -0
- package/data/probe/npm/tests/unit/edit-create-tools.test.js +609 -0
- package/data/probe/npm/tests/unit/enhancedMermaidValidation.test.js +577 -0
- package/data/probe/npm/tests/unit/extract-content.test.js +83 -0
- package/data/probe/npm/tests/unit/extract-multiple-targets.test.js +89 -0
- package/data/probe/npm/tests/unit/fallbackManager.test.js +442 -0
- package/data/probe/npm/tests/unit/githubCompatibilityValidation.test.js +258 -0
- package/data/probe/npm/tests/unit/imageConfig.test.js +149 -0
- package/data/probe/npm/tests/unit/imagePathResolution.test.js +345 -0
- package/data/probe/npm/tests/unit/json-fixing-agent.test.js +238 -0
- package/data/probe/npm/tests/unit/json-validation-enhanced-errors.test.js +199 -0
- package/data/probe/npm/tests/unit/jsonValidationInfiniteLoopFix.test.js +228 -0
- package/data/probe/npm/tests/unit/maidIntegration.test.js +139 -0
- package/data/probe/npm/tests/unit/maxIterationsWarning.test.js +195 -0
- package/data/probe/npm/tests/unit/mermaidEdgeLabelFix.test.js +161 -0
- package/data/probe/npm/tests/unit/mermaidHtmlEntities.test.js +76 -0
- package/data/probe/npm/tests/unit/mermaidInfiniteLoopFix.test.js +64 -0
- package/data/probe/npm/tests/unit/mermaidValidation.test.js +723 -0
- package/data/probe/npm/tests/unit/mermaidValidationVisorExample.test.js +309 -0
- package/data/probe/npm/tests/unit/probe-agent-clone-realistic.test.js +643 -0
- package/data/probe/npm/tests/unit/probe-agent-clone.test.js +476 -0
- package/data/probe/npm/tests/unit/probe-agent-delegate.test.js +400 -0
- package/data/probe/npm/tests/unit/probe-agent-model-option.test.js +118 -0
- package/data/probe/npm/tests/unit/probeTool-security.test.js +283 -0
- package/data/probe/npm/tests/unit/readImageTool.test.js +418 -0
- package/data/probe/npm/tests/unit/retryManager.test.js +317 -0
- package/data/probe/npm/tests/unit/schema-aware-reminders.test.js +288 -0
- package/data/probe/npm/tests/unit/schemaDefinitionDetection.test.js +115 -0
- package/data/probe/npm/tests/unit/schemaUtils.test.js +1268 -0
- package/data/probe/npm/tests/unit/simpleTelemetry.test.js +282 -0
- package/data/probe/npm/tests/unit/simplified-attempt-completion.test.js +274 -0
- package/data/probe/npm/tests/unit/single-quote-json-bug.test.js +231 -0
- package/data/probe/npm/tests/unit/subgraphAutoFix.test.js +110 -0
- package/data/probe/npm/tests/unit/system-prompt.test.js +32 -0
- package/data/probe/npm/tests/unit/types-probe-agent-options.test.js +42 -0
- package/data/probe/npm/tests/unit/xmlParsing.test.js +720 -0
- package/data/probe/npm/tsconfig.json +21 -0
- package/data/probe/result1.txt +19 -0
- package/data/probe/result2.txt +26 -0
- package/data/probe/scripts/benchmark.sh +270 -0
- package/data/probe/scripts/cache_memory_analysis.rs +844 -0
- package/data/probe/scripts/claude-hook-wrapper.sh +56 -0
- package/data/probe/site/.env.example +10 -0
- package/data/probe/site/DEPLOYMENT.md +86 -0
- package/data/probe/site/README.md +183 -0
- package/data/probe/site/adding-languages.md +135 -0
- package/data/probe/site/ai-chat.md +427 -0
- package/data/probe/site/ai-integration.md +1488 -0
- package/data/probe/site/blog/agentic-flow-custom-xml-protocol.md +407 -0
- package/data/probe/site/blog/index.md +118 -0
- package/data/probe/site/blog/v0.6.0-release.md +426 -0
- package/data/probe/site/blog.md +8 -0
- package/data/probe/site/changelog.md +200 -0
- package/data/probe/site/cli-mode.md +437 -0
- package/data/probe/site/code-extraction.md +436 -0
- package/data/probe/site/contributing/README.md +9 -0
- package/data/probe/site/contributing/documentation-cross-references.md +215 -0
- package/data/probe/site/contributing/documentation-maintenance.md +275 -0
- package/data/probe/site/contributing/documentation-structure.md +75 -0
- package/data/probe/site/documentation-cross-references.md +215 -0
- package/data/probe/site/documentation-guide.md +132 -0
- package/data/probe/site/documentation-maintenance.md +275 -0
- package/data/probe/site/features.md +147 -0
- package/data/probe/site/how-it-works.md +118 -0
- package/data/probe/site/index.md +175 -0
- package/data/probe/site/index.md.bak +133 -0
- package/data/probe/site/installation.md +235 -0
- package/data/probe/site/integrations/docker.md +248 -0
- package/data/probe/site/integrations/github-actions.md +413 -0
- package/data/probe/site/language-support-overview.md +168 -0
- package/data/probe/site/mcp-integration.md +587 -0
- package/data/probe/site/mcp-server.md +304 -0
- package/data/probe/site/navigation-structure.md +76 -0
- package/data/probe/site/nodejs-sdk.md +798 -0
- package/data/probe/site/output-formats.md +625 -0
- package/data/probe/site/package.json +21 -0
- package/data/probe/site/public/_headers +28 -0
- package/data/probe/site/public/_redirects +11 -0
- package/data/probe/site/quick-start.md +289 -0
- package/data/probe/site/search-functionality.md +291 -0
- package/data/probe/site/search-reference.md +291 -0
- package/data/probe/site/supported-languages.md +215 -0
- package/data/probe/site/use-cases/README.md +8 -0
- package/data/probe/site/use-cases/advanced-cli.md +253 -0
- package/data/probe/site/use-cases/ai-code-editors.md +239 -0
- package/data/probe/site/use-cases/building-ai-tools.md +529 -0
- package/data/probe/site/use-cases/cli-ai-workflows.md +285 -0
- package/data/probe/site/use-cases/deploying-probe-web-interface.md +255 -0
- package/data/probe/site/use-cases/integrating-probe-into-ai-code-editors.md +161 -0
- package/data/probe/site/use-cases/nodejs-sdk.md +596 -0
- package/data/probe/site/use-cases/team-chat.md +350 -0
- package/data/probe/site/web-interface.md +434 -0
- package/data/probe/site/wrangler.toml +9 -0
- package/data/probe/test-api-key.sh +1 -0
- package/data/probe/test-probe-implementation/hello.js +7 -0
- package/data/probe/test_cases/demonstrate_early_termination_issues.sh +176 -0
- package/data/probe/test_cases/early_termination_issues.rs +533 -0
- package/data/probe/test_data/test_nested_struct.go +26 -0
- package/data/probe/tests/README.md +286 -0
- package/data/probe/tests/README_search_determinism_tests.md +116 -0
- package/data/probe/tests/adjacent_comment_test.rs +152 -0
- package/data/probe/tests/apostrophe_handling_tests.rs +132 -0
- package/data/probe/tests/block_filtering_with_ast_tests.rs +669 -0
- package/data/probe/tests/block_merging_tests.rs +396 -0
- package/data/probe/tests/c_outline_format_tests.rs +2179 -0
- package/data/probe/tests/cache_invalidation_issues.rs.disabled +682 -0
- package/data/probe/tests/cache_order_tests.rs +147 -0
- package/data/probe/tests/cache_query_scoping_tests.rs +221 -0
- package/data/probe/tests/cli_tests.rs +680 -0
- package/data/probe/tests/comment_context_integration_test.rs +240 -0
- package/data/probe/tests/common.rs +33 -0
- package/data/probe/tests/complex_block_merging_tests.rs +599 -0
- package/data/probe/tests/complex_query_block_filtering_tests.rs +422 -0
- package/data/probe/tests/control_flow_closing_braces_test.rs +91 -0
- package/data/probe/tests/cpp_outline_format_tests.rs +1507 -0
- package/data/probe/tests/csharp_outline_format_tests.rs +941 -0
- package/data/probe/tests/elastic_query_integration_tests.rs +922 -0
- package/data/probe/tests/extract_command_tests.rs +1848 -0
- package/data/probe/tests/extract_deduplication_tests.rs +146 -0
- package/data/probe/tests/extract_input_file_tests.rs +84 -0
- package/data/probe/tests/extract_prompt_tests.rs +102 -0
- package/data/probe/tests/filename_search_tests.rs +96 -0
- package/data/probe/tests/fixtures/user/AssemblyInfo.cs +3 -0
- package/data/probe/tests/github_extract_tests.rs +234 -0
- package/data/probe/tests/go_comment_test.rs +253 -0
- package/data/probe/tests/go_outline_format_tests.rs +2587 -0
- package/data/probe/tests/go_path_resolver_tests.rs +96 -0
- package/data/probe/tests/html_outline_format_tests.rs +637 -0
- package/data/probe/tests/integration_tests.rs +837 -0
- package/data/probe/tests/ip_whitelist_test.rs +148 -0
- package/data/probe/tests/java_outline_format_tests.rs +1611 -0
- package/data/probe/tests/javascript_extract_tests.rs +315 -0
- package/data/probe/tests/javascript_outline_format_tests.rs +1464 -0
- package/data/probe/tests/json_format_tests.rs +436 -0
- package/data/probe/tests/json_schema_validation_tests.rs +450 -0
- package/data/probe/tests/lib_usage.rs +60 -0
- package/data/probe/tests/line_comment_context_extension_test.rs +459 -0
- package/data/probe/tests/line_map_cache_tests.rs +114 -0
- package/data/probe/tests/markdown_integration_tests.rs +190 -0
- package/data/probe/tests/mocks/test_ip_whitelist.go +11 -0
- package/data/probe/tests/mocks/test_object.js +27 -0
- package/data/probe/tests/mocks/test_struct.go +50 -0
- package/data/probe/tests/multi_keyword_pattern_tests.rs +464 -0
- package/data/probe/tests/multi_language_syntax_integration_tests.rs +218 -0
- package/data/probe/tests/multiple_capture_groups_tests.rs +169 -0
- package/data/probe/tests/negative_compound_word_tests.rs +246 -0
- package/data/probe/tests/nested_symbol_extraction_tests.rs +99 -0
- package/data/probe/tests/outline_cross_file_interference_test.rs +335 -0
- package/data/probe/tests/outline_keyword_preservation_test.rs +67 -0
- package/data/probe/tests/output_format_edge_cases_tests.rs +693 -0
- package/data/probe/tests/parallel_extraction_tests.rs +178 -0
- package/data/probe/tests/parallel_search_tests.rs +355 -0
- package/data/probe/tests/path_resolver_tests.rs +698 -0
- package/data/probe/tests/php_outline_format_extended_tests.rs +928 -0
- package/data/probe/tests/php_outline_format_tests.rs +768 -0
- package/data/probe/tests/property_tests.proptest-regressions +9 -0
- package/data/probe/tests/property_tests.rs +118 -0
- package/data/probe/tests/python_outline_format_tests.rs +1538 -0
- package/data/probe/tests/query_command_json_tests.rs +438 -0
- package/data/probe/tests/query_command_tests.rs +232 -0
- package/data/probe/tests/query_command_xml_tests.rs +569 -0
- package/data/probe/tests/quoted_term_with_negative_keyword_tests.rs +216 -0
- package/data/probe/tests/required_terms_filename_tests.rs +116 -0
- package/data/probe/tests/ruby_outline_format_tests.rs +1011 -0
- package/data/probe/tests/rust_line_comment_context_test.rs +151 -0
- package/data/probe/tests/rust_outline_format_enhanced_tests.rs +725 -0
- package/data/probe/tests/rust_outline_format_tests.rs +843 -0
- package/data/probe/tests/schemas/xml_output_schema.xsd +38 -0
- package/data/probe/tests/search_determinism_tests.rs +451 -0
- package/data/probe/tests/search_hints_tests.rs +253 -0
- package/data/probe/tests/special_character_escaping_tests.rs +417 -0
- package/data/probe/tests/stemming_compound_word_filtering_tests.rs +535 -0
- package/data/probe/tests/strict_elastic_syntax_tests.rs +404 -0
- package/data/probe/tests/swift_outline_format_tests.rs +3319 -0
- package/data/probe/tests/symbols_tests.rs +166 -0
- package/data/probe/tests/test_file.rs +45 -0
- package/data/probe/tests/test_tokenize.rs +28 -0
- package/data/probe/tests/timeout_tests.rs +82 -0
- package/data/probe/tests/tokenization_tests.rs +195 -0
- package/data/probe/tests/tokenized_block_filtering_tests.rs +174 -0
- package/data/probe/tests/typescript_extract_tests.rs +214 -0
- package/data/probe/tests/typescript_outline_format_tests.rs +2188 -0
- package/data/probe/tests/xml_format_tests.rs +568 -0
- package/data/probe/tests/xml_schema_validation_tests.rs +497 -0
- package/data/scripts/postinstall.mjs +9 -0
- package/data/scripts/set-version.js +0 -0
- package/data/scripts/wiki-build.sh +111 -0
- package/data/scripts/wiki-deploy.sh +73 -0
- package/data/serve.json +12 -0
- package/data/test/demo-dynamic.html +134 -0
- package/data/test/demo-esm.html +105 -0
- package/data/test/demo-iife.html +78 -0
- package/data/tsconfig.json +7 -0
- package/data/vite.server.ts +483 -0
- package/data/vitest.config.ts +40 -0
- package/data/wiki/Home.md +58 -0
- package/data/wiki/_Sidebar.md +39 -0
- package/docs-mcp.config.json +20 -0
- package/package.json +56 -0
- package/src/config.js +111 -0
- package/src/index.js +395 -0
|
@@ -0,0 +1,567 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backend manager for handling multiple implementation backends
|
|
3
|
+
* @module BackendManager
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { BackendError, ErrorTypes, ErrorHandler, RetryHandler } from './utils.js';
|
|
7
|
+
import { getDefaultTimeoutMs } from './timeouts.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Manages registration, selection, and execution of implementation backends
|
|
11
|
+
* @class
|
|
12
|
+
*/
|
|
13
|
+
class BackendManager {
|
|
14
|
+
/**
|
|
15
|
+
* @param {Object} config - Backend manager configuration
|
|
16
|
+
* @param {string} config.defaultBackend - Default backend name
|
|
17
|
+
* @param {string[]} [config.fallbackBackends] - Fallback backend names
|
|
18
|
+
* @param {string} [config.selectionStrategy='auto'] - Backend selection strategy
|
|
19
|
+
* @param {number} [config.maxConcurrentSessions=3] - Maximum concurrent sessions
|
|
20
|
+
* @param {number} [config.timeout=300000] - Default timeout in milliseconds
|
|
21
|
+
* @param {number} [config.retryAttempts=2] - Number of retry attempts
|
|
22
|
+
*/
|
|
23
|
+
constructor(config) {
|
|
24
|
+
this.config = {
|
|
25
|
+
defaultBackend: config.defaultBackend || 'aider',
|
|
26
|
+
selectionStrategy: config.selectionStrategy || 'auto',
|
|
27
|
+
maxConcurrentSessions: config.maxConcurrentSessions || 3,
|
|
28
|
+
timeout: config.timeout || getDefaultTimeoutMs(), // Use centralized default (20 minutes)
|
|
29
|
+
retryAttempts: config.retryAttempts || 2,
|
|
30
|
+
...config
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
this.backends = new Map();
|
|
34
|
+
this.activeSessionCount = 0;
|
|
35
|
+
this.sessionBackendMap = new Map();
|
|
36
|
+
this.initialized = false;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Initialize the backend manager
|
|
41
|
+
* @returns {Promise<void>}
|
|
42
|
+
*/
|
|
43
|
+
async initialize() {
|
|
44
|
+
if (this.initialized) return;
|
|
45
|
+
|
|
46
|
+
// Initialize any pre-registered backends
|
|
47
|
+
for (const [name, backend] of this.backends) {
|
|
48
|
+
try {
|
|
49
|
+
if (!backend.initialized) {
|
|
50
|
+
await backend.initialize(this.config.backends?.[name] || {});
|
|
51
|
+
}
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.warn(`Failed to initialize backend '${name}':`, error.message);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
this.initialized = true;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Register a new backend
|
|
62
|
+
* @param {import('../backends/BaseBackend')} backend - Backend instance
|
|
63
|
+
* @returns {Promise<void>}
|
|
64
|
+
*/
|
|
65
|
+
async registerBackend(backend) {
|
|
66
|
+
if (!backend || !backend.name) {
|
|
67
|
+
throw new Error('Invalid backend: must have a name property');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Check if backend already registered
|
|
71
|
+
if (this.backends.has(backend.name)) {
|
|
72
|
+
console.warn(`Backend '${backend.name}' is already registered, replacing...`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
this.backends.set(backend.name, backend);
|
|
76
|
+
|
|
77
|
+
// Initialize if manager is already initialized
|
|
78
|
+
if (this.initialized && !backend.initialized) {
|
|
79
|
+
try {
|
|
80
|
+
await backend.initialize(this.config.backends?.[backend.name] || {});
|
|
81
|
+
} catch (error) {
|
|
82
|
+
console.warn(`Failed to initialize backend '${backend.name}':`, error.message);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Unregister a backend
|
|
89
|
+
* @param {string} name - Backend name
|
|
90
|
+
* @returns {Promise<void>}
|
|
91
|
+
*/
|
|
92
|
+
async unregisterBackend(name) {
|
|
93
|
+
const backend = this.backends.get(name);
|
|
94
|
+
if (backend) {
|
|
95
|
+
await backend.cleanup();
|
|
96
|
+
this.backends.delete(name);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Get list of available backend names
|
|
102
|
+
* @returns {string[]}
|
|
103
|
+
*/
|
|
104
|
+
getAvailableBackends() {
|
|
105
|
+
return Array.from(this.backends.keys());
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Get backend instance by name
|
|
110
|
+
* @param {string} name - Backend name
|
|
111
|
+
* @returns {import('../backends/BaseBackend')|null}
|
|
112
|
+
*/
|
|
113
|
+
getBackend(name) {
|
|
114
|
+
return this.backends.get(name) || null;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Get backend information
|
|
119
|
+
* @param {string} name - Backend name
|
|
120
|
+
* @returns {import('../types/BackendTypes').BackendInfo|null}
|
|
121
|
+
*/
|
|
122
|
+
async getBackendInfo(name) {
|
|
123
|
+
const backend = this.backends.get(name);
|
|
124
|
+
if (!backend) return null;
|
|
125
|
+
|
|
126
|
+
const info = backend.getInfo();
|
|
127
|
+
info.available = await backend.isAvailable();
|
|
128
|
+
|
|
129
|
+
return info;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Select appropriate backend for request
|
|
134
|
+
* @param {import('../types/BackendTypes').ImplementRequest} request - Implementation request
|
|
135
|
+
* @returns {Promise<string>} Selected backend name
|
|
136
|
+
*/
|
|
137
|
+
async selectBackend(request) {
|
|
138
|
+
switch (this.config.selectionStrategy) {
|
|
139
|
+
case 'preference':
|
|
140
|
+
return this.selectByPreference(request);
|
|
141
|
+
case 'capability':
|
|
142
|
+
return this.selectByCapability(request);
|
|
143
|
+
case 'auto':
|
|
144
|
+
default:
|
|
145
|
+
return this.selectAuto(request);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Select backend using auto strategy
|
|
151
|
+
* @param {import('../types/BackendTypes').ImplementRequest} request - Implementation request
|
|
152
|
+
* @returns {Promise<string>}
|
|
153
|
+
* @private
|
|
154
|
+
*/
|
|
155
|
+
async selectAuto(request) {
|
|
156
|
+
console.error('[BackendManager] Starting backend selection with strategy: auto');
|
|
157
|
+
console.error(`[BackendManager] Default backend: ${this.config.defaultBackend}`);
|
|
158
|
+
console.error(`[BackendManager] Available backends: ${Array.from(this.backends.keys()).join(', ')}`);
|
|
159
|
+
|
|
160
|
+
// First try explicit backend if specified
|
|
161
|
+
if (request.options?.backend && this.backends.has(request.options.backend)) {
|
|
162
|
+
console.error(`[BackendManager] Checking explicit backend: ${request.options.backend}`);
|
|
163
|
+
const backend = this.backends.get(request.options.backend);
|
|
164
|
+
if (await backend.isAvailable()) {
|
|
165
|
+
console.error(`[BackendManager] Selected explicit backend: ${request.options.backend}`);
|
|
166
|
+
return request.options.backend;
|
|
167
|
+
} else {
|
|
168
|
+
// If explicit backend is not available, fail immediately (no fallbacks)
|
|
169
|
+
console.error(`[BackendManager] Explicit backend ${request.options.backend} is not available`);
|
|
170
|
+
throw new BackendError(
|
|
171
|
+
`Requested backend '${request.options.backend}' is not available`,
|
|
172
|
+
ErrorTypes.BACKEND_NOT_FOUND,
|
|
173
|
+
'BACKEND_NOT_AVAILABLE'
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Try default backend
|
|
179
|
+
if (this.backends.has(this.config.defaultBackend)) {
|
|
180
|
+
console.error(`[BackendManager] Checking default backend: ${this.config.defaultBackend}`);
|
|
181
|
+
const backend = this.backends.get(this.config.defaultBackend);
|
|
182
|
+
const isAvailable = await backend.isAvailable();
|
|
183
|
+
console.error(`[BackendManager] Default backend ${this.config.defaultBackend} available: ${isAvailable}`);
|
|
184
|
+
if (isAvailable) {
|
|
185
|
+
console.error(`[BackendManager] Selected default backend: ${this.config.defaultBackend}`);
|
|
186
|
+
return this.config.defaultBackend;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// No fallbacks - if default backend is not available, fail
|
|
191
|
+
console.error('[BackendManager] No available backends found!');
|
|
192
|
+
throw new BackendError(
|
|
193
|
+
`Default backend '${this.config.defaultBackend}' is not available`,
|
|
194
|
+
ErrorTypes.BACKEND_NOT_FOUND,
|
|
195
|
+
'NO_AVAILABLE_BACKENDS'
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Select backend by user preference
|
|
201
|
+
* @param {import('../types/BackendTypes').ImplementRequest} request - Implementation request
|
|
202
|
+
* @returns {Promise<string>}
|
|
203
|
+
* @private
|
|
204
|
+
*/
|
|
205
|
+
async selectByPreference(request) {
|
|
206
|
+
const preference = request.options?.backend || this.config.defaultBackend;
|
|
207
|
+
|
|
208
|
+
if (!this.backends.has(preference)) {
|
|
209
|
+
throw new BackendError(
|
|
210
|
+
`Preferred backend '${preference}' not found`,
|
|
211
|
+
ErrorTypes.BACKEND_NOT_FOUND,
|
|
212
|
+
'PREFERRED_BACKEND_NOT_FOUND'
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const backend = this.backends.get(preference);
|
|
217
|
+
if (!(await backend.isAvailable())) {
|
|
218
|
+
throw new BackendError(
|
|
219
|
+
`Preferred backend '${preference}' is not available`,
|
|
220
|
+
ErrorTypes.BACKEND_NOT_FOUND,
|
|
221
|
+
'PREFERRED_BACKEND_UNAVAILABLE'
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return preference;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Select backend by capability matching
|
|
230
|
+
* @param {import('../types/BackendTypes').ImplementRequest} request - Implementation request
|
|
231
|
+
* @returns {Promise<string>}
|
|
232
|
+
* @private
|
|
233
|
+
*/
|
|
234
|
+
async selectByCapability(request) {
|
|
235
|
+
const candidates = [];
|
|
236
|
+
|
|
237
|
+
for (const [name, backend] of this.backends) {
|
|
238
|
+
if (!(await backend.isAvailable())) continue;
|
|
239
|
+
|
|
240
|
+
const capabilities = backend.getCapabilities();
|
|
241
|
+
let score = 0;
|
|
242
|
+
|
|
243
|
+
// Score based on language support
|
|
244
|
+
if (request.context?.language) {
|
|
245
|
+
if (capabilities.supportsLanguages.includes(request.context.language)) {
|
|
246
|
+
score += 10;
|
|
247
|
+
} else if (capabilities.supportsLanguages.includes('all')) {
|
|
248
|
+
score += 5;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Score based on requested features
|
|
253
|
+
if (request.options?.generateTests && capabilities.supportsTestGeneration) {
|
|
254
|
+
score += 5;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (request.options?.streaming && capabilities.supportsStreaming) {
|
|
258
|
+
score += 3;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Prefer backends with higher concurrent session limits
|
|
262
|
+
score += Math.min(capabilities.maxConcurrentSessions, 5);
|
|
263
|
+
|
|
264
|
+
candidates.push({ name, score });
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (candidates.length === 0) {
|
|
268
|
+
throw new BackendError(
|
|
269
|
+
'No capable backends found',
|
|
270
|
+
ErrorTypes.BACKEND_NOT_FOUND,
|
|
271
|
+
'NO_CAPABLE_BACKENDS'
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Sort by score and return highest
|
|
276
|
+
candidates.sort((a, b) => b.score - a.score);
|
|
277
|
+
return candidates[0].name;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Execute implementation request
|
|
282
|
+
* @param {import('../types/BackendTypes').ImplementRequest} request - Implementation request
|
|
283
|
+
* @returns {Promise<import('../types/BackendTypes').ImplementResult>}
|
|
284
|
+
*/
|
|
285
|
+
async executeImplementation(request) {
|
|
286
|
+
// Ensure manager is initialized
|
|
287
|
+
await this.initialize();
|
|
288
|
+
|
|
289
|
+
// Check concurrent session limit
|
|
290
|
+
if (this.activeSessionCount >= this.config.maxConcurrentSessions) {
|
|
291
|
+
throw new BackendError(
|
|
292
|
+
'Maximum concurrent sessions reached',
|
|
293
|
+
ErrorTypes.QUOTA_EXCEEDED,
|
|
294
|
+
'MAX_SESSIONS_REACHED',
|
|
295
|
+
{ limit: this.config.maxConcurrentSessions, current: this.activeSessionCount }
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Select backend
|
|
300
|
+
console.error(`[BackendManager] Selecting backend for request ${request.sessionId}`);
|
|
301
|
+
const backendName = await this.selectBackend(request);
|
|
302
|
+
console.error(`[BackendManager] Selected backend: ${backendName}`);
|
|
303
|
+
const backend = this.backends.get(backendName);
|
|
304
|
+
|
|
305
|
+
if (!backend) {
|
|
306
|
+
throw new BackendError(
|
|
307
|
+
`Backend '${backendName}' not found`,
|
|
308
|
+
ErrorTypes.BACKEND_NOT_FOUND,
|
|
309
|
+
'BACKEND_NOT_FOUND'
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Track session
|
|
314
|
+
this.activeSessionCount++;
|
|
315
|
+
this.sessionBackendMap.set(request.sessionId, backendName);
|
|
316
|
+
|
|
317
|
+
try {
|
|
318
|
+
// Apply timeout if not specified
|
|
319
|
+
if (!request.options?.timeout) {
|
|
320
|
+
request.options = request.options || {};
|
|
321
|
+
request.options.timeout = this.config.timeout;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Execute with retry logic
|
|
325
|
+
const result = await RetryHandler.withRetry(
|
|
326
|
+
() => backend.execute(request),
|
|
327
|
+
{
|
|
328
|
+
maxAttempts: this.config.retryAttempts + 1,
|
|
329
|
+
shouldRetry: (error) => {
|
|
330
|
+
// Don't retry user cancellations or validation errors
|
|
331
|
+
if (error instanceof BackendError) {
|
|
332
|
+
if (error.type === ErrorTypes.CANCELLATION ||
|
|
333
|
+
error.type === ErrorTypes.VALIDATION_ERROR) {
|
|
334
|
+
return false;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
return ErrorHandler.isRetryable(error);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
// Add backend information to result
|
|
343
|
+
result.backend = backendName;
|
|
344
|
+
|
|
345
|
+
return result;
|
|
346
|
+
|
|
347
|
+
} catch (error) {
|
|
348
|
+
// Try fallback backends if configured
|
|
349
|
+
if (this.config.fallbackBackends.length > 0) {
|
|
350
|
+
console.warn(`Backend '${backendName}' failed, trying fallbacks...`);
|
|
351
|
+
|
|
352
|
+
for (const fallbackName of this.config.fallbackBackends) {
|
|
353
|
+
if (fallbackName === backendName) continue;
|
|
354
|
+
|
|
355
|
+
const fallbackBackend = this.backends.get(fallbackName);
|
|
356
|
+
if (!fallbackBackend || !(await fallbackBackend.isAvailable())) {
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
try {
|
|
361
|
+
console.log(`Trying fallback backend: ${fallbackName}`);
|
|
362
|
+
this.sessionBackendMap.set(request.sessionId, fallbackName);
|
|
363
|
+
|
|
364
|
+
const result = await fallbackBackend.execute(request);
|
|
365
|
+
result.backend = fallbackName;
|
|
366
|
+
result.fallback = true;
|
|
367
|
+
|
|
368
|
+
return result;
|
|
369
|
+
} catch (fallbackError) {
|
|
370
|
+
console.warn(`Fallback backend '${fallbackName}' also failed:`, fallbackError.message);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// All backends failed
|
|
376
|
+
throw error;
|
|
377
|
+
|
|
378
|
+
} finally {
|
|
379
|
+
this.activeSessionCount--;
|
|
380
|
+
this.sessionBackendMap.delete(request.sessionId);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Cancel an implementation session
|
|
386
|
+
* @param {string} sessionId - Session ID
|
|
387
|
+
* @returns {Promise<void>}
|
|
388
|
+
*/
|
|
389
|
+
async cancelImplementation(sessionId) {
|
|
390
|
+
const backendName = this.sessionBackendMap.get(sessionId);
|
|
391
|
+
if (!backendName) {
|
|
392
|
+
throw new BackendError(
|
|
393
|
+
`Session '${sessionId}' not found`,
|
|
394
|
+
ErrorTypes.SESSION_NOT_FOUND,
|
|
395
|
+
'SESSION_NOT_FOUND'
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
const backend = this.backends.get(backendName);
|
|
400
|
+
if (backend) {
|
|
401
|
+
await backend.cancel(sessionId);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
this.sessionBackendMap.delete(sessionId);
|
|
405
|
+
this.activeSessionCount = Math.max(0, this.activeSessionCount - 1);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* Get session status
|
|
410
|
+
* @param {string} sessionId - Session ID
|
|
411
|
+
* @returns {Promise<import('../types/BackendTypes').BackendStatus>}
|
|
412
|
+
*/
|
|
413
|
+
async getSessionStatus(sessionId) {
|
|
414
|
+
const backendName = this.sessionBackendMap.get(sessionId);
|
|
415
|
+
if (!backendName) {
|
|
416
|
+
return {
|
|
417
|
+
status: 'unknown',
|
|
418
|
+
message: 'Session not found'
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
const backend = this.backends.get(backendName);
|
|
423
|
+
if (!backend) {
|
|
424
|
+
return {
|
|
425
|
+
status: 'error',
|
|
426
|
+
message: 'Backend not found'
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
const status = await backend.getStatus(sessionId);
|
|
431
|
+
status.backend = backendName;
|
|
432
|
+
|
|
433
|
+
return status;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Validate configuration
|
|
438
|
+
* @returns {Promise<import('../types/BackendTypes').ValidationResult>}
|
|
439
|
+
*/
|
|
440
|
+
async validateConfiguration() {
|
|
441
|
+
const errors = [];
|
|
442
|
+
const warnings = [];
|
|
443
|
+
|
|
444
|
+
// Check default backend exists
|
|
445
|
+
if (!this.backends.has(this.config.defaultBackend)) {
|
|
446
|
+
errors.push(`Default backend '${this.config.defaultBackend}' not registered`);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// Fallback backends removed - no longer checking them
|
|
450
|
+
|
|
451
|
+
// Check at least one backend is available
|
|
452
|
+
let hasAvailable = false;
|
|
453
|
+
for (const [name, backend] of this.backends) {
|
|
454
|
+
if (await backend.isAvailable()) {
|
|
455
|
+
hasAvailable = true;
|
|
456
|
+
break;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
if (!hasAvailable) {
|
|
461
|
+
errors.push('No backends are available');
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
return {
|
|
465
|
+
valid: errors.length === 0,
|
|
466
|
+
errors,
|
|
467
|
+
warnings
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Check health of all backends
|
|
473
|
+
* @param {string} [name] - Specific backend to check, or all if not specified
|
|
474
|
+
* @returns {Promise<Object>}
|
|
475
|
+
*/
|
|
476
|
+
async checkBackendHealth(name = null) {
|
|
477
|
+
const results = {};
|
|
478
|
+
|
|
479
|
+
const backendsToCheck = name
|
|
480
|
+
? [name]
|
|
481
|
+
: Array.from(this.backends.keys());
|
|
482
|
+
|
|
483
|
+
for (const backendName of backendsToCheck) {
|
|
484
|
+
const backend = this.backends.get(backendName);
|
|
485
|
+
if (!backend) continue;
|
|
486
|
+
|
|
487
|
+
try {
|
|
488
|
+
const available = await backend.isAvailable();
|
|
489
|
+
const info = backend.getInfo();
|
|
490
|
+
|
|
491
|
+
results[backendName] = {
|
|
492
|
+
status: available ? 'healthy' : 'unavailable',
|
|
493
|
+
available,
|
|
494
|
+
version: info.version,
|
|
495
|
+
capabilities: info.capabilities,
|
|
496
|
+
dependencies: info.dependencies
|
|
497
|
+
};
|
|
498
|
+
} catch (error) {
|
|
499
|
+
results[backendName] = {
|
|
500
|
+
status: 'error',
|
|
501
|
+
available: false,
|
|
502
|
+
error: error.message
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
return results;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* Get recommended backend for a given context
|
|
512
|
+
* @param {Object} context - Request context
|
|
513
|
+
* @returns {string|null}
|
|
514
|
+
*/
|
|
515
|
+
getRecommendedBackend(context) {
|
|
516
|
+
// Simple recommendation logic
|
|
517
|
+
if (context.language) {
|
|
518
|
+
for (const [name, backend] of this.backends) {
|
|
519
|
+
const capabilities = backend.getCapabilities();
|
|
520
|
+
if (capabilities.supportsLanguages.includes(context.language)) {
|
|
521
|
+
return name;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
return this.config.defaultBackend;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
/**
|
|
530
|
+
* Check if a backend can handle a request
|
|
531
|
+
* @param {string} backendName - Backend name
|
|
532
|
+
* @param {import('../types/BackendTypes').ImplementRequest} request - Request to check
|
|
533
|
+
* @returns {boolean}
|
|
534
|
+
*/
|
|
535
|
+
canHandleRequest(backendName, request) {
|
|
536
|
+
const backend = this.backends.get(backendName);
|
|
537
|
+
if (!backend) return false;
|
|
538
|
+
|
|
539
|
+
const validation = backend.validateRequest(request);
|
|
540
|
+
return validation.valid;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* Clean up all backends
|
|
545
|
+
* @returns {Promise<void>}
|
|
546
|
+
*/
|
|
547
|
+
async cleanup() {
|
|
548
|
+
const cleanupPromises = [];
|
|
549
|
+
|
|
550
|
+
for (const [name, backend] of this.backends) {
|
|
551
|
+
cleanupPromises.push(
|
|
552
|
+
backend.cleanup().catch(error => {
|
|
553
|
+
console.error(`Error cleaning up backend '${name}':`, error);
|
|
554
|
+
})
|
|
555
|
+
);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
await Promise.all(cleanupPromises);
|
|
559
|
+
|
|
560
|
+
this.backends.clear();
|
|
561
|
+
this.sessionBackendMap.clear();
|
|
562
|
+
this.activeSessionCount = 0;
|
|
563
|
+
this.initialized = false;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
export default BackendManager;
|