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,280 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ from pathlib import Path
5
+
6
+ from dotenv import load_dotenv
7
+
8
+ _ENV_PATH = Path(__file__).parent / ".env"
9
+ load_dotenv(_ENV_PATH)
10
+
11
+
12
+ def _truthy(raw: str | None, default: bool = False) -> bool:
13
+ if raw is None or raw == "":
14
+ return default
15
+ return raw.strip().lower() in ("1", "true", "yes", "on")
16
+
17
+
18
+ class Config:
19
+ # PostgreSQL
20
+ DB_HOST: str = os.getenv("DB_HOST", "127.0.0.1")
21
+ DB_PORT: int = int(os.getenv("DB_PORT", "5432"))
22
+ DB_NAME: str = os.getenv("DB_NAME", "genai")
23
+ DB_USER: str = os.getenv("DB_USER", "genai")
24
+ DB_PASSWORD: str = os.getenv("DB_PASSWORD", "")
25
+
26
+ # Azure OpenAI - LLM
27
+ AZURE_API_KEY: str = os.getenv("AZURE_API_KEY", "")
28
+ AZURE_ENDPOINT: str = os.getenv("AZURE_ENDPOINT", "")
29
+ AZURE_DEPLOYMENT: str = os.getenv("AZURE_DEPLOYMENT", "gpt-4.1")
30
+ AZURE_API_VERSION: str = os.getenv("AZURE_API_VERSION", "2024-12-01-preview")
31
+
32
+ # Azure OpenAI - Embeddings
33
+ AZURE_EMBEDDING_DEPLOYMENT: str = os.getenv(
34
+ "AZURE_EMBEDDING_DEPLOYMENT", "text-embedding-3-large"
35
+ )
36
+ AZURE_EMBEDDINGS_API_VERSION: str = os.getenv(
37
+ "AZURE_EMBEDDINGS_API_VERSION", "2024-02-01"
38
+ )
39
+ EMBEDDING_DIM: int = int(os.getenv("EMBEDDING_DIM", "3072"))
40
+
41
+ # Knowledge Base paths (innominds project root)
42
+ _PROJECT_ROOT: Path = Path(__file__).resolve().parent.parent.parent
43
+
44
+ KB_DIR: Path = Path(
45
+ os.getenv(
46
+ "KB_DIR",
47
+ str(_PROJECT_ROOT / "Knowledge Base"),
48
+ )
49
+ )
50
+ MARKDOWN_OUTPUT_DIR: Path = Path(
51
+ os.getenv(
52
+ "MARKDOWN_OUTPUT_DIR",
53
+ str(_PROJECT_ROOT / "Knowledge Base" / "markdown_output"),
54
+ )
55
+ )
56
+
57
+ # Ingestion settings
58
+ BATCH_SIZE: int = int(os.getenv("BATCH_SIZE", "32"))
59
+ MAX_RETRIES: int = int(os.getenv("MAX_RETRIES", "3"))
60
+ LOG_LEVEL: str = os.getenv("LOG_LEVEL", "INFO")
61
+
62
+ # Supported file extensions
63
+ SUPPORTED_EXTENSIONS: tuple[str, ...] = (
64
+ ".pdf",
65
+ ".docx",
66
+ ".doc",
67
+ ".csv",
68
+ ".xlsx",
69
+ ".xls",
70
+ ".md",
71
+ ".mht",
72
+ )
73
+ SKIP_EXTENSIONS: tuple[str, ...] = (
74
+ ".zip",
75
+ ".py",
76
+ ".exe",
77
+ ".png",
78
+ ".jpg",
79
+ ".json",
80
+ ".DS_Store",
81
+ )
82
+
83
+ # ── V3 Retrieval / rerank / GraphRAG ───────────────────────────────────
84
+ RERANKER_BACKEND: str = os.getenv("RERANKER_BACKEND", "local").strip().lower()
85
+ # CPU-optimized default: MiniLM (~80MB, fast). For multilingual DE/EN use BAAI/bge-reranker-base
86
+ RERANKER_MODEL: str = os.getenv(
87
+ "RERANKER_MODEL",
88
+ "cross-encoder/ms-marco-MiniLM-L-6-v2",
89
+ )
90
+ RERANKER_DEVICE: str = os.getenv("RERANKER_DEVICE", "cpu").strip().lower()
91
+ RERANKER_CPU_PROFILE: bool = _truthy(os.getenv("RERANKER_CPU_PROFILE"), True)
92
+ RERANKER_TOP_N: int = int(os.getenv("RERANKER_TOP_N", "16"))
93
+ RERANKER_BATCH_SIZE: int = int(os.getenv("RERANKER_BATCH_SIZE", "8"))
94
+ RERANKER_MAX_LENGTH: int = int(os.getenv("RERANKER_MAX_LENGTH", "256"))
95
+ RERANKER_PASSAGE_CHARS: int = int(os.getenv("RERANKER_PASSAGE_CHARS", "2000"))
96
+ RERANKER_PARENT_CHARS: int = int(os.getenv("RERANKER_PARENT_CHARS", "1200"))
97
+ RERANKER_TORCH_THREADS: int = int(os.getenv("RERANKER_TORCH_THREADS", "4"))
98
+ RERANKER_SCORE_THRESHOLD: float = float(os.getenv("RERANKER_SCORE_THRESHOLD", "0.2"))
99
+ RETRIEVAL_CANDIDATE_MULTIPLIER: int = int(
100
+ os.getenv("RETRIEVAL_CANDIDATE_MULTIPLIER", "6"),
101
+ )
102
+
103
+ COHERE_API_KEY: str = os.getenv("COHERE_API_KEY", "")
104
+ COHERE_RERANK_MODEL: str = os.getenv(
105
+ "COHERE_RERANK_MODEL",
106
+ "rerank-multilingual-v3.0",
107
+ )
108
+
109
+ # ── Chunking strategy (env-tunable) ─────────────────────────────────────
110
+ CHUNK_PARENT_MAX_TOKENS: int = int(os.getenv("CHUNK_PARENT_MAX_TOKENS", "1024"))
111
+ CHUNK_PARENT_MIN_TOKENS: int = int(os.getenv("CHUNK_PARENT_MIN_TOKENS", "80"))
112
+ CHUNK_CHILD_MAX_TOKENS: int = int(os.getenv("CHUNK_CHILD_MAX_TOKENS", "220"))
113
+ CHUNK_CHILD_MIN_TOKENS: int = int(os.getenv("CHUNK_CHILD_MIN_TOKENS", "50"))
114
+ CHUNK_OVERLAP_TOKENS: int = int(os.getenv("CHUNK_OVERLAP_TOKENS", "64"))
115
+ CHUNK_CONTEXT_HEADERS: bool = _truthy(os.getenv("CHUNK_CONTEXT_HEADERS"), True)
116
+
117
+ # ── Live web retrieval (confidence-gated Stage 2 search) ─────────────────
118
+ WEB_RETRIEVAL_ENABLED: bool = _truthy(os.getenv("WEB_RETRIEVAL_ENABLED"), True)
119
+ CONFIDENCE_THRESHOLD: float = float(os.getenv("CONFIDENCE_THRESHOLD", "0.75"))
120
+ _raw_web_backends = os.getenv("WEB_SEARCH_BACKENDS", "firecrawl,ddgs,searxng")
121
+ WEB_SEARCH_BACKENDS: tuple[str, ...] = tuple(
122
+ s.strip().lower() for s in _raw_web_backends.split(",") if s.strip()
123
+ )
124
+ _raw_web_sources = os.getenv("WEB_SOURCES", "kb_igel,community")
125
+ WEB_SOURCES: tuple[str, ...] = tuple(
126
+ s.strip().lower() for s in _raw_web_sources.split(",") if s.strip()
127
+ )
128
+ WEB_MAX_PAGES: int = int(os.getenv("WEB_MAX_PAGES", "5"))
129
+ WEB_MIN_SCORE: float = float(os.getenv("WEB_MIN_SCORE", "0.15"))
130
+ WEB_CACHE_TTL_SECONDS: int = int(os.getenv("WEB_CACHE_TTL_SECONDS", "3600"))
131
+ WEB_BUDGET_RATIO: float = float(os.getenv("WEB_BUDGET_RATIO", "0.12"))
132
+ WEB_ALLOW_PRIVATE_HOSTS: bool = _truthy(os.getenv("WEB_ALLOW_PRIVATE_HOSTS"), False)
133
+ DDGS_BACKEND: str = os.getenv("DDGS_BACKEND", "auto")
134
+ DDGS_REGION: str = os.getenv("DDGS_REGION", "wt-wt")
135
+ SEARXNG_BASE_URL: str = os.getenv("SEARXNG_BASE_URL", "")
136
+ FIRECRAWL_BASE_URL: str = os.getenv("FIRECRAWL_BASE_URL", "")
137
+ FIRECRAWL_API_KEY: str = os.getenv("FIRECRAWL_API_KEY", "")
138
+ CRAWL4AI_ENABLED: bool = _truthy(os.getenv("CRAWL4AI_ENABLED"), True)
139
+ CRAWL4AI_TIMEOUT: int = int(os.getenv("CRAWL4AI_TIMEOUT", "30"))
140
+ _raw_strip = os.getenv("STRIP_PROMOTED_PATTERNS", "ad,sponsored,promo,advertisement")
141
+ STRIP_PROMOTED_PATTERNS: tuple[str, ...] = tuple(
142
+ s.strip().lower() for s in _raw_strip.split(",") if s.strip()
143
+ )
144
+ _raw_inc = os.getenv("WEB_SEARCH_INCLUDE_DOMAINS", "")
145
+ WEB_SEARCH_INCLUDE_DOMAINS: tuple[str, ...] = tuple(
146
+ s.strip().lower() for s in _raw_inc.split(",") if s.strip()
147
+ )
148
+ _raw_exc = os.getenv("WEB_SEARCH_EXCLUDE_DOMAINS", "")
149
+ WEB_SEARCH_EXCLUDE_DOMAINS: tuple[str, ...] = tuple(
150
+ s.strip().lower() for s in _raw_exc.split(",") if s.strip()
151
+ )
152
+ KB_IGEL_BASE_URL: str = os.getenv("KB_IGEL_BASE_URL", "https://kb.igel.com")
153
+ COMMUNITY_BASE_URL: str = os.getenv("COMMUNITY_BASE_URL", "https://community.igel.com")
154
+ KB_IGEL_ENABLED: bool = _truthy(os.getenv("KB_IGEL_ENABLED"), True)
155
+ COMMUNITY_ENABLED: bool = _truthy(os.getenv("COMMUNITY_ENABLED"), True)
156
+
157
+ # ── Unified query orchestration (RAG + EKG + Web + MCP) ───────────────────
158
+ QUERY_EXTERNAL_ENABLED: bool = _truthy(os.getenv("QUERY_EXTERNAL_ENABLED"), True)
159
+ _raw_mcp = os.getenv("QUERY_MCP_SOURCES", "jira,confluence")
160
+ QUERY_MCP_SOURCES: tuple[str, ...] = tuple(
161
+ s.strip().lower() for s in _raw_mcp.split(",") if s.strip()
162
+ )
163
+ QUERY_GENERATION_TIMEOUT_SECONDS: int = int(os.getenv("QUERY_GENERATION_TIMEOUT_SECONDS", "90"))
164
+ ASYNC_THREAD_LIMIT: int = int(os.getenv("ASYNC_THREAD_LIMIT", "16"))
165
+
166
+ KG_ENABLED: bool = _truthy(os.getenv("KG_ENABLED"), True)
167
+ KG_MAX_HOPS: int = min(3, max(0, int(os.getenv("KG_MAX_HOPS", "2"))))
168
+ CONTEXT_INCLUDE_IMAGES: bool = _truthy(os.getenv("CONTEXT_INCLUDE_IMAGES"), True)
169
+
170
+ CONTEXT_TOKEN_BUDGET: int = int(os.getenv("CONTEXT_TOKEN_BUDGET", "8000"))
171
+ CONTEXT_RESERVE_PROMPT: int = int(os.getenv("CONTEXT_RESERVE_PROMPT", "800"))
172
+ _raw_ms = os.getenv("CONTEXT_MIN_SCORE")
173
+ if _raw_ms is None or str(_raw_ms).strip() == "":
174
+ CONTEXT_MIN_SCORE: float | None = None
175
+ else:
176
+ CONTEXT_MIN_SCORE = float(_raw_ms)
177
+ CONTEXT_MAX_CHUNKS: int = int(os.getenv("CONTEXT_MAX_CHUNKS", "10"))
178
+ CONTEXT_KG_BUDGET_RATIO: float = float(os.getenv("CONTEXT_KG_BUDGET_RATIO", "0.22"))
179
+ CONTEXT_IMAGE_BUDGET_RATIO: float = float(
180
+ os.getenv("CONTEXT_IMAGE_BUDGET_RATIO", "0.08"),
181
+ )
182
+
183
+ GENERATION_RUNS_LOGGING: bool = _truthy(os.getenv("GENERATION_RUNS_LOGGING"), False)
184
+
185
+ # ── Evaluation (Phase 0) ─────────────────────────────────────────────────
186
+ EVAL_ENABLED: bool = _truthy(os.getenv("EVAL_ENABLED"), True)
187
+ BASELINE_PATH: Path = Path(
188
+ os.getenv(
189
+ "BASELINE_PATH",
190
+ str(Path(__file__).resolve().parent.parent / "eval" / "baseline.json"),
191
+ )
192
+ )
193
+ PRECEDENCE_RULES_PATH: Path = Path(
194
+ os.getenv(
195
+ "PRECEDENCE_RULES_PATH",
196
+ str(Path(__file__).resolve().parent.parent / "core" / "precedence.py"),
197
+ )
198
+ )
199
+
200
+ # ── Confidence thresholds (Phase 1) ──────────────────────────────────────
201
+ CONFIDENCE_REJECT_THRESHOLD: float = float(os.getenv("CONFIDENCE_REJECT_THRESHOLD", "0.4"))
202
+ CONFIDENCE_WARN_THRESHOLD: float = float(os.getenv("CONFIDENCE_WARN_THRESHOLD", "0.6"))
203
+
204
+ # ── Source filtering ─────────────────────────────────────────────────────
205
+ _raw_exclude = os.getenv("RETRIEVAL_EXCLUDE_SOURCES", "")
206
+ RETRIEVAL_EXCLUDE_SOURCES: tuple[str, ...] = tuple(
207
+ s.strip().lower() for s in _raw_exclude.split(",") if s.strip()
208
+ )
209
+
210
+ # ── Knowledge graph backend (Phase 3) ──────────────────────────────────
211
+ KG_BACKEND: str = os.getenv("KG_BACKEND", "postgres").strip().lower()
212
+ KG_SHADOW_MODE: bool = _truthy(os.getenv("KG_SHADOW_MODE"), False)
213
+ NEO4J_URI: str = os.getenv("NEO4J_URI", "bolt://localhost:7687")
214
+ NEO4J_USER: str = os.getenv("NEO4J_USER", "neo4j")
215
+ NEO4J_PASSWORD: str = os.getenv("NEO4J_PASSWORD", "")
216
+
217
+ # ── External connectors (Phase 8 — disabled by default) ──────────────────
218
+ JIRA_ENABLED: bool = _truthy(os.getenv("JIRA_ENABLED"), False)
219
+ JIRA_URL: str = os.getenv("JIRA_URL", "")
220
+ JIRA_USERNAME: str = os.getenv("JIRA_USERNAME", "")
221
+ JIRA_API_TOKEN: str = os.getenv("JIRA_API_TOKEN", "")
222
+
223
+ CONFLUENCE_ENABLED: bool = _truthy(os.getenv("CONFLUENCE_ENABLED"), False)
224
+ CONFLUENCE_URL: str = os.getenv("CONFLUENCE_URL", "")
225
+ CONFLUENCE_USERNAME: str = os.getenv("CONFLUENCE_USERNAME", "")
226
+ CONFLUENCE_API_TOKEN: str = os.getenv("CONFLUENCE_API_TOKEN", "")
227
+
228
+ BITBUCKET_ENABLED: bool = _truthy(os.getenv("BITBUCKET_ENABLED"), False)
229
+ TEAMCITY_ENABLED: bool = _truthy(os.getenv("TEAMCITY_ENABLED"), False)
230
+ TESTRAIL_ENABLED: bool = _truthy(os.getenv("TESTRAIL_ENABLED"), False)
231
+ SERVICENOW_ENABLED: bool = _truthy(os.getenv("SERVICENOW_ENABLED"), False)
232
+
233
+ # ── Operational memory (Phase 4) ─────────────────────────────────────────
234
+ COGNEE_ENABLED: bool = _truthy(os.getenv("COGNEE_ENABLED"), True)
235
+
236
+ # ── Temporal graph (Phase 6) ─────────────────────────────────────────────
237
+ GRAPHITI_ENABLED: bool = _truthy(os.getenv("GRAPHITI_ENABLED"), True)
238
+
239
+ # ── Agent orchestration (Phase 5) ────────────────────────────────────────
240
+ AGENTIC_ENABLED: bool = _truthy(os.getenv("AGENTIC_ENABLED"), True)
241
+
242
+ # ── Infrastructure (Phase 9) ─────────────────────────────────────────────
243
+ REDIS_URL: str = os.getenv("REDIS_URL", "redis://localhost:6379/0")
244
+ MINIO_ENDPOINT: str = os.getenv("MINIO_ENDPOINT", "localhost:9000")
245
+ MINIO_ACCESS_KEY: str = os.getenv("MINIO_ACCESS_KEY", "")
246
+ MINIO_SECRET_KEY: str = os.getenv("MINIO_SECRET_KEY", "")
247
+ API_KEY: str = os.getenv("API_KEY", "")
248
+ API_KEYS: str = os.getenv("API_KEYS", "")
249
+ API_KEY_REQUIRED: bool = _truthy(os.getenv("API_KEY_REQUIRED"), True)
250
+ RATE_LIMIT_ENABLED: bool = _truthy(os.getenv("RATE_LIMIT_ENABLED"), True)
251
+ JSON_LOGS: bool = _truthy(os.getenv("JSON_LOGS"), True)
252
+ DB_SSLMODE: str = os.getenv("DB_SSLMODE", "prefer")
253
+
254
+ # ── Retrieval optimization (Phase D) ─────────────────────────────────────
255
+ FTS_LANGUAGE: str = os.getenv("FTS_LANGUAGE", "english")
256
+ EMBED_CACHE_TTL: int = int(os.getenv("EMBED_CACHE_TTL", "3600"))
257
+ RETRIEVAL_CACHE_TTL: int = int(os.getenv("RETRIEVAL_CACHE_TTL", "300"))
258
+ QUERY_TIMEOUT_SECONDS: int = int(os.getenv("QUERY_TIMEOUT_SECONDS", "60"))
259
+ RETRIEVAL_TRACE_SAMPLE_RATE: float = float(os.getenv("RETRIEVAL_TRACE_SAMPLE_RATE", "0.1"))
260
+
261
+ # ── Generation modes (Phase I) ───────────────────────────────────────────
262
+ DEFAULT_GENERATION_MODE: str = os.getenv("DEFAULT_GENERATION_MODE", "pipeline")
263
+
264
+ @property
265
+ def api_key_map(self) -> dict[str, str]:
266
+ from knowledge_base.core.request_context import parse_api_keys
267
+ keys = parse_api_keys(self.API_KEYS)
268
+ if self.API_KEY and self.API_KEY not in keys:
269
+ keys[self.API_KEY] = "admin"
270
+ return keys
271
+
272
+ @property
273
+ def db_dsn(self) -> str:
274
+ return (
275
+ f"host={self.DB_HOST} port={self.DB_PORT} "
276
+ f"dbname={self.DB_NAME} user={self.DB_USER} password={self.DB_PASSWORD}"
277
+ )
278
+
279
+
280
+ cfg = Config()
@@ -0,0 +1,5 @@
1
+ """Connector package — Phase 8 (stubbed, config-driven)."""
2
+
3
+ from knowledge_base.connectors.base import BaseConnector
4
+
5
+ __all__ = ["BaseConnector"]
@@ -0,0 +1,44 @@
1
+ """Base connector interface — Phase 8."""
2
+ from __future__ import annotations
3
+
4
+ from abc import ABC, abstractmethod
5
+ from datetime import datetime
6
+ from typing import Any
7
+
8
+
9
+ class BaseConnector(ABC):
10
+ """All external connectors implement this interface."""
11
+
12
+ name: str = "base"
13
+ enabled: bool = False
14
+ supports_sync: bool = True
15
+
16
+ @abstractmethod
17
+ def connect(self) -> bool:
18
+ """Test connection to external system."""
19
+
20
+ @abstractmethod
21
+ def sync(self, since: datetime | None = None) -> list[dict]:
22
+ """Fetch new/updated items since last sync."""
23
+
24
+ @abstractmethod
25
+ def ingest_to_kg(self, items: list[dict]) -> int:
26
+ """Store items in knowledge graph. Returns count ingested."""
27
+
28
+ @abstractmethod
29
+ def ingest_to_rag(self, items: list[dict]) -> int:
30
+ """Store items in PostgreSQL vector store. Returns count ingested."""
31
+
32
+ def search(self, query: str, limit: int = 5, timeout: float | None = None) -> list[str]:
33
+ """Optional query-time URL search for MCP bridge connectors."""
34
+ return []
35
+
36
+ def fetch_page(self, url: str, timeout: float | None = None) -> dict[str, Any] | None:
37
+ """Optional query-time page fetch for MCP bridge connectors."""
38
+ return None
39
+
40
+ def health_check(self) -> dict[str, Any]:
41
+ if not self.enabled:
42
+ return {"status": "disabled", "connector": self.name}
43
+ ok = self.connect()
44
+ return {"status": "healthy" if ok else "error", "connector": self.name}
@@ -0,0 +1,25 @@
1
+ """Bitbucket connector — Phase 8 stub."""
2
+ from __future__ import annotations
3
+
4
+ from datetime import datetime
5
+
6
+ from knowledge_base.config import cfg
7
+ from knowledge_base.connectors.base import BaseConnector
8
+
9
+
10
+ class BitbucketConnector(BaseConnector):
11
+ name = "bitbucket"
12
+ enabled = cfg.BITBUCKET_ENABLED
13
+ supports_sync = False
14
+
15
+ def connect(self) -> bool:
16
+ return self.enabled
17
+
18
+ def sync(self, since: datetime | None = None) -> list[dict]:
19
+ return []
20
+
21
+ def ingest_to_kg(self, items: list[dict]) -> int:
22
+ return 0
23
+
24
+ def ingest_to_rag(self, items: list[dict]) -> int:
25
+ return 0
@@ -0,0 +1,112 @@
1
+ """IGEL Community / forum connector — fetch public community content."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import logging
6
+ from datetime import datetime
7
+ from typing import Any
8
+ from urllib.parse import quote_plus
9
+
10
+ from knowledge_base.config import cfg
11
+ from knowledge_base.connectors.base import BaseConnector
12
+ from knowledge_base.connectors.web_fetcher import fetch_url, search_confluence_site
13
+ from knowledge_base.parsers.html_parser import parse_html_page
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+
18
+ class CommunityConnector(BaseConnector):
19
+ """Fetch content from IGEL community sites (Discourse / forum pages)."""
20
+
21
+ name = "community"
22
+
23
+ def __init__(self) -> None:
24
+ self.base_url = getattr(
25
+ cfg,
26
+ "COMMUNITY_BASE_URL",
27
+ "https://community.igel.com",
28
+ ).rstrip("/")
29
+ self.enabled = getattr(cfg, "COMMUNITY_ENABLED", True)
30
+
31
+ def connect(self) -> bool:
32
+ result = fetch_url(self.base_url, cache_ttl=300)
33
+ return result.status_code in (200, 301, 302)
34
+
35
+ def search(self, query: str, *, limit: int | None = None, timeout: float | None = None) -> list[str]:
36
+ max_pages = limit or getattr(cfg, "WEB_MAX_PAGES", 3)
37
+ urls: list[str] = []
38
+ fetch_timeout = min(20.0, timeout) if timeout and timeout > 0 else 20.0
39
+
40
+ # Try community search endpoint
41
+ search_url = f"{self.base_url}/search?q={quote_plus(query)}"
42
+ result = fetch_url(search_url, cache_ttl=600, timeout=fetch_timeout)
43
+ if result.status_code == 200 and result.html:
44
+ import re
45
+
46
+ for href in re.findall(r'href="(/t/[^"]+)"', result.html):
47
+ full = f"{self.base_url}{href.split('?')[0]}"
48
+ if full not in urls:
49
+ urls.append(full)
50
+ if len(urls) >= max_pages:
51
+ return urls
52
+
53
+ # Fallback: also search official KB for community-tagged content
54
+ kb_urls = search_confluence_site(
55
+ getattr(cfg, "KB_IGEL_BASE_URL", "https://kb.igel.com"),
56
+ f"{query} community",
57
+ limit=max(1, max_pages // 2),
58
+ )
59
+ urls.extend(kb_urls)
60
+ return urls[:max_pages]
61
+
62
+ def fetch_page(self, url: str, timeout: float | None = None) -> dict[str, Any] | None:
63
+ fetch_timeout = min(20.0, timeout) if timeout and timeout > 0 else 20.0
64
+ result = fetch_url(
65
+ url,
66
+ cache_ttl=getattr(cfg, "WEB_CACHE_TTL_SECONDS", 3600),
67
+ timeout=fetch_timeout,
68
+ )
69
+ if result.status_code != 200 or not result.html:
70
+ return None
71
+ parsed = parse_html_page(result.html, url, source_type="community")
72
+ return {
73
+ "url": url,
74
+ "title": parsed.title,
75
+ "sections": parsed.sections,
76
+ "raw_text": parsed.raw_text,
77
+ "source_type": "community",
78
+ "product": "IGEL",
79
+ }
80
+
81
+ def sync(self, since: datetime | None = None) -> list[dict]:
82
+ return []
83
+
84
+ def ingest_to_kg(self, items: list[dict]) -> int:
85
+ if not items:
86
+ return 0
87
+ from knowledge_base.db.client import get_conn
88
+ import json
89
+ count = 0
90
+ with get_conn() as conn:
91
+ with conn.cursor() as cur:
92
+ for item in items:
93
+ title = item.get("title") or item.get("url", "")
94
+ if not title:
95
+ continue
96
+ payload = dict(item)
97
+ payload.setdefault("source", "community")
98
+ cur.execute(
99
+ """
100
+ INSERT INTO knowledge_graph_nodes (node_type, value, normalized, metadata)
101
+ VALUES ('feature', %s, %s, %s::jsonb)
102
+ ON CONFLICT (node_type, normalized) DO UPDATE SET metadata = EXCLUDED.metadata
103
+ """,
104
+ (title[:4000], title.lower()[:2000], json.dumps(payload)),
105
+ )
106
+ count += 1
107
+ return count
108
+
109
+ def ingest_to_rag(self, items: list[dict]) -> int:
110
+ from knowledge_base.ingestion.web_ingest import ingest_web_items
111
+
112
+ return ingest_web_items(items, source_label="community.igel.com")