@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.
Files changed (444) hide show
  1. package/README.md +138 -0
  2. package/data/.env.example +22 -0
  3. package/data/.gitattributes +47 -0
  4. package/data/.glfrc.json +7 -0
  5. package/data/.husky/pre-commit +5 -0
  6. package/data/.nvmrc +1 -0
  7. package/data/CHANGELOG.md +75 -0
  8. package/data/CODE_OF_CONDUCT.md +129 -0
  9. package/data/CONTRIBUTING.md +203 -0
  10. package/data/DOCS-STRUCTURE.md +307 -0
  11. package/data/I18N.md +292 -0
  12. package/data/LICENSE +22 -0
  13. package/data/README.md +315 -0
  14. package/data/SECURITY.md +125 -0
  15. package/data/WIKI-DEPLOYMENT.md +348 -0
  16. package/data/docs/AI-FEATURES.md +610 -0
  17. package/data/docs/API-REFERENCE.md +1022 -0
  18. package/data/docs/AUTHENTICATION.md +301 -0
  19. package/data/docs/BACKEND-API.md +468 -0
  20. package/data/docs/DEVELOPMENT.md +375 -0
  21. package/data/docs/EXAMPLES.md +622 -0
  22. package/data/docs/MCP-SERVER.md +307 -0
  23. package/data/docs/MIGRATION-GUIDE.md +367 -0
  24. package/data/docs/NPM-PUBLISH.md +193 -0
  25. package/data/docs/QUICKSTART.md +206 -0
  26. package/data/docs/REDIS-SETUP.md +162 -0
  27. package/data/docs/SERVER.md +228 -0
  28. package/data/docs/TROUBLESHOOTING.md +657 -0
  29. package/data/docs/WIDGET-GUIDE.md +638 -0
  30. package/data/docs/WIKI-HOME.md +58 -0
  31. package/data/docs/WIKI-SIDEBAR.md +39 -0
  32. package/data/package.json +171 -0
  33. package/data/playwright.config.ts +64 -0
  34. package/data/probe/.cargo/config.toml +10 -0
  35. package/data/probe/.claude/commands/performance-review.md +15 -0
  36. package/data/probe/.clinerules +288 -0
  37. package/data/probe/.dockerignore +57 -0
  38. package/data/probe/.githooks/post-commit +11 -0
  39. package/data/probe/.githooks/pre-commit +99 -0
  40. package/data/probe/.githooks/pre-commit-vow +9 -0
  41. package/data/probe/.prompts/engineer.md +41 -0
  42. package/data/probe/.roomodes +28 -0
  43. package/data/probe/.windsurfrules +0 -0
  44. package/data/probe/BASH_TOOL_SUMMARY.md +148 -0
  45. package/data/probe/BENCHMARKING.md +256 -0
  46. package/data/probe/CLAUDE.md +226 -0
  47. package/data/probe/CODE_OF_CONDUCT.md +128 -0
  48. package/data/probe/CONTRIBUTING.md +193 -0
  49. package/data/probe/Cargo.toml +120 -0
  50. package/data/probe/Cross.toml +10 -0
  51. package/data/probe/DOCKER-README.md +224 -0
  52. package/data/probe/Dockerfile +32 -0
  53. package/data/probe/ENHANCED_DEBUG_TELEMETRY.md +188 -0
  54. package/data/probe/LICENSE +201 -0
  55. package/data/probe/Makefile +210 -0
  56. package/data/probe/README.md +824 -0
  57. package/data/probe/SECURITY.md +67 -0
  58. package/data/probe/WINDOWS-GUIDE.md +294 -0
  59. package/data/probe/benches/parsing_benchmarks.rs +370 -0
  60. package/data/probe/benches/search_benchmarks.rs +599 -0
  61. package/data/probe/benches/simd_benchmarks.rs +372 -0
  62. package/data/probe/benches/timing_benchmarks.rs +287 -0
  63. package/data/probe/build-windows.bat +229 -0
  64. package/data/probe/codex-config/config.toml +6 -0
  65. package/data/probe/docs/PERFORMANCE_OPTIMIZATION.md +161 -0
  66. package/data/probe/examples/cache_demo.rs +46 -0
  67. package/data/probe/examples/chat/.dockerignore +37 -0
  68. package/data/probe/examples/chat/ChatSessionManager.js +295 -0
  69. package/data/probe/examples/chat/Dockerfile +98 -0
  70. package/data/probe/examples/chat/LICENSE +201 -0
  71. package/data/probe/examples/chat/LOCAL_IMAGE_SUPPORT.md +195 -0
  72. package/data/probe/examples/chat/MCP_INTEGRATION.md +400 -0
  73. package/data/probe/examples/chat/README.md +338 -0
  74. package/data/probe/examples/chat/TRACING.md +226 -0
  75. package/data/probe/examples/chat/appTracer.js +968 -0
  76. package/data/probe/examples/chat/auth.js +76 -0
  77. package/data/probe/examples/chat/bin/probe-chat.js +13 -0
  78. package/data/probe/examples/chat/build.js +104 -0
  79. package/data/probe/examples/chat/cancelRequest.js +84 -0
  80. package/data/probe/examples/chat/demo-agentic-image-flow.js +88 -0
  81. package/data/probe/examples/chat/demo-local-images.js +128 -0
  82. package/data/probe/examples/chat/fileSpanExporter.js +181 -0
  83. package/data/probe/examples/chat/implement/README.md +228 -0
  84. package/data/probe/examples/chat/implement/backends/AiderBackend.js +750 -0
  85. package/data/probe/examples/chat/implement/backends/BaseBackend.js +276 -0
  86. package/data/probe/examples/chat/implement/backends/ClaudeCodeBackend.js +767 -0
  87. package/data/probe/examples/chat/implement/backends/MockBackend.js +237 -0
  88. package/data/probe/examples/chat/implement/backends/registry.js +85 -0
  89. package/data/probe/examples/chat/implement/core/BackendManager.js +567 -0
  90. package/data/probe/examples/chat/implement/core/ImplementTool.js +354 -0
  91. package/data/probe/examples/chat/implement/core/config.js +428 -0
  92. package/data/probe/examples/chat/implement/core/timeouts.js +58 -0
  93. package/data/probe/examples/chat/implement/core/utils.js +496 -0
  94. package/data/probe/examples/chat/implement/types/BackendTypes.js +126 -0
  95. package/data/probe/examples/chat/index.js +669 -0
  96. package/data/probe/examples/chat/mcpServer.js +341 -0
  97. package/data/probe/examples/chat/npm/LICENSE +15 -0
  98. package/data/probe/examples/chat/npm/README.md +168 -0
  99. package/data/probe/examples/chat/npm/bin/probe-chat.js +156 -0
  100. package/data/probe/examples/chat/npm/index.js +259 -0
  101. package/data/probe/examples/chat/npm/package.json +54 -0
  102. package/data/probe/examples/chat/package.json +102 -0
  103. package/data/probe/examples/chat/probeChat.js +456 -0
  104. package/data/probe/examples/chat/probeTool.js +491 -0
  105. package/data/probe/examples/chat/storage/JsonChatStorage.js +476 -0
  106. package/data/probe/examples/chat/telemetry.js +281 -0
  107. package/data/probe/examples/chat/test/integration/chatFlows.test.js +320 -0
  108. package/data/probe/examples/chat/test/integration/toolCalling.test.js +471 -0
  109. package/data/probe/examples/chat/test/mocks/mockLLMProvider.js +269 -0
  110. package/data/probe/examples/chat/test/test-backends.js +90 -0
  111. package/data/probe/examples/chat/test/testUtils.js +530 -0
  112. package/data/probe/examples/chat/test/unit/backendTimeout.test.js +161 -0
  113. package/data/probe/examples/chat/test/unit/packageFiles.test.js +120 -0
  114. package/data/probe/examples/chat/test/verify-tests.js +118 -0
  115. package/data/probe/examples/chat/test-agentic-image-loading.js +294 -0
  116. package/data/probe/examples/chat/test-ai-sdk-telemetry.js +204 -0
  117. package/data/probe/examples/chat/test-chat-tracing.js +38 -0
  118. package/data/probe/examples/chat/test-direct-function.js +49 -0
  119. package/data/probe/examples/chat/test-file-size-validation.js +103 -0
  120. package/data/probe/examples/chat/test-full-mcp-integration.js +258 -0
  121. package/data/probe/examples/chat/test-github-context.txt +12 -0
  122. package/data/probe/examples/chat/test-hierarchy.js +203 -0
  123. package/data/probe/examples/chat/test-image-spans.js +37 -0
  124. package/data/probe/examples/chat/test-local-image-reading.js +176 -0
  125. package/data/probe/examples/chat/test-mcp-integration.js +136 -0
  126. package/data/probe/examples/chat/test-mcp-probe-server.js +161 -0
  127. package/data/probe/examples/chat/test-mcp-with-ai.js +279 -0
  128. package/data/probe/examples/chat/test-multiple-allowed-dirs.js +111 -0
  129. package/data/probe/examples/chat/test-probe-mcp-server.js +110 -0
  130. package/data/probe/examples/chat/test-security-validation.js +145 -0
  131. package/data/probe/examples/chat/test-simple-tracing.js +32 -0
  132. package/data/probe/examples/chat/test-trace-verification.js +235 -0
  133. package/data/probe/examples/chat/test-tracing.js +114 -0
  134. package/data/probe/examples/chat/tokenCounter.js +419 -0
  135. package/data/probe/examples/chat/tokenUsageDisplay.js +134 -0
  136. package/data/probe/examples/chat/webServer.js +1103 -0
  137. package/data/probe/examples/reranker/Cargo.toml +33 -0
  138. package/data/probe/examples/reranker/DEBUG_OUTPUT_ANALYSIS.md +71 -0
  139. package/data/probe/examples/reranker/MODELS.md +66 -0
  140. package/data/probe/examples/reranker/MODEL_COMPARISON.md +60 -0
  141. package/data/probe/examples/reranker/MULTI_MODEL_ANALYSIS.md +176 -0
  142. package/data/probe/examples/reranker/PERFORMANCE_SUMMARY.md +156 -0
  143. package/data/probe/examples/reranker/README.md +347 -0
  144. package/data/probe/examples/reranker/RUST_BERT_COMPARISON.md +82 -0
  145. package/data/probe/examples/reranker/TOKENIZATION_GUIDE.md +120 -0
  146. package/data/probe/examples/reranker/check_rust_tokenizer.py +108 -0
  147. package/data/probe/examples/reranker/convert_to_torchscript.py +109 -0
  148. package/data/probe/examples/reranker/debug_scoring.py +189 -0
  149. package/data/probe/examples/reranker/debug_tokenization.py +154 -0
  150. package/data/probe/examples/reranker/download_models.sh +73 -0
  151. package/data/probe/examples/reranker/requirements.txt +13 -0
  152. package/data/probe/examples/reranker/run_comprehensive_benchmark.sh +83 -0
  153. package/data/probe/examples/reranker/rust_bert_test/Cargo.toml +12 -0
  154. package/data/probe/examples/reranker/rust_bert_test/README.md +54 -0
  155. package/data/probe/examples/reranker/simple_test.py +50 -0
  156. package/data/probe/examples/reranker/test_all_models.sh +63 -0
  157. package/data/probe/examples/reranker/test_bert_results.sh +44 -0
  158. package/data/probe/examples/reranker/test_cross_encoder.py +334 -0
  159. package/data/probe/examples/reranker/test_cross_encoder.sh +80 -0
  160. package/data/probe/examples/reranker/test_exact_comparison.py +151 -0
  161. package/data/probe/examples/reranker/test_parallel_performance.sh +56 -0
  162. package/data/probe/examples/reranker/test_scores.py +132 -0
  163. package/data/probe/install.ps1 +508 -0
  164. package/data/probe/install.sh +460 -0
  165. package/data/probe/npm/CLONE_METHOD_EXAMPLES.md +596 -0
  166. package/data/probe/npm/CONTEXT_COMPACTION.md +303 -0
  167. package/data/probe/npm/DELEGATE_TOOL_README.md +166 -0
  168. package/data/probe/npm/MAID_INTEGRATION.md +313 -0
  169. package/data/probe/npm/MCP_INTEGRATION_SUMMARY.md +241 -0
  170. package/data/probe/npm/README.md +824 -0
  171. package/data/probe/npm/bin/.gitignore +7 -0
  172. package/data/probe/npm/bin/.gitkeep +0 -0
  173. package/data/probe/npm/bin/README.md +12 -0
  174. package/data/probe/npm/bin/probe +167 -0
  175. package/data/probe/npm/docs/CLAUDE_CODE_INTEGRATION.md +414 -0
  176. package/data/probe/npm/docs/CODEX_INTEGRATION.md +502 -0
  177. package/data/probe/npm/docs/EDIT_CREATE_TOOLS.md +233 -0
  178. package/data/probe/npm/docs/RETRY_AND_FALLBACK.md +674 -0
  179. package/data/probe/npm/example-usage.js +335 -0
  180. package/data/probe/npm/examples/multi-engine-demo.js +117 -0
  181. package/data/probe/npm/examples/probe-agent-cli.js +113 -0
  182. package/data/probe/npm/examples/test-agent-edit.js +114 -0
  183. package/data/probe/npm/examples/test-edit-create.js +120 -0
  184. package/data/probe/npm/examples/test-edit-direct.js +114 -0
  185. package/data/probe/npm/index.d.ts +744 -0
  186. package/data/probe/npm/jest.config.js +52 -0
  187. package/data/probe/npm/package.json +117 -0
  188. package/data/probe/npm/scripts/build-agent.cjs +75 -0
  189. package/data/probe/npm/scripts/build-cjs.js +124 -0
  190. package/data/probe/npm/scripts/build-mcp.cjs +36 -0
  191. package/data/probe/npm/scripts/postinstall.js +216 -0
  192. package/data/probe/npm/test-codex-e2e.js +78 -0
  193. package/data/probe/npm/test-download-lock.js +109 -0
  194. package/data/probe/npm/test-grep-security.js +94 -0
  195. package/data/probe/npm/test-grep-simplified.js +63 -0
  196. package/data/probe/npm/test-grep.js +51 -0
  197. package/data/probe/npm/tests/README.md +96 -0
  198. package/data/probe/npm/tests/agent-compact-history.test.js +174 -0
  199. package/data/probe/npm/tests/allow-tests-default.test.js +151 -0
  200. package/data/probe/npm/tests/contextCompactor.test.js +498 -0
  201. package/data/probe/npm/tests/delegate-config.test.js +353 -0
  202. package/data/probe/npm/tests/delegate-integration.test.js +348 -0
  203. package/data/probe/npm/tests/extractor-integration.test.js +162 -0
  204. package/data/probe/npm/tests/extractor.test.js +317 -0
  205. package/data/probe/npm/tests/fixtures/sampleDiagrams.js +267 -0
  206. package/data/probe/npm/tests/integration/claude-code-auto-fallback.spec.js +148 -0
  207. package/data/probe/npm/tests/integration/claude-code-multi-step.spec.js +127 -0
  208. package/data/probe/npm/tests/integration/claude-code-tool-events.spec.js +163 -0
  209. package/data/probe/npm/tests/integration/codex-auto-fallback.spec.js +191 -0
  210. package/data/probe/npm/tests/integration/codex-tool-events.spec.js +147 -0
  211. package/data/probe/npm/tests/integration/examplesChatMcp.test.js +402 -0
  212. package/data/probe/npm/tests/integration/mcpDotenvSupport.test.js +174 -0
  213. package/data/probe/npm/tests/integration/mcpErrorHandling.test.js +566 -0
  214. package/data/probe/npm/tests/integration/mcpRobustness.test.js +564 -0
  215. package/data/probe/npm/tests/integration/mcpStdoutPurity.test.js +355 -0
  216. package/data/probe/npm/tests/integration/probeAgentMcp.test.js +398 -0
  217. package/data/probe/npm/tests/integration/retryFallback.test.js +368 -0
  218. package/data/probe/npm/tests/integration/schema-in-initial-message.test.js +318 -0
  219. package/data/probe/npm/tests/integration/schema-validation-loop-prevention.test.js +244 -0
  220. package/data/probe/npm/tests/integration/schemaRetryLogic.test.js +94 -0
  221. package/data/probe/npm/tests/integration/validationFlow.test.js +329 -0
  222. package/data/probe/npm/tests/manual/test-codex-basic.js +110 -0
  223. package/data/probe/npm/tests/mcp/mcpClientManager.test.js +614 -0
  224. package/data/probe/npm/tests/mcp/mcpConfig.test.js +359 -0
  225. package/data/probe/npm/tests/mcp/mcpXmlBridge.test.js +436 -0
  226. package/data/probe/npm/tests/mcp/mockMcpServer.js +510 -0
  227. package/data/probe/npm/tests/mcp-strict-syntax.test.js +319 -0
  228. package/data/probe/npm/tests/mermaidQuoteEscaping.test.js +214 -0
  229. package/data/probe/npm/tests/nestedQuoteFix.test.js +40 -0
  230. package/data/probe/npm/tests/setup.js +46 -0
  231. package/data/probe/npm/tests/unit/allowed-tools.test.js +513 -0
  232. package/data/probe/npm/tests/unit/attempt-completion-closing-tag-in-content.test.js +188 -0
  233. package/data/probe/npm/tests/unit/attemptCompletionJsonFix.test.js +238 -0
  234. package/data/probe/npm/tests/unit/attemptCompletionJsonIssue.test.js +128 -0
  235. package/data/probe/npm/tests/unit/backtickAutoFix.test.js +35 -0
  236. package/data/probe/npm/tests/unit/bash-probe-agent-integration.test.js +389 -0
  237. package/data/probe/npm/tests/unit/bash-simple-commands.test.js +324 -0
  238. package/data/probe/npm/tests/unit/bash-tool-comprehensive.test.js +371 -0
  239. package/data/probe/npm/tests/unit/bash-tool-integration.test.js +310 -0
  240. package/data/probe/npm/tests/unit/bash-tool.test.js +341 -0
  241. package/data/probe/npm/tests/unit/completion-prompt.test.js +379 -0
  242. package/data/probe/npm/tests/unit/cwd-path-options.test.js +287 -0
  243. package/data/probe/npm/tests/unit/delegate-limits.test.js +422 -0
  244. package/data/probe/npm/tests/unit/direct-content-attempt-completion.test.js +235 -0
  245. package/data/probe/npm/tests/unit/edit-create-tools.test.js +609 -0
  246. package/data/probe/npm/tests/unit/enhancedMermaidValidation.test.js +577 -0
  247. package/data/probe/npm/tests/unit/extract-content.test.js +83 -0
  248. package/data/probe/npm/tests/unit/extract-multiple-targets.test.js +89 -0
  249. package/data/probe/npm/tests/unit/fallbackManager.test.js +442 -0
  250. package/data/probe/npm/tests/unit/githubCompatibilityValidation.test.js +258 -0
  251. package/data/probe/npm/tests/unit/imageConfig.test.js +149 -0
  252. package/data/probe/npm/tests/unit/imagePathResolution.test.js +345 -0
  253. package/data/probe/npm/tests/unit/json-fixing-agent.test.js +238 -0
  254. package/data/probe/npm/tests/unit/json-validation-enhanced-errors.test.js +199 -0
  255. package/data/probe/npm/tests/unit/jsonValidationInfiniteLoopFix.test.js +228 -0
  256. package/data/probe/npm/tests/unit/maidIntegration.test.js +139 -0
  257. package/data/probe/npm/tests/unit/maxIterationsWarning.test.js +195 -0
  258. package/data/probe/npm/tests/unit/mermaidEdgeLabelFix.test.js +161 -0
  259. package/data/probe/npm/tests/unit/mermaidHtmlEntities.test.js +76 -0
  260. package/data/probe/npm/tests/unit/mermaidInfiniteLoopFix.test.js +64 -0
  261. package/data/probe/npm/tests/unit/mermaidValidation.test.js +723 -0
  262. package/data/probe/npm/tests/unit/mermaidValidationVisorExample.test.js +309 -0
  263. package/data/probe/npm/tests/unit/probe-agent-clone-realistic.test.js +643 -0
  264. package/data/probe/npm/tests/unit/probe-agent-clone.test.js +476 -0
  265. package/data/probe/npm/tests/unit/probe-agent-delegate.test.js +400 -0
  266. package/data/probe/npm/tests/unit/probe-agent-model-option.test.js +118 -0
  267. package/data/probe/npm/tests/unit/probeTool-security.test.js +283 -0
  268. package/data/probe/npm/tests/unit/readImageTool.test.js +418 -0
  269. package/data/probe/npm/tests/unit/retryManager.test.js +317 -0
  270. package/data/probe/npm/tests/unit/schema-aware-reminders.test.js +288 -0
  271. package/data/probe/npm/tests/unit/schemaDefinitionDetection.test.js +115 -0
  272. package/data/probe/npm/tests/unit/schemaUtils.test.js +1268 -0
  273. package/data/probe/npm/tests/unit/simpleTelemetry.test.js +282 -0
  274. package/data/probe/npm/tests/unit/simplified-attempt-completion.test.js +274 -0
  275. package/data/probe/npm/tests/unit/single-quote-json-bug.test.js +231 -0
  276. package/data/probe/npm/tests/unit/subgraphAutoFix.test.js +110 -0
  277. package/data/probe/npm/tests/unit/system-prompt.test.js +32 -0
  278. package/data/probe/npm/tests/unit/types-probe-agent-options.test.js +42 -0
  279. package/data/probe/npm/tests/unit/xmlParsing.test.js +720 -0
  280. package/data/probe/npm/tsconfig.json +21 -0
  281. package/data/probe/result1.txt +19 -0
  282. package/data/probe/result2.txt +26 -0
  283. package/data/probe/scripts/benchmark.sh +270 -0
  284. package/data/probe/scripts/cache_memory_analysis.rs +844 -0
  285. package/data/probe/scripts/claude-hook-wrapper.sh +56 -0
  286. package/data/probe/site/.env.example +10 -0
  287. package/data/probe/site/DEPLOYMENT.md +86 -0
  288. package/data/probe/site/README.md +183 -0
  289. package/data/probe/site/adding-languages.md +135 -0
  290. package/data/probe/site/ai-chat.md +427 -0
  291. package/data/probe/site/ai-integration.md +1488 -0
  292. package/data/probe/site/blog/agentic-flow-custom-xml-protocol.md +407 -0
  293. package/data/probe/site/blog/index.md +118 -0
  294. package/data/probe/site/blog/v0.6.0-release.md +426 -0
  295. package/data/probe/site/blog.md +8 -0
  296. package/data/probe/site/changelog.md +200 -0
  297. package/data/probe/site/cli-mode.md +437 -0
  298. package/data/probe/site/code-extraction.md +436 -0
  299. package/data/probe/site/contributing/README.md +9 -0
  300. package/data/probe/site/contributing/documentation-cross-references.md +215 -0
  301. package/data/probe/site/contributing/documentation-maintenance.md +275 -0
  302. package/data/probe/site/contributing/documentation-structure.md +75 -0
  303. package/data/probe/site/documentation-cross-references.md +215 -0
  304. package/data/probe/site/documentation-guide.md +132 -0
  305. package/data/probe/site/documentation-maintenance.md +275 -0
  306. package/data/probe/site/features.md +147 -0
  307. package/data/probe/site/how-it-works.md +118 -0
  308. package/data/probe/site/index.md +175 -0
  309. package/data/probe/site/index.md.bak +133 -0
  310. package/data/probe/site/installation.md +235 -0
  311. package/data/probe/site/integrations/docker.md +248 -0
  312. package/data/probe/site/integrations/github-actions.md +413 -0
  313. package/data/probe/site/language-support-overview.md +168 -0
  314. package/data/probe/site/mcp-integration.md +587 -0
  315. package/data/probe/site/mcp-server.md +304 -0
  316. package/data/probe/site/navigation-structure.md +76 -0
  317. package/data/probe/site/nodejs-sdk.md +798 -0
  318. package/data/probe/site/output-formats.md +625 -0
  319. package/data/probe/site/package.json +21 -0
  320. package/data/probe/site/public/_headers +28 -0
  321. package/data/probe/site/public/_redirects +11 -0
  322. package/data/probe/site/quick-start.md +289 -0
  323. package/data/probe/site/search-functionality.md +291 -0
  324. package/data/probe/site/search-reference.md +291 -0
  325. package/data/probe/site/supported-languages.md +215 -0
  326. package/data/probe/site/use-cases/README.md +8 -0
  327. package/data/probe/site/use-cases/advanced-cli.md +253 -0
  328. package/data/probe/site/use-cases/ai-code-editors.md +239 -0
  329. package/data/probe/site/use-cases/building-ai-tools.md +529 -0
  330. package/data/probe/site/use-cases/cli-ai-workflows.md +285 -0
  331. package/data/probe/site/use-cases/deploying-probe-web-interface.md +255 -0
  332. package/data/probe/site/use-cases/integrating-probe-into-ai-code-editors.md +161 -0
  333. package/data/probe/site/use-cases/nodejs-sdk.md +596 -0
  334. package/data/probe/site/use-cases/team-chat.md +350 -0
  335. package/data/probe/site/web-interface.md +434 -0
  336. package/data/probe/site/wrangler.toml +9 -0
  337. package/data/probe/test-api-key.sh +1 -0
  338. package/data/probe/test-probe-implementation/hello.js +7 -0
  339. package/data/probe/test_cases/demonstrate_early_termination_issues.sh +176 -0
  340. package/data/probe/test_cases/early_termination_issues.rs +533 -0
  341. package/data/probe/test_data/test_nested_struct.go +26 -0
  342. package/data/probe/tests/README.md +286 -0
  343. package/data/probe/tests/README_search_determinism_tests.md +116 -0
  344. package/data/probe/tests/adjacent_comment_test.rs +152 -0
  345. package/data/probe/tests/apostrophe_handling_tests.rs +132 -0
  346. package/data/probe/tests/block_filtering_with_ast_tests.rs +669 -0
  347. package/data/probe/tests/block_merging_tests.rs +396 -0
  348. package/data/probe/tests/c_outline_format_tests.rs +2179 -0
  349. package/data/probe/tests/cache_invalidation_issues.rs.disabled +682 -0
  350. package/data/probe/tests/cache_order_tests.rs +147 -0
  351. package/data/probe/tests/cache_query_scoping_tests.rs +221 -0
  352. package/data/probe/tests/cli_tests.rs +680 -0
  353. package/data/probe/tests/comment_context_integration_test.rs +240 -0
  354. package/data/probe/tests/common.rs +33 -0
  355. package/data/probe/tests/complex_block_merging_tests.rs +599 -0
  356. package/data/probe/tests/complex_query_block_filtering_tests.rs +422 -0
  357. package/data/probe/tests/control_flow_closing_braces_test.rs +91 -0
  358. package/data/probe/tests/cpp_outline_format_tests.rs +1507 -0
  359. package/data/probe/tests/csharp_outline_format_tests.rs +941 -0
  360. package/data/probe/tests/elastic_query_integration_tests.rs +922 -0
  361. package/data/probe/tests/extract_command_tests.rs +1848 -0
  362. package/data/probe/tests/extract_deduplication_tests.rs +146 -0
  363. package/data/probe/tests/extract_input_file_tests.rs +84 -0
  364. package/data/probe/tests/extract_prompt_tests.rs +102 -0
  365. package/data/probe/tests/filename_search_tests.rs +96 -0
  366. package/data/probe/tests/fixtures/user/AssemblyInfo.cs +3 -0
  367. package/data/probe/tests/github_extract_tests.rs +234 -0
  368. package/data/probe/tests/go_comment_test.rs +253 -0
  369. package/data/probe/tests/go_outline_format_tests.rs +2587 -0
  370. package/data/probe/tests/go_path_resolver_tests.rs +96 -0
  371. package/data/probe/tests/html_outline_format_tests.rs +637 -0
  372. package/data/probe/tests/integration_tests.rs +837 -0
  373. package/data/probe/tests/ip_whitelist_test.rs +148 -0
  374. package/data/probe/tests/java_outline_format_tests.rs +1611 -0
  375. package/data/probe/tests/javascript_extract_tests.rs +315 -0
  376. package/data/probe/tests/javascript_outline_format_tests.rs +1464 -0
  377. package/data/probe/tests/json_format_tests.rs +436 -0
  378. package/data/probe/tests/json_schema_validation_tests.rs +450 -0
  379. package/data/probe/tests/lib_usage.rs +60 -0
  380. package/data/probe/tests/line_comment_context_extension_test.rs +459 -0
  381. package/data/probe/tests/line_map_cache_tests.rs +114 -0
  382. package/data/probe/tests/markdown_integration_tests.rs +190 -0
  383. package/data/probe/tests/mocks/test_ip_whitelist.go +11 -0
  384. package/data/probe/tests/mocks/test_object.js +27 -0
  385. package/data/probe/tests/mocks/test_struct.go +50 -0
  386. package/data/probe/tests/multi_keyword_pattern_tests.rs +464 -0
  387. package/data/probe/tests/multi_language_syntax_integration_tests.rs +218 -0
  388. package/data/probe/tests/multiple_capture_groups_tests.rs +169 -0
  389. package/data/probe/tests/negative_compound_word_tests.rs +246 -0
  390. package/data/probe/tests/nested_symbol_extraction_tests.rs +99 -0
  391. package/data/probe/tests/outline_cross_file_interference_test.rs +335 -0
  392. package/data/probe/tests/outline_keyword_preservation_test.rs +67 -0
  393. package/data/probe/tests/output_format_edge_cases_tests.rs +693 -0
  394. package/data/probe/tests/parallel_extraction_tests.rs +178 -0
  395. package/data/probe/tests/parallel_search_tests.rs +355 -0
  396. package/data/probe/tests/path_resolver_tests.rs +698 -0
  397. package/data/probe/tests/php_outline_format_extended_tests.rs +928 -0
  398. package/data/probe/tests/php_outline_format_tests.rs +768 -0
  399. package/data/probe/tests/property_tests.proptest-regressions +9 -0
  400. package/data/probe/tests/property_tests.rs +118 -0
  401. package/data/probe/tests/python_outline_format_tests.rs +1538 -0
  402. package/data/probe/tests/query_command_json_tests.rs +438 -0
  403. package/data/probe/tests/query_command_tests.rs +232 -0
  404. package/data/probe/tests/query_command_xml_tests.rs +569 -0
  405. package/data/probe/tests/quoted_term_with_negative_keyword_tests.rs +216 -0
  406. package/data/probe/tests/required_terms_filename_tests.rs +116 -0
  407. package/data/probe/tests/ruby_outline_format_tests.rs +1011 -0
  408. package/data/probe/tests/rust_line_comment_context_test.rs +151 -0
  409. package/data/probe/tests/rust_outline_format_enhanced_tests.rs +725 -0
  410. package/data/probe/tests/rust_outline_format_tests.rs +843 -0
  411. package/data/probe/tests/schemas/xml_output_schema.xsd +38 -0
  412. package/data/probe/tests/search_determinism_tests.rs +451 -0
  413. package/data/probe/tests/search_hints_tests.rs +253 -0
  414. package/data/probe/tests/special_character_escaping_tests.rs +417 -0
  415. package/data/probe/tests/stemming_compound_word_filtering_tests.rs +535 -0
  416. package/data/probe/tests/strict_elastic_syntax_tests.rs +404 -0
  417. package/data/probe/tests/swift_outline_format_tests.rs +3319 -0
  418. package/data/probe/tests/symbols_tests.rs +166 -0
  419. package/data/probe/tests/test_file.rs +45 -0
  420. package/data/probe/tests/test_tokenize.rs +28 -0
  421. package/data/probe/tests/timeout_tests.rs +82 -0
  422. package/data/probe/tests/tokenization_tests.rs +195 -0
  423. package/data/probe/tests/tokenized_block_filtering_tests.rs +174 -0
  424. package/data/probe/tests/typescript_extract_tests.rs +214 -0
  425. package/data/probe/tests/typescript_outline_format_tests.rs +2188 -0
  426. package/data/probe/tests/xml_format_tests.rs +568 -0
  427. package/data/probe/tests/xml_schema_validation_tests.rs +497 -0
  428. package/data/scripts/postinstall.mjs +9 -0
  429. package/data/scripts/set-version.js +0 -0
  430. package/data/scripts/wiki-build.sh +111 -0
  431. package/data/scripts/wiki-deploy.sh +73 -0
  432. package/data/serve.json +12 -0
  433. package/data/test/demo-dynamic.html +134 -0
  434. package/data/test/demo-esm.html +105 -0
  435. package/data/test/demo-iife.html +78 -0
  436. package/data/tsconfig.json +7 -0
  437. package/data/vite.server.ts +483 -0
  438. package/data/vitest.config.ts +40 -0
  439. package/data/wiki/Home.md +58 -0
  440. package/data/wiki/_Sidebar.md +39 -0
  441. package/docs-mcp.config.json +20 -0
  442. package/package.json +56 -0
  443. package/src/config.js +111 -0
  444. package/src/index.js +395 -0
@@ -0,0 +1,281 @@
1
+ import { NodeSDK } from '@opentelemetry/sdk-node';
2
+ import { resourceFromAttributes } from '@opentelemetry/resources';
3
+ import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from '@opentelemetry/semantic-conventions';
4
+ import { trace, context } from '@opentelemetry/api';
5
+ import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
6
+ import { BatchSpanProcessor, ConsoleSpanExporter } from '@opentelemetry/sdk-trace-base';
7
+ import { existsSync, mkdirSync } from 'fs';
8
+ import { dirname } from 'path';
9
+ import { FileSpanExporter } from './fileSpanExporter.js';
10
+
11
+ /**
12
+ * Custom OpenTelemetry configuration for probe-chat
13
+ */
14
+ export class TelemetryConfig {
15
+ constructor(options = {}) {
16
+ this.serviceName = options.serviceName || 'probe-chat';
17
+ this.serviceVersion = options.serviceVersion || '1.0.0';
18
+ this.enableFile = options.enableFile || false;
19
+ this.enableRemote = options.enableRemote || false;
20
+ this.enableConsole = options.enableConsole || false;
21
+ this.filePath = options.filePath || './traces.jsonl';
22
+ this.remoteEndpoint = options.remoteEndpoint || 'http://localhost:4318/v1/traces';
23
+ this.sdk = null;
24
+ this.tracer = null;
25
+ }
26
+
27
+ /**
28
+ * Initialize OpenTelemetry SDK
29
+ */
30
+ initialize() {
31
+ if (this.sdk) {
32
+ if (process.env.PROBE_NON_INTERACTIVE !== '1' || process.env.DEBUG_CHAT === '1') {
33
+ console.warn('Telemetry already initialized');
34
+ }
35
+ return;
36
+ }
37
+
38
+ const resource = resourceFromAttributes({
39
+ [ATTR_SERVICE_NAME]: this.serviceName,
40
+ [ATTR_SERVICE_VERSION]: this.serviceVersion,
41
+ });
42
+
43
+ const spanProcessors = [];
44
+
45
+ // Add file exporter if enabled
46
+ if (this.enableFile) {
47
+ try {
48
+ // Ensure the directory exists
49
+ const dir = dirname(this.filePath);
50
+ if (!existsSync(dir)) {
51
+ mkdirSync(dir, { recursive: true });
52
+ }
53
+
54
+ const fileExporter = new FileSpanExporter(this.filePath);
55
+ // CRITICAL FIX: Configure BatchSpanProcessor with shorter delays for better span export
56
+ spanProcessors.push(new BatchSpanProcessor(fileExporter, {
57
+ // The maximum queue size. After the size is reached spans are dropped.
58
+ maxQueueSize: 2048,
59
+ // The maximum batch size of every export. It must be smaller or equal to maxQueueSize.
60
+ maxExportBatchSize: 512,
61
+ // The interval between two consecutive exports
62
+ scheduledDelayMillis: 500, // Reduced from default 5000ms
63
+ // How long the export can run before it is cancelled
64
+ exportTimeoutMillis: 30000,
65
+ }));
66
+ if (process.env.PROBE_NON_INTERACTIVE !== '1' || process.env.DEBUG_CHAT === '1') {
67
+ console.log(`[Telemetry] File exporter enabled, writing to: ${this.filePath}`);
68
+ }
69
+ } catch (error) {
70
+ if (process.env.PROBE_NON_INTERACTIVE !== '1' || process.env.DEBUG_CHAT === '1') {
71
+ console.error(`[Telemetry] Failed to initialize file exporter: ${error.message}`);
72
+ }
73
+ }
74
+ }
75
+
76
+ // Add remote exporter if enabled
77
+ if (this.enableRemote) {
78
+ try {
79
+ const remoteExporter = new OTLPTraceExporter({
80
+ url: this.remoteEndpoint,
81
+ });
82
+ // Configure BatchSpanProcessor with shorter delays for better span export
83
+ spanProcessors.push(new BatchSpanProcessor(remoteExporter, {
84
+ maxQueueSize: 2048,
85
+ maxExportBatchSize: 512,
86
+ scheduledDelayMillis: 500, // Reduced from default 5000ms
87
+ exportTimeoutMillis: 30000,
88
+ }));
89
+ if (process.env.PROBE_NON_INTERACTIVE !== '1' || process.env.DEBUG_CHAT === '1') {
90
+ console.log(`[Telemetry] Remote exporter enabled, endpoint: ${this.remoteEndpoint}`);
91
+ }
92
+ } catch (error) {
93
+ if (process.env.PROBE_NON_INTERACTIVE !== '1' || process.env.DEBUG_CHAT === '1') {
94
+ console.error(`[Telemetry] Failed to initialize remote exporter: ${error.message}`);
95
+ }
96
+ }
97
+ }
98
+
99
+ // Add console exporter if enabled (useful for debugging)
100
+ if (this.enableConsole) {
101
+ const consoleExporter = new ConsoleSpanExporter();
102
+ // Configure BatchSpanProcessor with shorter delays for better span export
103
+ spanProcessors.push(new BatchSpanProcessor(consoleExporter, {
104
+ maxQueueSize: 2048,
105
+ maxExportBatchSize: 512,
106
+ scheduledDelayMillis: 500, // Reduced from default 5000ms
107
+ exportTimeoutMillis: 30000,
108
+ }));
109
+ if (process.env.PROBE_NON_INTERACTIVE !== '1' || process.env.DEBUG_CHAT === '1') {
110
+ console.log(`[Telemetry] Console exporter enabled`);
111
+ }
112
+ }
113
+
114
+ if (spanProcessors.length === 0) {
115
+ if (process.env.PROBE_NON_INTERACTIVE !== '1' || process.env.DEBUG_CHAT === '1') {
116
+ console.log('[Telemetry] No exporters configured, telemetry will not be collected');
117
+ }
118
+ return;
119
+ }
120
+
121
+ this.sdk = new NodeSDK({
122
+ resource,
123
+ spanProcessors,
124
+ });
125
+
126
+ try {
127
+ this.sdk.start();
128
+ this.tracer = trace.getTracer(this.serviceName, this.serviceVersion);
129
+ if (process.env.PROBE_NON_INTERACTIVE !== '1' || process.env.DEBUG_CHAT === '1') {
130
+ console.log(`[Telemetry] OpenTelemetry SDK initialized successfully`);
131
+ }
132
+ } catch (error) {
133
+ if (process.env.PROBE_NON_INTERACTIVE !== '1' || process.env.DEBUG_CHAT === '1') {
134
+ console.error(`[Telemetry] Failed to start OpenTelemetry SDK: ${error.message}`);
135
+ }
136
+ }
137
+ }
138
+
139
+ /**
140
+ * Get the tracer instance
141
+ */
142
+ getTracer() {
143
+ return this.tracer;
144
+ }
145
+
146
+ /**
147
+ * Create a span with the given name and attributes
148
+ */
149
+ createSpan(name, attributes = {}) {
150
+ if (!this.tracer) {
151
+ return null;
152
+ }
153
+
154
+ return this.tracer.startSpan(name, {
155
+ attributes,
156
+ });
157
+ }
158
+
159
+ /**
160
+ * Wrap a function to automatically create spans
161
+ */
162
+ wrapFunction(name, fn, attributes = {}) {
163
+ if (!this.tracer) {
164
+ return fn;
165
+ }
166
+
167
+ return async (...args) => {
168
+ const span = this.createSpan(name, attributes);
169
+ if (!span) {
170
+ return fn(...args);
171
+ }
172
+
173
+ try {
174
+ const result = await context.with(trace.setSpan(context.active(), span), () => fn(...args));
175
+ span.setStatus({ code: trace.SpanStatusCode.OK });
176
+ return result;
177
+ } catch (error) {
178
+ span.setStatus({
179
+ code: trace.SpanStatusCode.ERROR,
180
+ message: error.message,
181
+ });
182
+ span.recordException(error);
183
+ throw error;
184
+ } finally {
185
+ span.end();
186
+ }
187
+ };
188
+ }
189
+
190
+ /**
191
+ * Force flush all pending spans
192
+ */
193
+ async forceFlush() {
194
+ if (this.sdk) {
195
+ try {
196
+ // Get the active tracer provider
197
+ const tracerProvider = trace.getTracerProvider();
198
+
199
+ if (tracerProvider && typeof tracerProvider.forceFlush === 'function') {
200
+ // Call forceFlush on the tracer provider
201
+ await tracerProvider.forceFlush();
202
+
203
+ if (process.env.DEBUG_CHAT === '1') {
204
+ console.log('[Telemetry] TracerProvider flushed successfully');
205
+ }
206
+ }
207
+
208
+ // Also try to access registered span processors directly for better control
209
+ if (tracerProvider._registeredSpanProcessors) {
210
+ const flushPromises = [];
211
+
212
+ for (const processor of tracerProvider._registeredSpanProcessors) {
213
+ if (typeof processor.forceFlush === 'function') {
214
+ flushPromises.push(processor.forceFlush());
215
+ }
216
+ }
217
+
218
+ if (flushPromises.length > 0) {
219
+ await Promise.all(flushPromises);
220
+
221
+ if (process.env.DEBUG_CHAT === '1') {
222
+ console.log(`[Telemetry] Directly flushed ${flushPromises.length} span processors`);
223
+ }
224
+ }
225
+ }
226
+
227
+ // Add a small delay to ensure file writes complete
228
+ await new Promise(resolve => setTimeout(resolve, 100));
229
+
230
+ if (process.env.DEBUG_CHAT === '1') {
231
+ console.log('[Telemetry] OpenTelemetry spans flushed successfully');
232
+ }
233
+ } catch (error) {
234
+ if (process.env.PROBE_NON_INTERACTIVE !== '1' || process.env.DEBUG_CHAT === '1') {
235
+ console.error(`[Telemetry] Failed to flush OpenTelemetry spans: ${error.message}`);
236
+ }
237
+ }
238
+ }
239
+ }
240
+
241
+ /**
242
+ * Shutdown telemetry
243
+ */
244
+ async shutdown() {
245
+ if (this.sdk) {
246
+ try {
247
+ await this.sdk.shutdown();
248
+ if (process.env.PROBE_NON_INTERACTIVE !== '1' || process.env.DEBUG_CHAT === '1') {
249
+ console.log('[Telemetry] OpenTelemetry SDK shutdown successfully');
250
+ }
251
+ } catch (error) {
252
+ if (process.env.PROBE_NON_INTERACTIVE !== '1' || process.env.DEBUG_CHAT === '1') {
253
+ console.error(`[Telemetry] Failed to shutdown OpenTelemetry SDK: ${error.message}`);
254
+ }
255
+ }
256
+ }
257
+ }
258
+ }
259
+
260
+ /**
261
+ * Default telemetry configuration
262
+ */
263
+ export const defaultTelemetryConfig = new TelemetryConfig();
264
+
265
+ /**
266
+ * Initialize telemetry from environment variables
267
+ */
268
+ export function initializeTelemetryFromEnv() {
269
+ const config = new TelemetryConfig({
270
+ serviceName: process.env.OTEL_SERVICE_NAME || 'probe-chat',
271
+ serviceVersion: process.env.OTEL_SERVICE_VERSION || '1.0.0',
272
+ enableFile: process.env.OTEL_ENABLE_FILE === 'true',
273
+ enableRemote: process.env.OTEL_ENABLE_REMOTE === 'true',
274
+ enableConsole: process.env.OTEL_ENABLE_CONSOLE === 'true',
275
+ filePath: process.env.OTEL_FILE_PATH || './traces.jsonl',
276
+ remoteEndpoint: process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT || 'http://localhost:4318/v1/traces',
277
+ });
278
+
279
+ config.initialize();
280
+ return config;
281
+ }
@@ -0,0 +1,320 @@
1
+ import { describe, it, before, after, beforeEach, afterEach } from 'node:test';
2
+ import assert from 'node:assert';
3
+ import {
4
+ setupTestEnvironment,
5
+ createTestProbeChat,
6
+ captureConsoleOutput,
7
+ runChatInteraction,
8
+ testData
9
+ } from '../testUtils.js';
10
+ import { mockResponses } from '../mocks/mockLLMProvider.js';
11
+
12
+ describe('Chat Flow Integration Tests', () => {
13
+ let testEnv;
14
+ let consoleCapture;
15
+
16
+ before(() => {
17
+ testEnv = setupTestEnvironment();
18
+ });
19
+
20
+ after(() => {
21
+ testEnv.restore();
22
+ });
23
+
24
+ beforeEach(() => {
25
+ consoleCapture = captureConsoleOutput();
26
+ });
27
+
28
+ afterEach(() => {
29
+ consoleCapture.restore();
30
+ });
31
+
32
+ describe('Basic Chat Interactions', () => {
33
+ it('should handle simple text conversation', async () => {
34
+ const { probeChat, mockProvider } = await createTestProbeChat({
35
+ responses: [
36
+ { text: 'Hello! I am a mock AI assistant.' },
37
+ { text: 'The weather is simulated to be sunny.' }
38
+ ]
39
+ });
40
+
41
+ const messages = [
42
+ { role: 'user', content: 'Hello' },
43
+ { role: 'user', content: 'How is the weather?' }
44
+ ];
45
+
46
+ const results = await runChatInteraction(probeChat, messages);
47
+
48
+ assert.strictEqual(results.responses.length, 2);
49
+ assert.strictEqual(results.errors.length, 0);
50
+ assert.ok(results.streamedText.includes('Hello! I am a mock AI assistant.'));
51
+ assert.ok(results.streamedText.includes('The weather is simulated to be sunny.'));
52
+ });
53
+
54
+ it('should handle streaming responses', async () => {
55
+ const { probeChat } = await createTestProbeChat({
56
+ responses: [mockResponses.longStreamingResponse]
57
+ });
58
+
59
+ let streamChunks = [];
60
+ const results = await runChatInteraction(probeChat,
61
+ [{ role: 'user', content: 'Tell me a story' }],
62
+ {
63
+ onStream: (chunk) => {
64
+ streamChunks.push(chunk);
65
+ }
66
+ }
67
+ );
68
+
69
+ assert.strictEqual(results.errors.length, 0);
70
+ assert.ok(streamChunks.length > 1, 'Should receive multiple stream chunks');
71
+ assert.ok(results.streamedText.includes('longer response'));
72
+ assert.ok(results.streamedText.includes('streamed in chunks'));
73
+ });
74
+
75
+ it('should handle conversation context', async () => {
76
+ const { probeChat, mockProvider } = await createTestProbeChat({
77
+ responses: [
78
+ { text: 'My name is MockBot.' },
79
+ { text: 'You asked me about my name. I told you it is MockBot.' }
80
+ ]
81
+ });
82
+
83
+ // First message
84
+ await probeChat.sendMessage('What is your name?');
85
+
86
+ // Second message should have context
87
+ await probeChat.sendMessage('What did I just ask you?');
88
+
89
+ // Check that the context was maintained
90
+ const capturedCalls = mockProvider.capturedCalls;
91
+ assert.strictEqual(capturedCalls.length, 2);
92
+
93
+ // Second call should include previous messages
94
+ const secondCallMessages = capturedCalls[1].messages;
95
+ assert.ok(secondCallMessages.length >= 3); // user, assistant, user
96
+ assert.strictEqual(secondCallMessages[0].content, 'What is your name?');
97
+ });
98
+ });
99
+
100
+ describe('Error Handling', () => {
101
+ it('should handle API errors gracefully', async () => {
102
+ const { probeChat } = await createTestProbeChat({
103
+ mockProvider: {
104
+ throwError: 'Simulated API error'
105
+ }
106
+ });
107
+
108
+ const results = await runChatInteraction(probeChat,
109
+ [{ role: 'user', content: 'This should fail' }]
110
+ );
111
+
112
+ assert.strictEqual(results.errors.length, 1);
113
+ assert.ok(results.errors[0].message.includes('Simulated API error'));
114
+ });
115
+
116
+ it('should handle timeout scenarios', async () => {
117
+ const { probeChat } = await createTestProbeChat({
118
+ responses: [{ text: 'This will timeout' }],
119
+ chatOptions: {
120
+ timeout: 100 // 100ms timeout
121
+ },
122
+ mockProvider: {
123
+ streamDelay: 200 // 200ms delay per chunk
124
+ }
125
+ });
126
+
127
+ const startTime = Date.now();
128
+ const results = await runChatInteraction(probeChat,
129
+ [{ role: 'user', content: 'Test timeout' }]
130
+ );
131
+ const duration = Date.now() - startTime;
132
+
133
+ // Should timeout before completing the full stream
134
+ assert.ok(duration < 1000, 'Should timeout quickly');
135
+ });
136
+
137
+ it('should recover from errors and continue conversation', async () => {
138
+ const { probeChat, mockProvider } = await createTestProbeChat({
139
+ responses: [
140
+ { text: 'First response works' },
141
+ { text: 'Second response (will be skipped due to error)' },
142
+ { text: 'Third response after recovery' }
143
+ ]
144
+ });
145
+
146
+ // Override getNextResponse to simulate error on second call
147
+ let callCount = 0;
148
+ const originalGetNext = mockProvider.getNextResponse;
149
+ mockProvider.getNextResponse = function() {
150
+ callCount++;
151
+ if (callCount === 2) {
152
+ // Advance the response index so the third call gets the correct response
153
+ this.currentResponseIndex = (this.currentResponseIndex + 1) % this.responses.length;
154
+ throw new Error('Simulated error on second call');
155
+ }
156
+ return originalGetNext.call(this);
157
+ };
158
+
159
+ const messages = [
160
+ { role: 'user', content: 'First message' },
161
+ { role: 'user', content: 'This will error' },
162
+ { role: 'user', content: 'Should work again' }
163
+ ];
164
+
165
+ const results = await runChatInteraction(probeChat, messages);
166
+
167
+ // Verify the chat system recovered correctly
168
+ assert.strictEqual(results.responses.length, 2, 'Should have 2 successful responses');
169
+ assert.strictEqual(results.errors.length, 1, 'Should have 1 error');
170
+ assert.ok(results.streamedText.includes('First response works'), 'First response should be included');
171
+ assert.ok(results.streamedText.includes('Third response after recovery'), 'Third response should be included after recovery');
172
+ assert.ok(results.errors[0].message.includes('Simulated error on second call'), 'Error should be captured correctly');
173
+ });
174
+ });
175
+
176
+ describe('Multi-turn Conversations', () => {
177
+ it('should maintain conversation history', async () => {
178
+ const { probeChat, mockProvider } = await createTestProbeChat({
179
+ responses: [
180
+ { text: 'I can help you with coding.' },
181
+ { text: 'You asked about my capabilities. I mentioned coding help.' },
182
+ { text: 'Throughout our conversation, you asked about capabilities and I explained coding help.' }
183
+ ]
184
+ });
185
+
186
+ // Build conversation
187
+ await probeChat.sendMessage('What can you help with?');
188
+ await probeChat.sendMessage('What did I ask about?');
189
+ await probeChat.sendMessage('Summarize our conversation');
190
+
191
+ const calls = mockProvider.capturedCalls;
192
+ assert.ok(calls.length >= 3, 'Should have at least 3 calls');
193
+
194
+ // Find the actual chat calls (not duplicates)
195
+ const chatCalls = [];
196
+ const seenMessageCounts = new Set();
197
+ for (const call of calls) {
198
+ const msgCount = call.messages.length;
199
+ if (!seenMessageCounts.has(msgCount)) {
200
+ seenMessageCounts.add(msgCount);
201
+ chatCalls.push(call);
202
+ }
203
+ }
204
+
205
+ assert.strictEqual(chatCalls.length, 3, 'Should have 3 unique chat calls');
206
+
207
+ // Check conversation growth
208
+ assert.strictEqual(chatCalls[0].messages.length, 1); // Just user message
209
+ assert.strictEqual(chatCalls[1].messages.length, 3); // user, assistant, user
210
+ assert.strictEqual(chatCalls[2].messages.length, 5); // full conversation
211
+ });
212
+
213
+ it('should handle conversation reset', async () => {
214
+ const { probeChat, mockProvider } = await createTestProbeChat({
215
+ responses: [
216
+ { text: 'First conversation response' },
217
+ { text: 'Fresh start response' }
218
+ ]
219
+ });
220
+
221
+ // First conversation
222
+ await probeChat.sendMessage('First message');
223
+
224
+ // Reset conversation using clearHistory (the actual method)
225
+ const newSessionId = probeChat.clearHistory();
226
+ assert.ok(newSessionId, 'clearHistory should return a new session ID');
227
+
228
+ // New conversation
229
+ await probeChat.sendMessage('New conversation');
230
+
231
+ const calls = mockProvider.capturedCalls;
232
+ assert.strictEqual(calls.length, 2);
233
+
234
+ // Second call should not have history from first
235
+ assert.strictEqual(calls[1].messages.length, 1);
236
+ assert.strictEqual(calls[1].messages[0].content, 'New conversation');
237
+ });
238
+ });
239
+
240
+ describe('System Prompts and Configuration', () => {
241
+ it('should include system prompts in conversation', async () => {
242
+ const systemPrompt = 'You are a helpful coding assistant specialized in JavaScript.';
243
+ const { probeChat, mockProvider } = await createTestProbeChat({
244
+ responses: [{ text: 'I understand JavaScript very well.' }],
245
+ chatOptions: {
246
+ systemPrompt
247
+ }
248
+ });
249
+
250
+ await probeChat.sendMessage('Can you help with JS?');
251
+
252
+ const call = mockProvider.capturedCalls[0];
253
+ assert.ok(call.system || call.messages.some(m => m.role === 'system'));
254
+
255
+ if (call.system) {
256
+ assert.strictEqual(call.system, systemPrompt);
257
+ } else {
258
+ const systemMessage = call.messages.find(m => m.role === 'system');
259
+ assert.ok(systemMessage);
260
+ assert.strictEqual(systemMessage.content, systemPrompt);
261
+ }
262
+ });
263
+
264
+ it('should respect temperature and max tokens settings', async () => {
265
+ const { probeChat, mockProvider } = await createTestProbeChat({
266
+ responses: [{ text: 'Temperature test response' }],
267
+ chatOptions: {
268
+ temperature: 0.7,
269
+ maxTokens: 2000
270
+ }
271
+ });
272
+
273
+ await probeChat.sendMessage('Test message');
274
+
275
+ const call = mockProvider.capturedCalls[0];
276
+ assert.strictEqual(call.temperature, 0.7);
277
+ assert.strictEqual(call.maxTokens, 2000);
278
+ });
279
+ });
280
+
281
+ describe('Image Support', () => {
282
+ it('should handle image inputs in messages', async () => {
283
+ const { probeChat, mockProvider } = await createTestProbeChat({
284
+ responses: [{ text: 'I can see the image you provided.' }]
285
+ });
286
+
287
+ const messageWithImage = {
288
+ role: 'user',
289
+ content: [
290
+ { type: 'text', text: 'What is in this image?' },
291
+ { type: 'image', image: 'base64encodedimage' }
292
+ ]
293
+ };
294
+
295
+ await runChatInteraction(probeChat, [messageWithImage]);
296
+
297
+ const call = mockProvider.capturedCalls[0];
298
+ assert.ok(Array.isArray(call.messages[0].content));
299
+ assert.strictEqual(call.messages[0].content[0].type, 'text');
300
+ assert.strictEqual(call.messages[0].content[1].type, 'image');
301
+ });
302
+
303
+ it('should process image URLs', async () => {
304
+ const { probeChat, mockProvider } = await createTestProbeChat({
305
+ responses: [{ text: 'I processed the image from the URL.' }]
306
+ });
307
+
308
+ // Mock the processImageUrl method
309
+ probeChat.processImageUrl = async (url) => {
310
+ return 'mocked-base64-image-data';
311
+ };
312
+
313
+ await probeChat.sendMessage('Look at this image: https://example.com/image.png');
314
+
315
+ const call = mockProvider.capturedCalls[0];
316
+ // The message should be processed to include image data
317
+ assert.ok(call.messages[0].content);
318
+ });
319
+ });
320
+ });