igel-qe-core 1.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 (394) hide show
  1. package/dist/cli/index.js +38 -0
  2. package/dist/mcp/server.js +104 -0
  3. package/knowledge_base/__init__.py +3 -0
  4. package/knowledge_base/__pycache__/__init__.cpython-314.pyc +0 -0
  5. package/knowledge_base/__pycache__/__init__.cpython-37.pyc +0 -0
  6. package/knowledge_base/__pycache__/__init__.cpython-38.pyc +0 -0
  7. package/knowledge_base/__pycache__/confidence.cpython-37.pyc +0 -0
  8. package/knowledge_base/__pycache__/config.cpython-314.pyc +0 -0
  9. package/knowledge_base/__pycache__/config.cpython-37.pyc +0 -0
  10. package/knowledge_base/__pycache__/config.cpython-38.pyc +0 -0
  11. package/knowledge_base/__pycache__/context_fusion.cpython-314.pyc +0 -0
  12. package/knowledge_base/__pycache__/context_fusion.cpython-37.pyc +0 -0
  13. package/knowledge_base/__pycache__/feedback_analytics.cpython-37.pyc +0 -0
  14. package/knowledge_base/__pycache__/feedback_applier.cpython-37.pyc +0 -0
  15. package/knowledge_base/__pycache__/feedback_cli.cpython-37.pyc +0 -0
  16. package/knowledge_base/__pycache__/feedback_curator.cpython-37.pyc +0 -0
  17. package/knowledge_base/__pycache__/feedback_handler.cpython-37.pyc +0 -0
  18. package/knowledge_base/__pycache__/generate.cpython-37.pyc +0 -0
  19. package/knowledge_base/__pycache__/generate_qcapps134.cpython-37.pyc +0 -0
  20. package/knowledge_base/__pycache__/input_classifier.cpython-314.pyc +0 -0
  21. package/knowledge_base/__pycache__/input_classifier.cpython-37.pyc +0 -0
  22. package/knowledge_base/__pycache__/kg_extractor.cpython-37.pyc +0 -0
  23. package/knowledge_base/__pycache__/knowledge_graph.cpython-314.pyc +0 -0
  24. package/knowledge_base/__pycache__/knowledge_graph.cpython-37.pyc +0 -0
  25. package/knowledge_base/__pycache__/manual_tc_parser.cpython-314.pyc +0 -0
  26. package/knowledge_base/__pycache__/manual_tc_parser.cpython-37.pyc +0 -0
  27. package/knowledge_base/__pycache__/precedence.cpython-37.pyc +0 -0
  28. package/knowledge_base/__pycache__/prompts.cpython-314.pyc +0 -0
  29. package/knowledge_base/__pycache__/prompts.cpython-37.pyc +0 -0
  30. package/knowledge_base/__pycache__/reranker.cpython-314.pyc +0 -0
  31. package/knowledge_base/__pycache__/reranker.cpython-37.pyc +0 -0
  32. package/knowledge_base/__pycache__/retrieval_debug.cpython-314.pyc +0 -0
  33. package/knowledge_base/__pycache__/retrieval_debug.cpython-37.pyc +0 -0
  34. package/knowledge_base/__pycache__/retriever.cpython-314.pyc +0 -0
  35. package/knowledge_base/__pycache__/retriever.cpython-37.pyc +0 -0
  36. package/knowledge_base/__pycache__/server.cpython-37.pyc +0 -0
  37. package/knowledge_base/__pycache__/tc_transformer.cpython-314.pyc +0 -0
  38. package/knowledge_base/__pycache__/tc_transformer.cpython-37.pyc +0 -0
  39. package/knowledge_base/__pycache__/test_generator.cpython-314.pyc +0 -0
  40. package/knowledge_base/__pycache__/test_generator.cpython-37.pyc +0 -0
  41. package/knowledge_base/agents/__init__.py +6 -0
  42. package/knowledge_base/agents/__pycache__/__init__.cpython-37.pyc +0 -0
  43. package/knowledge_base/agents/__pycache__/__init__.cpython-38.pyc +0 -0
  44. package/knowledge_base/agents/__pycache__/fusion_agent.cpython-37.pyc +0 -0
  45. package/knowledge_base/agents/__pycache__/fusion_agent.cpython-38.pyc +0 -0
  46. package/knowledge_base/agents/__pycache__/graph.cpython-37.pyc +0 -0
  47. package/knowledge_base/agents/__pycache__/graph.cpython-38.pyc +0 -0
  48. package/knowledge_base/agents/__pycache__/healing_agent.cpython-37.pyc +0 -0
  49. package/knowledge_base/agents/__pycache__/intent_agent.cpython-37.pyc +0 -0
  50. package/knowledge_base/agents/__pycache__/intent_agent.cpython-38.pyc +0 -0
  51. package/knowledge_base/agents/__pycache__/kg_agent.cpython-37.pyc +0 -0
  52. package/knowledge_base/agents/__pycache__/kg_agent.cpython-38.pyc +0 -0
  53. package/knowledge_base/agents/__pycache__/memory_agent.cpython-37.pyc +0 -0
  54. package/knowledge_base/agents/__pycache__/memory_agent.cpython-38.pyc +0 -0
  55. package/knowledge_base/agents/__pycache__/rca_agent.cpython-37.pyc +0 -0
  56. package/knowledge_base/agents/__pycache__/reflection_agent.cpython-37.pyc +0 -0
  57. package/knowledge_base/agents/__pycache__/reflection_agent.cpython-38.pyc +0 -0
  58. package/knowledge_base/agents/__pycache__/regression_agent.cpython-37.pyc +0 -0
  59. package/knowledge_base/agents/__pycache__/retrieval_agent.cpython-37.pyc +0 -0
  60. package/knowledge_base/agents/__pycache__/retrieval_agent.cpython-38.pyc +0 -0
  61. package/knowledge_base/agents/__pycache__/script_agent.cpython-37.pyc +0 -0
  62. package/knowledge_base/agents/__pycache__/script_agent.cpython-38.pyc +0 -0
  63. package/knowledge_base/agents/__pycache__/state.cpython-37.pyc +0 -0
  64. package/knowledge_base/agents/__pycache__/state.cpython-38.pyc +0 -0
  65. package/knowledge_base/agents/__pycache__/temporal_agent.cpython-37.pyc +0 -0
  66. package/knowledge_base/agents/__pycache__/temporal_agent.cpython-38.pyc +0 -0
  67. package/knowledge_base/agents/__pycache__/validation_agent.cpython-37.pyc +0 -0
  68. package/knowledge_base/agents/__pycache__/validation_agent.cpython-38.pyc +0 -0
  69. package/knowledge_base/agents/automation_design_agent.py +123 -0
  70. package/knowledge_base/agents/code_intelligence_agent.py +147 -0
  71. package/knowledge_base/agents/confidence_agent.py +94 -0
  72. package/knowledge_base/agents/execution_validation_agent.py +129 -0
  73. package/knowledge_base/agents/feedback_agent.py +56 -0
  74. package/knowledge_base/agents/fusion_agent.py +113 -0
  75. package/knowledge_base/agents/graph.py +152 -0
  76. package/knowledge_base/agents/healing_agent.py +62 -0
  77. package/knowledge_base/agents/intent_agent.py +76 -0
  78. package/knowledge_base/agents/kg_agent.py +91 -0
  79. package/knowledge_base/agents/memory_agent.py +62 -0
  80. package/knowledge_base/agents/rca_agent.py +53 -0
  81. package/knowledge_base/agents/reflection_agent.py +62 -0
  82. package/knowledge_base/agents/regression_agent.py +81 -0
  83. package/knowledge_base/agents/requirement_agent.py +71 -0
  84. package/knowledge_base/agents/retrieval_agent.py +66 -0
  85. package/knowledge_base/agents/scenario_agent.py +81 -0
  86. package/knowledge_base/agents/script_agent.py +121 -0
  87. package/knowledge_base/agents/script_generator_agent.py +77 -0
  88. package/knowledge_base/agents/state.py +53 -0
  89. package/knowledge_base/agents/temporal_agent.py +48 -0
  90. package/knowledge_base/agents/testcase_agent.py +111 -0
  91. package/knowledge_base/agents/validation_agent.py +49 -0
  92. package/knowledge_base/agents/workflow_engine.py +87 -0
  93. package/knowledge_base/alembic/README.md +104 -0
  94. package/knowledge_base/alembic/__pycache__/env.cpython-37.pyc +0 -0
  95. package/knowledge_base/alembic/__pycache__/env.cpython-38.pyc +0 -0
  96. package/knowledge_base/alembic/env.py +76 -0
  97. package/knowledge_base/alembic/script.py.mako +5 -0
  98. package/knowledge_base/alembic/versions/.gitkeep +26 -0
  99. package/knowledge_base/alembic/versions/001_phase0_feedback.py +122 -0
  100. package/knowledge_base/alembic/versions/002_feedback_promotions.py +60 -0
  101. package/knowledge_base/alembic/versions/003_enterprise_hardening.py +74 -0
  102. package/knowledge_base/alembic/versions/__pycache__/001_phase0_feedback.cpython-37.pyc +0 -0
  103. package/knowledge_base/alembic/versions/__pycache__/001_phase0_feedback.cpython-38.pyc +0 -0
  104. package/knowledge_base/alembic/versions/__pycache__/002_feedback_promotions.cpython-37.pyc +0 -0
  105. package/knowledge_base/alembic/versions/__pycache__/002_feedback_promotions.cpython-38.pyc +0 -0
  106. package/knowledge_base/api/__init__.py +1 -0
  107. package/knowledge_base/api/__pycache__/__init__.cpython-37.pyc +0 -0
  108. package/knowledge_base/api/__pycache__/__init__.cpython-38.pyc +0 -0
  109. package/knowledge_base/api/__pycache__/middleware.cpython-38.pyc +0 -0
  110. package/knowledge_base/api/__pycache__/server.cpython-37.pyc +0 -0
  111. package/knowledge_base/api/__pycache__/server.cpython-38.pyc +0 -0
  112. package/knowledge_base/api/middleware.py +78 -0
  113. package/knowledge_base/api/server.py +778 -0
  114. package/knowledge_base/chunking/__init__.py +0 -0
  115. package/knowledge_base/chunking/__pycache__/__init__.cpython-37.pyc +0 -0
  116. package/knowledge_base/chunking/__pycache__/__init__.cpython-38.pyc +0 -0
  117. package/knowledge_base/chunking/__pycache__/chunker.cpython-37.pyc +0 -0
  118. package/knowledge_base/chunking/__pycache__/chunker.cpython-38.pyc +0 -0
  119. package/knowledge_base/chunking/__pycache__/validators.cpython-37.pyc +0 -0
  120. package/knowledge_base/chunking/__pycache__/validators.cpython-38.pyc +0 -0
  121. package/knowledge_base/chunking/chunker.py +402 -0
  122. package/knowledge_base/chunking/validators.py +144 -0
  123. package/knowledge_base/cli/__init__.py +1 -0
  124. package/knowledge_base/cli/__pycache__/__init__.cpython-37.pyc +0 -0
  125. package/knowledge_base/cli/__pycache__/__init__.cpython-38.pyc +0 -0
  126. package/knowledge_base/cli/__pycache__/feedback_cli.cpython-37.pyc +0 -0
  127. package/knowledge_base/cli/__pycache__/feedback_cli.cpython-38.pyc +0 -0
  128. package/knowledge_base/cli/__pycache__/generate.cpython-37.pyc +0 -0
  129. package/knowledge_base/cli/__pycache__/generate.cpython-38.pyc +0 -0
  130. package/knowledge_base/cli/__pycache__/generate_qcapps134.cpython-37.pyc +0 -0
  131. package/knowledge_base/cli/feedback_cli.py +121 -0
  132. package/knowledge_base/cli/generate.py +308 -0
  133. package/knowledge_base/cli/generate_qcapps134.py +391 -0
  134. package/knowledge_base/config/.env +100 -0
  135. package/knowledge_base/config/.env.example +75 -0
  136. package/knowledge_base/config/__init__.py +5 -0
  137. package/knowledge_base/config/__pycache__/__init__.cpython-37.pyc +0 -0
  138. package/knowledge_base/config/__pycache__/__init__.cpython-38.pyc +0 -0
  139. package/knowledge_base/config/__pycache__/settings.cpython-37.pyc +0 -0
  140. package/knowledge_base/config/__pycache__/settings.cpython-38.pyc +0 -0
  141. package/knowledge_base/config/settings.py +280 -0
  142. package/knowledge_base/connectors/__init__.py +5 -0
  143. package/knowledge_base/connectors/__pycache__/__init__.cpython-37.pyc +0 -0
  144. package/knowledge_base/connectors/__pycache__/__init__.cpython-38.pyc +0 -0
  145. package/knowledge_base/connectors/__pycache__/base.cpython-37.pyc +0 -0
  146. package/knowledge_base/connectors/__pycache__/base.cpython-38.pyc +0 -0
  147. package/knowledge_base/connectors/__pycache__/bitbucket_connector.cpython-37.pyc +0 -0
  148. package/knowledge_base/connectors/__pycache__/bitbucket_connector.cpython-38.pyc +0 -0
  149. package/knowledge_base/connectors/__pycache__/community_connector.cpython-38.pyc +0 -0
  150. package/knowledge_base/connectors/__pycache__/confluence_connector.cpython-37.pyc +0 -0
  151. package/knowledge_base/connectors/__pycache__/confluence_connector.cpython-38.pyc +0 -0
  152. package/knowledge_base/connectors/__pycache__/jira_connector.cpython-37.pyc +0 -0
  153. package/knowledge_base/connectors/__pycache__/jira_connector.cpython-38.pyc +0 -0
  154. package/knowledge_base/connectors/__pycache__/kb_igel_connector.cpython-38.pyc +0 -0
  155. package/knowledge_base/connectors/__pycache__/playwright_fetcher.cpython-38.pyc +0 -0
  156. package/knowledge_base/connectors/__pycache__/query_bridge.cpython-38.pyc +0 -0
  157. package/knowledge_base/connectors/__pycache__/search_backends.cpython-38.pyc +0 -0
  158. package/knowledge_base/connectors/__pycache__/serviceNow_connector.cpython-37.pyc +0 -0
  159. package/knowledge_base/connectors/__pycache__/serviceNow_connector.cpython-38.pyc +0 -0
  160. package/knowledge_base/connectors/__pycache__/sync_scheduler.cpython-37.pyc +0 -0
  161. package/knowledge_base/connectors/__pycache__/sync_scheduler.cpython-38.pyc +0 -0
  162. package/knowledge_base/connectors/__pycache__/teamcity_connector.cpython-37.pyc +0 -0
  163. package/knowledge_base/connectors/__pycache__/teamcity_connector.cpython-38.pyc +0 -0
  164. package/knowledge_base/connectors/__pycache__/testRail_connector.cpython-37.pyc +0 -0
  165. package/knowledge_base/connectors/__pycache__/testRail_connector.cpython-38.pyc +0 -0
  166. package/knowledge_base/connectors/__pycache__/web_fetcher.cpython-38.pyc +0 -0
  167. package/knowledge_base/connectors/base.py +44 -0
  168. package/knowledge_base/connectors/bitbucket_connector.py +25 -0
  169. package/knowledge_base/connectors/community_connector.py +112 -0
  170. package/knowledge_base/connectors/confluence_connector.py +165 -0
  171. package/knowledge_base/connectors/jira_connector.py +174 -0
  172. package/knowledge_base/connectors/kb_igel_connector.py +145 -0
  173. package/knowledge_base/connectors/playwright_fetcher.py +50 -0
  174. package/knowledge_base/connectors/query_bridge.py +170 -0
  175. package/knowledge_base/connectors/search_backends.py +368 -0
  176. package/knowledge_base/connectors/serviceNow_connector.py +25 -0
  177. package/knowledge_base/connectors/sync_scheduler.py +111 -0
  178. package/knowledge_base/connectors/teamcity_connector.py +25 -0
  179. package/knowledge_base/connectors/testRail_connector.py +25 -0
  180. package/knowledge_base/connectors/web_fetcher.py +280 -0
  181. package/knowledge_base/core/__init__.py +8 -0
  182. package/knowledge_base/core/__pycache__/__init__.cpython-37.pyc +0 -0
  183. package/knowledge_base/core/__pycache__/__init__.cpython-38.pyc +0 -0
  184. package/knowledge_base/core/__pycache__/cache.cpython-38.pyc +0 -0
  185. package/knowledge_base/core/__pycache__/circuit_breaker.cpython-38.pyc +0 -0
  186. package/knowledge_base/core/__pycache__/confidence.cpython-37.pyc +0 -0
  187. package/knowledge_base/core/__pycache__/confidence.cpython-38.pyc +0 -0
  188. package/knowledge_base/core/__pycache__/logging_setup.cpython-38.pyc +0 -0
  189. package/knowledge_base/core/__pycache__/metrics.cpython-38.pyc +0 -0
  190. package/knowledge_base/core/__pycache__/precedence.cpython-37.pyc +0 -0
  191. package/knowledge_base/core/__pycache__/precedence.cpython-38.pyc +0 -0
  192. package/knowledge_base/core/__pycache__/request_context.cpython-38.pyc +0 -0
  193. package/knowledge_base/core/cache.py +98 -0
  194. package/knowledge_base/core/circuit_breaker.py +33 -0
  195. package/knowledge_base/core/confidence.py +254 -0
  196. package/knowledge_base/core/logging_setup.py +39 -0
  197. package/knowledge_base/core/metrics.py +63 -0
  198. package/knowledge_base/core/precedence.py +354 -0
  199. package/knowledge_base/core/request_context.py +54 -0
  200. package/knowledge_base/db/__init__.py +0 -0
  201. package/knowledge_base/db/__pycache__/__init__.cpython-314.pyc +0 -0
  202. package/knowledge_base/db/__pycache__/__init__.cpython-37.pyc +0 -0
  203. package/knowledge_base/db/__pycache__/__init__.cpython-38.pyc +0 -0
  204. package/knowledge_base/db/__pycache__/client.cpython-314.pyc +0 -0
  205. package/knowledge_base/db/__pycache__/client.cpython-37.pyc +0 -0
  206. package/knowledge_base/db/__pycache__/client.cpython-38.pyc +0 -0
  207. package/knowledge_base/db/__pycache__/connector_sync.cpython-38.pyc +0 -0
  208. package/knowledge_base/db/__pycache__/feedback_schema.cpython-37.pyc +0 -0
  209. package/knowledge_base/db/__pycache__/feedback_schema.cpython-38.pyc +0 -0
  210. package/knowledge_base/db/__pycache__/kg_introspect.cpython-314.pyc +0 -0
  211. package/knowledge_base/db/__pycache__/kg_introspect.cpython-37.pyc +0 -0
  212. package/knowledge_base/db/__pycache__/kg_introspect.cpython-38.pyc +0 -0
  213. package/knowledge_base/db/__pycache__/schema.cpython-37.pyc +0 -0
  214. package/knowledge_base/db/__pycache__/schema.cpython-38.pyc +0 -0
  215. package/knowledge_base/db/client.py +100 -0
  216. package/knowledge_base/db/connector_sync.py +43 -0
  217. package/knowledge_base/db/feedback_schema.py +548 -0
  218. package/knowledge_base/db/igel_schema.py +150 -0
  219. package/knowledge_base/db/kg_introspect.py +116 -0
  220. package/knowledge_base/db/migrations.py +22 -0
  221. package/knowledge_base/db/schema.py +649 -0
  222. package/knowledge_base/deploy/Dockerfile +23 -0
  223. package/knowledge_base/deploy/feedback_automation.sh +18 -0
  224. package/knowledge_base/deploy/firecrawl-docker.sh +50 -0
  225. package/knowledge_base/deploy/igel-testgen.service +26 -0
  226. package/knowledge_base/deploy/install_reranker.sh +92 -0
  227. package/knowledge_base/deploy/requirements.txt +68 -0
  228. package/knowledge_base/deploy/run_server.sh +35 -0
  229. package/knowledge_base/docs/TEST_GENERATION_GUIDE.md +174 -0
  230. package/knowledge_base/embeddings/__init__.py +0 -0
  231. package/knowledge_base/embeddings/__pycache__/__init__.cpython-314.pyc +0 -0
  232. package/knowledge_base/embeddings/__pycache__/__init__.cpython-37.pyc +0 -0
  233. package/knowledge_base/embeddings/__pycache__/__init__.cpython-38.pyc +0 -0
  234. package/knowledge_base/embeddings/__pycache__/azure_embedder.cpython-314.pyc +0 -0
  235. package/knowledge_base/embeddings/__pycache__/azure_embedder.cpython-37.pyc +0 -0
  236. package/knowledge_base/embeddings/__pycache__/azure_embedder.cpython-38.pyc +0 -0
  237. package/knowledge_base/embeddings/azure_embedder.py +99 -0
  238. package/knowledge_base/eval/__init__.py +33 -0
  239. package/knowledge_base/eval/__main__.py +172 -0
  240. package/knowledge_base/eval/__pycache__/__init__.cpython-37.pyc +0 -0
  241. package/knowledge_base/eval/__pycache__/__init__.cpython-38.pyc +0 -0
  242. package/knowledge_base/eval/__pycache__/__main__.cpython-37.pyc +0 -0
  243. package/knowledge_base/eval/__pycache__/baseline.cpython-37.pyc +0 -0
  244. package/knowledge_base/eval/__pycache__/baseline.cpython-38.pyc +0 -0
  245. package/knowledge_base/eval/__pycache__/harness.cpython-37.pyc +0 -0
  246. package/knowledge_base/eval/__pycache__/harness.cpython-38.pyc +0 -0
  247. package/knowledge_base/eval/__pycache__/scorers.cpython-37.pyc +0 -0
  248. package/knowledge_base/eval/__pycache__/scorers.cpython-38.pyc +0 -0
  249. package/knowledge_base/eval/baseline.py +213 -0
  250. package/knowledge_base/eval/harness.py +400 -0
  251. package/knowledge_base/eval/queries_50.json +302 -0
  252. package/knowledge_base/eval/scorers.py +494 -0
  253. package/knowledge_base/exemplars/README.md +7 -0
  254. package/knowledge_base/exemplars/__pycache__/pytest_reference_snippet.cpython-37.pyc +0 -0
  255. package/knowledge_base/exemplars/gold_manual_concise_snippet.md +8 -0
  256. package/knowledge_base/exemplars/gold_manual_detailed_snippet.md +7 -0
  257. package/knowledge_base/exemplars/pytest_reference_snippet.py +37 -0
  258. package/knowledge_base/feedback/__init__.py +10 -0
  259. package/knowledge_base/feedback/__pycache__/__init__.cpython-37.pyc +0 -0
  260. package/knowledge_base/feedback/__pycache__/__init__.cpython-38.pyc +0 -0
  261. package/knowledge_base/feedback/__pycache__/analytics.cpython-37.pyc +0 -0
  262. package/knowledge_base/feedback/__pycache__/analytics.cpython-38.pyc +0 -0
  263. package/knowledge_base/feedback/__pycache__/applier.cpython-37.pyc +0 -0
  264. package/knowledge_base/feedback/__pycache__/applier.cpython-38.pyc +0 -0
  265. package/knowledge_base/feedback/__pycache__/curator.cpython-37.pyc +0 -0
  266. package/knowledge_base/feedback/__pycache__/curator.cpython-38.pyc +0 -0
  267. package/knowledge_base/feedback/__pycache__/handler.cpython-37.pyc +0 -0
  268. package/knowledge_base/feedback/__pycache__/handler.cpython-38.pyc +0 -0
  269. package/knowledge_base/feedback/analytics.py +72 -0
  270. package/knowledge_base/feedback/applier.py +93 -0
  271. package/knowledge_base/feedback/curator.py +49 -0
  272. package/knowledge_base/feedback/handler.py +151 -0
  273. package/knowledge_base/generation/__init__.py +5 -0
  274. package/knowledge_base/generation/__pycache__/__init__.cpython-37.pyc +0 -0
  275. package/knowledge_base/generation/__pycache__/__init__.cpython-38.pyc +0 -0
  276. package/knowledge_base/generation/__pycache__/input_classifier.cpython-37.pyc +0 -0
  277. package/knowledge_base/generation/__pycache__/input_classifier.cpython-38.pyc +0 -0
  278. package/knowledge_base/generation/__pycache__/manual_tc_parser.cpython-37.pyc +0 -0
  279. package/knowledge_base/generation/__pycache__/manual_tc_parser.cpython-38.pyc +0 -0
  280. package/knowledge_base/generation/__pycache__/prompts.cpython-37.pyc +0 -0
  281. package/knowledge_base/generation/__pycache__/prompts.cpython-38.pyc +0 -0
  282. package/knowledge_base/generation/__pycache__/tc_transformer.cpython-37.pyc +0 -0
  283. package/knowledge_base/generation/__pycache__/test_generator.cpython-37.pyc +0 -0
  284. package/knowledge_base/generation/__pycache__/test_generator.cpython-38.pyc +0 -0
  285. package/knowledge_base/generation/input_classifier.py +148 -0
  286. package/knowledge_base/generation/manual_tc_parser.py +180 -0
  287. package/knowledge_base/generation/prompts.py +755 -0
  288. package/knowledge_base/generation/tc_transformer.py +368 -0
  289. package/knowledge_base/generation/test_generator.py +553 -0
  290. package/knowledge_base/graph_db/__init__.py +5 -0
  291. package/knowledge_base/graph_db/__pycache__/__init__.cpython-37.pyc +0 -0
  292. package/knowledge_base/graph_db/__pycache__/__init__.cpython-38.pyc +0 -0
  293. package/knowledge_base/graph_db/__pycache__/graphiti_client.cpython-37.pyc +0 -0
  294. package/knowledge_base/graph_db/__pycache__/kg_traversal.cpython-37.pyc +0 -0
  295. package/knowledge_base/graph_db/__pycache__/migrate_kg.cpython-37.pyc +0 -0
  296. package/knowledge_base/graph_db/__pycache__/neo4j_client.cpython-37.pyc +0 -0
  297. package/knowledge_base/graph_db/__pycache__/neo4j_client.cpython-38.pyc +0 -0
  298. package/knowledge_base/graph_db/__pycache__/schema.cpython-37.pyc +0 -0
  299. package/knowledge_base/graph_db/__pycache__/temporal_ingest.cpython-37.pyc +0 -0
  300. package/knowledge_base/graph_db/graphiti_client.py +127 -0
  301. package/knowledge_base/graph_db/kg_traversal.py +192 -0
  302. package/knowledge_base/graph_db/migrate_kg.py +93 -0
  303. package/knowledge_base/graph_db/neo4j_client.py +116 -0
  304. package/knowledge_base/graph_db/schema.py +22 -0
  305. package/knowledge_base/graph_db/temporal_ingest.py +59 -0
  306. package/knowledge_base/ingestion/__init__.py +1 -0
  307. package/knowledge_base/ingestion/__pycache__/__init__.cpython-37.pyc +0 -0
  308. package/knowledge_base/ingestion/__pycache__/__init__.cpython-38.pyc +0 -0
  309. package/knowledge_base/ingestion/__pycache__/ingest.cpython-37.pyc +0 -0
  310. package/knowledge_base/ingestion/__pycache__/ingest.cpython-38.pyc +0 -0
  311. package/knowledge_base/ingestion/__pycache__/ingest_images.cpython-37.pyc +0 -0
  312. package/knowledge_base/ingestion/__pycache__/ingest_images.cpython-38.pyc +0 -0
  313. package/knowledge_base/ingestion/__pycache__/kg_extractor.cpython-37.pyc +0 -0
  314. package/knowledge_base/ingestion/__pycache__/kg_extractor.cpython-38.pyc +0 -0
  315. package/knowledge_base/ingestion/__pycache__/web_ingest.cpython-38.pyc +0 -0
  316. package/knowledge_base/ingestion/ingest.py +346 -0
  317. package/knowledge_base/ingestion/ingest_images.py +330 -0
  318. package/knowledge_base/ingestion/kg_extractor.py +358 -0
  319. package/knowledge_base/ingestion/web_ingest.py +83 -0
  320. package/knowledge_base/intelligence/__init__.py +1 -0
  321. package/knowledge_base/intelligence/__pycache__/__init__.cpython-37.pyc +0 -0
  322. package/knowledge_base/intelligence/__pycache__/execution_ingest.cpython-37.pyc +0 -0
  323. package/knowledge_base/intelligence/__pycache__/predictive_engine.cpython-37.pyc +0 -0
  324. package/knowledge_base/intelligence/__pycache__/risk_scorer.cpython-37.pyc +0 -0
  325. package/knowledge_base/intelligence/execution_ingest.py +34 -0
  326. package/knowledge_base/intelligence/predictive_engine.py +7 -0
  327. package/knowledge_base/intelligence/risk_scorer.py +8 -0
  328. package/knowledge_base/memory/__init__.py +6 -0
  329. package/knowledge_base/memory/__pycache__/__init__.cpython-37.pyc +0 -0
  330. package/knowledge_base/memory/__pycache__/__init__.cpython-38.pyc +0 -0
  331. package/knowledge_base/memory/__pycache__/cognee_client.cpython-37.pyc +0 -0
  332. package/knowledge_base/memory/__pycache__/cognee_client.cpython-38.pyc +0 -0
  333. package/knowledge_base/memory/__pycache__/ingest_memory.cpython-37.pyc +0 -0
  334. package/knowledge_base/memory/__pycache__/memory_types.cpython-37.pyc +0 -0
  335. package/knowledge_base/memory/__pycache__/memory_types.cpython-38.pyc +0 -0
  336. package/knowledge_base/memory/cognee_client.py +164 -0
  337. package/knowledge_base/memory/ingest_memory.py +60 -0
  338. package/knowledge_base/memory/memory_types.py +23 -0
  339. package/knowledge_base/models/test_requirement.py +84 -0
  340. package/knowledge_base/parsers/__init__.py +0 -0
  341. package/knowledge_base/parsers/__pycache__/__init__.cpython-37.pyc +0 -0
  342. package/knowledge_base/parsers/__pycache__/__init__.cpython-38.pyc +0 -0
  343. package/knowledge_base/parsers/__pycache__/csv_parser.cpython-37.pyc +0 -0
  344. package/knowledge_base/parsers/__pycache__/csv_parser.cpython-38.pyc +0 -0
  345. package/knowledge_base/parsers/__pycache__/doc_parser.cpython-37.pyc +0 -0
  346. package/knowledge_base/parsers/__pycache__/doc_parser.cpython-38.pyc +0 -0
  347. package/knowledge_base/parsers/__pycache__/html_parser.cpython-38.pyc +0 -0
  348. package/knowledge_base/parsers/__pycache__/image_extractor.cpython-37.pyc +0 -0
  349. package/knowledge_base/parsers/__pycache__/image_extractor.cpython-38.pyc +0 -0
  350. package/knowledge_base/parsers/__pycache__/markdown_parser.cpython-37.pyc +0 -0
  351. package/knowledge_base/parsers/__pycache__/markdown_parser.cpython-38.pyc +0 -0
  352. package/knowledge_base/parsers/__pycache__/pdf_parser.cpython-37.pyc +0 -0
  353. package/knowledge_base/parsers/__pycache__/pdf_parser.cpython-38.pyc +0 -0
  354. package/knowledge_base/parsers/csv_parser.py +126 -0
  355. package/knowledge_base/parsers/doc_parser.py +176 -0
  356. package/knowledge_base/parsers/html_parser.py +151 -0
  357. package/knowledge_base/parsers/image_extractor.py +370 -0
  358. package/knowledge_base/parsers/markdown_parser.py +116 -0
  359. package/knowledge_base/parsers/pdf_parser.py +178 -0
  360. package/knowledge_base/retrieval/__init__.py +1 -0
  361. package/knowledge_base/retrieval/__pycache__/__init__.cpython-37.pyc +0 -0
  362. package/knowledge_base/retrieval/__pycache__/__init__.cpython-38.pyc +0 -0
  363. package/knowledge_base/retrieval/__pycache__/context_fusion.cpython-37.pyc +0 -0
  364. package/knowledge_base/retrieval/__pycache__/context_fusion.cpython-38.pyc +0 -0
  365. package/knowledge_base/retrieval/__pycache__/knowledge_graph.cpython-37.pyc +0 -0
  366. package/knowledge_base/retrieval/__pycache__/knowledge_graph.cpython-38.pyc +0 -0
  367. package/knowledge_base/retrieval/__pycache__/reranker.cpython-37.pyc +0 -0
  368. package/knowledge_base/retrieval/__pycache__/reranker.cpython-38.pyc +0 -0
  369. package/knowledge_base/retrieval/__pycache__/retrieval_debug.cpython-37.pyc +0 -0
  370. package/knowledge_base/retrieval/__pycache__/retrieval_debug.cpython-38.pyc +0 -0
  371. package/knowledge_base/retrieval/__pycache__/retriever.cpython-37.pyc +0 -0
  372. package/knowledge_base/retrieval/__pycache__/retriever.cpython-38.pyc +0 -0
  373. package/knowledge_base/retrieval/__pycache__/unified_query.cpython-38.pyc +0 -0
  374. package/knowledge_base/retrieval/__pycache__/web_retriever.cpython-38.pyc +0 -0
  375. package/knowledge_base/retrieval/context_fusion.py +264 -0
  376. package/knowledge_base/retrieval/knowledge_graph.py +267 -0
  377. package/knowledge_base/retrieval/reranker.py +308 -0
  378. package/knowledge_base/retrieval/retrieval_debug.py +69 -0
  379. package/knowledge_base/retrieval/retriever.py +885 -0
  380. package/knowledge_base/retrieval/unified_query.py +189 -0
  381. package/knowledge_base/retrieval/web_retriever.py +337 -0
  382. package/knowledge_base/validators/__init__.py +1 -0
  383. package/knowledge_base/validators/__pycache__/__init__.cpython-314.pyc +0 -0
  384. package/knowledge_base/validators/__pycache__/__init__.cpython-37.pyc +0 -0
  385. package/knowledge_base/validators/__pycache__/step_fidelity.cpython-314.pyc +0 -0
  386. package/knowledge_base/validators/__pycache__/step_fidelity.cpython-37.pyc +0 -0
  387. package/knowledge_base/validators/step_fidelity.py +88 -0
  388. package/knowledge_base/vision/__init__.py +0 -0
  389. package/knowledge_base/vision/__pycache__/__init__.cpython-37.pyc +0 -0
  390. package/knowledge_base/vision/__pycache__/__init__.cpython-38.pyc +0 -0
  391. package/knowledge_base/vision/__pycache__/image_describer.cpython-37.pyc +0 -0
  392. package/knowledge_base/vision/__pycache__/image_describer.cpython-38.pyc +0 -0
  393. package/knowledge_base/vision/image_describer.py +202 -0
  394. package/package.json +31 -0
@@ -0,0 +1,91 @@
1
+ """Knowledge graph agent — enriches retrieval_agent KG context (no duplicate fetch)."""
2
+ from __future__ import annotations
3
+
4
+ import re
5
+ import time
6
+
7
+ from knowledge_base.agents.state import AgenticState
8
+ from knowledge_base.config import cfg
9
+ from knowledge_base.db.client import get_conn
10
+
11
+
12
+ def kg_agent(state: AgenticState) -> AgenticState:
13
+ t0 = time.perf_counter()
14
+ query = state.get("query", "")
15
+ kg_block = state.get("kg_context_block") or ""
16
+
17
+ try:
18
+ text = kg_block
19
+ keys = re.findall(r"\b(app\.[a-z0-9]+(?:\.[a-z0-9_]+)+)\b", text, re.I)
20
+ paths = re.findall(r"TC\s*Setup[^•\n]{5,120}", text, re.I)
21
+
22
+ verified_keys = []
23
+ for k in dict.fromkeys(keys)[:30]:
24
+ status = "confirmed" if _kg_has_entity("registry_key", k) else "unverified"
25
+ verified_keys.append({"key": k, "confidence": status})
26
+
27
+ related_tcs, related_defects = _fetch_related_entities(query)
28
+
29
+ state["kg_entities"] = {
30
+ "registry_keys": verified_keys,
31
+ "ui_paths": [{"path": p.strip(), "confidence": "confirmed"} for p in dict.fromkeys(paths)[:20]],
32
+ "related_testcases": related_tcs,
33
+ "related_defects": related_defects,
34
+ "feature_relationships": [],
35
+ "backend": cfg.KG_BACKEND,
36
+ }
37
+ status = "complete"
38
+ except Exception as e:
39
+ state["kg_entities"] = {}
40
+ status = "error"
41
+ state.setdefault("agent_trace", []).append({
42
+ "agent": "KGAgent", "status": "error", "reason": str(e),
43
+ })
44
+ return state
45
+
46
+ ents = len(state["kg_entities"].get("registry_keys", [])) + len(state["kg_entities"].get("ui_paths", []))
47
+ state.setdefault("agent_trace", []).append({
48
+ "agent": "KGAgent",
49
+ "status": status,
50
+ "backend": cfg.KG_BACKEND,
51
+ "entities_found": ents,
52
+ "timing_ms": round((time.perf_counter() - t0) * 1000, 1),
53
+ })
54
+ return state
55
+
56
+
57
+ def _kg_has_entity(node_type: str, value: str) -> bool:
58
+ with get_conn() as conn:
59
+ with conn.cursor() as cur:
60
+ cur.execute(
61
+ "SELECT 1 FROM knowledge_graph_nodes WHERE node_type=%s AND normalized=%s LIMIT 1",
62
+ (node_type, value.lower()[:2000]),
63
+ )
64
+ return cur.fetchone() is not None
65
+
66
+
67
+ def _fetch_related_entities(query: str) -> tuple[list, list]:
68
+ tcs: list[dict] = []
69
+ defects: list[dict] = []
70
+ tokens = [t for t in re.findall(r"\w{4,}", query.lower())[:5]]
71
+ if not tokens:
72
+ return tcs, defects
73
+ pattern = "%" + "%".join(tokens[:2]) + "%"
74
+ with get_conn() as conn:
75
+ with conn.cursor() as cur:
76
+ cur.execute(
77
+ """
78
+ SELECT node_type, value FROM knowledge_graph_nodes
79
+ WHERE node_type IN ('testcase', 'defect', 'error_code')
80
+ AND (normalized ILIKE %s OR value ILIKE %s)
81
+ LIMIT 10
82
+ """,
83
+ (pattern, pattern),
84
+ )
85
+ for node_type, value in cur.fetchall():
86
+ item = {"id": value, "title": value}
87
+ if node_type == "testcase":
88
+ tcs.append(item)
89
+ else:
90
+ defects.append(item)
91
+ return tcs, defects
@@ -0,0 +1,62 @@
1
+ """Memory agent — Phase 4/5 Cognee search."""
2
+ from __future__ import annotations
3
+
4
+ from knowledge_base.agents.state import AgenticState
5
+ from knowledge_base.config import cfg
6
+ from knowledge_base.memory.cognee_client import get_cognee_client
7
+ from knowledge_base.memory.memory_types import MemoryType
8
+
9
+
10
+ def memory_agent(state: AgenticState) -> AgenticState:
11
+ if not cfg.COGNEE_ENABLED:
12
+ state["memory_context"] = []
13
+ state.setdefault("agent_trace", []).append({
14
+ "agent": "MemoryAgent", "status": "skipped", "reason": "COGNEE_ENABLED=false",
15
+ })
16
+ return state
17
+
18
+ query = state.get("query", "")
19
+ feature = state.get("feature_area", "Unknown")
20
+ categories = state.get("query_categories", [])
21
+
22
+ try:
23
+ client = get_cognee_client()
24
+ types = [MemoryType.FEEDBACK.value, MemoryType.PATTERN.value]
25
+ if "troubleshooting" in categories or "regression" in categories:
26
+ types.append(MemoryType.EXECUTION.value)
27
+
28
+ results = client.search(
29
+ query=f"{feature} {query}",
30
+ memory_types=types,
31
+ feature_area=feature,
32
+ top_k=5,
33
+ min_relevance=0.5,
34
+ )
35
+ state["memory_context"] = [
36
+ {
37
+ "memory_id": m.memory_id,
38
+ "memory_type": m.memory_type.value,
39
+ "content": m.content,
40
+ "feature_area": m.feature_area,
41
+ "relevance_score": m.relevance_score,
42
+ "applied_at": m.applied_at,
43
+ "curator": m.curator,
44
+ }
45
+ for m in results
46
+ if m.feature_area == feature or feature == "Unknown"
47
+ ]
48
+ status = "complete"
49
+ except Exception as e:
50
+ state["memory_context"] = []
51
+ status = "error"
52
+ state.setdefault("agent_trace", []).append({
53
+ "agent": "MemoryAgent", "status": "error", "reason": str(e),
54
+ })
55
+ return state
56
+
57
+ state.setdefault("agent_trace", []).append({
58
+ "agent": "MemoryAgent",
59
+ "status": status,
60
+ "memories_retrieved": len(state["memory_context"]),
61
+ })
62
+ return state
@@ -0,0 +1,53 @@
1
+ """RCA agent — Phase 7."""
2
+ from __future__ import annotations
3
+
4
+ from knowledge_base.config import cfg
5
+ from knowledge_base.graph_db.kg_traversal import traverse_failure_path
6
+ from knowledge_base.memory.cognee_client import get_cognee_client
7
+ from knowledge_base.memory.memory_types import MemoryType
8
+
9
+
10
+ def analyze_failure(test_id: str, failure_log: str) -> dict:
11
+ """Traverse KG + memory to find root cause chain."""
12
+ if cfg.KG_BACKEND == "neo4j":
13
+ chain_result = traverse_failure_path(test_id)
14
+ else:
15
+ chain_result = {"status": "insufficient_graph_data", "chain": [], "missing": ["neo4j_primary"]}
16
+
17
+ similar = []
18
+ if cfg.COGNEE_ENABLED:
19
+ client = get_cognee_client()
20
+ memories = client.search(
21
+ query=f"{test_id} {failure_log[:200]}",
22
+ memory_types=[MemoryType.EXECUTION.value],
23
+ top_k=3,
24
+ )
25
+ similar = [{"content": m.content, "score": m.relevance_score} for m in memories]
26
+
27
+ if chain_result.get("status") == "insufficient_graph_data" and not similar:
28
+ return {
29
+ "status": "insufficient_graph_data",
30
+ "root_cause_chain": [],
31
+ "similar_failures": [],
32
+ "missing": chain_result.get("missing", []),
33
+ "confidence": 0.2,
34
+ }
35
+
36
+ summary = _build_summary(chain_result, similar, failure_log)
37
+ return {
38
+ "status": "complete",
39
+ "test_id": test_id,
40
+ "root_cause_chain": chain_result.get("root_cause_chain") or chain_result.get("chain", []),
41
+ "similar_failures": similar,
42
+ "suggested_fix": summary,
43
+ "confidence": 0.7 if chain_result.get("root_cause_chain") else 0.4,
44
+ }
45
+
46
+
47
+ def _build_summary(chain_result: dict, similar: list, failure_log: str) -> str:
48
+ chain = chain_result.get("root_cause_chain") or chain_result.get("chain") or []
49
+ if chain:
50
+ return f"Failure path: {' → '.join(str(c) for c in chain[:6])}"
51
+ if similar:
52
+ return f"Similar past failure pattern: {similar[0]['content'][:200]}"
53
+ return f"Analyze failure log manually: {failure_log[:300]}"
@@ -0,0 +1,62 @@
1
+ """Reflection agent — Phase 5."""
2
+ from __future__ import annotations
3
+
4
+ from knowledge_base.agents.state import AgenticState
5
+
6
+
7
+ def reflection_agent(state: AgenticState) -> AgenticState:
8
+ fused = state.get("fused_context") or {}
9
+ categories = state.get("query_categories", [])
10
+ version = state.get("version_scope", "unspecified")
11
+ temporal = state.get("temporal_context") or {}
12
+ intent = state.get("intent", "synthesize")
13
+ rag = state.get("rag_chunks", [])
14
+
15
+ notes: list[str] = []
16
+ procedure_steps = fused.get("procedure_steps") or []
17
+
18
+ if not fused.get("registry_keys") and "configuration" in categories:
19
+ notes.append("no_registry_keys")
20
+ if not fused.get("ui_paths"):
21
+ notes.append("no_ui_paths")
22
+ if len(procedure_steps) < 3:
23
+ notes.append("no_procedure_steps")
24
+ if version == "unspecified" and "version_specific" in categories:
25
+ notes.append("version_unconfirmed")
26
+ if version != "unspecified" and temporal.get("status") == "skipped":
27
+ notes.append("no_temporal_context")
28
+ if intent == "synthesize" and "negative_case" not in categories:
29
+ if not any("fail" in s.lower() or "error" in s.lower() for s in procedure_steps):
30
+ notes.append("no_negative_case_material")
31
+ if fused.get("context_quality", 0) < 0.5:
32
+ notes.append("low_context_quality")
33
+ if len(fused.get("conflicts") or []) > 2:
34
+ notes.append("unresolved_conflicts")
35
+
36
+ count = state.get("reflection_count", 0) + 1
37
+ state["reflection_count"] = count
38
+
39
+ if count >= 2:
40
+ state["force_to_validation"] = True
41
+ state["reflection_notes"] = []
42
+ state.setdefault("agent_trace", []).append({
43
+ "agent": "ReflectionAgent",
44
+ "status": "max_loops_reached",
45
+ "forced_to_validation": True,
46
+ })
47
+ else:
48
+ state["force_to_validation"] = False
49
+ state["reflection_notes"] = notes
50
+ state.setdefault("agent_trace", []).append({
51
+ "agent": "ReflectionAgent",
52
+ "status": "complete",
53
+ "reflection_notes": notes,
54
+ "loop": count,
55
+ })
56
+ return state
57
+
58
+
59
+ def should_loop_back(state: AgenticState) -> bool:
60
+ if state.get("force_to_validation"):
61
+ return False
62
+ return bool(state.get("reflection_notes"))
@@ -0,0 +1,81 @@
1
+ import logging
2
+ from typing import List, Dict, Any, Set
3
+ from pathlib import Path
4
+ from knowledge_base.db.client import get_conn
5
+ from knowledge_base.agents.code_intelligence_agent import CodeIntelligenceAgent
6
+
7
+ logger = logging.getLogger(__name__)
8
+
9
+ class BitbucketSyncAgent:
10
+ """Agent responsible for performing Delta Syncs from Bitbucket."""
11
+
12
+ def __init__(self, repo_path: Path):
13
+ self.repo_path = repo_path
14
+ self.code_agent = CodeIntelligenceAgent(repo_path)
15
+
16
+ def sync_changed_files(self, changed_files: List[Path]) -> int:
17
+ """Only index the specifically changed files (Delta Sync)."""
18
+ indexed = 0
19
+ for file in changed_files:
20
+ if not file.exists():
21
+ logger.info(f"File {file} deleted, removing from registry.")
22
+ rel_path = str(file.relative_to(self.repo_path))
23
+ with get_conn() as conn:
24
+ with conn.cursor() as cur:
25
+ cur.execute("DELETE FROM igel_asset_registry WHERE file_path = %s", (rel_path,))
26
+ conn.commit()
27
+ else:
28
+ indexed += self.code_agent.index_file(file)
29
+
30
+ return indexed
31
+
32
+ class RegressionAgent:
33
+ """Agent responsible for determining impact of code changes."""
34
+
35
+ def analyze_impact(self, changed_files: List[Path], repo_path: Path) -> Dict[str, Any]:
36
+ """Find requirements, test cases, and scripts affected by the changed files."""
37
+ impact = {
38
+ "affected_requirements": set(),
39
+ "affected_scripts": set(),
40
+ "affected_assets": set()
41
+ }
42
+
43
+ try:
44
+ with get_conn() as conn:
45
+ with conn.cursor() as cur:
46
+ for file in changed_files:
47
+ rel_path = str(file.relative_to(repo_path))
48
+
49
+ # 1. Find all assets in this file
50
+ cur.execute("SELECT id, name FROM igel_asset_registry WHERE file_path = %s", (rel_path,))
51
+ assets = cur.fetchall()
52
+ for asset_id, asset_name in assets:
53
+ impact["affected_assets"].add(asset_name)
54
+
55
+ # 2. Find all requirements mapped to this asset
56
+ cur.execute(
57
+ """
58
+ SELECT r.jira_key
59
+ FROM igel_requirements r
60
+ JOIN igel_asset_mappings m ON r.id = m.requirement_id
61
+ WHERE m.asset_id = %s
62
+ """,
63
+ (asset_id,)
64
+ )
65
+ for req_row in cur.fetchall():
66
+ impact["affected_requirements"].add(req_row[0])
67
+
68
+ # 3. Find if this file itself is an automation script
69
+ cur.execute("SELECT script_path FROM igel_automation_scripts WHERE script_path = %s", (rel_path,))
70
+ if cur.fetchone():
71
+ impact["affected_scripts"].add(rel_path)
72
+
73
+ except Exception as e:
74
+ logger.error(f"Failed to analyze impact: {e}")
75
+
76
+ # Convert sets to lists for JSON serialization
77
+ return {
78
+ "affected_requirements": list(impact["affected_requirements"]),
79
+ "affected_scripts": list(impact["affected_scripts"]),
80
+ "affected_assets": list(impact["affected_assets"])
81
+ }
@@ -0,0 +1,71 @@
1
+ import json
2
+ import logging
3
+ from typing import Dict, Any
4
+ from openai import AzureOpenAI
5
+ from knowledge_base.config import cfg
6
+ from knowledge_base.models.test_requirement import RequirementUnderstanding, TestRequirement
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+ _SYSTEM_PROMPT = """You are an expert IGEL Quality Engineering Architect.
11
+ Your task is to analyze a raw Jira/Xray Test Requirement and extract critical domain understanding.
12
+ You must extract actors, entities, explicit business rules, validations, constraints, and dependencies.
13
+ Output MUST be valid JSON matching this schema:
14
+ {
15
+ "actors": ["string"],
16
+ "entities": ["string"],
17
+ "business_rules": ["string"],
18
+ "validations": ["string"],
19
+ "constraints": ["string"],
20
+ "dependencies": ["string"]
21
+ }
22
+ """
23
+
24
+ _llm_client: AzureOpenAI | None = None
25
+
26
+ def _get_llm_client() -> AzureOpenAI:
27
+ global _llm_client
28
+ if _llm_client is None:
29
+ _llm_client = AzureOpenAI(
30
+ api_key=cfg.AZURE_API_KEY,
31
+ azure_endpoint=cfg.AZURE_ENDPOINT,
32
+ api_version=cfg.AZURE_API_VERSION,
33
+ )
34
+ return _llm_client
35
+
36
+ def extract_understanding(requirement: TestRequirement) -> RequirementUnderstanding:
37
+ """Analyze a requirement and extract its core semantic understanding."""
38
+ client = _get_llm_client()
39
+
40
+ user_prompt = f"Requirement Key: {requirement.jira_key}\nSummary: {requirement.summary}\nDescription: {requirement.description or 'None'}\n"
41
+
42
+ try:
43
+ response = client.chat.completions.create(
44
+ model=cfg.AZURE_DEPLOYMENT,
45
+ messages=[
46
+ {"role": "system", "content": _SYSTEM_PROMPT},
47
+ {"role": "user", "content": user_prompt},
48
+ ],
49
+ response_format={"type": "json_object"},
50
+ temperature=0.1,
51
+ max_tokens=1500,
52
+ )
53
+
54
+ content = response.choices[0].message.content or "{}"
55
+ data = json.loads(content)
56
+
57
+ understanding = RequirementUnderstanding(
58
+ actors=data.get("actors", []),
59
+ entities=data.get("entities", []),
60
+ business_rules=data.get("business_rules", []),
61
+ validations=data.get("validations", []),
62
+ constraints=data.get("constraints", []),
63
+ dependencies=data.get("dependencies", [])
64
+ )
65
+ logger.info(f"Successfully extracted understanding for {requirement.jira_key}")
66
+ return understanding
67
+
68
+ except Exception as e:
69
+ logger.error(f"Failed to extract understanding for {requirement.jira_key}: {e}")
70
+ # Return empty understanding on failure to not block the pipeline
71
+ return RequirementUnderstanding()
@@ -0,0 +1,66 @@
1
+ """Retrieval agent — Phase 5 (RAG + EKG + Web + MCP)."""
2
+ from __future__ import annotations
3
+
4
+ from knowledge_base.agents.state import AgenticState
5
+ from knowledge_base.retrieval.unified_query import unified_query
6
+
7
+
8
+ def retrieval_agent(state: AgenticState) -> AgenticState:
9
+ query = state.get("query", "")
10
+ top_k = state.get("top_k", 8)
11
+ product = state.get("product")
12
+
13
+ try:
14
+ uq = unified_query(query=query, top_k=top_k, product=product)
15
+ bundle = uq.rag
16
+ chunks = []
17
+ for r in bundle.results:
18
+ chunks.append({
19
+ "chunk_id": r.child_chunk_id,
20
+ "content": r.parent_content,
21
+ "source_type": (r.metadata.get("source_type") if r.metadata else None) or "igel_docs",
22
+ "source_name": r.file_name,
23
+ "version_tag": None,
24
+ "rrf_score": r.rrf_score,
25
+ "rerank_score": r.rerank_score,
26
+ })
27
+ state["rag_chunks"] = chunks
28
+ state["web_context"] = {
29
+ "block": uq.web_block,
30
+ "hits": [
31
+ {"url": h.url, "title": h.title, "source_type": h.source_type, "score": h.score}
32
+ for h in uq.web_hits
33
+ ],
34
+ }
35
+ state["mcp_context"] = {
36
+ "block": uq.mcp.block,
37
+ "hits": [
38
+ {"source": h.source, "title": h.title, "url": h.url, "score": h.score}
39
+ for h in uq.mcp.hits
40
+ ],
41
+ "sources_queried": uq.mcp.sources_queried,
42
+ }
43
+ state["sources_summary"] = uq.sources_summary
44
+ state["kg_context_block"] = bundle.kg_context.text_block
45
+ status = "complete" if chunks else "no_results"
46
+ top_score = chunks[0]["rrf_score"] if chunks else 0
47
+ except Exception as e:
48
+ state["rag_chunks"] = []
49
+ state["web_context"] = {"block": "", "hits": []}
50
+ state["mcp_context"] = {"block": "", "hits": [], "sources_queried": []}
51
+ status = "error"
52
+ top_score = 0
53
+ state.setdefault("agent_trace", []).append({
54
+ "agent": "RetrievalAgent", "status": "error", "reason": str(e),
55
+ })
56
+ return state
57
+
58
+ state.setdefault("agent_trace", []).append({
59
+ "agent": "RetrievalAgent",
60
+ "status": status,
61
+ "chunks_retrieved": len(state["rag_chunks"]),
62
+ "web_hits": len(state["web_context"]["hits"]),
63
+ "mcp_hits": len(state["mcp_context"]["hits"]),
64
+ "top_score": top_score,
65
+ })
66
+ return state
@@ -0,0 +1,81 @@
1
+ import json
2
+ import logging
3
+ from typing import List, Dict, Any
4
+ from openai import AzureOpenAI
5
+ from knowledge_base.config import cfg
6
+ from knowledge_base.models.test_requirement import (
7
+ TestRequirement,
8
+ TestStep,
9
+ BusinessRule,
10
+ ScenarioWithRules
11
+ )
12
+ from knowledge_base.agents.requirement_agent import _get_llm_client
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+ _SYSTEM_PROMPT = """You are an expert IGEL Quality Engineering Architect.
17
+ Your task is to take a specific Scenario (a test step from a Jira requirement) and generate an exhaustive list of Business Rules for it.
18
+ Business rules dictate exactly what MUST be tested (positive, negative, and edge cases).
19
+ Consider the requirement's overall understanding context when generating rules.
20
+ Output MUST be valid JSON matching this schema:
21
+ {
22
+ "business_rules": [
23
+ {
24
+ "rule_type": "positive" | "negative" | "edge",
25
+ "description": "string"
26
+ }
27
+ ]
28
+ }
29
+ """
30
+
31
+ def generate_business_rules(requirement: TestRequirement, step: TestStep) -> ScenarioWithRules:
32
+ """Analyze a scenario (test step) and extract exhaustive business rules."""
33
+ client = _get_llm_client()
34
+
35
+ # Construct context from the requirement's understanding if available
36
+ context_str = ""
37
+ if requirement.understanding:
38
+ context_str = f"Context (Actors): {', '.join(requirement.understanding.actors)}\n"
39
+ context_str += f"Context (Entities): {', '.join(requirement.understanding.entities)}\n"
40
+ context_str += f"Context (Constraints): {', '.join(requirement.understanding.constraints)}\n"
41
+
42
+ user_prompt = f"Requirement: {requirement.summary}\n{context_str}\n"
43
+ user_prompt += f"Scenario (Step {step.step_number}):\nAction: {step.action}\nData: {step.test_data or 'N/A'}\nExpected: {step.expected_result or 'N/A'}\n"
44
+ user_prompt += "\nGenerate exhaustive business rules for this scenario."
45
+
46
+ try:
47
+ response = client.chat.completions.create(
48
+ model=cfg.AZURE_DEPLOYMENT,
49
+ messages=[
50
+ {"role": "system", "content": _SYSTEM_PROMPT},
51
+ {"role": "user", "content": user_prompt},
52
+ ],
53
+ response_format={"type": "json_object"},
54
+ temperature=0.2,
55
+ max_tokens=2000,
56
+ )
57
+
58
+ content = response.choices[0].message.content or "{}"
59
+ data = json.loads(content)
60
+
61
+ rules = []
62
+ for r in data.get("business_rules", []):
63
+ if isinstance(r, dict) and "rule_type" in r and "description" in r:
64
+ rules.append(BusinessRule(
65
+ rule_type=r["rule_type"],
66
+ description=r["description"]
67
+ ))
68
+
69
+ logger.info(f"Generated {len(rules)} business rules for step {step.step_number}")
70
+ return ScenarioWithRules(scenario=step, business_rules=rules)
71
+
72
+ except Exception as e:
73
+ logger.error(f"Failed to generate business rules for step {step.step_number}: {e}")
74
+ return ScenarioWithRules(scenario=step, business_rules=[])
75
+
76
+ def generate_all_scenarios(requirement: TestRequirement) -> List[ScenarioWithRules]:
77
+ """Process all steps in a requirement to generate comprehensive business rules."""
78
+ scenarios = []
79
+ for step in requirement.steps:
80
+ scenarios.append(generate_business_rules(requirement, step))
81
+ return scenarios