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,50 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Deploy self-hosted Firecrawl for KB web search (no API key required).
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
INSTALL_DIR="${FIRECRAWL_INSTALL_DIR:-/opt/firecrawl}"
|
|
6
|
+
PORT="${FIRECRAWL_PORT:-3002}"
|
|
7
|
+
|
|
8
|
+
if ! command -v docker >/dev/null 2>&1; then
|
|
9
|
+
echo "ERROR: docker is not installed. Install Docker first, then re-run this script."
|
|
10
|
+
exit 1
|
|
11
|
+
fi
|
|
12
|
+
|
|
13
|
+
if ! docker compose version >/dev/null 2>&1; then
|
|
14
|
+
echo "ERROR: docker compose plugin is required."
|
|
15
|
+
exit 1
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
if [ ! -d "$INSTALL_DIR/.git" ]; then
|
|
19
|
+
echo "Cloning Firecrawl into $INSTALL_DIR ..."
|
|
20
|
+
git clone --depth 1 https://github.com/mendableai/firecrawl.git "$INSTALL_DIR"
|
|
21
|
+
else
|
|
22
|
+
echo "Updating Firecrawl in $INSTALL_DIR ..."
|
|
23
|
+
git -C "$INSTALL_DIR" pull --ff-only || true
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
cd "$INSTALL_DIR"
|
|
27
|
+
cat > .env << EOF
|
|
28
|
+
PORT=${PORT}
|
|
29
|
+
HOST=0.0.0.0
|
|
30
|
+
USE_DB_AUTHENTICATION=false
|
|
31
|
+
BULL_AUTH_KEY=igel-kb-local
|
|
32
|
+
EOF
|
|
33
|
+
|
|
34
|
+
echo "Building and starting Firecrawl on port ${PORT} ..."
|
|
35
|
+
docker compose build
|
|
36
|
+
docker compose up -d
|
|
37
|
+
|
|
38
|
+
echo "Waiting for Firecrawl health ..."
|
|
39
|
+
for i in $(seq 1 30); do
|
|
40
|
+
if curl -sf "http://127.0.0.1:${PORT}/" >/dev/null 2>&1; then
|
|
41
|
+
echo "Firecrawl is up at http://127.0.0.1:${PORT}"
|
|
42
|
+
echo "Set in knowledge_base/config/.env:"
|
|
43
|
+
echo " FIRECRAWL_BASE_URL=http://127.0.0.1:${PORT}"
|
|
44
|
+
exit 0
|
|
45
|
+
fi
|
|
46
|
+
sleep 5
|
|
47
|
+
done
|
|
48
|
+
|
|
49
|
+
echo "WARN: Firecrawl may still be starting. Check: docker compose -C $INSTALL_DIR logs -f"
|
|
50
|
+
exit 0
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# systemd service unit for the IGEL Test Case Generation API.
|
|
2
|
+
#
|
|
3
|
+
# Install:
|
|
4
|
+
# sudo cp igel-testgen.service /etc/systemd/system/
|
|
5
|
+
# sudo systemctl daemon-reload
|
|
6
|
+
# sudo systemctl enable igel-testgen
|
|
7
|
+
# sudo systemctl start igel-testgen
|
|
8
|
+
|
|
9
|
+
[Unit]
|
|
10
|
+
Description=IGEL Test Case Generation API (RAG + KG)
|
|
11
|
+
After=network.target postgresql.service
|
|
12
|
+
Wants=postgresql.service
|
|
13
|
+
|
|
14
|
+
[Service]
|
|
15
|
+
Type=simple
|
|
16
|
+
User=root
|
|
17
|
+
WorkingDirectory=/root/IGEL/IGEL_Automation_Claude/IGEL/innominds
|
|
18
|
+
EnvironmentFile=-/root/IGEL/IGEL_Automation_Claude/IGEL/innominds/knowledge_base/config/.env
|
|
19
|
+
ExecStartPre=/bin/bash -c 'until pg_isready -h ${DB_HOST:-localhost} -p ${DB_PORT:-5432}; do sleep 2; done'
|
|
20
|
+
ExecStart=/bin/bash knowledge_base/deploy/run_server.sh
|
|
21
|
+
Restart=always
|
|
22
|
+
RestartSec=5
|
|
23
|
+
TimeoutStopSec=30
|
|
24
|
+
|
|
25
|
+
[Install]
|
|
26
|
+
WantedBy=multi-user.target
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Install free/open-source local reranker (BAAI/bge-reranker-v2-m3 via sentence-transformers).
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
PYTHON="${KB_PYTHON:-python3.8}"
|
|
6
|
+
if ! command -v "$PYTHON" >/dev/null 2>&1; then
|
|
7
|
+
PYTHON=python3
|
|
8
|
+
fi
|
|
9
|
+
|
|
10
|
+
echo "Using Python: $($PYTHON --version 2>&1)"
|
|
11
|
+
|
|
12
|
+
# Bootstrap user pip if system pip is broken (OpenSSL/pyOpenSSL conflicts on older Ubuntu).
|
|
13
|
+
if ! "$PYTHON" -m pip --version >/dev/null 2>&1; then
|
|
14
|
+
echo "Bootstrapping pip..."
|
|
15
|
+
curl -sS "https://bootstrap.pypa.io/pip/$($PYTHON -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')/get-pip.py" \
|
|
16
|
+
-o /tmp/get-pip-kb.py
|
|
17
|
+
"$PYTHON" /tmp/get-pip-kb.py --user
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
PIP="$($PYTHON -m pip --version >/dev/null 2>&1 && echo "$PYTHON -m pip" || echo "$HOME/.local/bin/pip$($PYTHON -c 'import sys; print(sys.version_info.minor)')")"
|
|
21
|
+
# shellcheck disable=SC2086
|
|
22
|
+
$PIP install --upgrade \
|
|
23
|
+
'jinja2>=3.1.2,<3.2' \
|
|
24
|
+
'MarkupSafe>=2.1.0,<3' \
|
|
25
|
+
'tokenizers>=0.20,<0.21' \
|
|
26
|
+
'transformers>=4.41.0,<4.47' \
|
|
27
|
+
'sentence-transformers>=3.2.0,<3.3' \
|
|
28
|
+
'torch>=2.0,<2.5'
|
|
29
|
+
|
|
30
|
+
# Remove stale metadata that makes transformers think tokenizers 0.21 is installed.
|
|
31
|
+
SITE=$("$PYTHON" -c "import site; print(site.getsitepackages()[0])")
|
|
32
|
+
rm -rf "${SITE}/tokenizers-0.21.0.dist-info" 2>/dev/null || true
|
|
33
|
+
|
|
34
|
+
echo "Verifying CPU OSS reranker (MiniLM — fast on CPU)..."
|
|
35
|
+
"$PYTHON" << 'PYEOF'
|
|
36
|
+
import markupsafe
|
|
37
|
+
if not hasattr(markupsafe, "soft_unicode"):
|
|
38
|
+
markupsafe.soft_unicode = getattr(markupsafe, "soft_str", str)
|
|
39
|
+
from time import perf_counter
|
|
40
|
+
from sentence_transformers import CrossEncoder
|
|
41
|
+
model = CrossEncoder("cross-encoder/ms-marco-MiniLM-L-6-v2", max_length=256, device="cpu")
|
|
42
|
+
pairs = [
|
|
43
|
+
("UMS SSO login", "Section: SSO\nPassage: Configure Entra ID SSO in UMS"),
|
|
44
|
+
("UMS SSO login", "Section: Battery\nPassage: Power management settings"),
|
|
45
|
+
] * 8
|
|
46
|
+
t0 = perf_counter()
|
|
47
|
+
scores = model.predict(pairs, show_progress_bar=False, batch_size=8)
|
|
48
|
+
elapsed = perf_counter() - t0
|
|
49
|
+
print(f"OK — MiniLM reranked {len(pairs)} pairs in {elapsed:.2f}s, top score={float(max(scores)):.4f}")
|
|
50
|
+
PYEOF
|
|
51
|
+
|
|
52
|
+
echo "Done. Set RERANKER_BACKEND=local in config/.env (default)."
|
|
53
|
+
|
|
54
|
+
echo "Installing free web search (DuckDuckGo ddgs)..."
|
|
55
|
+
# shellcheck disable=SC2086
|
|
56
|
+
$PIP install 'duckduckgo-search>=6.0.0,<7.0.0' 2>/dev/null || $PIP install 'ddgs>=6.0.0'
|
|
57
|
+
|
|
58
|
+
echo "Installing Firecrawl SDK + Playwright (web search + JS page extraction)..."
|
|
59
|
+
# crawl4ai requires Python 3.9+ (numpy>=1.26); on 3.8 we use Playwright directly.
|
|
60
|
+
# shellcheck disable=SC2086
|
|
61
|
+
$PIP install 'firecrawl-py>=1.0.0' 'playwright>=1.40.0,<1.49.0'
|
|
62
|
+
if "$PYTHON" -c 'import sys; exit(0 if sys.version_info >= (3, 9) else 1)'; then
|
|
63
|
+
$PIP install 'crawl4ai>=0.4.0,<0.5.0' || true
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
echo "Setting up Playwright browser (Chromium)..."
|
|
67
|
+
"$PYTHON" -m playwright install chromium 2>/dev/null || true
|
|
68
|
+
if command -v crawl4ai-setup >/dev/null 2>&1; then
|
|
69
|
+
crawl4ai-setup || true
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
echo "Verifying DuckDuckGo search..."
|
|
73
|
+
"$PYTHON" << 'PYEOF'
|
|
74
|
+
try:
|
|
75
|
+
from duckduckgo_search import DDGS
|
|
76
|
+
except ImportError:
|
|
77
|
+
from ddgs import DDGS
|
|
78
|
+
with DDGS() as ddgs:
|
|
79
|
+
rows = list(ddgs.text("IGEL OS SSO", max_results=2) or [])
|
|
80
|
+
echo "Verifying Crawl4AI import..."
|
|
81
|
+
"$PYTHON" << 'PYEOF'
|
|
82
|
+
try:
|
|
83
|
+
from crawl4ai import AsyncWebCrawler
|
|
84
|
+
print("OK — crawl4ai import")
|
|
85
|
+
except Exception as e:
|
|
86
|
+
print(f"WARN — crawl4ai: {e}")
|
|
87
|
+
try:
|
|
88
|
+
import firecrawl
|
|
89
|
+
print("OK — firecrawl-py import")
|
|
90
|
+
except Exception as e:
|
|
91
|
+
print(f"WARN — firecrawl-py: {e}")
|
|
92
|
+
PYEOF
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Knowledge Base Ingestion Pipeline - Additional Dependencies
|
|
2
|
+
# Install with: pip install -r requirements_kb.txt
|
|
3
|
+
|
|
4
|
+
# PostgreSQL + pgvector
|
|
5
|
+
psycopg2-binary==2.9.9
|
|
6
|
+
pgvector==0.3.6
|
|
7
|
+
|
|
8
|
+
# Database migrations
|
|
9
|
+
alembic==1.13.1
|
|
10
|
+
|
|
11
|
+
# Azure OpenAI
|
|
12
|
+
openai==1.57.4
|
|
13
|
+
|
|
14
|
+
# Document Parsing
|
|
15
|
+
pdfplumber==0.11.4
|
|
16
|
+
pymupdf>=1.24.0
|
|
17
|
+
python-docx==1.1.2
|
|
18
|
+
mammoth==1.8.0
|
|
19
|
+
pandas>=2.0.0,<2.1.0; python_version < "3.9"
|
|
20
|
+
pandas>=2.2.0; python_version >= "3.9"
|
|
21
|
+
openpyxl==3.1.5
|
|
22
|
+
|
|
23
|
+
# Token counting
|
|
24
|
+
tiktoken>=0.5.0
|
|
25
|
+
|
|
26
|
+
# Config / Utils
|
|
27
|
+
pydantic>=2.7.0
|
|
28
|
+
eval_type_backport>=0.2.0; python_version < "3.10"
|
|
29
|
+
python-dotenv==1.0.1
|
|
30
|
+
tenacity==9.0.0
|
|
31
|
+
rich==13.9.4
|
|
32
|
+
|
|
33
|
+
# OSS local reranker (CrossEncoder — free, runs on CPU/GPU)
|
|
34
|
+
# Default model: BAAI/bge-reranker-v2-m3 (multilingual, best open-source for IGEL DE/EN)
|
|
35
|
+
# Install: bash knowledge_base/deploy/install_reranker.sh
|
|
36
|
+
jinja2>=3.1.2,<3.2
|
|
37
|
+
MarkupSafe>=2.1.0,<3
|
|
38
|
+
tokenizers>=0.20,<0.21
|
|
39
|
+
transformers>=4.41.0,<4.47
|
|
40
|
+
sentence-transformers>=3.2.0,<3.3
|
|
41
|
+
torch>=2.0,<2.5; python_version < "3.9"
|
|
42
|
+
|
|
43
|
+
# Optional hosted reranker (not required for OSS setup)
|
|
44
|
+
# cohere>=5.0.0
|
|
45
|
+
|
|
46
|
+
# Web retrieval (confidence-gated — Firecrawl search + Crawl4AI fetch)
|
|
47
|
+
httpx>=0.27.0
|
|
48
|
+
beautifulsoup4>=4.12.0
|
|
49
|
+
lxml>=5.0.0
|
|
50
|
+
duckduckgo-search>=6.0.0,<7.0.0; python_version < "3.9"
|
|
51
|
+
firecrawl-py>=1.0.0
|
|
52
|
+
playwright>=1.40.0,<1.49.0
|
|
53
|
+
crawl4ai>=0.4.0,<0.5.0; python_version >= "3.9"
|
|
54
|
+
|
|
55
|
+
# REST API server (always-running service)
|
|
56
|
+
fastapi>=0.111.0
|
|
57
|
+
uvicorn[standard]>=0.30.0
|
|
58
|
+
redis>=5.0.0
|
|
59
|
+
# Phase 3: Neo4j graph DB (optional — enable with KG_SHADOW_MODE=true)
|
|
60
|
+
neo4j>=5.15.0
|
|
61
|
+
|
|
62
|
+
# Phase 4-6: Optional OSS packages (PostgreSQL fallbacks exist if not installed)
|
|
63
|
+
# cognee
|
|
64
|
+
# graphiti-core
|
|
65
|
+
|
|
66
|
+
# Phase 5: Agent orchestration (sequential fallback if not installed)
|
|
67
|
+
langgraph>=0.0.8; python_version < "3.9"
|
|
68
|
+
langgraph>=0.2.0; python_version >= "3.9"
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Start the IGEL Test Generation API server.
|
|
3
|
+
# Run this directly or use the systemd service (igel-testgen.service).
|
|
4
|
+
#
|
|
5
|
+
# Default: binds to 0.0.0.0:8000 so any machine on the network can call the API.
|
|
6
|
+
# Override with environment variables: TESTGEN_HOST, TESTGEN_PORT
|
|
7
|
+
|
|
8
|
+
set -euo pipefail
|
|
9
|
+
|
|
10
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
|
+
PROJECT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
12
|
+
|
|
13
|
+
cd "$PROJECT_DIR"
|
|
14
|
+
|
|
15
|
+
# Prefer Python 3.8+ (Pydantic v2 / FastAPI stack)
|
|
16
|
+
PYTHON="${TESTGEN_PYTHON:-python3.8}"
|
|
17
|
+
if ! command -v "$PYTHON" >/dev/null 2>&1; then
|
|
18
|
+
PYTHON=python3
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
HOST="${TESTGEN_HOST:-0.0.0.0}"
|
|
22
|
+
PORT="${TESTGEN_PORT:-8000}"
|
|
23
|
+
WORKERS="${TESTGEN_WORKERS:-1}"
|
|
24
|
+
|
|
25
|
+
echo "Starting IGEL Test Generation API on ${HOST}:${PORT} (workers=${WORKERS})"
|
|
26
|
+
echo " Project dir: $PROJECT_DIR"
|
|
27
|
+
echo " Python: $($PYTHON --version 2>&1)"
|
|
28
|
+
echo " Swagger UI: http://${HOST}:${PORT}/docs"
|
|
29
|
+
echo ""
|
|
30
|
+
|
|
31
|
+
exec "$PYTHON" -m uvicorn knowledge_base.api.server:app \
|
|
32
|
+
--host "$HOST" \
|
|
33
|
+
--port "$PORT" \
|
|
34
|
+
--workers "$WORKERS" \
|
|
35
|
+
--log-level info
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# IGEL test case generation — operator guide
|
|
2
|
+
|
|
3
|
+
This document is for anyone running the RAG-powered test generator in `knowledge_base/`. The CLI (`python -m knowledge_base.cli.generate`) **always retrieves context from PostgreSQL** (vector + full-text hybrid search + knowledge graph) before calling the LLM. Outputs are only as accurate as the **ingested documentation** in the KB.
|
|
4
|
+
|
|
5
|
+
## How it works (short)
|
|
6
|
+
|
|
7
|
+
1. Your **topic** string is embedded and searched against `kb_chunks` / related tables.
|
|
8
|
+
2. Top passages are merged via **Reciprocal Rank Fusion** (vector + FTS), optionally **reranked** by a cross-encoder.
|
|
9
|
+
3. The **Knowledge Graph** is queried for registry keys, TC Setup paths, and feature entities linked to the retrieved chunks — these supply the *exact strings* the LLM uses in test steps.
|
|
10
|
+
4. Text chunks + KG entities + image context are fused under a token budget.
|
|
11
|
+
5. That context is sent to the model with strict instructions: **ground steps in the KB**, no vague expected results, no invented URLs or product paths.
|
|
12
|
+
6. Artifacts are written under `tests/Generated/` (by default): Markdown spec, Python pytest file, and an appended **KB retrieval traceability** section listing chunk IDs for audit.
|
|
13
|
+
|
|
14
|
+
Use `--debug` to print full retrieval diagnostics (scores, inclusion reasons, KG nodes).
|
|
15
|
+
|
|
16
|
+
## Faithful modes (manual TC → pytest)
|
|
17
|
+
|
|
18
|
+
The generator **classifies** every request:
|
|
19
|
+
|
|
20
|
+
| Mode | When | Behavior |
|
|
21
|
+
|------|------|----------|
|
|
22
|
+
| **Transform** | Pasted manual TC has 3+ structured steps (CSV / JIRA export) | **Preserve** step count and intent; map to Markdown + pytest; light KB retrieval for supplementary paths/keys only. |
|
|
23
|
+
| **Expand** | Pasted TC is partial (few steps or incomplete expected results) | **Keep** existing steps verbatim; use RAG/KG to **fill gaps** only. |
|
|
24
|
+
| **Synthesize** | Topic-only (no structured paste) | Full RAG + KG (same as legacy behavior). |
|
|
25
|
+
|
|
26
|
+
- **CLI**: pass `--source-tc-file path/to/export.csv` (optional `--detail-level concise|detailed|auto`).
|
|
27
|
+
- **API**: `POST /generate` with optional `source_tc` (string) and `detail_level`, or `POST /convert` with required `source_tc` for dedicated manual-TC conversion.
|
|
28
|
+
|
|
29
|
+
Step-fidelity checks run after generation; warnings are returned when counts or preservation rules may be violated.
|
|
30
|
+
|
|
31
|
+
## Prerequisites
|
|
32
|
+
|
|
33
|
+
- PostgreSQL reachable with the KB populated (`knowledge_base/.env`, see `config.py` / `db/client.py`).
|
|
34
|
+
- Documents ingested (`python -m knowledge_base.ingestion.ingest` — this **also populates the Knowledge Graph automatically**).
|
|
35
|
+
- Azure OpenAI credentials configured for the LLM and embeddings.
|
|
36
|
+
|
|
37
|
+
## Ingestion (single command — RAG + KG in sync)
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
python -m knowledge_base.ingestion.ingest # Ingest all new docs + build KG
|
|
41
|
+
python -m knowledge_base.ingestion.ingest --file x.pdf # Single file (KG extracted for that doc)
|
|
42
|
+
python -m knowledge_base.ingestion.ingest --reset # Full re-ingest from scratch
|
|
43
|
+
python -m knowledge_base.ingestion.ingest --stats # Show document, chunk, KG, and image counts
|
|
44
|
+
python -m knowledge_base.ingestion.ingest --skip-kg # Text + embeddings only (rare; skips KG)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**No separate KG step is needed.** Each ingested document automatically has its registry keys (`app.*`), TC Setup paths, and feature nodes extracted into `knowledge_graph_nodes` / `knowledge_graph_edges`. The `--stats` output shows `kg_nodes`, `kg_edges`, and `kg_orphan_parents` (parents with no KG entity — ideally 0 or low).
|
|
48
|
+
|
|
49
|
+
If you ever need a backfill (e.g. after upgrading the KG extractor logic), you can still run the standalone extractor:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
python -m knowledge_base.ingestion.kg_extractor
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Always-running API service (recommended)
|
|
56
|
+
|
|
57
|
+
The server runs on **192.168.204.65:8000** and responds to any user query — no commands to run per test case.
|
|
58
|
+
|
|
59
|
+
### Starting the service
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# Option 1: systemd (starts on boot, restarts on crash)
|
|
63
|
+
sudo cp knowledge_base/igel-testgen.service /etc/systemd/system/
|
|
64
|
+
sudo systemctl daemon-reload
|
|
65
|
+
sudo systemctl enable igel-testgen
|
|
66
|
+
sudo systemctl start igel-testgen
|
|
67
|
+
|
|
68
|
+
# Option 2: directly
|
|
69
|
+
cd /root/IGEL/IGEL_Automation_Claude/IGEL/innominds
|
|
70
|
+
./knowledge_base/run_server.sh
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### API endpoints
|
|
74
|
+
|
|
75
|
+
| Method | Path | What it does |
|
|
76
|
+
|--------|------|------|
|
|
77
|
+
| `POST` | `/query` | Ask any test-case question — returns detailed executable steps |
|
|
78
|
+
| `POST` | `/generate` | Full generation from `topic` and/or pasted `source_tc` (auto-routed) |
|
|
79
|
+
| `POST` | `/convert` | Convert pasted manual TC (`source_tc` required) — transform/expand pipeline |
|
|
80
|
+
| `GET` | `/health` | Check DB, KB, KG readiness |
|
|
81
|
+
| `GET` | `/stats` | Document/chunk/KG counts |
|
|
82
|
+
|
|
83
|
+
Swagger docs at **http://192.168.204.65:8000/docs**
|
|
84
|
+
|
|
85
|
+
### Example: ask for test steps
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
curl -X POST http://192.168.204.65:8000/query \
|
|
89
|
+
-H "Content-Type: application/json" \
|
|
90
|
+
-d '{"question": "How to test Entra ID SSO login on IGEL OS 12", "top_k": 10}'
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Response includes `answer` (full detailed steps), `kb_sources` (chunk IDs for traceability), and `kg_entities_used`.
|
|
94
|
+
|
|
95
|
+
### Example: generate full test case
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
curl -X POST http://192.168.204.65:8000/generate \
|
|
99
|
+
-H "Content-Type: application/json" \
|
|
100
|
+
-d '{"topic": "RDP session connection validation", "output_format": "both"}'
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Example: faithful conversion (pasted manual TC)
|
|
104
|
+
|
|
105
|
+
Use `POST /convert` with a JSON body where `source_tc` is the full pasted export (CSV or JIRA table). For large pastes, build the JSON in code or use HTTPie/`curl --data-binary @body.json`. Optional: same payload on `POST /generate` with `"source_tc": "..."` plus a short `"topic"` label.
|
|
106
|
+
|
|
107
|
+
Response includes `markdown_content`, `python_content`, `traceability_table`, and metadata.
|
|
108
|
+
|
|
109
|
+
## CLI generation (alternative, for scripting)
|
|
110
|
+
|
|
111
|
+
From the `innominds` package root (where `knowledge_base` is importable):
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
python -m knowledge_base.cli.generate "Entra ID SSO login validation" --format both
|
|
115
|
+
python -m knowledge_base.cli.generate "UMS profile assignment" --product UMS --top-k 10
|
|
116
|
+
python -m knowledge_base.cli.generate "Chromium policies QCAPPS-429" --source-tc-file path/to/jira_export.csv --detail-level detailed
|
|
117
|
+
python -m knowledge_base.cli.generate --interactive
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
- **`--product`**: narrows search (UMS, IGEL OS, COSMOS, etc.); if nothing matches, retrieval retries without the filter.
|
|
121
|
+
- **`--top-k`**: more chunks retrieved before budgeting; use when the topic is broad.
|
|
122
|
+
- **`--source-tc-file`**: pasted official manual steps — enables **transform** or **expand** instead of topic-only synthesis.
|
|
123
|
+
- **`--detail-level`**: `concise`, `detailed`, or `auto` (classifier default).
|
|
124
|
+
- **`--debug`**: JSON dump of retrieval traces after generation.
|
|
125
|
+
|
|
126
|
+
## What you should ask (topic phrasing)
|
|
127
|
+
|
|
128
|
+
The topic is the **search query**. Be specific so retrieval pulls the right manuals:
|
|
129
|
+
|
|
130
|
+
- Good: `"Entra ID SSO login validation on IGEL OS 12"` / `"UMS assign profile and verify device reboot"`.
|
|
131
|
+
- Weak: `"SSO"` (too vague — retrieval may miss the right procedures).
|
|
132
|
+
|
|
133
|
+
The model is instructed to return a **full JIRA-style test** even if your topic is short. **Detail still depends on what the KB returns.** If the database does not contain a path, command, or URL, the generator must not invent it.
|
|
134
|
+
|
|
135
|
+
## How the Knowledge Graph improves test steps
|
|
136
|
+
|
|
137
|
+
The KG supplies **structured entities** that link across documents:
|
|
138
|
+
|
|
139
|
+
| KG node type | Example | How it ends up in test steps |
|
|
140
|
+
|---|---|---|
|
|
141
|
+
| `registry_key` | `app.igel.sessions.rdp0.host` | Exact `get`/`set` commands in SSH steps |
|
|
142
|
+
| `ui_path` | `TC Setup > Sessions > RDP > Session Name` | Exact UMS navigation in TC Setup sections |
|
|
143
|
+
| `feature` | "RDP Global Settings" | Cross-section relationship (links multiple chunks) |
|
|
144
|
+
|
|
145
|
+
Without KG, the model only sees the 8-10 retrieved passages. With KG, it also sees **every registry key and UI path related to those passages**, even if they come from different documents. This means:
|
|
146
|
+
- Steps use **real** `app.*` keys, not paraphrased descriptions.
|
|
147
|
+
- TC Setup paths are **copied verbatim** from the graph, not guessed.
|
|
148
|
+
- Related features from other documents surface as additional context.
|
|
149
|
+
|
|
150
|
+
## Executable, non-vague steps (policy)
|
|
151
|
+
|
|
152
|
+
Prompts enforce:
|
|
153
|
+
|
|
154
|
+
- **Concrete actions**: exact TC Setup paths, CLI with full syntax, file paths, policy names, UI strings — copied from KB passages + KG entities where present.
|
|
155
|
+
- **Concrete expected results**: observable checks (log lines, labels, command output), not standalone "Pass" or "works as expected."
|
|
156
|
+
- **URLs**: only those present in retrieved docs (or standard patterns documented there). Tenant hosts belong in `ums_cred` / `api_config` in generated Python, not hardcoded guesses.
|
|
157
|
+
- **Python**: pytest code is generated with the **same KB excerpt** in the prompt, so `--format py` is still DB-grounded.
|
|
158
|
+
|
|
159
|
+
## Generated Python tests and configuration
|
|
160
|
+
|
|
161
|
+
Generated tests use shared creds and helpers (`ums_cred`, `device_cred`, `api_config`). Ensure `testdata/` and config match your environment so generated steps are **runnable**, not just syntactically valid.
|
|
162
|
+
|
|
163
|
+
## Traceability
|
|
164
|
+
|
|
165
|
+
Each run prints **KB_REF** lines (file, section, chunk UUIDs). Generated Markdown ends with a traceability table. Use that to open the same passages in PostgreSQL or re-ingest logs when a step looks wrong.
|
|
166
|
+
|
|
167
|
+
## If output is shallow or generic
|
|
168
|
+
|
|
169
|
+
1. Check `--stats`: ensure `kg_nodes > 0` and `kg_orphan_parents` is low.
|
|
170
|
+
2. Improve ingestion (more complete source docs).
|
|
171
|
+
3. Increase `--top-k` or refine `--product` / topic wording.
|
|
172
|
+
4. Run with `--debug` and confirm chunks are relevant (`included` / ranks).
|
|
173
|
+
|
|
174
|
+
The LLM cannot replace missing documentation; it only structures what retrieval provides.
|
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Azure OpenAI Embeddings — text-embedding-3-large (3072 dims)
|
|
3
|
+
|
|
4
|
+
Features:
|
|
5
|
+
- Batched embedding (32 texts per API call)
|
|
6
|
+
- Exponential backoff retry on rate-limit / transient errors
|
|
7
|
+
- Returns embeddings as list[list[float]] aligned to input order
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
import time
|
|
11
|
+
import logging
|
|
12
|
+
from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type
|
|
13
|
+
|
|
14
|
+
from openai import AzureOpenAI, RateLimitError, APIConnectionError, APITimeoutError
|
|
15
|
+
from knowledge_base.config import cfg
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
_client: AzureOpenAI | None = None
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _get_client() -> AzureOpenAI:
|
|
23
|
+
global _client
|
|
24
|
+
if _client is None:
|
|
25
|
+
_client = AzureOpenAI(
|
|
26
|
+
api_key=cfg.AZURE_API_KEY,
|
|
27
|
+
azure_endpoint=cfg.AZURE_ENDPOINT,
|
|
28
|
+
api_version=cfg.AZURE_EMBEDDINGS_API_VERSION,
|
|
29
|
+
)
|
|
30
|
+
return _client
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@retry(
|
|
34
|
+
retry=retry_if_exception_type((RateLimitError, APIConnectionError, APITimeoutError)),
|
|
35
|
+
wait=wait_exponential(multiplier=1, min=2, max=30),
|
|
36
|
+
stop=stop_after_attempt(cfg.MAX_RETRIES),
|
|
37
|
+
reraise=True,
|
|
38
|
+
)
|
|
39
|
+
def _embed_batch(texts: list[str]) -> list[list[float]]:
|
|
40
|
+
"""Embed a single batch (max 32 texts) with retry on transient errors."""
|
|
41
|
+
client = _get_client()
|
|
42
|
+
response = client.embeddings.create(
|
|
43
|
+
model=cfg.AZURE_EMBEDDING_DEPLOYMENT,
|
|
44
|
+
input=texts,
|
|
45
|
+
dimensions=cfg.EMBEDDING_DIM,
|
|
46
|
+
)
|
|
47
|
+
# Response items are ordered by index
|
|
48
|
+
sorted_data = sorted(response.data, key=lambda x: x.index)
|
|
49
|
+
return [item.embedding for item in sorted_data]
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def embed_texts(texts: list[str], batch_size: int = 32) -> list[list[float]]:
|
|
53
|
+
"""
|
|
54
|
+
Embed a list of texts in batches.
|
|
55
|
+
Returns list of embeddings in the same order as input texts.
|
|
56
|
+
Empty or whitespace-only texts get a zero vector.
|
|
57
|
+
"""
|
|
58
|
+
results: list[list[float] | None] = [None] * len(texts)
|
|
59
|
+
zero_vector = [0.0] * cfg.EMBEDDING_DIM
|
|
60
|
+
|
|
61
|
+
# Separate non-empty texts with their original indices
|
|
62
|
+
to_embed: list[tuple[int, str]] = [
|
|
63
|
+
(i, t.strip()) for i, t in enumerate(texts) if t.strip()
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
for batch_start in range(0, len(to_embed), batch_size):
|
|
67
|
+
batch = to_embed[batch_start:batch_start + batch_size]
|
|
68
|
+
indices = [item[0] for item in batch]
|
|
69
|
+
batch_texts = [item[1] for item in batch]
|
|
70
|
+
|
|
71
|
+
try:
|
|
72
|
+
embeddings = _embed_batch(batch_texts)
|
|
73
|
+
for idx, emb in zip(indices, embeddings):
|
|
74
|
+
results[idx] = emb
|
|
75
|
+
logger.debug("Embedded batch %d–%d", batch_start, batch_start + len(batch))
|
|
76
|
+
except Exception as e:
|
|
77
|
+
logger.error("Embedding batch %d–%d failed: %s", batch_start, batch_start + len(batch), e)
|
|
78
|
+
# Fill failed batch with zero vectors rather than crashing ingestion
|
|
79
|
+
for idx in indices:
|
|
80
|
+
results[idx] = zero_vector
|
|
81
|
+
|
|
82
|
+
# Small pause between batches to stay within rate limits
|
|
83
|
+
if batch_start + batch_size < len(to_embed):
|
|
84
|
+
time.sleep(0.3)
|
|
85
|
+
|
|
86
|
+
# Fill empty/whitespace texts with zero vectors
|
|
87
|
+
return [r if r is not None else zero_vector for r in results]
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def embed_single(text: str) -> list[float]:
|
|
91
|
+
"""Embed a single text — convenience wrapper for query-time use."""
|
|
92
|
+
if not text.strip():
|
|
93
|
+
return [0.0] * cfg.EMBEDDING_DIM
|
|
94
|
+
return embed_texts([text])[0]
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def format_for_pgvector(embedding: list[float]) -> str:
|
|
98
|
+
"""Format embedding as PostgreSQL vector literal string."""
|
|
99
|
+
return "[" + ",".join(f"{v:.8f}" for v in embedding) + "]"
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""
|
|
2
|
+
IGEL Knowledge Base Evaluation Framework
|
|
3
|
+
=========================================
|
|
4
|
+
Provides 5-dimensional scoring for test case generation quality:
|
|
5
|
+
- Retrieval confidence
|
|
6
|
+
- Domain confidence
|
|
7
|
+
- Structural completeness
|
|
8
|
+
- Script executability
|
|
9
|
+
- Publish confidence
|
|
10
|
+
"""
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
from knowledge_base.eval.scorers import (
|
|
14
|
+
RetrievalScorer,
|
|
15
|
+
DomainScorer,
|
|
16
|
+
StructuralScorer,
|
|
17
|
+
ExecutabilityScorer,
|
|
18
|
+
PublishScorer,
|
|
19
|
+
EvaluationResult,
|
|
20
|
+
)
|
|
21
|
+
from knowledge_base.eval.harness import EvaluationHarness
|
|
22
|
+
from knowledge_base.eval.baseline import BaselineManager
|
|
23
|
+
|
|
24
|
+
__all__ = [
|
|
25
|
+
"RetrievalScorer",
|
|
26
|
+
"DomainScorer",
|
|
27
|
+
"StructuralScorer",
|
|
28
|
+
"ExecutabilityScorer",
|
|
29
|
+
"PublishScorer",
|
|
30
|
+
"EvaluationResult",
|
|
31
|
+
"EvaluationHarness",
|
|
32
|
+
"BaselineManager",
|
|
33
|
+
]
|