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