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,548 @@
1
+ """
2
+ Feedback Event Schema for IGEL KB System
3
+ =========================================
4
+ Captures user feedback on generated test cases for continuous learning.
5
+
6
+ Two-Step Feedback Flow:
7
+ 1. CAPTURE: User provides feedback → stored as event
8
+ 2. CURATE: QE engineer reviews → decides if/how to improve system
9
+ 3. PROMOTE: Approved feedback becomes training signal
10
+
11
+ Never auto-edit based on raw feedback — human curation is mandatory gate.
12
+ """
13
+ from __future__ import annotations
14
+
15
+ from knowledge_base.config import cfg
16
+ from knowledge_base.db.client import get_conn
17
+
18
+ # ─────────────────────────────────────────────────────────────────────────────
19
+ # Feedback Events Table
20
+ # ─────────────────────────────────────────────────────────────────────────────
21
+
22
+ _FEEDBACK_SCHEMA_SQL = """
23
+ -- Feedback events: user corrections, ratings, edits to generated test cases
24
+ CREATE TABLE IF NOT EXISTS feedback_events (
25
+ id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
26
+
27
+ -- Source query and generation
28
+ query TEXT NOT NULL,
29
+ generated_output JSONB NOT NULL, -- full response (markdown, python, chunks)
30
+ generation_metadata JSONB DEFAULT '{}'::jsonb, -- retrieval scores, model params, etc.
31
+
32
+ -- User feedback
33
+ feedback_type TEXT NOT NULL, -- rating, correction, edit, rejection
34
+ feedback_data JSONB NOT NULL, -- structured feedback payload
35
+ user_id TEXT, -- optional user identifier
36
+ session_id TEXT, -- session/request tracking
37
+
38
+ -- Curation status (two-step gate)
39
+ status TEXT NOT NULL DEFAULT 'pending', -- pending, reviewed, approved, rejected, applied
40
+ curator_id TEXT, -- QE engineer who reviewed
41
+ curator_notes TEXT, -- why approved/rejected
42
+ curated_at TIMESTAMP,
43
+
44
+ -- Application tracking (if approved and promoted)
45
+ applied_action TEXT, -- added_to_training, updated_kg, refined_prompt
46
+ applied_at TIMESTAMP,
47
+
48
+ -- Timestamps
49
+ created_at TIMESTAMP DEFAULT NOW(),
50
+
51
+ -- Source precedence context (Gold TC > Jira > Confluence > Docs)
52
+ source_context JSONB DEFAULT '{}'::jsonb -- which docs were retrieved, precedence applied
53
+ );
54
+
55
+ -- Indexes for feedback queries
56
+ CREATE INDEX IF NOT EXISTS idx_feedback_status ON feedback_events(status);
57
+ CREATE INDEX IF NOT EXISTS idx_feedback_type ON feedback_events(feedback_type);
58
+ CREATE INDEX IF NOT EXISTS idx_feedback_created ON feedback_events(created_at DESC);
59
+ CREATE INDEX IF NOT EXISTS idx_feedback_curator ON feedback_events(curator_id);
60
+ CREATE INDEX IF NOT EXISTS idx_feedback_query ON feedback_events USING gin(to_tsvector('english', query));
61
+
62
+
63
+ -- ─────────────────────────────────────────────────────────────────────────────
64
+ -- Evaluation Runs Table
65
+ -- ─────────────────────────────────────────────────────────────────────────────
66
+
67
+ CREATE TABLE IF NOT EXISTS eval_runs (
68
+ id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
69
+
70
+ -- Run identification
71
+ run_id TEXT UNIQUE NOT NULL, -- human-readable ID (e.g., "baseline", "phase2_v1")
72
+ run_type TEXT NOT NULL, -- baseline, regression, comparison, manual
73
+
74
+ -- Aggregate scores (5 dimensions + overall)
75
+ avg_retrieval DOUBLE PRECISION,
76
+ avg_domain DOUBLE PRECISION,
77
+ avg_structural DOUBLE PRECISION,
78
+ avg_executability DOUBLE PRECISION,
79
+ avg_publish DOUBLE PRECISION,
80
+ avg_overall DOUBLE PRECISION,
81
+ pass_rate DOUBLE PRECISION,
82
+
83
+ -- Metadata
84
+ query_count INT NOT NULL,
85
+ duration_seconds DOUBLE PRECISION,
86
+ system_version TEXT, -- git commit, phase identifier, etc.
87
+ metadata JSONB DEFAULT '{}'::jsonb,
88
+
89
+ -- Timestamps
90
+ created_at TIMESTAMP DEFAULT NOW()
91
+ );
92
+
93
+ -- Indexes for eval runs
94
+ CREATE INDEX IF NOT EXISTS idx_eval_runs_id ON eval_runs(run_id);
95
+ CREATE INDEX IF NOT EXISTS idx_eval_runs_type ON eval_runs(run_type);
96
+ CREATE INDEX IF NOT EXISTS idx_eval_runs_created ON eval_runs(created_at DESC);
97
+
98
+
99
+ -- ─────────────────────────────────────────────────────────────────────────────
100
+ -- Evaluation Results Table (detailed per-query results)
101
+ -- ─────────────────────────────────────────────────────────────────────────────
102
+
103
+ CREATE TABLE IF NOT EXISTS eval_results (
104
+ id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
105
+
106
+ -- Parent run
107
+ eval_run_id UUID NOT NULL REFERENCES eval_runs(id) ON DELETE CASCADE,
108
+
109
+ -- Query
110
+ query_id TEXT NOT NULL, -- query identifier from queries_50.json
111
+ query TEXT NOT NULL,
112
+
113
+ -- Generated output
114
+ generated_output JSONB NOT NULL, -- full response
115
+
116
+ -- 5-dimensional scores
117
+ retrieval_score DOUBLE PRECISION,
118
+ retrieval_feedback TEXT[],
119
+ domain_score DOUBLE PRECISION,
120
+ domain_feedback TEXT[],
121
+ structural_score DOUBLE PRECISION,
122
+ structural_feedback TEXT[],
123
+ executability_score DOUBLE PRECISION,
124
+ executability_feedback TEXT[],
125
+ publish_score DOUBLE PRECISION,
126
+ publish_feedback TEXT[],
127
+ overall_score DOUBLE PRECISION,
128
+ passed BOOLEAN,
129
+
130
+ -- Metadata
131
+ duration_seconds DOUBLE PRECISION,
132
+ metadata JSONB DEFAULT '{}'::jsonb,
133
+
134
+ created_at TIMESTAMP DEFAULT NOW()
135
+ );
136
+
137
+ -- Indexes for eval results
138
+ CREATE INDEX IF NOT EXISTS idx_eval_results_run ON eval_results(eval_run_id);
139
+ CREATE INDEX IF NOT EXISTS idx_eval_results_passed ON eval_results(passed);
140
+ CREATE INDEX IF NOT EXISTS idx_eval_results_overall ON eval_results(overall_score DESC);
141
+
142
+
143
+ -- ─────────────────────────────────────────────────────────────────────────────
144
+ -- Feedback Promotions (curated feedback approved for operational memory)
145
+ -- ─────────────────────────────────────────────────────────────────────────────
146
+
147
+ CREATE TABLE IF NOT EXISTS feedback_promotions (
148
+ id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
149
+ feedback_event_id UUID NOT NULL REFERENCES feedback_events(id) ON DELETE CASCADE,
150
+ curator_id TEXT NOT NULL,
151
+ curator_notes TEXT,
152
+ promoted_content JSONB NOT NULL DEFAULT '{}'::jsonb,
153
+ status TEXT NOT NULL DEFAULT 'pending', -- pending, applied, rejected
154
+ applied_at TIMESTAMP,
155
+ created_at TIMESTAMP DEFAULT NOW()
156
+ );
157
+
158
+ CREATE INDEX IF NOT EXISTS idx_feedback_promotions_status ON feedback_promotions(status);
159
+ CREATE INDEX IF NOT EXISTS idx_feedback_promotions_event ON feedback_promotions(feedback_event_id);
160
+
161
+
162
+ -- ─────────────────────────────────────────────────────────────────────────────
163
+ -- Feedback Audit Trail (lifecycle tracking for promoted items)
164
+ -- ─────────────────────────────────────────────────────────────────────────────
165
+
166
+ CREATE TABLE IF NOT EXISTS feedback_audit_trail (
167
+ id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
168
+ promotion_id UUID REFERENCES feedback_promotions(id) ON DELETE SET NULL,
169
+ feedback_event_id UUID REFERENCES feedback_events(id) ON DELETE SET NULL,
170
+ action TEXT NOT NULL,
171
+ actor_id TEXT,
172
+ details JSONB DEFAULT '{}'::jsonb,
173
+ created_at TIMESTAMP DEFAULT NOW()
174
+ );
175
+
176
+ CREATE INDEX IF NOT EXISTS idx_feedback_audit_promotion ON feedback_audit_trail(promotion_id);
177
+ CREATE INDEX IF NOT EXISTS idx_feedback_audit_event ON feedback_audit_trail(feedback_event_id);
178
+ CREATE INDEX IF NOT EXISTS idx_feedback_audit_created ON feedback_audit_trail(created_at DESC);
179
+ """
180
+
181
+
182
+ def ensure_feedback_tables() -> None:
183
+ """Create feedback and evaluation tables if they don't exist."""
184
+ with get_conn() as conn:
185
+ with conn.cursor() as cur:
186
+ cur.execute(_FEEDBACK_SCHEMA_SQL)
187
+ print(" Feedback tables ready (feedback_events, eval_runs, eval_results, feedback_promotions, feedback_audit_trail)")
188
+
189
+
190
+ def insert_feedback_event(
191
+ query: str,
192
+ generated_output: dict,
193
+ feedback_type: str,
194
+ feedback_data: dict,
195
+ generation_metadata: dict | None = None,
196
+ user_id: str | None = None,
197
+ session_id: str | None = None,
198
+ source_context: dict | None = None,
199
+ ) -> str:
200
+ """Insert a new feedback event. Returns event ID."""
201
+ import json
202
+
203
+ sql = """
204
+ INSERT INTO feedback_events
205
+ (query, generated_output, generation_metadata, feedback_type, feedback_data,
206
+ user_id, session_id, source_context)
207
+ VALUES (%s, %s::jsonb, %s::jsonb, %s, %s::jsonb, %s, %s, %s::jsonb)
208
+ RETURNING id
209
+ """
210
+
211
+ with get_conn() as conn:
212
+ with conn.cursor() as cur:
213
+ cur.execute(sql, (
214
+ query,
215
+ json.dumps(generated_output),
216
+ json.dumps(generation_metadata or {}),
217
+ feedback_type,
218
+ json.dumps(feedback_data),
219
+ user_id,
220
+ session_id,
221
+ json.dumps(source_context or {}),
222
+ ))
223
+ return str(cur.fetchone()[0])
224
+
225
+
226
+ def update_feedback_curation(
227
+ event_id: str,
228
+ status: str,
229
+ curator_id: str,
230
+ curator_notes: str | None = None,
231
+ ) -> None:
232
+ """Update curation status of a feedback event (reviewed, approved, rejected)."""
233
+ sql = """
234
+ UPDATE feedback_events
235
+ SET status = %s,
236
+ curator_id = %s,
237
+ curator_notes = %s,
238
+ curated_at = NOW()
239
+ WHERE id = %s
240
+ """
241
+
242
+ with get_conn() as conn:
243
+ with conn.cursor() as cur:
244
+ cur.execute(sql, (status, curator_id, curator_notes, event_id))
245
+
246
+
247
+ def mark_feedback_applied(
248
+ event_id: str,
249
+ applied_action: str,
250
+ ) -> None:
251
+ """Mark feedback as applied to the system."""
252
+ sql = """
253
+ UPDATE feedback_events
254
+ SET status = 'applied',
255
+ applied_action = %s,
256
+ applied_at = NOW()
257
+ WHERE id = %s
258
+ """
259
+
260
+ with get_conn() as conn:
261
+ with conn.cursor() as cur:
262
+ cur.execute(sql, (applied_action, event_id))
263
+
264
+
265
+ def insert_eval_run(
266
+ run_id: str,
267
+ run_type: str,
268
+ avg_scores: dict,
269
+ pass_rate: float,
270
+ query_count: int,
271
+ duration_seconds: float,
272
+ system_version: str | None = None,
273
+ metadata: dict | None = None,
274
+ ) -> str:
275
+ """Insert an evaluation run summary. Returns eval_run UUID."""
276
+ import json
277
+
278
+ sql = """
279
+ INSERT INTO eval_runs
280
+ (run_id, run_type, avg_retrieval, avg_domain, avg_structural,
281
+ avg_executability, avg_publish, avg_overall, pass_rate,
282
+ query_count, duration_seconds, system_version, metadata)
283
+ VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s::jsonb)
284
+ RETURNING id
285
+ """
286
+
287
+ with get_conn() as conn:
288
+ with conn.cursor() as cur:
289
+ cur.execute(sql, (
290
+ run_id,
291
+ run_type,
292
+ avg_scores.get("retrieval"),
293
+ avg_scores.get("domain"),
294
+ avg_scores.get("structural"),
295
+ avg_scores.get("executability"),
296
+ avg_scores.get("publish"),
297
+ avg_scores.get("overall"),
298
+ pass_rate,
299
+ query_count,
300
+ duration_seconds,
301
+ system_version,
302
+ json.dumps(metadata or {}),
303
+ ))
304
+ return str(cur.fetchone()[0])
305
+
306
+
307
+ def insert_eval_results_batch(eval_run_uuid: str, results: list[dict]) -> None:
308
+ """Batch insert detailed per-query evaluation results."""
309
+ import json
310
+
311
+ sql = """
312
+ INSERT INTO eval_results
313
+ (eval_run_id, query_id, query, generated_output,
314
+ retrieval_score, retrieval_feedback, domain_score, domain_feedback,
315
+ structural_score, structural_feedback, executability_score, executability_feedback,
316
+ publish_score, publish_feedback, overall_score, passed,
317
+ duration_seconds, metadata)
318
+ VALUES (%s, %s, %s, %s::jsonb, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s::jsonb)
319
+ """
320
+
321
+ with get_conn() as conn:
322
+ with conn.cursor() as cur:
323
+ for r in results:
324
+ cur.execute(sql, (
325
+ eval_run_uuid,
326
+ r["query_id"],
327
+ r["query"],
328
+ json.dumps(r["generated_output"]),
329
+ r["retrieval_score"],
330
+ r["retrieval_feedback"],
331
+ r["domain_score"],
332
+ r["domain_feedback"],
333
+ r["structural_score"],
334
+ r["structural_feedback"],
335
+ r["executability_score"],
336
+ r["executability_feedback"],
337
+ r["publish_score"],
338
+ r["publish_feedback"],
339
+ r["overall_score"],
340
+ r["passed"],
341
+ r.get("duration_seconds"),
342
+ json.dumps(r.get("metadata", {})),
343
+ ))
344
+
345
+
346
+ def insert_feedback_promotion(
347
+ feedback_event_id: str,
348
+ curator_id: str,
349
+ promoted_content: dict,
350
+ curator_notes: str | None = None,
351
+ ) -> str:
352
+ """Create a promotion record for curated feedback. Returns promotion UUID."""
353
+ import json
354
+
355
+ sql = """
356
+ INSERT INTO feedback_promotions
357
+ (feedback_event_id, curator_id, curator_notes, promoted_content, status)
358
+ VALUES (%s, %s, %s, %s::jsonb, 'pending')
359
+ RETURNING id
360
+ """
361
+ with get_conn() as conn:
362
+ with conn.cursor() as cur:
363
+ cur.execute(sql, (
364
+ feedback_event_id,
365
+ curator_id,
366
+ curator_notes,
367
+ json.dumps(promoted_content),
368
+ ))
369
+ promotion_id = str(cur.fetchone()[0])
370
+ insert_feedback_audit(
371
+ promotion_id=promotion_id,
372
+ feedback_event_id=feedback_event_id,
373
+ action="promotion_created",
374
+ actor_id=curator_id,
375
+ details={"status": "pending"},
376
+ cursor=cur,
377
+ )
378
+ return promotion_id
379
+
380
+
381
+ def mark_promotion_applied(promotion_id: str, actor_id: str | None = None) -> None:
382
+ """Mark a promotion as applied to the system."""
383
+ sql = """
384
+ UPDATE feedback_promotions
385
+ SET status = 'applied', applied_at = NOW()
386
+ WHERE id = %s
387
+ RETURNING feedback_event_id
388
+ """
389
+ with get_conn() as conn:
390
+ with conn.cursor() as cur:
391
+ cur.execute(sql, (promotion_id,))
392
+ row = cur.fetchone()
393
+ if row:
394
+ insert_feedback_audit(
395
+ promotion_id=promotion_id,
396
+ feedback_event_id=str(row[0]),
397
+ action="promotion_applied",
398
+ actor_id=actor_id,
399
+ details={"status": "applied"},
400
+ cursor=cur,
401
+ )
402
+
403
+
404
+ def insert_feedback_audit(
405
+ action: str,
406
+ promotion_id: str | None = None,
407
+ feedback_event_id: str | None = None,
408
+ actor_id: str | None = None,
409
+ details: dict | None = None,
410
+ cursor=None,
411
+ ) -> str:
412
+ """Record an audit trail entry for feedback lifecycle events."""
413
+ import json
414
+
415
+ sql = """
416
+ INSERT INTO feedback_audit_trail
417
+ (promotion_id, feedback_event_id, action, actor_id, details)
418
+ VALUES (%s, %s, %s, %s, %s::jsonb)
419
+ RETURNING id
420
+ """
421
+ params = (
422
+ promotion_id,
423
+ feedback_event_id,
424
+ action,
425
+ actor_id,
426
+ json.dumps(details or {}),
427
+ )
428
+ if cursor is not None:
429
+ cursor.execute(sql, params)
430
+ return str(cursor.fetchone()[0])
431
+
432
+ with get_conn() as conn:
433
+ with conn.cursor() as cur:
434
+ cur.execute(sql, params)
435
+ return str(cur.fetchone()[0])
436
+
437
+
438
+ def list_feedback_events(
439
+ status: str = "pending",
440
+ limit: int = 10,
441
+ offset: int = 0,
442
+ ) -> list[dict]:
443
+ """List feedback events by curation status."""
444
+ import json
445
+
446
+ sql = """
447
+ SELECT id::text, query, feedback_type, status, created_at,
448
+ generated_output, feedback_data, curator_notes
449
+ FROM feedback_events
450
+ WHERE status = %s
451
+ ORDER BY created_at DESC
452
+ LIMIT %s OFFSET %s
453
+ """
454
+ with get_conn() as conn:
455
+ with conn.cursor() as cur:
456
+ cur.execute(sql, (status, limit, offset))
457
+ rows = cur.fetchall()
458
+
459
+ results = []
460
+ for row in rows:
461
+ results.append({
462
+ "id": row[0],
463
+ "query": row[1],
464
+ "feedback_type": row[2],
465
+ "status": row[3],
466
+ "created_at": row[4].isoformat() if row[4] else None,
467
+ "generated_output": row[5] if isinstance(row[5], dict) else json.loads(row[5] or "{}"),
468
+ "feedback_data": row[6] if isinstance(row[6], dict) else json.loads(row[6] or "{}"),
469
+ "curator_notes": row[7],
470
+ })
471
+ return results
472
+
473
+
474
+ def get_feedback_event(event_id: str) -> dict | None:
475
+ """Fetch a single feedback event by UUID."""
476
+ import json
477
+
478
+ sql = """
479
+ SELECT id::text, query, feedback_type, status, created_at, curated_at,
480
+ generated_output, feedback_data, generation_metadata, source_context,
481
+ curator_id, curator_notes, applied_action, applied_at
482
+ FROM feedback_events WHERE id = %s
483
+ """
484
+ with get_conn() as conn:
485
+ with conn.cursor() as cur:
486
+ cur.execute(sql, (event_id,))
487
+ row = cur.fetchone()
488
+
489
+ if not row:
490
+ return None
491
+
492
+ def _j(val):
493
+ if val is None:
494
+ return {}
495
+ return val if isinstance(val, dict) else json.loads(val)
496
+
497
+ return {
498
+ "id": row[0],
499
+ "query": row[1],
500
+ "feedback_type": row[2],
501
+ "status": row[3],
502
+ "created_at": row[4].isoformat() if row[4] else None,
503
+ "curated_at": row[5].isoformat() if row[5] else None,
504
+ "generated_output": _j(row[6]),
505
+ "feedback_data": _j(row[7]),
506
+ "generation_metadata": _j(row[8]),
507
+ "source_context": _j(row[9]),
508
+ "curator_id": row[10],
509
+ "curator_notes": row[11],
510
+ "applied_action": row[12],
511
+ "applied_at": row[13].isoformat() if row[13] else None,
512
+ }
513
+
514
+
515
+ def list_promotions(status: str = "pending", limit: int = 20) -> list[dict]:
516
+ """List feedback promotions by status."""
517
+ import json
518
+
519
+ sql = """
520
+ SELECT p.id::text, p.feedback_event_id::text, p.curator_id, p.curator_notes,
521
+ p.promoted_content, p.status, p.applied_at, p.created_at,
522
+ e.query, e.feedback_type
523
+ FROM feedback_promotions p
524
+ JOIN feedback_events e ON e.id = p.feedback_event_id
525
+ WHERE p.status = %s
526
+ ORDER BY p.created_at DESC
527
+ LIMIT %s
528
+ """
529
+ with get_conn() as conn:
530
+ with conn.cursor() as cur:
531
+ cur.execute(sql, (status, limit))
532
+ rows = cur.fetchall()
533
+
534
+ out = []
535
+ for row in rows:
536
+ out.append({
537
+ "id": row[0],
538
+ "feedback_event_id": row[1],
539
+ "curator_id": row[2],
540
+ "curator_notes": row[3],
541
+ "promoted_content": row[4] if isinstance(row[4], dict) else json.loads(row[4] or "{}"),
542
+ "status": row[5],
543
+ "applied_at": row[6].isoformat() if row[6] else None,
544
+ "created_at": row[7].isoformat() if row[7] else None,
545
+ "query": row[8],
546
+ "feedback_type": row[9],
547
+ })
548
+ return out
@@ -0,0 +1,150 @@
1
+ """
2
+ Enterprise Schema for IGEL QE Agent
3
+ ===================================
4
+ Manages tables for the AI Platform Layer:
5
+ - Automation Asset Registry (Code Intelligence)
6
+ - Requirement Tracking (Xray integration)
7
+ - Granular Feedback (4-level precision)
8
+ - Regression Intelligence (Impact mappings)
9
+ """
10
+ from __future__ import annotations
11
+
12
+ import logging
13
+ from knowledge_base.db.client import get_conn
14
+ from knowledge_base.config import cfg
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+ _IGEL_SCHEMA_SQL = f"""
19
+ -- Enable extensions if not already present
20
+ CREATE EXTENSION IF NOT EXISTS vector;
21
+ CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
22
+
23
+ -- ==========================================
24
+ -- 1. Automation Asset Registry
25
+ -- ==========================================
26
+ CREATE TABLE IF NOT EXISTS igel_asset_registry (
27
+ id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
28
+ asset_type TEXT NOT NULL, -- 'page_object', 'fixture', 'utility', 'api_client', 'base_class'
29
+ name TEXT NOT NULL,
30
+ file_path TEXT NOT NULL,
31
+ description TEXT, -- Docstring or AI summary
32
+ signature TEXT, -- Class/Function signature
33
+ dependencies JSONB DEFAULT '[]'::jsonb, -- Other assets this depends on
34
+ embedding VECTOR({cfg.EMBEDDING_DIM}),
35
+ file_hash TEXT,
36
+ last_indexed TIMESTAMP DEFAULT NOW()
37
+ );
38
+
39
+ CREATE INDEX IF NOT EXISTS asset_type_idx ON igel_asset_registry(asset_type);
40
+
41
+ -- ==========================================
42
+ -- 2. Requirement Modeling & Understanding
43
+ -- ==========================================
44
+ CREATE TABLE IF NOT EXISTS igel_requirements (
45
+ id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
46
+ jira_key TEXT UNIQUE NOT NULL,
47
+ summary TEXT NOT NULL,
48
+ description TEXT,
49
+ labels JSONB DEFAULT '[]'::jsonb,
50
+ components JSONB DEFAULT '[]'::jsonb,
51
+ status TEXT,
52
+ created_at TIMESTAMP DEFAULT NOW()
53
+ );
54
+
55
+ -- AI Extracted Understanding
56
+ CREATE TABLE IF NOT EXISTS igel_requirement_understanding (
57
+ id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
58
+ requirement_id UUID NOT NULL REFERENCES igel_requirements(id) ON DELETE CASCADE,
59
+ actors JSONB DEFAULT '[]'::jsonb,
60
+ entities JSONB DEFAULT '[]'::jsonb,
61
+ validations JSONB DEFAULT '[]'::jsonb,
62
+ constraints JSONB DEFAULT '[]'::jsonb,
63
+ dependencies JSONB DEFAULT '[]'::jsonb,
64
+ analyzed_at TIMESTAMP DEFAULT NOW()
65
+ );
66
+
67
+ CREATE TABLE IF NOT EXISTS igel_scenarios (
68
+ id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
69
+ requirement_id UUID NOT NULL REFERENCES igel_requirements(id) ON DELETE CASCADE,
70
+ step_number INT NOT NULL,
71
+ action TEXT NOT NULL,
72
+ test_data TEXT,
73
+ expected_result TEXT,
74
+ created_at TIMESTAMP DEFAULT NOW(),
75
+ UNIQUE(requirement_id, step_number)
76
+ );
77
+
78
+ CREATE TABLE IF NOT EXISTS igel_business_rules (
79
+ id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
80
+ scenario_id UUID NOT NULL REFERENCES igel_scenarios(id) ON DELETE CASCADE,
81
+ rule_type TEXT NOT NULL, -- 'positive', 'negative', 'edge'
82
+ description TEXT NOT NULL,
83
+ created_at TIMESTAMP DEFAULT NOW()
84
+ );
85
+
86
+ -- ==========================================
87
+ -- 3. Test Cases & Generation Artifacts
88
+ -- ==========================================
89
+ CREATE TABLE IF NOT EXISTS igel_generated_testcases (
90
+ id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
91
+ tc_reference TEXT UNIQUE NOT NULL, -- e.g., 'TC_IGEL-1234_S01_B01'
92
+ business_rule_id UUID NOT NULL REFERENCES igel_business_rules(id) ON DELETE CASCADE,
93
+ title TEXT NOT NULL,
94
+ test_type TEXT NOT NULL,
95
+ priority TEXT NOT NULL,
96
+ preconditions JSONB DEFAULT '[]'::jsonb,
97
+ steps JSONB DEFAULT '[]'::jsonb,
98
+ confidence_score FLOAT NOT NULL,
99
+ confidence_metrics JSONB NOT NULL, -- Breakdown (coverage, traceability, etc.)
100
+ status TEXT DEFAULT 'pending_review', -- 'pending_review', 'approved', 'rejected'
101
+ created_at TIMESTAMP DEFAULT NOW()
102
+ );
103
+
104
+ CREATE TABLE IF NOT EXISTS igel_automation_scripts (
105
+ id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
106
+ requirement_id UUID NOT NULL REFERENCES igel_requirements(id) ON DELETE CASCADE,
107
+ script_path TEXT NOT NULL,
108
+ automation_plan JSONB NOT NULL, -- The JSON plan from Design Agent
109
+ code_content TEXT NOT NULL,
110
+ validation_status TEXT DEFAULT 'pending', -- 'pending', 'syntax_failed', 'import_failed', 'passed'
111
+ created_at TIMESTAMP DEFAULT NOW()
112
+ );
113
+
114
+ -- ==========================================
115
+ -- 4. Regression Intelligence (Impact Analysis)
116
+ -- ==========================================
117
+ CREATE TABLE IF NOT EXISTS igel_asset_mappings (
118
+ id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
119
+ requirement_id UUID NOT NULL REFERENCES igel_requirements(id) ON DELETE CASCADE,
120
+ asset_id UUID NOT NULL REFERENCES igel_asset_registry(id) ON DELETE CASCADE,
121
+ mapping_type TEXT NOT NULL, -- 'required_for_test', 'used_in_script'
122
+ created_at TIMESTAMP DEFAULT NOW()
123
+ );
124
+
125
+ -- ==========================================
126
+ -- 5. Granular Human Feedback
127
+ -- ==========================================
128
+ CREATE TABLE IF NOT EXISTS igel_granular_feedback (
129
+ id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
130
+ level TEXT NOT NULL, -- 'requirement', 'scenario', 'testcase', 'teststep'
131
+ target_id TEXT NOT NULL, -- The UUID of the target entity
132
+ feedback_type TEXT NOT NULL, -- 'correction', 'rejection', 'enhancement', 'approval'
133
+ user_comment TEXT,
134
+ corrected_data JSONB, -- The explicit fix applied by the user
135
+ applied BOOLEAN DEFAULT FALSE,
136
+ created_at TIMESTAMP DEFAULT NOW()
137
+ );
138
+ """
139
+
140
+ def ensure_igel_tables():
141
+ """Create IGEL enterprise tables if they don't exist."""
142
+ try:
143
+ with get_conn() as conn:
144
+ with conn.cursor() as cur:
145
+ cur.execute(_IGEL_SCHEMA_SQL)
146
+ conn.commit()
147
+ logger.info("IGEL Enterprise DB schema verified.")
148
+ except Exception as e:
149
+ logger.error(f"Failed to create IGEL schema: {{e}}")
150
+ raise