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,494 @@
1
+ """
2
+ 5-Dimension Scoring for Test Case Generation Quality
3
+ ====================================================
4
+ Each scorer returns a score [0.0, 1.0] and detailed feedback.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ import ast
9
+ import re
10
+ from dataclasses import dataclass, field
11
+ from typing import Any
12
+
13
+
14
+ @dataclass
15
+ class ScoreDimension:
16
+ """Single dimension score with feedback."""
17
+ name: str
18
+ score: float # 0.0 to 1.0
19
+ feedback: list[str] = field(default_factory=list)
20
+ metadata: dict[str, Any] = field(default_factory=dict)
21
+
22
+
23
+ @dataclass
24
+ class EvaluationResult:
25
+ """Complete evaluation result with all 5 dimensions."""
26
+ query: str
27
+ retrieval: ScoreDimension
28
+ domain: ScoreDimension
29
+ structural: ScoreDimension
30
+ executability: ScoreDimension
31
+ publish: ScoreDimension
32
+
33
+ @property
34
+ def overall_score(self) -> float:
35
+ """Weighted average: publish is composite of the other 4."""
36
+ return (
37
+ self.retrieval.score * 0.25 +
38
+ self.domain.score * 0.25 +
39
+ self.structural.score * 0.25 +
40
+ self.executability.score * 0.25
41
+ )
42
+
43
+ @property
44
+ def passed(self) -> bool:
45
+ """Pass if all dimensions >= 0.6 and overall >= 0.7."""
46
+ return (
47
+ self.retrieval.score >= 0.6 and
48
+ self.domain.score >= 0.6 and
49
+ self.structural.score >= 0.6 and
50
+ self.executability.score >= 0.6 and
51
+ self.overall_score >= 0.7
52
+ )
53
+
54
+
55
+ # ── Retrieval Confidence Scorer ──────────────────────────────────────────────
56
+
57
+ class RetrievalScorer:
58
+ """Score retrieval quality: Did we find relevant chunks?"""
59
+
60
+ def score(
61
+ self,
62
+ query: str,
63
+ retrieved_chunks: list,
64
+ retrieval_metadata: dict,
65
+ ) -> ScoreDimension:
66
+ """
67
+ Scoring criteria:
68
+ - Number of chunks retrieved (more = better signal, up to 10)
69
+ - RRF scores (higher = better relevance)
70
+ - Rerank scores if available
71
+ - Diversity (chunks from different documents)
72
+ """
73
+ feedback = []
74
+ score = 0.0
75
+
76
+ if not retrieved_chunks:
77
+ return ScoreDimension(
78
+ name="retrieval_confidence",
79
+ score=0.0,
80
+ feedback=["CRITICAL: No chunks retrieved"],
81
+ )
82
+
83
+ # Criterion 1: Number of chunks (max score 0.3)
84
+ chunk_count = len(retrieved_chunks)
85
+ chunk_score = min(chunk_count / 10.0, 1.0) * 0.3
86
+ score += chunk_score
87
+ feedback.append(f"Retrieved {chunk_count} chunks (score: {chunk_score:.2f})")
88
+
89
+ # Criterion 2: RRF scores (max score 0.4)
90
+ rrf_scores = [
91
+ getattr(c, 'rrf_score', 0.0) for c in retrieved_chunks
92
+ ]
93
+ if rrf_scores:
94
+ avg_rrf = sum(rrf_scores) / len(rrf_scores)
95
+ # RRF scores typically range 0-0.1, normalize to 0-1
96
+ rrf_normalized = min(avg_rrf * 10, 1.0)
97
+ rrf_component = rrf_normalized * 0.4
98
+ score += rrf_component
99
+ feedback.append(
100
+ f"Avg RRF score: {avg_rrf:.4f} (normalized: {rrf_normalized:.2f}, "
101
+ f"component: {rrf_component:.2f})"
102
+ )
103
+
104
+ # Criterion 3: Rerank scores if available (max score 0.3)
105
+ rerank_scores = [
106
+ getattr(c, 'rerank_score', None) for c in retrieved_chunks
107
+ ]
108
+ rerank_scores = [s for s in rerank_scores if s is not None]
109
+ if rerank_scores:
110
+ avg_rerank = sum(rerank_scores) / len(rerank_scores)
111
+ rerank_component = min(avg_rerank, 1.0) * 0.3
112
+ score += rerank_component
113
+ feedback.append(
114
+ f"Avg rerank score: {avg_rerank:.2f} (component: {rerank_component:.2f})"
115
+ )
116
+ else:
117
+ feedback.append("No reranking applied (missing 0.3 score)")
118
+ score += 0.0 # penalty for no reranking
119
+
120
+ return ScoreDimension(
121
+ name="retrieval_confidence",
122
+ score=min(score, 1.0),
123
+ feedback=feedback,
124
+ metadata={
125
+ "chunk_count": chunk_count,
126
+ "rrf_scores": rrf_scores,
127
+ "rerank_scores": rerank_scores,
128
+ },
129
+ )
130
+
131
+
132
+ # ── Domain Confidence Scorer ──────────────────────────────────────────────────
133
+
134
+ class DomainScorer:
135
+ """Score domain validity: Are entities (registry keys, UI paths) validated?"""
136
+
137
+ def __init__(self, kg_client=None):
138
+ """kg_client: optional KG client to verify entities against graph."""
139
+ self.kg_client = kg_client
140
+
141
+ def score(
142
+ self,
143
+ markdown_output: str,
144
+ python_output: str | None,
145
+ retrieved_chunks: list,
146
+ kg_entities: dict | None = None,
147
+ ) -> ScoreDimension:
148
+ """
149
+ Scoring criteria:
150
+ - Registry keys present and verified against KG
151
+ - UI paths present and verified against KG
152
+ - No hallucinated entities
153
+ - Product consistency
154
+ """
155
+ feedback = []
156
+ score = 1.0 # start at 1.0, deduct for issues
157
+
158
+ combined = markdown_output + "\n" + (python_output or "")
159
+
160
+ # Extract registry keys
161
+ registry_keys = re.findall(r'\bapp\.[a-z0-9_]+(?:\.[a-z0-9_]+)*', combined, re.I)
162
+ registry_keys = list(set(registry_keys))
163
+
164
+ # Extract UI paths (TC Setup > ...)
165
+ ui_paths = re.findall(
166
+ r'TC Setup\s*>\s*(?:[^>\n]+\s*>\s*)*[^>\n]+',
167
+ combined,
168
+ re.I
169
+ )
170
+ ui_paths = list(set(ui_paths))
171
+
172
+ feedback.append(f"Found {len(registry_keys)} registry keys")
173
+ feedback.append(f"Found {len(ui_paths)} UI paths")
174
+
175
+ # If KG client available, verify entities
176
+ if self.kg_client and kg_entities:
177
+ verified_keys = kg_entities.get('registry_keys', [])
178
+ verified_paths = kg_entities.get('ui_paths', [])
179
+
180
+ # Check registry keys
181
+ unverified_keys = [
182
+ k for k in registry_keys
183
+ if k.lower() not in [v.lower() for v in verified_keys]
184
+ ]
185
+ if unverified_keys:
186
+ penalty = len(unverified_keys) * 0.1
187
+ score -= penalty
188
+ feedback.append(
189
+ f"WARNING: {len(unverified_keys)} unverified registry keys "
190
+ f"(penalty: -{penalty:.2f}): {unverified_keys[:3]}"
191
+ )
192
+
193
+ # Check UI paths
194
+ unverified_paths = [
195
+ p for p in ui_paths
196
+ if not any(p.lower() in v.lower() or v.lower() in p.lower() for v in verified_paths)
197
+ ]
198
+ if unverified_paths:
199
+ penalty = len(unverified_paths) * 0.1
200
+ score -= penalty
201
+ feedback.append(
202
+ f"WARNING: {len(unverified_paths)} unverified UI paths "
203
+ f"(penalty: -{penalty:.2f})"
204
+ )
205
+ else:
206
+ # No KG verification — partial penalty
207
+ if registry_keys or ui_paths:
208
+ score -= 0.2
209
+ feedback.append(
210
+ "WARNING: No KG verification available (penalty: -0.2)"
211
+ )
212
+
213
+ # Check for common hallucination patterns
214
+ hallucination_patterns = [
215
+ r'http://example\.com',
216
+ r'TODO:',
217
+ r'PLACEHOLDER',
218
+ r'\[insert.*?\]',
219
+ ]
220
+ for pattern in hallucination_patterns:
221
+ if re.search(pattern, combined, re.I):
222
+ score -= 0.15
223
+ feedback.append(f"HALLUCINATION: Found pattern '{pattern}' (penalty: -0.15)")
224
+
225
+ return ScoreDimension(
226
+ name="domain_confidence",
227
+ score=max(score, 0.0),
228
+ feedback=feedback,
229
+ metadata={
230
+ "registry_keys": registry_keys,
231
+ "ui_paths": ui_paths,
232
+ },
233
+ )
234
+
235
+
236
+ # ── Structural Completeness Scorer ────────────────────────────────────────────
237
+
238
+ class StructuralScorer:
239
+ """Score structural quality: Does TC have all required sections?"""
240
+
241
+ def score(
242
+ self,
243
+ markdown_output: str,
244
+ python_output: str | None,
245
+ ) -> ScoreDimension:
246
+ """
247
+ Scoring criteria:
248
+ - Preconditions section exists
249
+ - Steps table exists with >= 3 steps
250
+ - Each step has test data and expected result
251
+ - Cleanup/teardown mentioned
252
+ - Markdown follows template structure
253
+ """
254
+ feedback = []
255
+ score = 0.0
256
+
257
+ # Criterion 1: Preconditions (0.2)
258
+ if re.search(r'##\s*Preconditions?', markdown_output, re.I):
259
+ score += 0.2
260
+ feedback.append("✓ Preconditions section present (+0.2)")
261
+ else:
262
+ feedback.append("✗ Missing preconditions section")
263
+
264
+ # Criterion 2: Steps table (0.3)
265
+ steps_match = re.search(
266
+ r'\|\s*#\s*\|\s*STEP\s*\|.*?\n\|[-|\s]+\n(.*?)(?=\n##|\Z)',
267
+ markdown_output,
268
+ re.DOTALL | re.I
269
+ )
270
+ if steps_match:
271
+ table_body = steps_match.group(1)
272
+ step_rows = [
273
+ row.strip() for row in table_body.split('\n')
274
+ if row.strip() and not row.strip().startswith('|---')
275
+ ]
276
+ step_count = len(step_rows)
277
+
278
+ if step_count >= 3:
279
+ score += 0.3
280
+ feedback.append(f"✓ Steps table with {step_count} steps (+0.3)")
281
+ else:
282
+ partial = (step_count / 3) * 0.3
283
+ score += partial
284
+ feedback.append(
285
+ f"✗ Only {step_count} steps (expected >= 3, partial: +{partial:.2f})"
286
+ )
287
+ else:
288
+ feedback.append("✗ Missing steps table")
289
+
290
+ # Criterion 3: Expected results (0.2)
291
+ expected_count = len(re.findall(r'expected result', markdown_output, re.I))
292
+ if expected_count >= 3:
293
+ score += 0.2
294
+ feedback.append(f"✓ Expected results present ({expected_count} mentions, +0.2)")
295
+ else:
296
+ partial = (expected_count / 3) * 0.2
297
+ score += partial
298
+ feedback.append(
299
+ f"✗ Few expected results ({expected_count} mentions, +{partial:.2f})"
300
+ )
301
+
302
+ # Criterion 4: Cleanup/teardown (0.15)
303
+ if re.search(r'\b(cleanup|teardown|reboot|reset)\b', markdown_output, re.I):
304
+ score += 0.15
305
+ feedback.append("✓ Cleanup mentioned (+0.15)")
306
+ else:
307
+ feedback.append("✗ No cleanup/teardown mentioned")
308
+
309
+ # Criterion 5: Python structure if available (0.15)
310
+ if python_output:
311
+ has_steps = bool(re.findall(r'def\s+\w+_step\d+\s*\(', python_output))
312
+ has_cleanup = 'def.*cleanup' in python_output.lower()
313
+
314
+ if has_steps:
315
+ score += 0.1
316
+ feedback.append("✓ Python has step functions (+0.1)")
317
+ if has_cleanup:
318
+ score += 0.05
319
+ feedback.append("✓ Python has cleanup (+0.05)")
320
+
321
+ return ScoreDimension(
322
+ name="structural_completeness",
323
+ score=min(score, 1.0),
324
+ feedback=feedback,
325
+ )
326
+
327
+
328
+ # ── Executability Scorer ──────────────────────────────────────────────────────
329
+
330
+ class ExecutabilityScorer:
331
+ """Score Python script quality: Does it parse, import, pass lint?"""
332
+
333
+ def score(
334
+ self,
335
+ python_output: str | None,
336
+ ) -> ScoreDimension:
337
+ """
338
+ Scoring criteria:
339
+ - Python parses (AST valid)
340
+ - Required imports present (pytest, allure, etc.)
341
+ - Fixture usage correct
342
+ - Registry key operations use proper helpers
343
+ - No bare asserts (use proper assertions)
344
+ """
345
+ feedback = []
346
+ score = 0.0
347
+
348
+ if not python_output:
349
+ return ScoreDimension(
350
+ name="script_executability",
351
+ score=0.0,
352
+ feedback=["No Python output to score"],
353
+ )
354
+
355
+ # Criterion 1: Valid Python syntax (0.3)
356
+ try:
357
+ ast.parse(python_output)
358
+ score += 0.3
359
+ feedback.append("✓ Valid Python syntax (+0.3)")
360
+ except SyntaxError as e:
361
+ feedback.append(f"✗ Syntax error: {e}")
362
+ return ScoreDimension(
363
+ name="script_executability",
364
+ score=0.0,
365
+ feedback=feedback,
366
+ )
367
+
368
+ # Criterion 2: Required imports (0.25)
369
+ required_imports = ['pytest', 'allure']
370
+ present_imports = []
371
+ for imp in required_imports:
372
+ if f'import {imp}' in python_output or f'from {imp}' in python_output:
373
+ present_imports.append(imp)
374
+
375
+ import_score = (len(present_imports) / len(required_imports)) * 0.25
376
+ score += import_score
377
+ if len(present_imports) == len(required_imports):
378
+ feedback.append(f"✓ All required imports present (+0.25)")
379
+ else:
380
+ missing = set(required_imports) - set(present_imports)
381
+ feedback.append(
382
+ f"✗ Missing imports: {missing} (+{import_score:.2f})"
383
+ )
384
+
385
+ # Criterion 3: Fixture usage (0.2)
386
+ common_fixtures = ['ums_cred', 'device_cred', 'api_config']
387
+ used_fixtures = [f for f in common_fixtures if f in python_output]
388
+ if used_fixtures:
389
+ score += 0.2
390
+ feedback.append(f"✓ Uses fixtures: {used_fixtures} (+0.2)")
391
+ else:
392
+ feedback.append("✗ No standard fixtures used")
393
+
394
+ # Criterion 4: Proper assertions (0.15)
395
+ bare_asserts = len(re.findall(r'\bassert\s+\w', python_output))
396
+ proper_asserts = len(re.findall(r'assert.*==|assert.*in|assert.*is', python_output))
397
+
398
+ if proper_asserts >= bare_asserts * 0.8: # 80% proper assertions
399
+ score += 0.15
400
+ feedback.append(
401
+ f"✓ Proper assertions ({proper_asserts}/{bare_asserts}, +0.15)"
402
+ )
403
+ else:
404
+ partial = (proper_asserts / max(bare_asserts, 1)) * 0.15
405
+ score += partial
406
+ feedback.append(
407
+ f"✗ Some bare asserts ({proper_asserts}/{bare_asserts}, +{partial:.2f})"
408
+ )
409
+
410
+ # Criterion 5: Registry key helper usage (0.1)
411
+ if 'app.' in python_output:
412
+ # Should use get/set helpers, not raw registry operations
413
+ has_helpers = bool(re.search(r'\b(get|set)_registry\b', python_output))
414
+ if has_helpers:
415
+ score += 0.1
416
+ feedback.append("✓ Uses registry helpers (+0.1)")
417
+ else:
418
+ feedback.append("✗ Registry keys without helpers")
419
+ else:
420
+ # No registry keys = neutral (no penalty)
421
+ score += 0.1
422
+ feedback.append("✓ No registry operations needed (+0.1)")
423
+
424
+ return ScoreDimension(
425
+ name="script_executability",
426
+ score=min(score, 1.0),
427
+ feedback=feedback,
428
+ )
429
+
430
+
431
+ # ── Publish Confidence Scorer ─────────────────────────────────────────────────
432
+
433
+ class PublishScorer:
434
+ """Composite score: Ready for human use without editing?"""
435
+
436
+ def score(
437
+ self,
438
+ retrieval: ScoreDimension,
439
+ domain: ScoreDimension,
440
+ structural: ScoreDimension,
441
+ executability: ScoreDimension,
442
+ ) -> ScoreDimension:
443
+ """
444
+ Weighted composite:
445
+ - Retrieval: 25%
446
+ - Domain: 25%
447
+ - Structural: 25%
448
+ - Executability: 25%
449
+
450
+ Thresholds:
451
+ - >= 0.85: Publish immediately
452
+ - 0.70-0.84: Publish with low-priority review
453
+ - 0.60-0.69: Human review required
454
+ - < 0.60: Block, fix before publish
455
+ """
456
+ composite = (
457
+ retrieval.score * 0.25 +
458
+ domain.score * 0.25 +
459
+ structural.score * 0.25 +
460
+ executability.score * 0.25
461
+ )
462
+
463
+ feedback = []
464
+
465
+ if composite >= 0.85:
466
+ feedback.append("PUBLISH: High confidence, ready for immediate use")
467
+ elif composite >= 0.70:
468
+ feedback.append("PUBLISH: Good confidence, low-priority review recommended")
469
+ elif composite >= 0.60:
470
+ feedback.append("REVIEW REQUIRED: Moderate confidence, human validation needed")
471
+ else:
472
+ feedback.append("BLOCK: Low confidence, requires fixes before publishing")
473
+
474
+ # Flag specific issues
475
+ if retrieval.score < 0.6:
476
+ feedback.append("ISSUE: Poor retrieval quality")
477
+ if domain.score < 0.6:
478
+ feedback.append("ISSUE: Unverified or hallucinated entities")
479
+ if structural.score < 0.6:
480
+ feedback.append("ISSUE: Incomplete test case structure")
481
+ if executability.score < 0.6:
482
+ feedback.append("ISSUE: Script has errors or missing components")
483
+
484
+ return ScoreDimension(
485
+ name="publish_confidence",
486
+ score=composite,
487
+ feedback=feedback,
488
+ metadata={
489
+ "retrieval": retrieval.score,
490
+ "domain": domain.score,
491
+ "structural": structural.score,
492
+ "executability": executability.score,
493
+ },
494
+ )
@@ -0,0 +1,7 @@
1
+ # Few-shot exemplars for fidelity-first generation
2
+
3
+ - **pytest_reference_snippet.py** — Reference pytest shape (`@allure.step`, `TCnnn_stepN`, `api_config`, UMS/WUMS, SSH, OCR).
4
+ - **gold_manual_concise_snippet.md** — Short IGEL manual TC style (few steps, terse expected results).
5
+ - **gold_manual_detailed_snippet.md** — Long TC style (many steps, full `TC Setup` paths).
6
+
7
+ These are **style anchors**, not KB content. Transform mode still uses the user-pasted TC as primary truth.
@@ -0,0 +1,8 @@
1
+ # Example: concise official manual style (UMS device lifecycle)
2
+
3
+ | Step | Test Data | Expected Result |
4
+ |------|-----------|-----------------|
5
+ | Register endpoint | Register in UMS (Radar). Check WUMS import. | Endpoint registered; license applied if configured. |
6
+ | Check device info | Open device details: system + license. | Information displayed correctly. |
7
+ | Assign profiles | Assign app + standard profiles; save now / on reboot. | Profiles applied per option; apps from portal if applicable. |
8
+ | Reboot | Reboot via UMS. | Endpoint reboots. |
@@ -0,0 +1,7 @@
1
+ # Example: detailed official manual style (browser policies)
2
+
3
+ Steps preserve exact `TC Setup` navigation and verification URLs from IGEL QA.
4
+
5
+ 1. Open **TC Setup > Chromium Browser > Global Settings > General** — enable *Automatic browser restart on exit*. Expected: setting applied after policy sync.
6
+ 2. Open **TC Setup > Chromium Browser > Global Settings > Security & Encryption > JavaScript**. Navigate to `https://browserleaks.com/javascript` in session. Expected: behavior matches policy (enabled/disabled as configured).
7
+ 3. Use **chrome://policy** in session to confirm policies applied. Expected: configured keys visible and match TC Setup values.
@@ -0,0 +1,37 @@
1
+ import time, allure
2
+ from core.api.UMS import UMS
3
+ from core.ssh.ssh import SSHClient
4
+ from core.ui.ui_automation_text import OcrUiInteractor
5
+ from config.read_config import ums_cred, device_cred
6
+ from core.ssh.my_logger import logger
7
+ from core.api.ums_wums_api import UMSWUMSApi
8
+
9
+ click = OcrUiInteractor()
10
+
11
+ def get_ssh():
12
+ return SSHClient(host=device_cred["host"], user=device_cred["user"],
13
+ pwd=device_cred["pwd"], port=device_cred["port"])
14
+
15
+ def _assign(ums, wums, device, profile_key, default_name, api_config):
16
+ profile = ums.get_profile_details(api_config.get(profile_key, default_name))
17
+ wums.assign_object(device["id"], profile["id"], "profile")
18
+ return profile
19
+
20
+ def _detach(ums, wums, device, profile_key, default_name, api_config):
21
+ profile = ums.get_profile_details(api_config.get(profile_key, default_name))
22
+ wums.detach_profile(device["id"], profile["id"])
23
+
24
+ @allure.step("TC001 S1: Assign profile and verify UI")
25
+ def TC001_step1(api_config, browser):
26
+ try:
27
+ ums = UMS(ums_cred["base_url"], ums_cred["username"], ums_cred["password"])
28
+ wums = UMSWUMSApi(ums_cred["weburl"], ums_cred["username"], ums_cred["password"])
29
+ dev = ums.get_vm_details(device_cred["hostname"])
30
+ _assign(ums, wums, dev, "profile_key", "Default-Profile", api_config)
31
+ return click.is_text_present_on_screen("ExpectedLabel", refresh_before_check=True)
32
+ except Exception as e:
33
+ logger.error(f"TC001_step1: {e}"); return False
34
+
35
+ @allure.feature("Feature Area")
36
+ @allure.severity(allure.severity_level.CRITICAL)
37
+ def test_TC001_step1(api_config, browser_instance): assert TC001_step1(api_config, browser_instance)
@@ -0,0 +1,10 @@
1
+ """Human feedback capture, curation, and application."""
2
+
3
+ from knowledge_base.feedback.handler import apply_feedback, apply_promotion, capture_feedback, curate_feedback
4
+
5
+ __all__ = [
6
+ "apply_feedback",
7
+ "apply_promotion",
8
+ "capture_feedback",
9
+ "curate_feedback",
10
+ ]
@@ -0,0 +1,72 @@
1
+ """Feedback analytics — Phase 2 weekly failure pattern reports."""
2
+ from __future__ import annotations
3
+
4
+ from datetime import datetime, timedelta
5
+
6
+ from knowledge_base.db.client import get_conn
7
+
8
+
9
+ def generate_weekly_report(days: int = 7) -> dict:
10
+ """Aggregate feedback trends for the last N days."""
11
+ since = datetime.utcnow() - timedelta(days=days)
12
+
13
+ with get_conn() as conn:
14
+ with conn.cursor() as cur:
15
+ cur.execute(
16
+ """
17
+ SELECT feedback_type, COUNT(*) FROM feedback_events
18
+ WHERE created_at >= %s
19
+ GROUP BY feedback_type ORDER BY COUNT(*) DESC
20
+ """,
21
+ (since,),
22
+ )
23
+ by_type = {row[0]: row[1] for row in cur.fetchall()}
24
+
25
+ cur.execute(
26
+ """
27
+ SELECT status, COUNT(*) FROM feedback_events
28
+ WHERE created_at >= %s
29
+ GROUP BY status ORDER BY COUNT(*) DESC
30
+ """,
31
+ (since,),
32
+ )
33
+ by_status = {row[0]: row[1] for row in cur.fetchall()}
34
+
35
+ cur.execute(
36
+ """
37
+ SELECT feedback_type, COUNT(*) FROM feedback_events
38
+ WHERE created_at >= %s AND status = 'pending'
39
+ GROUP BY feedback_type ORDER BY COUNT(*) DESC LIMIT 5
40
+ """,
41
+ (since,),
42
+ )
43
+ top_pending = [{"type": r[0], "count": r[1]} for r in cur.fetchall()]
44
+
45
+ cur.execute(
46
+ """
47
+ SELECT COUNT(*) FROM feedback_promotions
48
+ WHERE created_at >= %s AND status = 'applied'
49
+ """,
50
+ (since,),
51
+ )
52
+ applied_count = cur.fetchone()[0]
53
+
54
+ return {
55
+ "period_days": days,
56
+ "generated_at": datetime.utcnow().isoformat(),
57
+ "by_feedback_type": by_type,
58
+ "by_status": by_status,
59
+ "top_pending_patterns": top_pending,
60
+ "promotions_applied": applied_count,
61
+ "summary": _build_summary(by_type, by_status, top_pending),
62
+ }
63
+
64
+
65
+ def _build_summary(by_type: dict, by_status: dict, top_pending: list) -> str:
66
+ total = sum(by_type.values())
67
+ pending = by_status.get("pending", 0)
68
+ lines = [f"Total feedback events (7d): {total}", f"Pending review: {pending}"]
69
+ if top_pending:
70
+ top = top_pending[0]
71
+ lines.append(f"Top failure pattern: {top['type']} ({top['count']} events)")
72
+ return " | ".join(lines)