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,121 @@
|
|
|
1
|
+
"""Script generation agent — Phase 5."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from knowledge_base.agents.state import AgenticState
|
|
5
|
+
from knowledge_base.core.confidence import flatten_confidence_for_api, score_generation
|
|
6
|
+
from knowledge_base.config import cfg
|
|
7
|
+
from knowledge_base.generation.prompts import (
|
|
8
|
+
PromptContext,
|
|
9
|
+
build_markdown_user_prompt,
|
|
10
|
+
build_python_user_prompt,
|
|
11
|
+
build_system_prompt,
|
|
12
|
+
)
|
|
13
|
+
from knowledge_base.retrieval.retriever import SearchResult
|
|
14
|
+
from knowledge_base.generation.test_generator import _call_gpt, _infer_feature_area, _strip_code_fences
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def script_agent(state: AgenticState) -> AgenticState:
|
|
18
|
+
query = state.get("query", "")
|
|
19
|
+
fused = state.get("fused_context") or {}
|
|
20
|
+
test_id = state.get("test_id") or "TC_AGENT_001"
|
|
21
|
+
feature = state.get("feature_area") or _infer_feature_area(query)
|
|
22
|
+
product = state.get("product")
|
|
23
|
+
output_format = state.get("output_format", "both")
|
|
24
|
+
|
|
25
|
+
rag_chunks_raw = state.get("rag_chunks", [])
|
|
26
|
+
search_results = []
|
|
27
|
+
for i, c in enumerate(rag_chunks_raw):
|
|
28
|
+
search_results.append(SearchResult(
|
|
29
|
+
child_chunk_id=c.get("chunk_id", str(i)),
|
|
30
|
+
parent_chunk_id=c.get("chunk_id", str(i)),
|
|
31
|
+
document_id="",
|
|
32
|
+
child_content=c.get("content", "")[:500],
|
|
33
|
+
parent_content=c.get("content", ""),
|
|
34
|
+
section_title=c.get("source_name", ""),
|
|
35
|
+
file_name=c.get("source_name", ""),
|
|
36
|
+
product=product or "IGEL",
|
|
37
|
+
chunk_type="procedure",
|
|
38
|
+
rrf_score=c.get("rrf_score", 0.0),
|
|
39
|
+
rerank_score=c.get("rerank_score"),
|
|
40
|
+
))
|
|
41
|
+
|
|
42
|
+
extra_blocks = []
|
|
43
|
+
if fused.get("memory_insights"):
|
|
44
|
+
extra_blocks.append("## Operational Memory Insights\n" + "\n".join(f"- {m}" for m in fused["memory_insights"]))
|
|
45
|
+
if fused.get("temporal_changes"):
|
|
46
|
+
extra_blocks.append("## Version-Specific Context\n" + str(fused["temporal_changes"]))
|
|
47
|
+
if state.get("validation_errors"):
|
|
48
|
+
extra_blocks.append("## Validation Errors\n" + "\n".join(state["validation_errors"]))
|
|
49
|
+
if state.get("force_to_validation") and fused.get("missing_signals"):
|
|
50
|
+
extra_blocks.append("⚠️ CONTEXT GAPS DETECTED\n" + "\n".join(fused["missing_signals"]))
|
|
51
|
+
|
|
52
|
+
kg_block = _format_kg_block(fused)
|
|
53
|
+
prefix = "\n\n".join(extra_blocks + ([kg_block] if kg_block else []))
|
|
54
|
+
|
|
55
|
+
web_block = fused.get("web_block") or (state.get("web_context") or {}).get("block", "")
|
|
56
|
+
mcp_block = fused.get("mcp_block") or (state.get("mcp_context") or {}).get("block", "")
|
|
57
|
+
kg_from_retrieval = state.get("kg_context_block") or ""
|
|
58
|
+
|
|
59
|
+
ctx = PromptContext(
|
|
60
|
+
topic=query,
|
|
61
|
+
test_id=test_id,
|
|
62
|
+
feature_area=feature,
|
|
63
|
+
product=product,
|
|
64
|
+
context_chunks=search_results,
|
|
65
|
+
kg_context_block="\n\n".join(p for p in [kg_from_retrieval, prefix] if p),
|
|
66
|
+
web_context_block=web_block,
|
|
67
|
+
mcp_context_block=mcp_block,
|
|
68
|
+
skip_assemble_window=True,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
markdown = ""
|
|
72
|
+
python_out = None
|
|
73
|
+
|
|
74
|
+
try:
|
|
75
|
+
if output_format in ("md", "both"):
|
|
76
|
+
md_prompt = build_markdown_user_prompt(ctx)
|
|
77
|
+
if "version_unspecified" in state.get("query_categories", []):
|
|
78
|
+
md_prompt = "⚠️ VERSION NOT CONFIRMED\n\n" + md_prompt
|
|
79
|
+
markdown = _call_gpt(build_system_prompt(), md_prompt, max_tokens=4096, temperature=0.2)
|
|
80
|
+
|
|
81
|
+
if output_format in ("py", "both"):
|
|
82
|
+
py_prompt = build_python_user_prompt(ctx, markdown or query)
|
|
83
|
+
raw = _call_gpt(build_system_prompt(), py_prompt, max_tokens=3072, temperature=0.1)
|
|
84
|
+
python_out = _strip_code_fences(raw)
|
|
85
|
+
except Exception as e:
|
|
86
|
+
state.setdefault("agent_trace", []).append({
|
|
87
|
+
"agent": "ScriptAgent", "status": "error", "reason": str(e),
|
|
88
|
+
})
|
|
89
|
+
state["markdown_output"] = f"⚠️ Generation failed: {e}"
|
|
90
|
+
return state
|
|
91
|
+
|
|
92
|
+
if cfg.EVAL_ENABLED:
|
|
93
|
+
raw_conf = score_generation(
|
|
94
|
+
query=query,
|
|
95
|
+
markdown_output=markdown,
|
|
96
|
+
python_output=python_out,
|
|
97
|
+
retrieved_chunks=search_results,
|
|
98
|
+
retrieval_metadata={"chunk_count": len(search_results)},
|
|
99
|
+
kg_entities=state.get("kg_entities"),
|
|
100
|
+
)
|
|
101
|
+
state["confidence"] = flatten_confidence_for_api(raw_conf)
|
|
102
|
+
|
|
103
|
+
state["markdown_output"] = markdown
|
|
104
|
+
state["python_output"] = python_out
|
|
105
|
+
state.setdefault("agent_trace", []).append({
|
|
106
|
+
"agent": "ScriptAgent",
|
|
107
|
+
"status": "complete",
|
|
108
|
+
"confidence": state.get("confidence", {}).get("publish"),
|
|
109
|
+
})
|
|
110
|
+
return state
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def _format_kg_block(fused: dict) -> str:
|
|
114
|
+
lines = []
|
|
115
|
+
for k in fused.get("registry_keys") or []:
|
|
116
|
+
key = k.get("key", k) if isinstance(k, dict) else k
|
|
117
|
+
lines.append(f"Registry: {key}")
|
|
118
|
+
for p in fused.get("ui_paths") or []:
|
|
119
|
+
path = p.get("path", p) if isinstance(p, dict) else p
|
|
120
|
+
lines.append(f"UI Path: {path}")
|
|
121
|
+
return "\n".join(lines)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
from typing import List, Tuple
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from openai import AzureOpenAI
|
|
6
|
+
from knowledge_base.config import cfg
|
|
7
|
+
from knowledge_base.agents.requirement_agent import _get_llm_client
|
|
8
|
+
from knowledge_base.models.test_requirement import TestCaseWithConfidence
|
|
9
|
+
from knowledge_base.agents.automation_design_agent import AutomationPlan
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
_SYSTEM_PROMPT = """You are an expert IGEL Quality Engineering Automation Developer.
|
|
14
|
+
Your task is to generate a robust, enterprise-grade `pytest` test script for the provided approved test cases.
|
|
15
|
+
You MUST strictly adhere to the provided Automation Plan.
|
|
16
|
+
Do NOT import or use ANY fixtures, page objects, or utilities that are not explicitly listed in the Automation Plan.
|
|
17
|
+
Write valid Python 3 code. Include docstrings.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def generate_script(test_cases: List[TestCaseWithConfidence], plan: AutomationPlan, output_path: Path) -> Tuple[bool, str, str]:
|
|
21
|
+
"""
|
|
22
|
+
Generate pytest code for the given test cases using the specified automation plan.
|
|
23
|
+
Returns (success, generated_code, error_message).
|
|
24
|
+
"""
|
|
25
|
+
client = _get_llm_client()
|
|
26
|
+
|
|
27
|
+
approved_tcs = [tc.test_case for tc in test_cases if tc.is_approved]
|
|
28
|
+
if not approved_tcs:
|
|
29
|
+
return False, "", "No approved test cases to automate."
|
|
30
|
+
|
|
31
|
+
user_prompt = "Automation Plan (STRICT COMPLIANCE REQUIRED):\n"
|
|
32
|
+
user_prompt += f"Allowed Page Objects: {', '.join(plan.page_objects)}\n"
|
|
33
|
+
user_prompt += f"Allowed Fixtures: {', '.join(plan.fixtures)}\n"
|
|
34
|
+
user_prompt += f"Allowed Utilities: {', '.join(plan.utilities)}\n\n"
|
|
35
|
+
|
|
36
|
+
user_prompt += "Test Cases to Automate:\n"
|
|
37
|
+
for tc in approved_tcs:
|
|
38
|
+
user_prompt += f"\n--- Test Case: {tc.title} ({tc.tc_reference}) ---\n"
|
|
39
|
+
for step in tc.steps:
|
|
40
|
+
user_prompt += f"Step {step.step_number}: {step.action} (Data: {step.data}) -> Expected: {step.expected_result}\n"
|
|
41
|
+
|
|
42
|
+
try:
|
|
43
|
+
response = client.chat.completions.create(
|
|
44
|
+
model=cfg.AZURE_DEPLOYMENT,
|
|
45
|
+
messages=[
|
|
46
|
+
{"role": "system", "content": _SYSTEM_PROMPT},
|
|
47
|
+
{"role": "user", "content": user_prompt},
|
|
48
|
+
],
|
|
49
|
+
temperature=0.1, # Extremely low temperature for code generation
|
|
50
|
+
max_tokens=4000,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
content = response.choices[0].message.content or ""
|
|
54
|
+
|
|
55
|
+
# Strip markdown code fences if present
|
|
56
|
+
code = content
|
|
57
|
+
if code.startswith("```python"):
|
|
58
|
+
code = code.split("```python")[1]
|
|
59
|
+
if code.startswith("```"):
|
|
60
|
+
code = code.split("```")[1]
|
|
61
|
+
if code.endswith("```"):
|
|
62
|
+
code = code.rsplit("```", 1)[0]
|
|
63
|
+
|
|
64
|
+
code = code.strip()
|
|
65
|
+
|
|
66
|
+
# Ensure output directory exists
|
|
67
|
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
68
|
+
with open(output_path, "w", encoding="utf-8") as f:
|
|
69
|
+
f.write(code)
|
|
70
|
+
|
|
71
|
+
logger.info(f"Generated pytest script at {output_path}")
|
|
72
|
+
return True, code, ""
|
|
73
|
+
|
|
74
|
+
except Exception as e:
|
|
75
|
+
err = f"Failed to generate script: {e}"
|
|
76
|
+
logger.error(err)
|
|
77
|
+
return False, "", err
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""LangGraph agent state schema — Phase 5."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from typing import Any, Dict, List, Optional
|
|
5
|
+
|
|
6
|
+
# Dict-based state (compatible with Python 3.7+; TypedDict requires 3.8+)
|
|
7
|
+
AgenticState = Dict[str, Any]
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def initial_state(
|
|
11
|
+
query: str,
|
|
12
|
+
*,
|
|
13
|
+
product: Optional[str] = None,
|
|
14
|
+
top_k: int = 8,
|
|
15
|
+
output_format: str = "both",
|
|
16
|
+
test_id: Optional[str] = None,
|
|
17
|
+
raw_request: Optional[dict] = None,
|
|
18
|
+
) -> AgenticState:
|
|
19
|
+
return {
|
|
20
|
+
"query": query,
|
|
21
|
+
"raw_request": raw_request or {},
|
|
22
|
+
"intent": "",
|
|
23
|
+
"feature_area": "Unknown",
|
|
24
|
+
"version_scope": "unspecified",
|
|
25
|
+
"query_categories": [],
|
|
26
|
+
"rag_chunks": [],
|
|
27
|
+
"kg_entities": {},
|
|
28
|
+
"web_context": {"block": "", "hits": []},
|
|
29
|
+
"mcp_context": {"block": "", "hits": [], "sources_queried": []},
|
|
30
|
+
"sources_summary": {},
|
|
31
|
+
"kg_context_block": "",
|
|
32
|
+
"temporal_context": {},
|
|
33
|
+
"memory_context": [],
|
|
34
|
+
"fused_context": {},
|
|
35
|
+
"reflection_notes": [],
|
|
36
|
+
"reflection_count": 0,
|
|
37
|
+
"force_to_validation": False,
|
|
38
|
+
"validation_errors": [],
|
|
39
|
+
"validation_warnings": [],
|
|
40
|
+
"validation_passed": True,
|
|
41
|
+
"registry_keys_verified": [],
|
|
42
|
+
"ui_paths_verified": [],
|
|
43
|
+
"markdown_output": "",
|
|
44
|
+
"python_output": None,
|
|
45
|
+
"sources_used": [],
|
|
46
|
+
"confidence": {},
|
|
47
|
+
"agent_trace": [],
|
|
48
|
+
"feedback_id": None,
|
|
49
|
+
"product": product,
|
|
50
|
+
"top_k": top_k,
|
|
51
|
+
"output_format": output_format,
|
|
52
|
+
"test_id": test_id,
|
|
53
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""Temporal agent — Phase 6 Graphiti integration."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from knowledge_base.agents.state import AgenticState
|
|
5
|
+
from knowledge_base.config import cfg
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def temporal_agent(state: AgenticState) -> AgenticState:
|
|
9
|
+
version = state.get("version_scope", "unspecified")
|
|
10
|
+
categories = state.get("query_categories", [])
|
|
11
|
+
feature = state.get("feature_area", "Unknown")
|
|
12
|
+
|
|
13
|
+
if version == "unspecified" and "version_specific" not in categories:
|
|
14
|
+
state["temporal_context"] = {
|
|
15
|
+
"status": "skipped",
|
|
16
|
+
"reason": "No version scope specified",
|
|
17
|
+
}
|
|
18
|
+
state.setdefault("agent_trace", []).append({
|
|
19
|
+
"agent": "TemporalAgent", "status": "skipped",
|
|
20
|
+
})
|
|
21
|
+
return state
|
|
22
|
+
|
|
23
|
+
if not cfg.GRAPHITI_ENABLED:
|
|
24
|
+
state["temporal_context"] = {
|
|
25
|
+
"status": "skipped",
|
|
26
|
+
"reason": "Graphiti not enabled (GRAPHITI_ENABLED=false)",
|
|
27
|
+
}
|
|
28
|
+
state.setdefault("agent_trace", []).append({
|
|
29
|
+
"agent": "TemporalAgent", "status": "skipped", "reason": "Graphiti disabled",
|
|
30
|
+
})
|
|
31
|
+
return state
|
|
32
|
+
|
|
33
|
+
try:
|
|
34
|
+
from knowledge_base.graph_db.graphiti_client import get_graphiti_client
|
|
35
|
+
|
|
36
|
+
client = get_graphiti_client()
|
|
37
|
+
temporal = client.query_feature_changes(feature, version)
|
|
38
|
+
state["temporal_context"] = temporal
|
|
39
|
+
status = temporal.get("status", "complete")
|
|
40
|
+
except Exception as e:
|
|
41
|
+
state["temporal_context"] = {"status": "error", "reason": str(e)}
|
|
42
|
+
status = "error"
|
|
43
|
+
|
|
44
|
+
state.setdefault("agent_trace", []).append({
|
|
45
|
+
"agent": "TemporalAgent", "status": status,
|
|
46
|
+
"version_queried": version,
|
|
47
|
+
})
|
|
48
|
+
return state
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
from typing import List, Dict, Any
|
|
4
|
+
from openai import AzureOpenAI
|
|
5
|
+
from knowledge_base.config import cfg
|
|
6
|
+
from knowledge_base.models.test_requirement import (
|
|
7
|
+
TestRequirement,
|
|
8
|
+
ScenarioWithRules,
|
|
9
|
+
GeneratedTestCase,
|
|
10
|
+
ManualTestStep,
|
|
11
|
+
BusinessRule
|
|
12
|
+
)
|
|
13
|
+
from knowledge_base.agents.requirement_agent import _get_llm_client
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
_SYSTEM_PROMPT = """You are an expert IGEL Quality Engineering Architect.
|
|
18
|
+
Your task is to take a Business Rule for a specific Scenario and generate a detailed Manual Test Case.
|
|
19
|
+
The test case must strictly follow the business rule.
|
|
20
|
+
Output MUST be valid JSON matching this schema:
|
|
21
|
+
{
|
|
22
|
+
"title": "string",
|
|
23
|
+
"priority": "critical" | "high" | "medium" | "low",
|
|
24
|
+
"preconditions": ["string"],
|
|
25
|
+
"steps": [
|
|
26
|
+
{
|
|
27
|
+
"step_number": 1,
|
|
28
|
+
"action": "string",
|
|
29
|
+
"data": "string",
|
|
30
|
+
"expected_result": "string"
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
def generate_test_case(requirement: TestRequirement, scenario_rules: ScenarioWithRules, rule: BusinessRule) -> GeneratedTestCase:
|
|
37
|
+
"""Generate a specific test case from a business rule."""
|
|
38
|
+
client = _get_llm_client()
|
|
39
|
+
|
|
40
|
+
# Construct context
|
|
41
|
+
user_prompt = f"Requirement: {requirement.summary}\n"
|
|
42
|
+
user_prompt += f"Scenario Action: {scenario_rules.scenario.action}\n"
|
|
43
|
+
user_prompt += f"Business Rule ({rule.rule_type}): {rule.description}\n\n"
|
|
44
|
+
user_prompt += "Generate a detailed manual test case for this business rule."
|
|
45
|
+
|
|
46
|
+
try:
|
|
47
|
+
response = client.chat.completions.create(
|
|
48
|
+
model=cfg.AZURE_DEPLOYMENT,
|
|
49
|
+
messages=[
|
|
50
|
+
{"role": "system", "content": _SYSTEM_PROMPT},
|
|
51
|
+
{"role": "user", "content": user_prompt},
|
|
52
|
+
],
|
|
53
|
+
response_format={"type": "json_object"},
|
|
54
|
+
temperature=0.2,
|
|
55
|
+
max_tokens=2000,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
content = response.choices[0].message.content or "{}"
|
|
59
|
+
data = json.loads(content)
|
|
60
|
+
|
|
61
|
+
# Build manual steps
|
|
62
|
+
steps = []
|
|
63
|
+
for s in data.get("steps", []):
|
|
64
|
+
if isinstance(s, dict) and "action" in s and "expected_result" in s:
|
|
65
|
+
steps.append(ManualTestStep(
|
|
66
|
+
step_number=s.get("step_number", len(steps) + 1),
|
|
67
|
+
action=s["action"],
|
|
68
|
+
data=s.get("data", ""),
|
|
69
|
+
expected_result=s["expected_result"]
|
|
70
|
+
))
|
|
71
|
+
|
|
72
|
+
tc_ref = f"TC_{requirement.jira_key}_S{scenario_rules.scenario.step_number:02d}_{rule.rule_type[:1].upper()}"
|
|
73
|
+
|
|
74
|
+
tc = GeneratedTestCase(
|
|
75
|
+
tc_reference=tc_ref,
|
|
76
|
+
business_rule=rule,
|
|
77
|
+
title=data.get("title", f"Test for {rule.description}"),
|
|
78
|
+
test_type=rule.rule_type,
|
|
79
|
+
priority=data.get("priority", "medium"),
|
|
80
|
+
preconditions=data.get("preconditions", []),
|
|
81
|
+
steps=steps,
|
|
82
|
+
confidence_score=0.0,
|
|
83
|
+
confidence_metrics={}
|
|
84
|
+
)
|
|
85
|
+
logger.info(f"Generated test case {tc_ref} with {len(steps)} steps")
|
|
86
|
+
return tc
|
|
87
|
+
|
|
88
|
+
except Exception as e:
|
|
89
|
+
logger.error(f"Failed to generate test case for rule '{rule.description}': {e}")
|
|
90
|
+
# Return a stubbed TC on failure
|
|
91
|
+
return GeneratedTestCase(
|
|
92
|
+
tc_reference=f"TC_{requirement.jira_key}_ERR",
|
|
93
|
+
business_rule=rule,
|
|
94
|
+
title="Failed to generate",
|
|
95
|
+
test_type=rule.rule_type,
|
|
96
|
+
priority="low",
|
|
97
|
+
preconditions=[],
|
|
98
|
+
steps=[],
|
|
99
|
+
confidence_score=0.0,
|
|
100
|
+
confidence_metrics={}
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
def generate_cases_for_scenario(requirement: TestRequirement, scenario_rules: ScenarioWithRules) -> List[GeneratedTestCase]:
|
|
104
|
+
"""Generate test cases for all business rules in a scenario."""
|
|
105
|
+
cases = []
|
|
106
|
+
# Enumerate to make refs unique if there are multiple of same type
|
|
107
|
+
for i, rule in enumerate(scenario_rules.business_rules):
|
|
108
|
+
tc = generate_test_case(requirement, scenario_rules, rule)
|
|
109
|
+
tc.tc_reference = f"{tc.tc_reference}{i+1:02d}"
|
|
110
|
+
cases.append(tc)
|
|
111
|
+
return cases
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Tuple, List
|
|
3
|
+
from knowledge_base.models.test_requirement import GeneratedTestCase, ScenarioWithRules, TestRequirement
|
|
4
|
+
|
|
5
|
+
logger = logging.getLogger(__name__)
|
|
6
|
+
|
|
7
|
+
def validate_structural(tc: GeneratedTestCase) -> Tuple[bool, List[str]]:
|
|
8
|
+
"""Verify structural integrity of the generated test case."""
|
|
9
|
+
errors = []
|
|
10
|
+
|
|
11
|
+
if not tc.title or len(tc.title) < 5:
|
|
12
|
+
errors.append("Title is missing or too short")
|
|
13
|
+
if not tc.steps:
|
|
14
|
+
errors.append("No steps generated")
|
|
15
|
+
|
|
16
|
+
for i, step in enumerate(tc.steps):
|
|
17
|
+
if not step.action:
|
|
18
|
+
errors.append(f"Step {step.step_number}: Missing action")
|
|
19
|
+
if not step.expected_result:
|
|
20
|
+
errors.append(f"Step {step.step_number}: Missing expected result")
|
|
21
|
+
|
|
22
|
+
return len(errors) == 0, errors
|
|
23
|
+
|
|
24
|
+
def validate_traceability(tc: GeneratedTestCase, scenario: ScenarioWithRules) -> Tuple[bool, List[str]]:
|
|
25
|
+
"""Verify test case traces back to the business rule and scenario."""
|
|
26
|
+
errors = []
|
|
27
|
+
|
|
28
|
+
# In a real system, you might use an LLM or embedding to verify the generated steps
|
|
29
|
+
# actually cover the specific business rule constraint.
|
|
30
|
+
# For now, we perform basic deterministic checks.
|
|
31
|
+
if tc.business_rule.description not in [r.description for r in scenario.business_rules]:
|
|
32
|
+
errors.append("Test case business rule does not belong to the parent scenario")
|
|
33
|
+
|
|
34
|
+
return len(errors) == 0, errors
|
|
35
|
+
|
|
36
|
+
def run_validation_pipeline(tc: GeneratedTestCase, scenario: ScenarioWithRules) -> Tuple[bool, List[str]]:
|
|
37
|
+
"""Run all validation checks before confidence scoring."""
|
|
38
|
+
all_errors = []
|
|
39
|
+
|
|
40
|
+
struct_ok, struct_errs = validate_structural(tc)
|
|
41
|
+
all_errors.extend(struct_errs)
|
|
42
|
+
|
|
43
|
+
trace_ok, trace_errs = validate_traceability(tc, scenario)
|
|
44
|
+
all_errors.extend(trace_errs)
|
|
45
|
+
|
|
46
|
+
if all_errors:
|
|
47
|
+
logger.warning(f"Validation failed for {tc.tc_reference}: {', '.join(all_errors)}")
|
|
48
|
+
|
|
49
|
+
return len(all_errors) == 0, all_errors
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import List, Tuple
|
|
4
|
+
|
|
5
|
+
from knowledge_base.models.test_requirement import TestRequirement, GeneratedTestCase, TestCaseWithConfidence
|
|
6
|
+
from knowledge_base.agents.requirement_agent import extract_understanding
|
|
7
|
+
from knowledge_base.agents.scenario_agent import generate_all_scenarios
|
|
8
|
+
from knowledge_base.agents.testcase_agent import generate_cases_for_scenario
|
|
9
|
+
from knowledge_base.agents.validation_agent import run_validation_pipeline
|
|
10
|
+
from knowledge_base.agents.confidence_agent import compute_hybrid_confidence
|
|
11
|
+
from knowledge_base.agents.automation_design_agent import design_automation_plan
|
|
12
|
+
from knowledge_base.agents.script_generator_agent import generate_script
|
|
13
|
+
from knowledge_base.agents.execution_validation_agent import ExecutionValidationAgent
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
class WorkflowEngine:
|
|
18
|
+
"""Predictable orchestration engine replacing the bottleneck Queen Agent."""
|
|
19
|
+
|
|
20
|
+
def __init__(self, repo_path: Path):
|
|
21
|
+
self.repo_path = repo_path
|
|
22
|
+
self.exec_validator = ExecutionValidationAgent(repo_path)
|
|
23
|
+
|
|
24
|
+
def run_requirement_flow(self, req: TestRequirement) -> TestRequirement:
|
|
25
|
+
"""Requirement -> Requirement Understanding -> Scenario -> Business Rules"""
|
|
26
|
+
logger.info(f"Starting requirement flow for {req.jira_key}")
|
|
27
|
+
|
|
28
|
+
# 1. Understanding Layer
|
|
29
|
+
understanding = extract_understanding(req)
|
|
30
|
+
req.understanding = understanding
|
|
31
|
+
|
|
32
|
+
# 2. Scenario & Business Rules Layer
|
|
33
|
+
scenarios_with_rules = generate_all_scenarios(req)
|
|
34
|
+
|
|
35
|
+
# In reality, you'd persist `scenarios_with_rules` to DB here
|
|
36
|
+
return req, scenarios_with_rules
|
|
37
|
+
|
|
38
|
+
def run_testcase_flow(self, req: TestRequirement, scenarios_with_rules: List) -> List[TestCaseWithConfidence]:
|
|
39
|
+
"""Business Rules -> Test Cases -> Validation -> Confidence"""
|
|
40
|
+
logger.info(f"Starting test case flow for {req.jira_key}")
|
|
41
|
+
all_cases = []
|
|
42
|
+
|
|
43
|
+
for sr in scenarios_with_rules:
|
|
44
|
+
# 1. Generate Test Cases
|
|
45
|
+
tcs = generate_cases_for_scenario(req, sr)
|
|
46
|
+
|
|
47
|
+
for tc in tcs:
|
|
48
|
+
# 2. Structural/Traceability Validation
|
|
49
|
+
ok, errs = run_validation_pipeline(tc, sr)
|
|
50
|
+
if not ok:
|
|
51
|
+
# Depending on policy, skip or mark for human review
|
|
52
|
+
pass
|
|
53
|
+
|
|
54
|
+
# 3. Deterministic Confidence Scoring
|
|
55
|
+
tc_conf = compute_hybrid_confidence(tc, sr)
|
|
56
|
+
all_cases.append(tc_conf)
|
|
57
|
+
|
|
58
|
+
# Persist to igel_generated_testcases here
|
|
59
|
+
return all_cases
|
|
60
|
+
|
|
61
|
+
def run_script_flow(self, req: TestRequirement, test_cases: List[TestCaseWithConfidence], output_path: Path) -> Tuple[bool, str]:
|
|
62
|
+
"""Approved Test Cases -> Automation Design -> Script -> Execution Validation"""
|
|
63
|
+
logger.info(f"Starting script flow for {req.jira_key}")
|
|
64
|
+
|
|
65
|
+
# Filter for approved
|
|
66
|
+
approved = [tc for tc in test_cases if tc.is_approved]
|
|
67
|
+
if not approved:
|
|
68
|
+
return False, "No approved test cases available for automation."
|
|
69
|
+
|
|
70
|
+
# 1. Automation Design Agent
|
|
71
|
+
plan = design_automation_plan(test_cases)
|
|
72
|
+
|
|
73
|
+
# 2. Script Generator
|
|
74
|
+
ok, code, err = generate_script(test_cases, plan, output_path)
|
|
75
|
+
if not ok:
|
|
76
|
+
return False, err
|
|
77
|
+
|
|
78
|
+
# 3. Execution Validation Pipeline
|
|
79
|
+
ok, status, err = self.exec_validator.validate_pipeline(code, output_path)
|
|
80
|
+
|
|
81
|
+
# Persist to igel_automation_scripts here
|
|
82
|
+
|
|
83
|
+
if not ok:
|
|
84
|
+
logger.warning(f"Execution validation failed ({status}): {err}")
|
|
85
|
+
return False, err
|
|
86
|
+
|
|
87
|
+
return True, "Script successfully generated and validated."
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Database Migrations with Alembic
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This directory contains Alembic migrations for the IGEL Knowledge Base database schema.
|
|
6
|
+
|
|
7
|
+
## Setup
|
|
8
|
+
|
|
9
|
+
1. **Install dependencies**:
|
|
10
|
+
```bash
|
|
11
|
+
pip install -r requirements_kb.txt
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
2. **Configure database connection**:
|
|
15
|
+
Ensure your `.env` file has PostgreSQL credentials:
|
|
16
|
+
```
|
|
17
|
+
DB_HOST=192.168.204.65
|
|
18
|
+
DB_PORT=5432
|
|
19
|
+
DB_NAME=AI_Led_QE
|
|
20
|
+
DB_USER=genai
|
|
21
|
+
DB_PASSWORD=your_password
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
3. **Initialize database** (if needed):
|
|
25
|
+
```bash
|
|
26
|
+
python -m knowledge_base.db.schema # Creates base tables
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Running Migrations
|
|
30
|
+
|
|
31
|
+
### Apply all pending migrations
|
|
32
|
+
```bash
|
|
33
|
+
cd /root/IGEL/IGEL_Automation_Claude/IGEL/innominds
|
|
34
|
+
alembic upgrade head
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Check current migration status
|
|
38
|
+
```bash
|
|
39
|
+
alembic current
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### View migration history
|
|
43
|
+
```bash
|
|
44
|
+
alembic history
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Rollback one migration
|
|
48
|
+
```bash
|
|
49
|
+
alembic downgrade -1
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Rollback to specific revision
|
|
53
|
+
```bash
|
|
54
|
+
alembic downgrade 001_phase0_feedback
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Creating New Migrations
|
|
58
|
+
|
|
59
|
+
### Auto-generate migration (recommended)
|
|
60
|
+
```bash
|
|
61
|
+
alembic revision --autogenerate -m "Add new column to feedback_events"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Manual migration
|
|
65
|
+
```bash
|
|
66
|
+
alembic revision -m "Custom schema change"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Then edit the generated file in `knowledge_base/alembic/versions/`.
|
|
70
|
+
|
|
71
|
+
## Migration Files
|
|
72
|
+
|
|
73
|
+
- `001_phase0_feedback.py` - Phase 0: Adds feedback_events, eval_runs, eval_results tables
|
|
74
|
+
|
|
75
|
+
## Best Practices
|
|
76
|
+
|
|
77
|
+
1. **Always test migrations in dev environment first**
|
|
78
|
+
2. **Review auto-generated migrations** - Alembic may miss custom types or constraints
|
|
79
|
+
3. **Include both upgrade() and downgrade()** - Always provide rollback path
|
|
80
|
+
4. **Never edit applied migrations** - Create new migration instead
|
|
81
|
+
5. **Backup before production migrations**:
|
|
82
|
+
```bash
|
|
83
|
+
pg_dump -U genai AI_Led_QE > backup_$(date +%Y%m%d_%H%M%S).sql
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Troubleshooting
|
|
87
|
+
|
|
88
|
+
### Migration fails with "relation already exists"
|
|
89
|
+
The table may have been created by `schema.py`. Options:
|
|
90
|
+
1. Drop the table: `DROP TABLE feedback_events CASCADE;`
|
|
91
|
+
2. Or mark migration as applied: `alembic stamp 001_phase0_feedback`
|
|
92
|
+
|
|
93
|
+
### Database connection error
|
|
94
|
+
- Check `.env` file has correct credentials
|
|
95
|
+
- Verify PostgreSQL is running: `psql -U genai -d AI_Led_QE -h 192.168.204.65`
|
|
96
|
+
- Check network connectivity to DB server
|
|
97
|
+
|
|
98
|
+
### "Can't locate revision identified by"
|
|
99
|
+
Reset Alembic's version tracking:
|
|
100
|
+
```bash
|
|
101
|
+
# WARNING: Only in dev environment
|
|
102
|
+
DROP TABLE IF EXISTS alembic_version;
|
|
103
|
+
alembic stamp head
|
|
104
|
+
```
|
|
Binary file
|
|
Binary file
|