@yasserkhanorg/impact-gate 2.0.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 (587) hide show
  1. package/LICENSE +168 -0
  2. package/README.md +520 -0
  3. package/dist/adapters/cypress.d.ts +10 -0
  4. package/dist/adapters/cypress.d.ts.map +1 -0
  5. package/dist/adapters/cypress.js +86 -0
  6. package/dist/adapters/framework_adapter.d.ts +41 -0
  7. package/dist/adapters/framework_adapter.d.ts.map +1 -0
  8. package/dist/adapters/framework_adapter.js +152 -0
  9. package/dist/adapters/playwright.d.ts +10 -0
  10. package/dist/adapters/playwright.d.ts.map +1 -0
  11. package/dist/adapters/playwright.js +86 -0
  12. package/dist/adapters/pytest.d.ts +10 -0
  13. package/dist/adapters/pytest.d.ts.map +1 -0
  14. package/dist/adapters/pytest.js +96 -0
  15. package/dist/adapters/supertest.d.ts +12 -0
  16. package/dist/adapters/supertest.d.ts.map +1 -0
  17. package/dist/adapters/supertest.js +85 -0
  18. package/dist/agent/api_catalog.d.ts +11 -0
  19. package/dist/agent/api_catalog.d.ts.map +1 -0
  20. package/dist/agent/api_catalog.js +210 -0
  21. package/dist/agent/config.d.ts +193 -0
  22. package/dist/agent/config.d.ts.map +1 -0
  23. package/dist/agent/config.js +875 -0
  24. package/dist/agent/feedback.d.ts +91 -0
  25. package/dist/agent/feedback.d.ts.map +1 -0
  26. package/dist/agent/feedback.js +323 -0
  27. package/dist/agent/git.d.ts +19 -0
  28. package/dist/agent/git.d.ts.map +1 -0
  29. package/dist/agent/git.js +257 -0
  30. package/dist/agent/handoff.d.ts +22 -0
  31. package/dist/agent/handoff.d.ts.map +1 -0
  32. package/dist/agent/handoff.js +180 -0
  33. package/dist/agent/llm_agents_flow.d.ts +15 -0
  34. package/dist/agent/llm_agents_flow.d.ts.map +1 -0
  35. package/dist/agent/llm_agents_flow.js +434 -0
  36. package/dist/agent/native_flow.d.ts +6 -0
  37. package/dist/agent/native_flow.d.ts.map +1 -0
  38. package/dist/agent/native_flow.js +179 -0
  39. package/dist/agent/pipeline.d.ts +7 -0
  40. package/dist/agent/pipeline.d.ts.map +1 -0
  41. package/dist/agent/pipeline.js +260 -0
  42. package/dist/agent/pipeline_types.d.ts +54 -0
  43. package/dist/agent/pipeline_types.d.ts.map +1 -0
  44. package/dist/agent/pipeline_types.js +4 -0
  45. package/dist/agent/pipeline_utils.d.ts +12 -0
  46. package/dist/agent/pipeline_utils.d.ts.map +1 -0
  47. package/dist/agent/pipeline_utils.js +156 -0
  48. package/dist/agent/plan.d.ts +170 -0
  49. package/dist/agent/plan.d.ts.map +1 -0
  50. package/dist/agent/plan.js +86 -0
  51. package/dist/agent/playwright_report.d.ts +8 -0
  52. package/dist/agent/playwright_report.d.ts.map +1 -0
  53. package/dist/agent/playwright_report.js +126 -0
  54. package/dist/agent/process_runner.d.ts +10 -0
  55. package/dist/agent/process_runner.d.ts.map +1 -0
  56. package/dist/agent/process_runner.js +92 -0
  57. package/dist/agent/spec_generator.d.ts +5 -0
  58. package/dist/agent/spec_generator.d.ts.map +1 -0
  59. package/dist/agent/spec_generator.js +253 -0
  60. package/dist/agent/test_path.d.ts +2 -0
  61. package/dist/agent/test_path.d.ts.map +1 -0
  62. package/dist/agent/test_path.js +23 -0
  63. package/dist/agent/traceability_capture.d.ts +18 -0
  64. package/dist/agent/traceability_capture.d.ts.map +1 -0
  65. package/dist/agent/traceability_capture.js +313 -0
  66. package/dist/agent/traceability_ingest.d.ts +21 -0
  67. package/dist/agent/traceability_ingest.d.ts.map +1 -0
  68. package/dist/agent/traceability_ingest.js +237 -0
  69. package/dist/agent/types.d.ts +42 -0
  70. package/dist/agent/types.d.ts.map +1 -0
  71. package/dist/agent/types.js +4 -0
  72. package/dist/agent/utils.d.ts +13 -0
  73. package/dist/agent/utils.d.ts.map +1 -0
  74. package/dist/agent/utils.js +152 -0
  75. package/dist/agent/validation_runner.d.ts +5 -0
  76. package/dist/agent/validation_runner.d.ts.map +1 -0
  77. package/dist/agent/validation_runner.js +77 -0
  78. package/dist/agentic/fix_loop.d.ts +26 -0
  79. package/dist/agentic/fix_loop.d.ts.map +1 -0
  80. package/dist/agentic/fix_loop.js +96 -0
  81. package/dist/agentic/playwright_runner.d.ts +43 -0
  82. package/dist/agentic/playwright_runner.d.ts.map +1 -0
  83. package/dist/agentic/playwright_runner.js +165 -0
  84. package/dist/agentic/runner.d.ts +27 -0
  85. package/dist/agentic/runner.d.ts.map +1 -0
  86. package/dist/agentic/runner.js +210 -0
  87. package/dist/agentic/types.d.ts +62 -0
  88. package/dist/agentic/types.d.ts.map +1 -0
  89. package/dist/agentic/types.js +4 -0
  90. package/dist/agents/coverage-evaluator.d.ts +8 -0
  91. package/dist/agents/coverage-evaluator.d.ts.map +1 -0
  92. package/dist/agents/coverage-evaluator.js +41 -0
  93. package/dist/agents/cross-impact.d.ts +13 -0
  94. package/dist/agents/cross-impact.d.ts.map +1 -0
  95. package/dist/agents/cross-impact.js +140 -0
  96. package/dist/agents/executor.d.ts +8 -0
  97. package/dist/agents/executor.d.ts.map +1 -0
  98. package/dist/agents/executor.js +75 -0
  99. package/dist/agents/explorer.d.ts +12 -0
  100. package/dist/agents/explorer.d.ts.map +1 -0
  101. package/dist/agents/explorer.js +43 -0
  102. package/dist/agents/generator.d.ts +8 -0
  103. package/dist/agents/generator.d.ts.map +1 -0
  104. package/dist/agents/generator.js +77 -0
  105. package/dist/agents/healer.d.ts +8 -0
  106. package/dist/agents/healer.d.ts.map +1 -0
  107. package/dist/agents/healer.js +31 -0
  108. package/dist/agents/impact-analyst.d.ts +8 -0
  109. package/dist/agents/impact-analyst.d.ts.map +1 -0
  110. package/dist/agents/impact-analyst.js +38 -0
  111. package/dist/agents/regression-advisor.d.ts +8 -0
  112. package/dist/agents/regression-advisor.d.ts.map +1 -0
  113. package/dist/agents/regression-advisor.js +116 -0
  114. package/dist/agents/strategist.d.ts +9 -0
  115. package/dist/agents/strategist.d.ts.map +1 -0
  116. package/dist/agents/strategist.js +92 -0
  117. package/dist/agents/test-designer.d.ts +8 -0
  118. package/dist/agents/test-designer.d.ts.map +1 -0
  119. package/dist/agents/test-designer.js +111 -0
  120. package/dist/anthropic_provider.d.ts +65 -0
  121. package/dist/anthropic_provider.d.ts.map +1 -0
  122. package/dist/anthropic_provider.js +334 -0
  123. package/dist/api.d.ts +48 -0
  124. package/dist/api.d.ts.map +1 -0
  125. package/dist/api.js +151 -0
  126. package/dist/base_provider.d.ts +109 -0
  127. package/dist/base_provider.d.ts.map +1 -0
  128. package/dist/base_provider.js +203 -0
  129. package/dist/budget_ledger.d.ts +28 -0
  130. package/dist/budget_ledger.d.ts.map +1 -0
  131. package/dist/budget_ledger.js +62 -0
  132. package/dist/cache/cached_provider.d.ts +49 -0
  133. package/dist/cache/cached_provider.d.ts.map +1 -0
  134. package/dist/cache/cached_provider.js +91 -0
  135. package/dist/cache/response_cache.d.ts +79 -0
  136. package/dist/cache/response_cache.d.ts.map +1 -0
  137. package/dist/cache/response_cache.js +177 -0
  138. package/dist/cli/commands/analyze.d.ts +3 -0
  139. package/dist/cli/commands/analyze.d.ts.map +1 -0
  140. package/dist/cli/commands/analyze.js +77 -0
  141. package/dist/cli/commands/bootstrap.d.ts +3 -0
  142. package/dist/cli/commands/bootstrap.d.ts.map +1 -0
  143. package/dist/cli/commands/bootstrap.js +109 -0
  144. package/dist/cli/commands/cost_report.d.ts +3 -0
  145. package/dist/cli/commands/cost_report.d.ts.map +1 -0
  146. package/dist/cli/commands/cost_report.js +115 -0
  147. package/dist/cli/commands/crew.d.ts +3 -0
  148. package/dist/cli/commands/crew.d.ts.map +1 -0
  149. package/dist/cli/commands/crew.js +255 -0
  150. package/dist/cli/commands/feedback.d.ts +3 -0
  151. package/dist/cli/commands/feedback.d.ts.map +1 -0
  152. package/dist/cli/commands/feedback.js +39 -0
  153. package/dist/cli/commands/finalize.d.ts +3 -0
  154. package/dist/cli/commands/finalize.d.ts.map +1 -0
  155. package/dist/cli/commands/finalize.js +41 -0
  156. package/dist/cli/commands/gate.d.ts +3 -0
  157. package/dist/cli/commands/gate.d.ts.map +1 -0
  158. package/dist/cli/commands/gate.js +89 -0
  159. package/dist/cli/commands/generate.d.ts +4 -0
  160. package/dist/cli/commands/generate.d.ts.map +1 -0
  161. package/dist/cli/commands/generate.js +108 -0
  162. package/dist/cli/commands/heal.d.ts +3 -0
  163. package/dist/cli/commands/heal.d.ts.map +1 -0
  164. package/dist/cli/commands/heal.js +60 -0
  165. package/dist/cli/commands/impact.d.ts +4 -0
  166. package/dist/cli/commands/impact.d.ts.map +1 -0
  167. package/dist/cli/commands/impact.js +33 -0
  168. package/dist/cli/commands/init.d.ts +2 -0
  169. package/dist/cli/commands/init.d.ts.map +1 -0
  170. package/dist/cli/commands/init.js +169 -0
  171. package/dist/cli/commands/llm_health.d.ts +2 -0
  172. package/dist/cli/commands/llm_health.d.ts.map +1 -0
  173. package/dist/cli/commands/llm_health.js +22 -0
  174. package/dist/cli/commands/plan.d.ts +4 -0
  175. package/dist/cli/commands/plan.d.ts.map +1 -0
  176. package/dist/cli/commands/plan.js +120 -0
  177. package/dist/cli/commands/plan_crew.d.ts +17 -0
  178. package/dist/cli/commands/plan_crew.d.ts.map +1 -0
  179. package/dist/cli/commands/plan_crew.js +316 -0
  180. package/dist/cli/commands/traceability.d.ts +4 -0
  181. package/dist/cli/commands/traceability.d.ts.map +1 -0
  182. package/dist/cli/commands/traceability.js +77 -0
  183. package/dist/cli/commands/train.d.ts +3 -0
  184. package/dist/cli/commands/train.d.ts.map +1 -0
  185. package/dist/cli/commands/train.js +391 -0
  186. package/dist/cli/defaults.d.ts +35 -0
  187. package/dist/cli/defaults.d.ts.map +1 -0
  188. package/dist/cli/defaults.js +172 -0
  189. package/dist/cli/errors.d.ts +27 -0
  190. package/dist/cli/errors.d.ts.map +1 -0
  191. package/dist/cli/errors.js +57 -0
  192. package/dist/cli/parse_args.d.ts +6 -0
  193. package/dist/cli/parse_args.d.ts.map +1 -0
  194. package/dist/cli/parse_args.js +257 -0
  195. package/dist/cli/types.d.ts +87 -0
  196. package/dist/cli/types.d.ts.map +1 -0
  197. package/dist/cli/types.js +4 -0
  198. package/dist/cli/usage.d.ts +2 -0
  199. package/dist/cli/usage.d.ts.map +1 -0
  200. package/dist/cli/usage.js +109 -0
  201. package/dist/cli.d.ts +3 -0
  202. package/dist/cli.d.ts.map +1 -0
  203. package/dist/cli.js +194 -0
  204. package/dist/crew/context.d.ts +55 -0
  205. package/dist/crew/context.d.ts.map +1 -0
  206. package/dist/crew/context.js +36 -0
  207. package/dist/crew/orchestrator.d.ts +50 -0
  208. package/dist/crew/orchestrator.d.ts.map +1 -0
  209. package/dist/crew/orchestrator.js +329 -0
  210. package/dist/crew/protocol.d.ts +46 -0
  211. package/dist/crew/protocol.d.ts.map +1 -0
  212. package/dist/crew/protocol.js +4 -0
  213. package/dist/crew/provider.d.ts +17 -0
  214. package/dist/crew/provider.d.ts.map +1 -0
  215. package/dist/crew/provider.js +36 -0
  216. package/dist/crew/sanitize.d.ts +3 -0
  217. package/dist/crew/sanitize.d.ts.map +1 -0
  218. package/dist/crew/sanitize.js +31 -0
  219. package/dist/crew/types.d.ts +52 -0
  220. package/dist/crew/types.d.ts.map +1 -0
  221. package/dist/crew/types.js +4 -0
  222. package/dist/crew/workflows.d.ts +52 -0
  223. package/dist/crew/workflows.d.ts.map +1 -0
  224. package/dist/crew/workflows.js +36 -0
  225. package/dist/custom_provider.d.ts +20 -0
  226. package/dist/custom_provider.d.ts.map +1 -0
  227. package/dist/custom_provider.js +277 -0
  228. package/dist/engine/ai_enrichment.d.ts +44 -0
  229. package/dist/engine/ai_enrichment.d.ts.map +1 -0
  230. package/dist/engine/ai_enrichment.js +267 -0
  231. package/dist/engine/diff_loader.d.ts +11 -0
  232. package/dist/engine/diff_loader.d.ts.map +1 -0
  233. package/dist/engine/diff_loader.js +63 -0
  234. package/dist/engine/impact_engine.d.ts +72 -0
  235. package/dist/engine/impact_engine.d.ts.map +1 -0
  236. package/dist/engine/impact_engine.js +298 -0
  237. package/dist/engine/plan_builder.d.ts +11 -0
  238. package/dist/engine/plan_builder.d.ts.map +1 -0
  239. package/dist/engine/plan_builder.js +599 -0
  240. package/dist/esm/adapters/cypress.js +49 -0
  241. package/dist/esm/adapters/framework_adapter.js +114 -0
  242. package/dist/esm/adapters/playwright.js +49 -0
  243. package/dist/esm/adapters/pytest.js +59 -0
  244. package/dist/esm/adapters/supertest.js +48 -0
  245. package/dist/esm/agent/api_catalog.js +199 -0
  246. package/dist/esm/agent/config.js +872 -0
  247. package/dist/esm/agent/feedback.js +317 -0
  248. package/dist/esm/agent/git.js +252 -0
  249. package/dist/esm/agent/handoff.js +177 -0
  250. package/dist/esm/agent/llm_agents_flow.js +421 -0
  251. package/dist/esm/agent/native_flow.js +175 -0
  252. package/dist/esm/agent/pipeline.js +256 -0
  253. package/dist/esm/agent/pipeline_types.js +3 -0
  254. package/dist/esm/agent/pipeline_utils.js +146 -0
  255. package/dist/esm/agent/plan.js +83 -0
  256. package/dist/esm/agent/playwright_report.js +123 -0
  257. package/dist/esm/agent/process_runner.js +83 -0
  258. package/dist/esm/agent/spec_generator.js +249 -0
  259. package/dist/esm/agent/test_path.js +20 -0
  260. package/dist/esm/agent/traceability_capture.js +310 -0
  261. package/dist/esm/agent/traceability_ingest.js +234 -0
  262. package/dist/esm/agent/types.js +3 -0
  263. package/dist/esm/agent/utils.js +138 -0
  264. package/dist/esm/agent/validation_runner.js +73 -0
  265. package/dist/esm/agentic/fix_loop.js +91 -0
  266. package/dist/esm/agentic/playwright_runner.js +161 -0
  267. package/dist/esm/agentic/runner.js +207 -0
  268. package/dist/esm/agentic/types.js +3 -0
  269. package/dist/esm/agents/coverage-evaluator.js +37 -0
  270. package/dist/esm/agents/cross-impact.js +136 -0
  271. package/dist/esm/agents/executor.js +71 -0
  272. package/dist/esm/agents/explorer.js +39 -0
  273. package/dist/esm/agents/generator.js +73 -0
  274. package/dist/esm/agents/healer.js +27 -0
  275. package/dist/esm/agents/impact-analyst.js +34 -0
  276. package/dist/esm/agents/regression-advisor.js +112 -0
  277. package/dist/esm/agents/strategist.js +88 -0
  278. package/dist/esm/agents/test-designer.js +107 -0
  279. package/dist/esm/anthropic_provider.js +326 -0
  280. package/dist/esm/api.js +143 -0
  281. package/dist/esm/base_provider.js +198 -0
  282. package/dist/esm/budget_ledger.js +58 -0
  283. package/dist/esm/cache/cached_provider.js +85 -0
  284. package/dist/esm/cache/response_cache.js +140 -0
  285. package/dist/esm/cli/commands/analyze.js +74 -0
  286. package/dist/esm/cli/commands/bootstrap.js +106 -0
  287. package/dist/esm/cli/commands/cost_report.js +112 -0
  288. package/dist/esm/cli/commands/crew.js +252 -0
  289. package/dist/esm/cli/commands/feedback.js +36 -0
  290. package/dist/esm/cli/commands/finalize.js +38 -0
  291. package/dist/esm/cli/commands/gate.js +86 -0
  292. package/dist/esm/cli/commands/generate.js +105 -0
  293. package/dist/esm/cli/commands/heal.js +57 -0
  294. package/dist/esm/cli/commands/impact.js +30 -0
  295. package/dist/esm/cli/commands/init.js +133 -0
  296. package/dist/esm/cli/commands/llm_health.js +19 -0
  297. package/dist/esm/cli/commands/plan.js +117 -0
  298. package/dist/esm/cli/commands/plan_crew.js +309 -0
  299. package/dist/esm/cli/commands/traceability.js +73 -0
  300. package/dist/esm/cli/commands/train.js +355 -0
  301. package/dist/esm/cli/defaults.js +165 -0
  302. package/dist/esm/cli/errors.js +52 -0
  303. package/dist/esm/cli/parse_args.js +251 -0
  304. package/dist/esm/cli/types.js +3 -0
  305. package/dist/esm/cli/usage.js +106 -0
  306. package/dist/esm/cli.js +192 -0
  307. package/dist/esm/crew/context.js +32 -0
  308. package/dist/esm/crew/orchestrator.js +325 -0
  309. package/dist/esm/crew/protocol.js +3 -0
  310. package/dist/esm/crew/provider.js +33 -0
  311. package/dist/esm/crew/sanitize.js +27 -0
  312. package/dist/esm/crew/types.js +3 -0
  313. package/dist/esm/crew/workflows.js +33 -0
  314. package/dist/esm/custom_provider.js +273 -0
  315. package/dist/esm/engine/ai_enrichment.js +264 -0
  316. package/dist/esm/engine/diff_loader.js +59 -0
  317. package/dist/esm/engine/impact_engine.js +291 -0
  318. package/dist/esm/engine/plan_builder.js +593 -0
  319. package/dist/esm/index.js +72 -0
  320. package/dist/esm/knowledge/api_surface.js +408 -0
  321. package/dist/esm/knowledge/cluster_utils.js +60 -0
  322. package/dist/esm/knowledge/context_loader.js +85 -0
  323. package/dist/esm/knowledge/failure_history.js +121 -0
  324. package/dist/esm/knowledge/kg_bridge.js +381 -0
  325. package/dist/esm/knowledge/kg_types.js +3 -0
  326. package/dist/esm/knowledge/route_families.js +393 -0
  327. package/dist/esm/knowledge/spec_index.js +122 -0
  328. package/dist/esm/logger.js +115 -0
  329. package/dist/esm/mcp-server.js +621 -0
  330. package/dist/esm/metrics/prometheus.js +149 -0
  331. package/dist/esm/model_router.js +59 -0
  332. package/dist/esm/ollama_provider.js +301 -0
  333. package/dist/esm/openai_provider.js +243 -0
  334. package/dist/esm/package.json +3 -0
  335. package/dist/esm/pipeline/orchestrator.js +228 -0
  336. package/dist/esm/pipeline/spec_verifier.js +75 -0
  337. package/dist/esm/pipeline/stage0_preprocess.js +102 -0
  338. package/dist/esm/pipeline/stage1_impact.js +140 -0
  339. package/dist/esm/pipeline/stage2_coverage.js +153 -0
  340. package/dist/esm/pipeline/stage3_generation.js +284 -0
  341. package/dist/esm/pipeline/stage4_heal.js +288 -0
  342. package/dist/esm/progress.js +112 -0
  343. package/dist/esm/prompts/coverage.js +57 -0
  344. package/dist/esm/prompts/cross-impact.js +53 -0
  345. package/dist/esm/prompts/generation.js +297 -0
  346. package/dist/esm/prompts/generation_profile.js +147 -0
  347. package/dist/esm/prompts/heal.js +91 -0
  348. package/dist/esm/prompts/impact.js +63 -0
  349. package/dist/esm/prompts/json_extract.js +36 -0
  350. package/dist/esm/prompts/strategist.js +61 -0
  351. package/dist/esm/prompts/test-designer.js +92 -0
  352. package/dist/esm/provider_factory.js +366 -0
  353. package/dist/esm/provider_interface.js +23 -0
  354. package/dist/esm/provider_utils.js +96 -0
  355. package/dist/esm/qa-agent/cli.js +205 -0
  356. package/dist/esm/qa-agent/orchestrator.js +120 -0
  357. package/dist/esm/qa-agent/phase1/runner.js +139 -0
  358. package/dist/esm/qa-agent/phase1/scope.js +126 -0
  359. package/dist/esm/qa-agent/phase2/agent_browser.js +95 -0
  360. package/dist/esm/qa-agent/phase2/agent_loop.js +351 -0
  361. package/dist/esm/qa-agent/phase2/exploration_state.js +97 -0
  362. package/dist/esm/qa-agent/phase2/tools.js +386 -0
  363. package/dist/esm/qa-agent/phase2/vision.js +75 -0
  364. package/dist/esm/qa-agent/phase3/feedback.js +34 -0
  365. package/dist/esm/qa-agent/phase3/reporter.js +145 -0
  366. package/dist/esm/qa-agent/phase3/spec_generator.js +62 -0
  367. package/dist/esm/qa-agent/phase3/verdict.js +66 -0
  368. package/dist/esm/qa-agent/safe_env.js +23 -0
  369. package/dist/esm/qa-agent/types.js +3 -0
  370. package/dist/esm/reporters/junit.js +86 -0
  371. package/dist/esm/reporters/reporter.js +3 -0
  372. package/dist/esm/reporters/sarif.js +132 -0
  373. package/dist/esm/resilience/circuit_breaker.js +78 -0
  374. package/dist/esm/resilience/retry.js +56 -0
  375. package/dist/esm/sanitize.js +66 -0
  376. package/dist/esm/training/enricher.js +345 -0
  377. package/dist/esm/training/kg_scanner.js +115 -0
  378. package/dist/esm/training/merger.js +204 -0
  379. package/dist/esm/training/scanner.js +923 -0
  380. package/dist/esm/training/types.js +6 -0
  381. package/dist/esm/training/validator.js +254 -0
  382. package/dist/esm/validation/guardrails.js +101 -0
  383. package/dist/esm/validation/output_schema.js +80 -0
  384. package/dist/esm/version.js +33 -0
  385. package/dist/index.d.ts +99 -0
  386. package/dist/index.d.ts.map +1 -0
  387. package/dist/index.js +169 -0
  388. package/dist/knowledge/api_surface.d.ts +37 -0
  389. package/dist/knowledge/api_surface.d.ts.map +1 -0
  390. package/dist/knowledge/api_surface.js +418 -0
  391. package/dist/knowledge/cluster_utils.d.ts +28 -0
  392. package/dist/knowledge/cluster_utils.d.ts.map +1 -0
  393. package/dist/knowledge/cluster_utils.js +67 -0
  394. package/dist/knowledge/context_loader.d.ts +13 -0
  395. package/dist/knowledge/context_loader.d.ts.map +1 -0
  396. package/dist/knowledge/context_loader.js +90 -0
  397. package/dist/knowledge/failure_history.d.ts +39 -0
  398. package/dist/knowledge/failure_history.d.ts.map +1 -0
  399. package/dist/knowledge/failure_history.js +128 -0
  400. package/dist/knowledge/kg_bridge.d.ts +31 -0
  401. package/dist/knowledge/kg_bridge.d.ts.map +1 -0
  402. package/dist/knowledge/kg_bridge.js +388 -0
  403. package/dist/knowledge/kg_types.d.ts +75 -0
  404. package/dist/knowledge/kg_types.d.ts.map +1 -0
  405. package/dist/knowledge/kg_types.js +4 -0
  406. package/dist/knowledge/route_families.d.ts +98 -0
  407. package/dist/knowledge/route_families.d.ts.map +1 -0
  408. package/dist/knowledge/route_families.js +410 -0
  409. package/dist/knowledge/spec_index.d.ts +18 -0
  410. package/dist/knowledge/spec_index.d.ts.map +1 -0
  411. package/dist/knowledge/spec_index.js +128 -0
  412. package/dist/logger.d.ts +31 -0
  413. package/dist/logger.d.ts.map +1 -0
  414. package/dist/logger.js +119 -0
  415. package/dist/mcp-server.d.ts +68 -0
  416. package/dist/mcp-server.d.ts.map +1 -0
  417. package/dist/mcp-server.js +629 -0
  418. package/dist/metrics/prometheus.d.ts +37 -0
  419. package/dist/metrics/prometheus.d.ts.map +1 -0
  420. package/dist/metrics/prometheus.js +153 -0
  421. package/dist/model_router.d.ts +28 -0
  422. package/dist/model_router.d.ts.map +1 -0
  423. package/dist/model_router.js +63 -0
  424. package/dist/ollama_provider.d.ts +65 -0
  425. package/dist/ollama_provider.d.ts.map +1 -0
  426. package/dist/ollama_provider.js +309 -0
  427. package/dist/openai_provider.d.ts +23 -0
  428. package/dist/openai_provider.d.ts.map +1 -0
  429. package/dist/openai_provider.js +251 -0
  430. package/dist/pipeline/orchestrator.d.ts +33 -0
  431. package/dist/pipeline/orchestrator.d.ts.map +1 -0
  432. package/dist/pipeline/orchestrator.js +231 -0
  433. package/dist/pipeline/spec_verifier.d.ts +20 -0
  434. package/dist/pipeline/spec_verifier.d.ts.map +1 -0
  435. package/dist/pipeline/spec_verifier.js +79 -0
  436. package/dist/pipeline/stage0_preprocess.d.ts +31 -0
  437. package/dist/pipeline/stage0_preprocess.d.ts.map +1 -0
  438. package/dist/pipeline/stage0_preprocess.js +105 -0
  439. package/dist/pipeline/stage1_impact.d.ts +19 -0
  440. package/dist/pipeline/stage1_impact.d.ts.map +1 -0
  441. package/dist/pipeline/stage1_impact.js +143 -0
  442. package/dist/pipeline/stage2_coverage.d.ts +19 -0
  443. package/dist/pipeline/stage2_coverage.d.ts.map +1 -0
  444. package/dist/pipeline/stage2_coverage.js +156 -0
  445. package/dist/pipeline/stage3_generation.d.ts +43 -0
  446. package/dist/pipeline/stage3_generation.d.ts.map +1 -0
  447. package/dist/pipeline/stage3_generation.js +287 -0
  448. package/dist/pipeline/stage4_heal.d.ts +62 -0
  449. package/dist/pipeline/stage4_heal.d.ts.map +1 -0
  450. package/dist/pipeline/stage4_heal.js +294 -0
  451. package/dist/progress.d.ts +22 -0
  452. package/dist/progress.d.ts.map +1 -0
  453. package/dist/progress.js +116 -0
  454. package/dist/prompts/coverage.d.ts +39 -0
  455. package/dist/prompts/coverage.d.ts.map +1 -0
  456. package/dist/prompts/coverage.js +61 -0
  457. package/dist/prompts/cross-impact.d.ts +23 -0
  458. package/dist/prompts/cross-impact.d.ts.map +1 -0
  459. package/dist/prompts/cross-impact.js +57 -0
  460. package/dist/prompts/generation.d.ts +25 -0
  461. package/dist/prompts/generation.d.ts.map +1 -0
  462. package/dist/prompts/generation.js +302 -0
  463. package/dist/prompts/generation_profile.d.ts +29 -0
  464. package/dist/prompts/generation_profile.d.ts.map +1 -0
  465. package/dist/prompts/generation_profile.js +151 -0
  466. package/dist/prompts/heal.d.ts +23 -0
  467. package/dist/prompts/heal.d.ts.map +1 -0
  468. package/dist/prompts/heal.js +95 -0
  469. package/dist/prompts/impact.d.ts +31 -0
  470. package/dist/prompts/impact.d.ts.map +1 -0
  471. package/dist/prompts/impact.js +67 -0
  472. package/dist/prompts/json_extract.d.ts +14 -0
  473. package/dist/prompts/json_extract.d.ts.map +1 -0
  474. package/dist/prompts/json_extract.js +39 -0
  475. package/dist/prompts/strategist.d.ts +25 -0
  476. package/dist/prompts/strategist.d.ts.map +1 -0
  477. package/dist/prompts/strategist.js +65 -0
  478. package/dist/prompts/test-designer.d.ts +35 -0
  479. package/dist/prompts/test-designer.d.ts.map +1 -0
  480. package/dist/prompts/test-designer.js +96 -0
  481. package/dist/provider_factory.d.ts +104 -0
  482. package/dist/provider_factory.d.ts.map +1 -0
  483. package/dist/provider_factory.js +371 -0
  484. package/dist/provider_interface.d.ts +365 -0
  485. package/dist/provider_interface.d.ts.map +1 -0
  486. package/dist/provider_interface.js +28 -0
  487. package/dist/provider_utils.d.ts +39 -0
  488. package/dist/provider_utils.d.ts.map +1 -0
  489. package/dist/provider_utils.js +103 -0
  490. package/dist/qa-agent/cli.d.ts +3 -0
  491. package/dist/qa-agent/cli.d.ts.map +1 -0
  492. package/dist/qa-agent/cli.js +207 -0
  493. package/dist/qa-agent/orchestrator.d.ts +3 -0
  494. package/dist/qa-agent/orchestrator.d.ts.map +1 -0
  495. package/dist/qa-agent/orchestrator.js +123 -0
  496. package/dist/qa-agent/phase1/runner.d.ts +3 -0
  497. package/dist/qa-agent/phase1/runner.d.ts.map +1 -0
  498. package/dist/qa-agent/phase1/runner.js +142 -0
  499. package/dist/qa-agent/phase1/scope.d.ts +6 -0
  500. package/dist/qa-agent/phase1/scope.d.ts.map +1 -0
  501. package/dist/qa-agent/phase1/scope.js +129 -0
  502. package/dist/qa-agent/phase2/agent_browser.d.ts +35 -0
  503. package/dist/qa-agent/phase2/agent_browser.d.ts.map +1 -0
  504. package/dist/qa-agent/phase2/agent_browser.js +99 -0
  505. package/dist/qa-agent/phase2/agent_loop.d.ts +3 -0
  506. package/dist/qa-agent/phase2/agent_loop.d.ts.map +1 -0
  507. package/dist/qa-agent/phase2/agent_loop.js +357 -0
  508. package/dist/qa-agent/phase2/exploration_state.d.ts +12 -0
  509. package/dist/qa-agent/phase2/exploration_state.d.ts.map +1 -0
  510. package/dist/qa-agent/phase2/exploration_state.js +109 -0
  511. package/dist/qa-agent/phase2/tools.d.ts +28 -0
  512. package/dist/qa-agent/phase2/tools.d.ts.map +1 -0
  513. package/dist/qa-agent/phase2/tools.js +390 -0
  514. package/dist/qa-agent/phase2/vision.d.ts +3 -0
  515. package/dist/qa-agent/phase2/vision.d.ts.map +1 -0
  516. package/dist/qa-agent/phase2/vision.js +78 -0
  517. package/dist/qa-agent/phase3/feedback.d.ts +3 -0
  518. package/dist/qa-agent/phase3/feedback.d.ts.map +1 -0
  519. package/dist/qa-agent/phase3/feedback.js +37 -0
  520. package/dist/qa-agent/phase3/reporter.d.ts +3 -0
  521. package/dist/qa-agent/phase3/reporter.d.ts.map +1 -0
  522. package/dist/qa-agent/phase3/reporter.js +148 -0
  523. package/dist/qa-agent/phase3/spec_generator.d.ts +3 -0
  524. package/dist/qa-agent/phase3/spec_generator.d.ts.map +1 -0
  525. package/dist/qa-agent/phase3/spec_generator.js +65 -0
  526. package/dist/qa-agent/phase3/verdict.d.ts +3 -0
  527. package/dist/qa-agent/phase3/verdict.d.ts.map +1 -0
  528. package/dist/qa-agent/phase3/verdict.js +69 -0
  529. package/dist/qa-agent/safe_env.d.ts +3 -0
  530. package/dist/qa-agent/safe_env.d.ts.map +1 -0
  531. package/dist/qa-agent/safe_env.js +26 -0
  532. package/dist/qa-agent/types.d.ts +130 -0
  533. package/dist/qa-agent/types.d.ts.map +1 -0
  534. package/dist/qa-agent/types.js +4 -0
  535. package/dist/reporters/junit.d.ts +6 -0
  536. package/dist/reporters/junit.d.ts.map +1 -0
  537. package/dist/reporters/junit.js +89 -0
  538. package/dist/reporters/reporter.d.ts +42 -0
  539. package/dist/reporters/reporter.d.ts.map +1 -0
  540. package/dist/reporters/reporter.js +4 -0
  541. package/dist/reporters/sarif.d.ts +7 -0
  542. package/dist/reporters/sarif.d.ts.map +1 -0
  543. package/dist/reporters/sarif.js +135 -0
  544. package/dist/resilience/circuit_breaker.d.ts +36 -0
  545. package/dist/resilience/circuit_breaker.d.ts.map +1 -0
  546. package/dist/resilience/circuit_breaker.js +82 -0
  547. package/dist/resilience/retry.d.ts +11 -0
  548. package/dist/resilience/retry.d.ts.map +1 -0
  549. package/dist/resilience/retry.js +59 -0
  550. package/dist/sanitize.d.ts +15 -0
  551. package/dist/sanitize.d.ts.map +1 -0
  552. package/dist/sanitize.js +71 -0
  553. package/dist/training/enricher.d.ts +17 -0
  554. package/dist/training/enricher.d.ts.map +1 -0
  555. package/dist/training/enricher.js +350 -0
  556. package/dist/training/kg_scanner.d.ts +13 -0
  557. package/dist/training/kg_scanner.d.ts.map +1 -0
  558. package/dist/training/kg_scanner.js +118 -0
  559. package/dist/training/merger.d.ts +15 -0
  560. package/dist/training/merger.d.ts.map +1 -0
  561. package/dist/training/merger.js +208 -0
  562. package/dist/training/scanner.d.ts +36 -0
  563. package/dist/training/scanner.d.ts.map +1 -0
  564. package/dist/training/scanner.js +932 -0
  565. package/dist/training/types.d.ts +117 -0
  566. package/dist/training/types.d.ts.map +1 -0
  567. package/dist/training/types.js +9 -0
  568. package/dist/training/validator.d.ts +21 -0
  569. package/dist/training/validator.d.ts.map +1 -0
  570. package/dist/training/validator.js +262 -0
  571. package/dist/validation/guardrails.d.ts +31 -0
  572. package/dist/validation/guardrails.d.ts.map +1 -0
  573. package/dist/validation/guardrails.js +112 -0
  574. package/dist/validation/output_schema.d.ts +67 -0
  575. package/dist/validation/output_schema.d.ts.map +1 -0
  576. package/dist/validation/output_schema.js +84 -0
  577. package/dist/version.d.ts +6 -0
  578. package/dist/version.d.ts.map +1 -0
  579. package/dist/version.js +36 -0
  580. package/package.json +126 -0
  581. package/schemas/flow-decision.schema.json +83 -0
  582. package/schemas/gap.schema.json +18 -0
  583. package/schemas/impact.schema.json +455 -0
  584. package/schemas/plan.schema.json +491 -0
  585. package/schemas/route-families.schema.json +137 -0
  586. package/schemas/subsystem-risk-map.schema.json +62 -0
  587. package/schemas/traceability-input.schema.json +122 -0
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
3
+ // See LICENSE.txt for license information.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.buildTestDesignerPrompt = buildTestDesignerPrompt;
6
+ exports.parseTestDesignerResponse = parseTestDesignerResponse;
7
+ const json_extract_js_1 = require("./json_extract.js");
8
+ const api_surface_js_1 = require("../knowledge/api_surface.js");
9
+ const sanitize_js_1 = require("../crew/sanitize.js");
10
+ function buildTestDesignerPrompt(ctx) {
11
+ const relevantClasses = ctx.apiSurface.pageObjects
12
+ .map((po) => po.className)
13
+ .filter((name) => {
14
+ const lower = name.toLowerCase();
15
+ const hints = [ctx.flow.routeFamily, ctx.flow.featureId, ...ctx.flow.userActions.join(' ').split(/\s+/)]
16
+ .filter(Boolean)
17
+ .map((s) => s.toLowerCase().replace(/[^a-z]/g, ''));
18
+ return lower.includes('page') || hints.some((h) => h.length > 3 && lower.includes(h));
19
+ })
20
+ .slice(0, 10);
21
+ const apiBlock = relevantClasses.length > 0
22
+ ? (0, api_surface_js_1.formatApiSurfaceForPrompt)(ctx.apiSurface, relevantClasses)
23
+ : 'No page objects available.';
24
+ const existingSpecsBlock = ctx.existingSpecs.length > 0
25
+ ? ctx.existingSpecs.map((s) => `- ${s.relativePath}: ${s.testTitles.join(', ')}`).join('\n')
26
+ : 'No existing specs.';
27
+ const crossImpactBlock = ctx.crossImpacts.length > 0
28
+ ? ctx.crossImpacts.map((ci) => `- ${ci.sourceFamily} → ${ci.affectedFamily}: ${ci.sharedDependency} (${ci.riskLevel})`).join('\n')
29
+ : 'None detected.';
30
+ const categories = ctx.strategy.testCategories.join(', ');
31
+ return [
32
+ `You are a senior QA engineer designing comprehensive test cases for a ${ctx.profile?.projectName || 'project'} user flow.`,
33
+ '',
34
+ `FLOW: ${ctx.flow.flowName}`,
35
+ `Flow ID: ${ctx.flow.flowId}`,
36
+ `Route Family: ${ctx.flow.routeFamily}${ctx.flow.featureId ? ` / ${ctx.flow.featureId}` : ''}`,
37
+ `Route: ${ctx.flow.specificRoute || '(not specified)'}`,
38
+ `Priority: ${ctx.strategy.priority}`,
39
+ `Approach: ${ctx.strategy.approach}`,
40
+ `User Actions: ${(0, sanitize_js_1.sanitizeForPrompt)(ctx.flow.userActions.join('; ') || 'unknown')}`,
41
+ `Evidence: ${(0, sanitize_js_1.sanitizeForPrompt)(ctx.flow.evidence)}`,
42
+ '',
43
+ `REQUIRED TEST CATEGORIES: ${categories}`,
44
+ '',
45
+ 'AVAILABLE PAGE OBJECTS:',
46
+ apiBlock,
47
+ '',
48
+ 'EXISTING SPECS (avoid duplicating these):',
49
+ existingSpecsBlock,
50
+ '',
51
+ 'CROSS-FAMILY IMPACTS:',
52
+ crossImpactBlock,
53
+ '',
54
+ 'TASK: Design structured test cases for this flow.',
55
+ '',
56
+ 'Return strict JSON only with this shape:',
57
+ '{"testDesign":{"flowId":"<id>","flowName":"<name>","testCases":[{"name":"<descriptive name>","type":"<category>","preconditions":["<state required>"],"steps":["<user action>"],"expectedOutcome":"<what should happen>","priority":"P0|P1|P2","rationale":"<why this test matters>"}]}}',
58
+ '',
59
+ 'TYPE VALUES: happy-path, edge-case, boundary, negative, state-transition, race-condition, permission, accessibility, performance',
60
+ '',
61
+ 'Rules:',
62
+ '- Every test must describe a specific USER ACTION, not an implementation detail.',
63
+ '- Steps must be concrete: "click Create Channel button" not "test channel creation".',
64
+ '- Include preconditions (logged-in role, existing data state, etc.).',
65
+ '- Reference only page objects and methods listed above.',
66
+ '- Include a mandatory rationale explaining why this specific test case matters.',
67
+ '- Do NOT duplicate tests already covered by existing specs.',
68
+ '- Maximum 15 test cases per flow.',
69
+ '- For accessibility: test keyboard navigation, screen reader support, ARIA labels.',
70
+ '- For performance: test with realistic data volumes, measure load times.',
71
+ '- For edge cases: test unicode input, max-length fields, empty states, concurrent edits.',
72
+ '',
73
+ 'FEW-SHOT EXAMPLES:',
74
+ '',
75
+ 'Edge case example:',
76
+ '```json',
77
+ '{"name":"channel creation with unicode characters and max-length name","type":"edge-case","preconditions":["logged in as team member","team has < 1000 channels"],"steps":["open create channel dialog","enter 64-character name with emoji and CJK characters","click Create"],"expectedOutcome":"channel created successfully, name renders correctly in sidebar and header","priority":"P1","rationale":"catches encoding issues in channel name storage and rendering"}',
78
+ '```',
79
+ '',
80
+ 'Permission example:',
81
+ '```json',
82
+ '{"name":"guest user cannot archive a public channel","type":"permission","preconditions":["logged in as guest user","guest has access to public channel"],"steps":["open channel header menu","look for Archive Channel option"],"expectedOutcome":"Archive Channel option is not visible in the menu","priority":"P0","rationale":"permission escalation bug — guests archiving channels could disrupt entire teams"}',
83
+ '```',
84
+ '',
85
+ 'Accessibility example:',
86
+ '```json',
87
+ '{"name":"keyboard navigation through channel switcher results","type":"accessibility","preconditions":["logged in","channel switcher open via Ctrl+K"],"steps":["type partial channel name","press ArrowDown to navigate results","press Enter to select"],"expectedOutcome":"focus moves visually and via aria-activedescendant, selected channel opens","priority":"P1","rationale":"screen reader users rely on keyboard navigation — broken focus management makes the app unusable"}',
88
+ '```',
89
+ ].join('\n');
90
+ }
91
+ function parseTestDesignerResponse(text) {
92
+ return (0, json_extract_js_1.extractJsonFromResponse)(text, (obj) => {
93
+ const r = obj;
94
+ return r?.testDesign?.testCases != null && Array.isArray(r.testDesign.testCases);
95
+ });
96
+ }
@@ -0,0 +1,104 @@
1
+ import type { LLMProvider, ProviderConfig } from './provider_interface.js';
2
+ /**
3
+ * LLM Provider Factory
4
+ *
5
+ * Creates and configures LLM providers based on configuration.
6
+ * Supports multiple strategies:
7
+ * - Single provider (Ollama, Anthropic, etc.)
8
+ * - Hybrid provider (free primary + premium fallback)
9
+ * - Auto-selection based on environment
10
+ *
11
+ * Usage:
12
+ *
13
+ * // Create single provider
14
+ * const provider = LLMProviderFactory.create({
15
+ * type: 'ollama',
16
+ * config: { model: 'deepseek-r1:7b' }
17
+ * });
18
+ *
19
+ * // Create hybrid provider
20
+ * const provider = LLMProviderFactory.createHybrid({
21
+ * primary: { type: 'ollama', config: { model: 'deepseek-r1:7b' } },
22
+ * fallback: { type: 'anthropic', config: { apiKey: '...' } },
23
+ * useFallbackFor: ['vision']
24
+ * });
25
+ *
26
+ * // Auto-detect from environment
27
+ * const provider = LLMProviderFactory.createFromEnv();
28
+ */
29
+ export declare class LLMProviderFactory {
30
+ /**
31
+ * Create a single LLM provider
32
+ */
33
+ static create(config: ProviderConfig): LLMProvider;
34
+ /**
35
+ * Create a hybrid provider (free primary + premium fallback)
36
+ *
37
+ * Use cases:
38
+ * - Most operations use free Ollama
39
+ * - Vision tasks fall back to Claude
40
+ * - Complex diagnosis falls back to Claude
41
+ *
42
+ * This gives best cost/quality balance:
43
+ * - ~$20/month instead of $80/month (75% cost reduction)
44
+ * - Still get premium quality for vision and complex tasks
45
+ */
46
+ static createHybrid(config: HybridConfig): LLMProvider;
47
+ /**
48
+ * Auto-detect provider from environment variables
49
+ *
50
+ * Priority:
51
+ * 1. LLM_PROVIDER env var (ollama, anthropic, openai)
52
+ * 2. ANTHROPIC_API_KEY exists → Anthropic
53
+ * 3. OPENAI_API_KEY exists → OpenAI
54
+ * 4. Ollama running locally → Ollama
55
+ * 5. Error (no provider available)
56
+ */
57
+ static createFromEnv(): Promise<LLMProvider>;
58
+ /**
59
+ * Create provider from an explicit preference when supplied, otherwise
60
+ * fall back to environment auto-detection.
61
+ */
62
+ static createFromPreference(providerPreference?: string): Promise<LLMProvider>;
63
+ /**
64
+ * Create provider from simple string format
65
+ *
66
+ * Examples:
67
+ * - "ollama" → Ollama with defaults
68
+ * - "ollama:deepseek-r1:14b" → Ollama with specific model
69
+ * - "anthropic" → Anthropic with env API key
70
+ * - "anthropic:claude-opus-4-5" → Anthropic with specific model
71
+ * - "openai" → OpenAI with env API key
72
+ * - "openai:gpt-4" → OpenAI with specific model
73
+ */
74
+ static createFromString(providerString: string): LLMProvider;
75
+ }
76
+ /**
77
+ * Hybrid Provider Configuration
78
+ */
79
+ export interface HybridConfig {
80
+ /**
81
+ * Primary provider (used for most operations)
82
+ * Typically a free provider like Ollama
83
+ */
84
+ primary: ProviderConfig;
85
+ /**
86
+ * Fallback provider (used for specific capabilities)
87
+ * Typically a premium provider like Anthropic
88
+ */
89
+ fallback: ProviderConfig;
90
+ /**
91
+ * When to use fallback provider
92
+ * Options: 'vision', 'complex-diagnosis', 'high-confidence-needed'
93
+ */
94
+ useFallbackFor?: Array<'vision' | 'complex-diagnosis' | 'high-confidence-needed'>;
95
+ }
96
+ /**
97
+ * Helper to validate provider setup
98
+ */
99
+ export declare function validateProviderSetup(provider: LLMProvider): Promise<{
100
+ valid: boolean;
101
+ message: string;
102
+ capabilities: string[];
103
+ }>;
104
+ //# sourceMappingURL=provider_factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider_factory.d.ts","sourceRoot":"","sources":["../src/provider_factory.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAKR,WAAW,EAIX,cAAc,EAEjB,MAAM,yBAAyB,CAAC;AAGjC;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,kBAAkB;IAC3B;;OAEG;IACH,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,WAAW;IAmBlD;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,WAAW;IAWtD;;;;;;;;;OASG;WACU,aAAa,IAAI,OAAO,CAAC,WAAW,CAAC;IAyElD;;;OAGG;WACU,oBAAoB,CAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IASpF;;;;;;;;;;OAUG;IACH,MAAM,CAAC,gBAAgB,CAAC,cAAc,EAAE,MAAM,GAAG,WAAW;CAkC/D;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IACzB;;;OAGG;IACH,OAAO,EAAE,cAAc,CAAC;IAExB;;;OAGG;IACH,QAAQ,EAAE,cAAc,CAAC;IAEzB;;;OAGG;IACH,cAAc,CAAC,EAAE,KAAK,CAAC,QAAQ,GAAG,mBAAmB,GAAG,wBAAwB,CAAC,CAAC;CACrF;AAoKD;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,QAAQ,EAAE,WAAW,GAAG,OAAO,CAAC;IACxE,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;CAC1B,CAAC,CAsCD"}
@@ -0,0 +1,371 @@
1
+ "use strict";
2
+ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
3
+ // See LICENSE.txt for license information.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.LLMProviderFactory = void 0;
6
+ exports.validateProviderSetup = validateProviderSetup;
7
+ const anthropic_provider_js_1 = require("./anthropic_provider.js");
8
+ const logger_js_1 = require("./logger.js");
9
+ const custom_provider_js_1 = require("./custom_provider.js");
10
+ const ollama_provider_js_1 = require("./ollama_provider.js");
11
+ const openai_provider_js_1 = require("./openai_provider.js");
12
+ const provider_interface_js_1 = require("./provider_interface.js");
13
+ /**
14
+ * LLM Provider Factory
15
+ *
16
+ * Creates and configures LLM providers based on configuration.
17
+ * Supports multiple strategies:
18
+ * - Single provider (Ollama, Anthropic, etc.)
19
+ * - Hybrid provider (free primary + premium fallback)
20
+ * - Auto-selection based on environment
21
+ *
22
+ * Usage:
23
+ *
24
+ * // Create single provider
25
+ * const provider = LLMProviderFactory.create({
26
+ * type: 'ollama',
27
+ * config: { model: 'deepseek-r1:7b' }
28
+ * });
29
+ *
30
+ * // Create hybrid provider
31
+ * const provider = LLMProviderFactory.createHybrid({
32
+ * primary: { type: 'ollama', config: { model: 'deepseek-r1:7b' } },
33
+ * fallback: { type: 'anthropic', config: { apiKey: '...' } },
34
+ * useFallbackFor: ['vision']
35
+ * });
36
+ *
37
+ * // Auto-detect from environment
38
+ * const provider = LLMProviderFactory.createFromEnv();
39
+ */
40
+ class LLMProviderFactory {
41
+ /**
42
+ * Create a single LLM provider
43
+ */
44
+ static create(config) {
45
+ switch (config.type) {
46
+ case 'ollama':
47
+ return new ollama_provider_js_1.OllamaProvider(config.config);
48
+ case 'anthropic':
49
+ return new anthropic_provider_js_1.AnthropicProvider(config.config);
50
+ case 'openai':
51
+ return new openai_provider_js_1.OpenAIProvider(config.config);
52
+ case 'custom':
53
+ return new custom_provider_js_1.CustomProvider(config.config);
54
+ default:
55
+ throw new Error(`Unknown provider type: ${config.type}`);
56
+ }
57
+ }
58
+ /**
59
+ * Create a hybrid provider (free primary + premium fallback)
60
+ *
61
+ * Use cases:
62
+ * - Most operations use free Ollama
63
+ * - Vision tasks fall back to Claude
64
+ * - Complex diagnosis falls back to Claude
65
+ *
66
+ * This gives best cost/quality balance:
67
+ * - ~$20/month instead of $80/month (75% cost reduction)
68
+ * - Still get premium quality for vision and complex tasks
69
+ */
70
+ static createHybrid(config) {
71
+ const primary = this.create(config.primary);
72
+ const fallback = this.create(config.fallback);
73
+ return new HybridProvider({
74
+ primary,
75
+ fallback,
76
+ useFallbackFor: config.useFallbackFor || ['vision'],
77
+ });
78
+ }
79
+ /**
80
+ * Auto-detect provider from environment variables
81
+ *
82
+ * Priority:
83
+ * 1. LLM_PROVIDER env var (ollama, anthropic, openai)
84
+ * 2. ANTHROPIC_API_KEY exists → Anthropic
85
+ * 3. OPENAI_API_KEY exists → OpenAI
86
+ * 4. Ollama running locally → Ollama
87
+ * 5. Error (no provider available)
88
+ */
89
+ static async createFromEnv() {
90
+ const providerType = process.env.LLM_PROVIDER?.toLowerCase();
91
+ const normalizedProviderType = providerType?.trim().toLowerCase();
92
+ if (normalizedProviderType && !['ollama', 'openai', 'anthropic', 'auto'].includes(normalizedProviderType)) {
93
+ throw new Error(`Unknown LLM_PROVIDER value "${providerType}". Expected one of: ollama, openai, anthropic, auto`);
94
+ }
95
+ if (normalizedProviderType === 'ollama') {
96
+ return new ollama_provider_js_1.OllamaProvider({
97
+ baseUrl: process.env.OLLAMA_BASE_URL || 'http://localhost:11434/v1',
98
+ model: process.env.OLLAMA_MODEL || 'deepseek-r1:7b',
99
+ });
100
+ }
101
+ if (normalizedProviderType === 'openai') {
102
+ if (!process.env.OPENAI_API_KEY) {
103
+ throw new Error('OPENAI_API_KEY environment variable is required for OpenAI provider');
104
+ }
105
+ return new openai_provider_js_1.OpenAIProvider({
106
+ apiKey: process.env.OPENAI_API_KEY,
107
+ model: process.env.OPENAI_MODEL || 'gpt-4',
108
+ baseUrl: process.env.OPENAI_BASE_URL,
109
+ organizationId: process.env.OPENAI_ORG_ID,
110
+ });
111
+ }
112
+ if (normalizedProviderType === 'anthropic') {
113
+ if (!process.env.ANTHROPIC_API_KEY) {
114
+ throw new Error('ANTHROPIC_API_KEY environment variable is required for Anthropic provider');
115
+ }
116
+ return new anthropic_provider_js_1.AnthropicProvider({
117
+ apiKey: process.env.ANTHROPIC_API_KEY,
118
+ model: process.env.ANTHROPIC_MODEL || 'claude-sonnet-4-5-20250929',
119
+ });
120
+ }
121
+ if (process.env.ANTHROPIC_API_KEY) {
122
+ return new anthropic_provider_js_1.AnthropicProvider({
123
+ apiKey: process.env.ANTHROPIC_API_KEY,
124
+ model: process.env.ANTHROPIC_MODEL || 'claude-sonnet-4-5-20250929',
125
+ });
126
+ }
127
+ if (process.env.OPENAI_API_KEY) {
128
+ return new openai_provider_js_1.OpenAIProvider({
129
+ apiKey: process.env.OPENAI_API_KEY,
130
+ model: process.env.OPENAI_MODEL || 'gpt-4',
131
+ baseUrl: process.env.OPENAI_BASE_URL,
132
+ organizationId: process.env.OPENAI_ORG_ID,
133
+ });
134
+ }
135
+ // Try Ollama as default
136
+ const ollama = new ollama_provider_js_1.OllamaProvider({});
137
+ const health = await ollama.checkHealth();
138
+ if (health.healthy) {
139
+ logger_js_1.logger.info('Auto-detected Ollama provider (free, local)');
140
+ return ollama;
141
+ }
142
+ throw new Error('No LLM provider available. Please either:\n' +
143
+ '1. Install Ollama: curl -fsSL https://ollama.com/install.sh | sh\n' +
144
+ '2. Set ANTHROPIC_API_KEY environment variable\n' +
145
+ '3. Set OPENAI_API_KEY environment variable\n' +
146
+ '4. Set LLM_PROVIDER environment variable');
147
+ }
148
+ /**
149
+ * Create provider from an explicit preference when supplied, otherwise
150
+ * fall back to environment auto-detection.
151
+ */
152
+ static async createFromPreference(providerPreference) {
153
+ const normalized = providerPreference?.trim().toLowerCase();
154
+ if (!normalized || normalized === 'auto') {
155
+ return this.createFromEnv();
156
+ }
157
+ return this.createFromString(normalized);
158
+ }
159
+ /**
160
+ * Create provider from simple string format
161
+ *
162
+ * Examples:
163
+ * - "ollama" → Ollama with defaults
164
+ * - "ollama:deepseek-r1:14b" → Ollama with specific model
165
+ * - "anthropic" → Anthropic with env API key
166
+ * - "anthropic:claude-opus-4-5" → Anthropic with specific model
167
+ * - "openai" → OpenAI with env API key
168
+ * - "openai:gpt-4" → OpenAI with specific model
169
+ */
170
+ static createFromString(providerString) {
171
+ const [type, ...modelParts] = providerString.split(':');
172
+ const model = modelParts.join(':');
173
+ switch (type.toLowerCase()) {
174
+ case 'ollama':
175
+ return new ollama_provider_js_1.OllamaProvider({
176
+ model: model || 'deepseek-r1:7b',
177
+ });
178
+ case 'anthropic':
179
+ if (!process.env.ANTHROPIC_API_KEY) {
180
+ throw new Error('ANTHROPIC_API_KEY environment variable is required');
181
+ }
182
+ return new anthropic_provider_js_1.AnthropicProvider({
183
+ apiKey: process.env.ANTHROPIC_API_KEY,
184
+ model: model || 'claude-sonnet-4-5-20250929',
185
+ });
186
+ case 'openai':
187
+ if (!process.env.OPENAI_API_KEY) {
188
+ throw new Error('OPENAI_API_KEY environment variable is required');
189
+ }
190
+ return new openai_provider_js_1.OpenAIProvider({
191
+ apiKey: process.env.OPENAI_API_KEY,
192
+ model: model || 'gpt-4',
193
+ baseUrl: process.env.OPENAI_BASE_URL,
194
+ organizationId: process.env.OPENAI_ORG_ID,
195
+ });
196
+ default:
197
+ throw new Error(`Unknown provider type: ${type}`);
198
+ }
199
+ }
200
+ }
201
+ exports.LLMProviderFactory = LLMProviderFactory;
202
+ /**
203
+ * Hybrid Provider - Mix free and premium providers
204
+ *
205
+ * Strategy:
206
+ * - Use free provider (Ollama) for most operations (~80% of requests)
207
+ * - Fall back to premium (Claude) only when needed (~20% of requests)
208
+ *
209
+ * Cost savings example:
210
+ * - Pure Claude: $80/month
211
+ * - Pure Ollama: $0/month but no vision
212
+ * - Hybrid: $20/month (75% cost reduction, keeps vision)
213
+ */
214
+ class HybridProvider {
215
+ constructor(config) {
216
+ this.name = 'hybrid';
217
+ this.capabilities = {
218
+ // Report combined capabilities
219
+ vision: true, // Fallback provides vision
220
+ streaming: true, // Both support streaming
221
+ maxTokens: 0, // Will be set in constructor
222
+ costPer1MInputTokens: 0, // Variable cost
223
+ costPer1MOutputTokens: 0, // Variable cost
224
+ supportsTools: true,
225
+ supportsPromptCaching: false,
226
+ typicalResponseTimeMs: 0, // Variable
227
+ };
228
+ this.primary = config.primary;
229
+ this.fallback = config.fallback;
230
+ this.useFallbackFor = new Set(config.useFallbackFor);
231
+ // Set combined capabilities
232
+ this.capabilities.maxTokens = Math.max(this.primary.capabilities.maxTokens, this.fallback.capabilities.maxTokens);
233
+ this.capabilities.typicalResponseTimeMs = this.primary.capabilities.typicalResponseTimeMs;
234
+ }
235
+ async generateText(prompt, options) {
236
+ // Use primary for text generation (free)
237
+ logger_js_1.logger.debug(`[Hybrid] Using ${this.primary.name} for text generation`);
238
+ return await this.primary.generateText(prompt, options);
239
+ }
240
+ async analyzeImage(images, prompt, options) {
241
+ // Check if vision is a fallback trigger
242
+ if (this.useFallbackFor.has('vision')) {
243
+ // Use fallback if primary doesn't support vision
244
+ if (!this.primary.capabilities.vision) {
245
+ logger_js_1.logger.debug(`[Hybrid] Using ${this.fallback.name} for vision analysis (primary doesn't support vision)`);
246
+ if (!this.fallback.analyzeImage) {
247
+ throw new provider_interface_js_1.UnsupportedCapabilityError(this.name, 'vision');
248
+ }
249
+ return await this.fallback.analyzeImage(images, prompt, options);
250
+ }
251
+ }
252
+ // Try primary first
253
+ if (this.primary.analyzeImage) {
254
+ logger_js_1.logger.debug(`[Hybrid] Using ${this.primary.name} for vision analysis`);
255
+ return await this.primary.analyzeImage(images, prompt, options);
256
+ }
257
+ throw new provider_interface_js_1.UnsupportedCapabilityError(this.name, 'vision');
258
+ }
259
+ async *streamText(prompt, options) {
260
+ // Use primary for streaming (free)
261
+ if (!this.primary.streamText) {
262
+ throw new provider_interface_js_1.UnsupportedCapabilityError(this.primary.name, 'streaming');
263
+ }
264
+ logger_js_1.logger.debug(`[Hybrid] Using ${this.primary.name} for streaming`);
265
+ yield* this.primary.streamText(prompt, options);
266
+ }
267
+ getUsageStats() {
268
+ const primaryStats = this.primary.getUsageStats();
269
+ const fallbackStats = this.fallback.getUsageStats();
270
+ // Combine stats
271
+ const totalRequests = primaryStats.requestCount + fallbackStats.requestCount;
272
+ return {
273
+ requestCount: totalRequests,
274
+ totalInputTokens: primaryStats.totalInputTokens + fallbackStats.totalInputTokens,
275
+ totalOutputTokens: primaryStats.totalOutputTokens + fallbackStats.totalOutputTokens,
276
+ totalTokens: primaryStats.totalTokens + fallbackStats.totalTokens,
277
+ totalCost: primaryStats.totalCost + fallbackStats.totalCost,
278
+ averageResponseTimeMs: totalRequests > 0
279
+ ? (primaryStats.averageResponseTimeMs * primaryStats.requestCount +
280
+ fallbackStats.averageResponseTimeMs * fallbackStats.requestCount) / totalRequests
281
+ : 0,
282
+ failedRequests: primaryStats.failedRequests + fallbackStats.failedRequests,
283
+ startTime: new Date(Math.min(primaryStats.startTime.getTime(), fallbackStats.startTime.getTime())),
284
+ lastUpdated: new Date(Math.max(primaryStats.lastUpdated.getTime(), fallbackStats.lastUpdated.getTime())),
285
+ };
286
+ }
287
+ resetUsageStats() {
288
+ this.primary.resetUsageStats();
289
+ this.fallback.resetUsageStats();
290
+ }
291
+ async checkHealth() {
292
+ const primaryHealth = await this.primary.checkHealth();
293
+ if (primaryHealth.healthy) {
294
+ return { healthy: true, message: `${this.primary.name}: ${primaryHealth.message}` };
295
+ }
296
+ const fallbackHealth = await this.fallback.checkHealth();
297
+ if (fallbackHealth.healthy) {
298
+ return {
299
+ healthy: true,
300
+ message: `${this.primary.name} unhealthy (${primaryHealth.message}); fallback ${this.fallback.name}: ${fallbackHealth.message}`,
301
+ };
302
+ }
303
+ return {
304
+ healthy: false,
305
+ message: `${this.primary.name} unhealthy (${primaryHealth.message}); fallback ${this.fallback.name} unhealthy (${fallbackHealth.message})`,
306
+ };
307
+ }
308
+ /**
309
+ * Get breakdown of which provider was used for what
310
+ */
311
+ getProviderBreakdown() {
312
+ const primaryStats = this.primary.getUsageStats();
313
+ const fallbackStats = this.fallback.getUsageStats();
314
+ // Calculate what it would cost if we used only fallback
315
+ const totalRequests = primaryStats.requestCount + fallbackStats.requestCount;
316
+ const fallbackCostPerRequest = fallbackStats.requestCount > 0 ? fallbackStats.totalCost / fallbackStats.requestCount : 0;
317
+ const hypotheticalFullCost = totalRequests * fallbackCostPerRequest;
318
+ const actualCost = primaryStats.totalCost + fallbackStats.totalCost;
319
+ const savings = hypotheticalFullCost - actualCost;
320
+ const savingsPercent = hypotheticalFullCost > 0 ? (savings / hypotheticalFullCost) * 100 : 0;
321
+ return {
322
+ primary: {
323
+ name: this.primary.name,
324
+ stats: primaryStats,
325
+ },
326
+ fallback: {
327
+ name: this.fallback.name,
328
+ stats: fallbackStats,
329
+ },
330
+ costSavings: `$${savings.toFixed(2)} saved (${savingsPercent.toFixed(1)}% reduction)`,
331
+ };
332
+ }
333
+ }
334
+ /**
335
+ * Helper to validate provider setup
336
+ */
337
+ async function validateProviderSetup(provider) {
338
+ const capabilities = [];
339
+ if (provider.capabilities.vision) {
340
+ capabilities.push('✓ Vision support (screenshot comparison)');
341
+ }
342
+ else {
343
+ capabilities.push('✗ No vision support');
344
+ }
345
+ if (provider.capabilities.streaming) {
346
+ capabilities.push('✓ Streaming responses');
347
+ }
348
+ if (provider.capabilities.supportsTools) {
349
+ capabilities.push('✓ Function calling');
350
+ }
351
+ capabilities.push(`✓ ${provider.capabilities.maxTokens.toLocaleString()} token context window`);
352
+ capabilities.push(`✓ Cost: $${provider.capabilities.costPer1MOutputTokens}/1M tokens`);
353
+ try {
354
+ // Try a simple request
355
+ const response = await provider.generateText('Say "OK" if you can read this', {
356
+ maxTokens: 10,
357
+ });
358
+ return {
359
+ valid: response.text.length > 0,
360
+ message: `Provider '${provider.name}' is working correctly`,
361
+ capabilities,
362
+ };
363
+ }
364
+ catch (error) {
365
+ return {
366
+ valid: false,
367
+ message: `Provider '${provider.name}' validation failed: ${error instanceof Error ? error.message : String(error)}`,
368
+ capabilities,
369
+ };
370
+ }
371
+ }