@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,530 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import { ProbeChat } from '../probeChat.js';
|
|
5
|
+
import { MockLLMProvider, createMockStreamText } from './mocks/mockLLMProvider.js';
|
|
6
|
+
import MockBackend from '../implement/backends/MockBackend.js';
|
|
7
|
+
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = path.dirname(__filename);
|
|
10
|
+
|
|
11
|
+
// Test environment setup
|
|
12
|
+
export function setupTestEnvironment() {
|
|
13
|
+
// Store original environment
|
|
14
|
+
const originalEnv = { ...process.env };
|
|
15
|
+
|
|
16
|
+
// Clear API keys to ensure mock providers are used
|
|
17
|
+
delete process.env.ANTHROPIC_API_KEY;
|
|
18
|
+
delete process.env.OPENAI_API_KEY;
|
|
19
|
+
delete process.env.GOOGLE_API_KEY;
|
|
20
|
+
|
|
21
|
+
// Set test mode
|
|
22
|
+
process.env.NODE_ENV = 'test';
|
|
23
|
+
process.env.PROBE_TEST_MODE = 'true';
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
restore: () => {
|
|
27
|
+
Object.keys(process.env).forEach(key => {
|
|
28
|
+
if (!(key in originalEnv)) {
|
|
29
|
+
delete process.env[key];
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
Object.assign(process.env, originalEnv);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Create a test instance of ProbeChat with mocks
|
|
38
|
+
export async function createTestProbeChat(options = {}) {
|
|
39
|
+
const mockProvider = options.mockProvider instanceof MockLLMProvider ?
|
|
40
|
+
options.mockProvider :
|
|
41
|
+
new MockLLMProvider({
|
|
42
|
+
responses: options.responses || [],
|
|
43
|
+
...(typeof options.mockProvider === 'object' ? options.mockProvider : {})
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const mockStreamText = createMockStreamText(mockProvider);
|
|
47
|
+
|
|
48
|
+
// Create instance with mocks injected
|
|
49
|
+
const probeChat = new ProbeChat({
|
|
50
|
+
modelName: 'mock-model',
|
|
51
|
+
provider: 'mock',
|
|
52
|
+
...options.chatOptions
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Set temperature and maxTokens if provided
|
|
56
|
+
if (options.chatOptions?.temperature !== undefined) {
|
|
57
|
+
probeChat.temperature = options.chatOptions.temperature;
|
|
58
|
+
}
|
|
59
|
+
if (options.chatOptions?.maxTokens !== undefined) {
|
|
60
|
+
probeChat.maxTokens = options.chatOptions.maxTokens;
|
|
61
|
+
}
|
|
62
|
+
if (options.chatOptions?.systemPrompt !== undefined) {
|
|
63
|
+
probeChat.customPrompt = options.chatOptions.systemPrompt;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Override the streamText function
|
|
67
|
+
probeChat.streamText = mockStreamText;
|
|
68
|
+
|
|
69
|
+
// Override model initialization to use our mock
|
|
70
|
+
probeChat.initializeModel = function() {
|
|
71
|
+
this.model = mockProvider.createMockModel();
|
|
72
|
+
this.modelId = 'mock-model';
|
|
73
|
+
this.modelInfo = {
|
|
74
|
+
provider: 'mock',
|
|
75
|
+
contextWindow: 100000,
|
|
76
|
+
maxOutput: 4096,
|
|
77
|
+
supportsImages: true,
|
|
78
|
+
supportsPromptCaching: false
|
|
79
|
+
};
|
|
80
|
+
this.isInitialized = true;
|
|
81
|
+
this.noApiKeysMode = false; // Disable API key mode for tests
|
|
82
|
+
this.apiType = 'mock';
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// Initialize the mock model
|
|
86
|
+
probeChat.initializeModel();
|
|
87
|
+
|
|
88
|
+
// Create mock tool instances
|
|
89
|
+
const mockTools = {
|
|
90
|
+
probe_search: {
|
|
91
|
+
execute: async (args) => {
|
|
92
|
+
console.log('Mock probe_search called with:', args);
|
|
93
|
+
return createMockProbeResults();
|
|
94
|
+
},
|
|
95
|
+
validate: (args) => {
|
|
96
|
+
if (!args.query) {
|
|
97
|
+
throw new Error('Missing required field: query');
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
probe_query: {
|
|
102
|
+
execute: async (args) => {
|
|
103
|
+
console.log('Mock probe_query called with:', args);
|
|
104
|
+
return {
|
|
105
|
+
matches: [{
|
|
106
|
+
file: 'test.js',
|
|
107
|
+
matches: [{ text: 'mock match' }]
|
|
108
|
+
}]
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
probe_extract: {
|
|
113
|
+
execute: async (args) => {
|
|
114
|
+
console.log('Mock probe_extract called with:', args);
|
|
115
|
+
return {
|
|
116
|
+
content: 'mock extracted content',
|
|
117
|
+
language: 'javascript',
|
|
118
|
+
start_line: 1,
|
|
119
|
+
end_line: 10
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
implement: {
|
|
124
|
+
execute: async (args, options) => {
|
|
125
|
+
console.log('Mock implement called with:', args);
|
|
126
|
+
return {
|
|
127
|
+
sessionId: 'mock-session',
|
|
128
|
+
status: 'success',
|
|
129
|
+
filesModified: ['mock.js'],
|
|
130
|
+
summary: 'Mock implementation complete'
|
|
131
|
+
};
|
|
132
|
+
},
|
|
133
|
+
handleError: (error) => {
|
|
134
|
+
console.error('Mock implement error:', error);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
// Make tools accessible for test overrides
|
|
140
|
+
probeChat.tools = mockTools;
|
|
141
|
+
|
|
142
|
+
// Store mock provider reference for test access
|
|
143
|
+
probeChat.mockProvider = mockProvider;
|
|
144
|
+
|
|
145
|
+
// Add missing ProbeChat methods for tests
|
|
146
|
+
probeChat.messages = [];
|
|
147
|
+
probeChat.history = probeChat.messages; // Alias for compatibility with real implementation
|
|
148
|
+
probeChat.sendMessage = async function(message) {
|
|
149
|
+
return await this.chat(message);
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
probeChat.chat = async function(message, options = {}) {
|
|
153
|
+
let userMessage;
|
|
154
|
+
if (typeof message === 'string') {
|
|
155
|
+
userMessage = { role: 'user', content: message };
|
|
156
|
+
} else if (message.role && message.content) {
|
|
157
|
+
userMessage = message;
|
|
158
|
+
} else {
|
|
159
|
+
userMessage = { role: 'user', content: message.content || message };
|
|
160
|
+
}
|
|
161
|
+
this.messages.push(userMessage);
|
|
162
|
+
|
|
163
|
+
// Call the mock provider with streaming support
|
|
164
|
+
const response = await mockStreamText({
|
|
165
|
+
model: this.model,
|
|
166
|
+
messages: this.messages,
|
|
167
|
+
system: this.customPrompt || 'You are a helpful assistant.',
|
|
168
|
+
temperature: this.temperature,
|
|
169
|
+
maxTokens: this.maxTokens
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
let fullResponse = '';
|
|
173
|
+
|
|
174
|
+
// Stream chunks if callback provided
|
|
175
|
+
if (options.onStream) {
|
|
176
|
+
for await (const chunk of response.textStream) {
|
|
177
|
+
options.onStream(chunk);
|
|
178
|
+
fullResponse += chunk;
|
|
179
|
+
}
|
|
180
|
+
} else {
|
|
181
|
+
// Otherwise just collect the full response
|
|
182
|
+
for await (const chunk of response.textStream) {
|
|
183
|
+
fullResponse += chunk;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Check if the mock provider returned tool calls and convert them to XML format
|
|
188
|
+
const currentResponseIndex = this.mockProvider.currentResponseIndex - 1;
|
|
189
|
+
const mockResponse = this.mockProvider.responses[currentResponseIndex];
|
|
190
|
+
if (mockResponse?.toolCalls) {
|
|
191
|
+
// Convert AI SDK tool calls to XML format that ProbeChat expects
|
|
192
|
+
for (const toolCall of mockResponse.toolCalls) {
|
|
193
|
+
const xmlToolCall = this.convertToolCallToXml(toolCall);
|
|
194
|
+
fullResponse += '\n\n' + xmlToolCall;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const assistantMessage = { role: 'assistant', content: fullResponse };
|
|
199
|
+
this.messages.push(assistantMessage);
|
|
200
|
+
|
|
201
|
+
return fullResponse;
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
// Helper to convert AI SDK tool calls to XML format
|
|
205
|
+
probeChat.convertToolCallToXml = function(toolCall) {
|
|
206
|
+
const { toolName, args } = toolCall;
|
|
207
|
+
let xmlContent = `<${toolName}>`;
|
|
208
|
+
|
|
209
|
+
if (args) {
|
|
210
|
+
for (const [key, value] of Object.entries(args)) {
|
|
211
|
+
xmlContent += `\n<${key}>${value}</${key}>`;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
xmlContent += `\n</${toolName}>`;
|
|
216
|
+
return xmlContent;
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
probeChat.resetConversation = function() {
|
|
220
|
+
this.messages = [];
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
probeChat.clearHistory = function() {
|
|
224
|
+
this.messages = [];
|
|
225
|
+
this.history = this.messages; // Alias for compatibility
|
|
226
|
+
return 'mock-session-id'; // Return a mock session ID like the real implementation
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
probeChat.handleToolError = function(error, toolName) {
|
|
230
|
+
console.error(`Tool error in ${toolName}:`, error);
|
|
231
|
+
return `Error executing ${toolName}: ${error.message}`;
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
probeChat.processImageUrl = async function(url) {
|
|
235
|
+
return 'mock-base64-image-data';
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
// Register mock backend if implement tool is being tested
|
|
239
|
+
if (options.useMockBackend) {
|
|
240
|
+
const mockBackend = new MockBackend();
|
|
241
|
+
|
|
242
|
+
if (options.mockBackendResponses) {
|
|
243
|
+
mockBackend.setResponses(options.mockBackendResponses);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Override the implement tool's execute method to use our mock backend
|
|
247
|
+
const originalImplementExecute = probeChat.tools.implement.execute;
|
|
248
|
+
probeChat.tools.implement.execute = async function(args, options) {
|
|
249
|
+
// Force the mock backend
|
|
250
|
+
args.backend = 'mock';
|
|
251
|
+
|
|
252
|
+
// If we need to register the backend, do it here
|
|
253
|
+
if (this.backendManager) {
|
|
254
|
+
await this.backendManager.registerBackend(mockBackend);
|
|
255
|
+
} else {
|
|
256
|
+
// Direct execution with mock backend
|
|
257
|
+
return await mockBackend.implement(args, options);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return originalImplementExecute ? originalImplementExecute.call(this, args, options) :
|
|
261
|
+
await mockBackend.implement(args, options);
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
// Return both for test access
|
|
265
|
+
return { probeChat, mockProvider, mockBackend };
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return { probeChat, mockProvider };
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Helper to capture console output
|
|
272
|
+
export function captureConsoleOutput() {
|
|
273
|
+
const originalLog = console.log;
|
|
274
|
+
const originalError = console.error;
|
|
275
|
+
const output = [];
|
|
276
|
+
const errors = [];
|
|
277
|
+
|
|
278
|
+
console.log = (...args) => {
|
|
279
|
+
output.push(args.join(' '));
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
console.error = (...args) => {
|
|
283
|
+
errors.push(args.join(' '));
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
return {
|
|
287
|
+
output,
|
|
288
|
+
errors,
|
|
289
|
+
restore: () => {
|
|
290
|
+
console.log = originalLog;
|
|
291
|
+
console.error = originalError;
|
|
292
|
+
},
|
|
293
|
+
getOutput: () => output.join('\n'),
|
|
294
|
+
getErrors: () => errors.join('\n')
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Helper to create temporary test files
|
|
299
|
+
export function createTempTestFiles(files) {
|
|
300
|
+
const tempDir = path.join(__dirname, 'temp-test-' + Date.now());
|
|
301
|
+
fs.mkdirSync(tempDir, { recursive: true });
|
|
302
|
+
|
|
303
|
+
const createdFiles = [];
|
|
304
|
+
|
|
305
|
+
for (const [filePath, content] of Object.entries(files)) {
|
|
306
|
+
const fullPath = path.join(tempDir, filePath);
|
|
307
|
+
const dir = path.dirname(fullPath);
|
|
308
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
309
|
+
fs.writeFileSync(fullPath, content);
|
|
310
|
+
createdFiles.push(fullPath);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
return {
|
|
314
|
+
tempDir,
|
|
315
|
+
files: createdFiles,
|
|
316
|
+
cleanup: () => {
|
|
317
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Helper to run a chat interaction and capture results
|
|
323
|
+
export async function runChatInteraction(probeChat, messages, options = {}) {
|
|
324
|
+
const results = {
|
|
325
|
+
responses: [],
|
|
326
|
+
toolCalls: [],
|
|
327
|
+
errors: [],
|
|
328
|
+
streamedText: ''
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
// Override chat to handle tool calls from mock responses
|
|
332
|
+
const originalChat = probeChat.chat.bind(probeChat);
|
|
333
|
+
probeChat.chat = async function(message, opts = {}) {
|
|
334
|
+
const response = await originalChat(message, {
|
|
335
|
+
...opts,
|
|
336
|
+
onStream: (text) => {
|
|
337
|
+
results.streamedText += text;
|
|
338
|
+
if (opts.onStream) opts.onStream(text);
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
// Check if the mock provider returned tool calls and execute them
|
|
343
|
+
const lastCall = probeChat.mockProvider?.capturedCalls[probeChat.mockProvider.capturedCalls.length - 1];
|
|
344
|
+
if (lastCall) {
|
|
345
|
+
const mockResponse = probeChat.mockProvider.responses[probeChat.mockProvider.currentResponseIndex - 1];
|
|
346
|
+
if (mockResponse?.toolCalls) {
|
|
347
|
+
for (const toolCall of mockResponse.toolCalls) {
|
|
348
|
+
results.toolCalls.push(toolCall);
|
|
349
|
+
|
|
350
|
+
// Actually execute the tool to trigger the test's tracking
|
|
351
|
+
const toolName = toolCall.toolName;
|
|
352
|
+
if (probeChat.tools && probeChat.tools[toolName]) {
|
|
353
|
+
try {
|
|
354
|
+
// Validate tool arguments if validate method exists
|
|
355
|
+
if (typeof probeChat.tools[toolName].validate === 'function') {
|
|
356
|
+
probeChat.tools[toolName].validate(toolCall.args);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
await probeChat.tools[toolName].execute(toolCall.args);
|
|
360
|
+
} catch (error) {
|
|
361
|
+
// Tool execution errors are expected in some tests
|
|
362
|
+
console.warn(`Tool execution error for ${toolName}:`, error.message);
|
|
363
|
+
|
|
364
|
+
// Call the global error handler if it exists (for testing)
|
|
365
|
+
if (typeof probeChat.handleToolError === 'function') {
|
|
366
|
+
probeChat.handleToolError(error, toolName);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// Call the tool-specific error handler if it exists (for testing)
|
|
370
|
+
if (typeof probeChat.tools[toolName].handleError === 'function') {
|
|
371
|
+
probeChat.tools[toolName].handleError(error);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
if (opts.onToolCall) opts.onToolCall(toolCall);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
return response;
|
|
382
|
+
};
|
|
383
|
+
|
|
384
|
+
// Store reference to mock provider in probeChat for access
|
|
385
|
+
if (probeChat.model?.mockProvider) {
|
|
386
|
+
probeChat.mockProvider = probeChat.model.mockProvider;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
for (const message of messages) {
|
|
390
|
+
try {
|
|
391
|
+
let currentResponse = await probeChat.chat(message, options);
|
|
392
|
+
results.responses.push(currentResponse);
|
|
393
|
+
|
|
394
|
+
// Continue the conversation if there are more responses with tool calls
|
|
395
|
+
// This simulates multi-turn tool calling conversations
|
|
396
|
+
let maxTurns = 10; // Prevent infinite loops
|
|
397
|
+
while (maxTurns > 0 && probeChat.mockProvider &&
|
|
398
|
+
probeChat.mockProvider.currentResponseIndex < probeChat.mockProvider.responses.length) {
|
|
399
|
+
|
|
400
|
+
const nextResponseIndex = probeChat.mockProvider.currentResponseIndex;
|
|
401
|
+
const nextResponse = probeChat.mockProvider.responses[nextResponseIndex];
|
|
402
|
+
|
|
403
|
+
// If the next response has tool calls, continue the conversation
|
|
404
|
+
if (nextResponse?.toolCalls) {
|
|
405
|
+
// Add a synthetic assistant message to continue the flow
|
|
406
|
+
const continuationResponse = await probeChat.chat({
|
|
407
|
+
role: 'assistant',
|
|
408
|
+
content: nextResponse.text || 'Continuing with next tool...'
|
|
409
|
+
}, options);
|
|
410
|
+
results.responses.push(continuationResponse);
|
|
411
|
+
} else {
|
|
412
|
+
// No more tool calls, conversation ends
|
|
413
|
+
break;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
maxTurns--;
|
|
417
|
+
}
|
|
418
|
+
} catch (error) {
|
|
419
|
+
results.errors.push(error);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// Restore original chat
|
|
424
|
+
probeChat.chat = originalChat;
|
|
425
|
+
|
|
426
|
+
return results;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// Helper to create test probe search results
|
|
430
|
+
export function createMockProbeResults(options = {}) {
|
|
431
|
+
const defaultResult = {
|
|
432
|
+
path: options.path || 'test/file.js',
|
|
433
|
+
matches: options.matches || [{
|
|
434
|
+
line: 1,
|
|
435
|
+
column: 0,
|
|
436
|
+
match: options.match || 'test match',
|
|
437
|
+
context: options.context || 'function test() { return "test match"; }'
|
|
438
|
+
}],
|
|
439
|
+
score: options.score || 0.95,
|
|
440
|
+
excerpt: options.excerpt || 'function test() { return "test match"; }',
|
|
441
|
+
symbols: options.symbols || [{
|
|
442
|
+
name: 'test',
|
|
443
|
+
kind: 'function',
|
|
444
|
+
line: 1
|
|
445
|
+
}]
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
return {
|
|
449
|
+
results: options.results || [defaultResult],
|
|
450
|
+
total_matches: options.total_matches || 1,
|
|
451
|
+
search_time_ms: options.search_time_ms || 50,
|
|
452
|
+
bytes_processed: options.bytes_processed || 1000,
|
|
453
|
+
files_searched: options.files_searched || 10
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
// Helper to wait for async operations
|
|
458
|
+
export function waitFor(condition, timeout = 5000) {
|
|
459
|
+
return new Promise((resolve, reject) => {
|
|
460
|
+
const startTime = Date.now();
|
|
461
|
+
const interval = setInterval(() => {
|
|
462
|
+
if (condition()) {
|
|
463
|
+
clearInterval(interval);
|
|
464
|
+
resolve();
|
|
465
|
+
} else if (Date.now() - startTime > timeout) {
|
|
466
|
+
clearInterval(interval);
|
|
467
|
+
reject(new Error('Timeout waiting for condition'));
|
|
468
|
+
}
|
|
469
|
+
}, 100);
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// Test assertion helpers
|
|
474
|
+
export const assert = {
|
|
475
|
+
includesText: (actual, expected, message) => {
|
|
476
|
+
if (!actual.includes(expected)) {
|
|
477
|
+
throw new Error(message || `Expected "${actual}" to include "${expected}"`);
|
|
478
|
+
}
|
|
479
|
+
},
|
|
480
|
+
|
|
481
|
+
toolCallMade: (toolCalls, toolName, message) => {
|
|
482
|
+
const found = toolCalls.some(call => call.toolName === toolName);
|
|
483
|
+
if (!found) {
|
|
484
|
+
throw new Error(message || `Expected tool call "${toolName}" to be made`);
|
|
485
|
+
}
|
|
486
|
+
},
|
|
487
|
+
|
|
488
|
+
noErrors: (errors, message) => {
|
|
489
|
+
if (errors.length > 0) {
|
|
490
|
+
throw new Error(message || `Expected no errors but got: ${errors.map(e => e.message).join(', ')}`);
|
|
491
|
+
}
|
|
492
|
+
},
|
|
493
|
+
|
|
494
|
+
responseCount: (responses, expected, message) => {
|
|
495
|
+
if (responses.length !== expected) {
|
|
496
|
+
throw new Error(message || `Expected ${expected} responses but got ${responses.length}`);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
|
|
501
|
+
// Export test data
|
|
502
|
+
export const testData = {
|
|
503
|
+
sampleCode: {
|
|
504
|
+
javascript: `function fibonacci(n) {
|
|
505
|
+
if (n <= 1) return n;
|
|
506
|
+
return fibonacci(n - 1) + fibonacci(n - 2);
|
|
507
|
+
}`,
|
|
508
|
+
python: `def fibonacci(n):
|
|
509
|
+
if n <= 1:
|
|
510
|
+
return n
|
|
511
|
+
return fibonacci(n - 1) + fibonacci(n - 2)`,
|
|
512
|
+
rust: `fn fibonacci(n: u32) -> u32 {
|
|
513
|
+
match n {
|
|
514
|
+
0 | 1 => n,
|
|
515
|
+
_ => fibonacci(n - 1) + fibonacci(n - 2)
|
|
516
|
+
}
|
|
517
|
+
}`
|
|
518
|
+
},
|
|
519
|
+
|
|
520
|
+
sampleQueries: {
|
|
521
|
+
simple: 'function fibonacci',
|
|
522
|
+
complex: 'function AND (recursive OR recursion)',
|
|
523
|
+
withPath: { query: 'fibonacci', path: './src' },
|
|
524
|
+
withOptions: {
|
|
525
|
+
query: 'fibonacci',
|
|
526
|
+
maxResults: 5,
|
|
527
|
+
maxTokens: 1000
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
};
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { test, describe, before, after } from 'node:test';
|
|
2
|
+
import assert from 'node:assert';
|
|
3
|
+
import { spawn } from 'child_process';
|
|
4
|
+
import { setTimeout as delay } from 'timers/promises';
|
|
5
|
+
|
|
6
|
+
describe('Backend Timeout Cleanup Tests', () => {
|
|
7
|
+
// Helper to count active timers
|
|
8
|
+
function getActiveTimerCount() {
|
|
9
|
+
// This is a simplified check - in real tests you might use
|
|
10
|
+
// process._getActiveHandles() or similar debugging tools
|
|
11
|
+
return process._getActiveHandles().filter(h =>
|
|
12
|
+
h && h.constructor && h.constructor.name === 'Timeout'
|
|
13
|
+
).length;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
test('should properly clear timeout when process completes successfully', async () => {
|
|
17
|
+
const initialTimerCount = getActiveTimerCount();
|
|
18
|
+
|
|
19
|
+
// Simulate a simple command that completes quickly
|
|
20
|
+
const child = spawn('echo', ['test'], { shell: true });
|
|
21
|
+
let timeoutFired = false;
|
|
22
|
+
|
|
23
|
+
// Set a timeout (similar to backend implementation)
|
|
24
|
+
const timeoutId = setTimeout(() => {
|
|
25
|
+
timeoutFired = true;
|
|
26
|
+
if (!child.killed) {
|
|
27
|
+
child.kill('SIGTERM');
|
|
28
|
+
}
|
|
29
|
+
}, 5000); // 5 second timeout
|
|
30
|
+
|
|
31
|
+
await new Promise((resolve, reject) => {
|
|
32
|
+
child.on('close', (code) => {
|
|
33
|
+
clearTimeout(timeoutId); // This is what we added to fix the issue
|
|
34
|
+
resolve(code);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
child.on('error', (error) => {
|
|
38
|
+
clearTimeout(timeoutId); // This is what we added to fix the issue
|
|
39
|
+
reject(error);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Give event loop time to clean up
|
|
44
|
+
await delay(100);
|
|
45
|
+
|
|
46
|
+
// Verify timeout was cleared and didn't fire
|
|
47
|
+
assert.strictEqual(timeoutFired, false, 'Timeout should not have fired');
|
|
48
|
+
|
|
49
|
+
// Check that we don't have extra timers hanging around
|
|
50
|
+
const finalTimerCount = getActiveTimerCount();
|
|
51
|
+
assert.ok(
|
|
52
|
+
finalTimerCount <= initialTimerCount + 1, // Allow for test framework timers
|
|
53
|
+
`Timer leak detected: started with ${initialTimerCount} timers, ended with ${finalTimerCount}`
|
|
54
|
+
);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test('should properly clear timeout when process fails', async () => {
|
|
58
|
+
const initialTimerCount = getActiveTimerCount();
|
|
59
|
+
|
|
60
|
+
// Simulate a command that fails
|
|
61
|
+
const child = spawn('exit', ['1'], { shell: true });
|
|
62
|
+
let timeoutFired = false;
|
|
63
|
+
|
|
64
|
+
const timeoutId = setTimeout(() => {
|
|
65
|
+
timeoutFired = true;
|
|
66
|
+
if (!child.killed) {
|
|
67
|
+
child.kill('SIGTERM');
|
|
68
|
+
}
|
|
69
|
+
}, 5000);
|
|
70
|
+
|
|
71
|
+
const exitCode = await new Promise((resolve, reject) => {
|
|
72
|
+
child.on('close', (code) => {
|
|
73
|
+
clearTimeout(timeoutId);
|
|
74
|
+
resolve(code);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
child.on('error', (error) => {
|
|
78
|
+
clearTimeout(timeoutId);
|
|
79
|
+
reject(error);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
await delay(100);
|
|
84
|
+
|
|
85
|
+
assert.strictEqual(exitCode, 1, 'Process should have failed with exit code 1');
|
|
86
|
+
assert.strictEqual(timeoutFired, false, 'Timeout should not have fired');
|
|
87
|
+
|
|
88
|
+
const finalTimerCount = getActiveTimerCount();
|
|
89
|
+
assert.ok(
|
|
90
|
+
finalTimerCount <= initialTimerCount + 1,
|
|
91
|
+
`Timer leak detected: started with ${initialTimerCount} timers, ended with ${finalTimerCount}`
|
|
92
|
+
);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test('timeout should fire and kill process if it runs too long', async () => {
|
|
96
|
+
let timeoutFired = false;
|
|
97
|
+
let processKilled = false;
|
|
98
|
+
|
|
99
|
+
// Simulate a long-running command
|
|
100
|
+
const child = spawn('sleep', ['10'], { shell: true });
|
|
101
|
+
|
|
102
|
+
const timeoutId = setTimeout(() => {
|
|
103
|
+
timeoutFired = true;
|
|
104
|
+
if (!child.killed) {
|
|
105
|
+
processKilled = true;
|
|
106
|
+
child.kill('SIGTERM');
|
|
107
|
+
}
|
|
108
|
+
}, 100); // Very short timeout to ensure it fires
|
|
109
|
+
|
|
110
|
+
const exitCode = await new Promise((resolve) => {
|
|
111
|
+
child.on('close', (code) => {
|
|
112
|
+
clearTimeout(timeoutId);
|
|
113
|
+
resolve(code);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
child.on('error', () => {
|
|
117
|
+
clearTimeout(timeoutId);
|
|
118
|
+
resolve(-1);
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
assert.strictEqual(timeoutFired, true, 'Timeout should have fired');
|
|
123
|
+
assert.strictEqual(processKilled, true, 'Process should have been killed');
|
|
124
|
+
assert.notStrictEqual(exitCode, 0, 'Process should not have completed successfully');
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test('multiple executions should not accumulate timers', async () => {
|
|
128
|
+
const initialTimerCount = getActiveTimerCount();
|
|
129
|
+
|
|
130
|
+
// Run multiple quick commands
|
|
131
|
+
for (let i = 0; i < 5; i++) {
|
|
132
|
+
const child = spawn('echo', [`test${i}`], { shell: true });
|
|
133
|
+
|
|
134
|
+
const timeoutId = setTimeout(() => {
|
|
135
|
+
if (!child.killed) {
|
|
136
|
+
child.kill('SIGTERM');
|
|
137
|
+
}
|
|
138
|
+
}, 5000);
|
|
139
|
+
|
|
140
|
+
await new Promise((resolve, reject) => {
|
|
141
|
+
child.on('close', () => {
|
|
142
|
+
clearTimeout(timeoutId);
|
|
143
|
+
resolve();
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
child.on('error', (error) => {
|
|
147
|
+
clearTimeout(timeoutId);
|
|
148
|
+
reject(error);
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
await delay(100);
|
|
154
|
+
|
|
155
|
+
const finalTimerCount = getActiveTimerCount();
|
|
156
|
+
assert.ok(
|
|
157
|
+
finalTimerCount <= initialTimerCount + 2, // Allow some variance for test framework
|
|
158
|
+
`Timer accumulation detected: started with ${initialTimerCount} timers, ended with ${finalTimerCount} after 5 executions`
|
|
159
|
+
);
|
|
160
|
+
});
|
|
161
|
+
});
|