aiecs 1.0.1__py3-none-any.whl → 1.7.6__py3-none-any.whl
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.
Potentially problematic release.
This version of aiecs might be problematic. Click here for more details.
- aiecs/__init__.py +13 -16
- aiecs/__main__.py +7 -7
- aiecs/aiecs_client.py +269 -75
- aiecs/application/executors/operation_executor.py +79 -54
- aiecs/application/knowledge_graph/__init__.py +7 -0
- aiecs/application/knowledge_graph/builder/__init__.py +37 -0
- aiecs/application/knowledge_graph/builder/data_quality.py +302 -0
- aiecs/application/knowledge_graph/builder/data_reshaping.py +293 -0
- aiecs/application/knowledge_graph/builder/document_builder.py +369 -0
- aiecs/application/knowledge_graph/builder/graph_builder.py +490 -0
- aiecs/application/knowledge_graph/builder/import_optimizer.py +396 -0
- aiecs/application/knowledge_graph/builder/schema_inference.py +462 -0
- aiecs/application/knowledge_graph/builder/schema_mapping.py +563 -0
- aiecs/application/knowledge_graph/builder/structured_pipeline.py +1384 -0
- aiecs/application/knowledge_graph/builder/text_chunker.py +317 -0
- aiecs/application/knowledge_graph/extractors/__init__.py +27 -0
- aiecs/application/knowledge_graph/extractors/base.py +98 -0
- aiecs/application/knowledge_graph/extractors/llm_entity_extractor.py +422 -0
- aiecs/application/knowledge_graph/extractors/llm_relation_extractor.py +347 -0
- aiecs/application/knowledge_graph/extractors/ner_entity_extractor.py +241 -0
- aiecs/application/knowledge_graph/fusion/__init__.py +78 -0
- aiecs/application/knowledge_graph/fusion/ab_testing.py +395 -0
- aiecs/application/knowledge_graph/fusion/abbreviation_expander.py +327 -0
- aiecs/application/knowledge_graph/fusion/alias_index.py +597 -0
- aiecs/application/knowledge_graph/fusion/alias_matcher.py +384 -0
- aiecs/application/knowledge_graph/fusion/cache_coordinator.py +343 -0
- aiecs/application/knowledge_graph/fusion/entity_deduplicator.py +433 -0
- aiecs/application/knowledge_graph/fusion/entity_linker.py +511 -0
- aiecs/application/knowledge_graph/fusion/evaluation_dataset.py +240 -0
- aiecs/application/knowledge_graph/fusion/knowledge_fusion.py +632 -0
- aiecs/application/knowledge_graph/fusion/matching_config.py +489 -0
- aiecs/application/knowledge_graph/fusion/name_normalizer.py +352 -0
- aiecs/application/knowledge_graph/fusion/relation_deduplicator.py +183 -0
- aiecs/application/knowledge_graph/fusion/semantic_name_matcher.py +464 -0
- aiecs/application/knowledge_graph/fusion/similarity_pipeline.py +534 -0
- aiecs/application/knowledge_graph/pattern_matching/__init__.py +21 -0
- aiecs/application/knowledge_graph/pattern_matching/pattern_matcher.py +342 -0
- aiecs/application/knowledge_graph/pattern_matching/query_executor.py +366 -0
- aiecs/application/knowledge_graph/profiling/__init__.py +12 -0
- aiecs/application/knowledge_graph/profiling/query_plan_visualizer.py +195 -0
- aiecs/application/knowledge_graph/profiling/query_profiler.py +223 -0
- aiecs/application/knowledge_graph/reasoning/__init__.py +27 -0
- aiecs/application/knowledge_graph/reasoning/evidence_synthesis.py +341 -0
- aiecs/application/knowledge_graph/reasoning/inference_engine.py +500 -0
- aiecs/application/knowledge_graph/reasoning/logic_form_parser.py +163 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/__init__.py +79 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/ast_builder.py +513 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/ast_nodes.py +913 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/ast_validator.py +866 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/error_handler.py +475 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/parser.py +396 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/query_context.py +208 -0
- aiecs/application/knowledge_graph/reasoning/logic_query_integration.py +170 -0
- aiecs/application/knowledge_graph/reasoning/query_planner.py +855 -0
- aiecs/application/knowledge_graph/reasoning/reasoning_engine.py +518 -0
- aiecs/application/knowledge_graph/retrieval/__init__.py +27 -0
- aiecs/application/knowledge_graph/retrieval/query_intent_classifier.py +211 -0
- aiecs/application/knowledge_graph/retrieval/retrieval_strategies.py +592 -0
- aiecs/application/knowledge_graph/retrieval/strategy_types.py +23 -0
- aiecs/application/knowledge_graph/search/__init__.py +59 -0
- aiecs/application/knowledge_graph/search/hybrid_search.py +457 -0
- aiecs/application/knowledge_graph/search/reranker.py +293 -0
- aiecs/application/knowledge_graph/search/reranker_strategies.py +535 -0
- aiecs/application/knowledge_graph/search/text_similarity.py +392 -0
- aiecs/application/knowledge_graph/traversal/__init__.py +15 -0
- aiecs/application/knowledge_graph/traversal/enhanced_traversal.py +305 -0
- aiecs/application/knowledge_graph/traversal/path_scorer.py +271 -0
- aiecs/application/knowledge_graph/validators/__init__.py +13 -0
- aiecs/application/knowledge_graph/validators/relation_validator.py +239 -0
- aiecs/application/knowledge_graph/visualization/__init__.py +11 -0
- aiecs/application/knowledge_graph/visualization/graph_visualizer.py +313 -0
- aiecs/common/__init__.py +9 -0
- aiecs/common/knowledge_graph/__init__.py +17 -0
- aiecs/common/knowledge_graph/runnable.py +471 -0
- aiecs/config/__init__.py +20 -5
- aiecs/config/config.py +762 -31
- aiecs/config/graph_config.py +131 -0
- aiecs/config/tool_config.py +399 -0
- aiecs/core/__init__.py +29 -13
- aiecs/core/interface/__init__.py +2 -2
- aiecs/core/interface/execution_interface.py +22 -22
- aiecs/core/interface/storage_interface.py +37 -88
- aiecs/core/registry/__init__.py +31 -0
- aiecs/core/registry/service_registry.py +92 -0
- aiecs/domain/__init__.py +270 -1
- aiecs/domain/agent/__init__.py +191 -0
- aiecs/domain/agent/base_agent.py +3870 -0
- aiecs/domain/agent/exceptions.py +99 -0
- aiecs/domain/agent/graph_aware_mixin.py +569 -0
- aiecs/domain/agent/hybrid_agent.py +1435 -0
- aiecs/domain/agent/integration/__init__.py +29 -0
- aiecs/domain/agent/integration/context_compressor.py +216 -0
- aiecs/domain/agent/integration/context_engine_adapter.py +587 -0
- aiecs/domain/agent/integration/protocols.py +281 -0
- aiecs/domain/agent/integration/retry_policy.py +218 -0
- aiecs/domain/agent/integration/role_config.py +213 -0
- aiecs/domain/agent/knowledge_aware_agent.py +1892 -0
- aiecs/domain/agent/lifecycle.py +291 -0
- aiecs/domain/agent/llm_agent.py +692 -0
- aiecs/domain/agent/memory/__init__.py +12 -0
- aiecs/domain/agent/memory/conversation.py +1124 -0
- aiecs/domain/agent/migration/__init__.py +14 -0
- aiecs/domain/agent/migration/conversion.py +163 -0
- aiecs/domain/agent/migration/legacy_wrapper.py +86 -0
- aiecs/domain/agent/models.py +884 -0
- aiecs/domain/agent/observability.py +479 -0
- aiecs/domain/agent/persistence.py +449 -0
- aiecs/domain/agent/prompts/__init__.py +29 -0
- aiecs/domain/agent/prompts/builder.py +159 -0
- aiecs/domain/agent/prompts/formatters.py +187 -0
- aiecs/domain/agent/prompts/template.py +255 -0
- aiecs/domain/agent/registry.py +253 -0
- aiecs/domain/agent/tool_agent.py +444 -0
- aiecs/domain/agent/tools/__init__.py +15 -0
- aiecs/domain/agent/tools/schema_generator.py +364 -0
- aiecs/domain/community/__init__.py +155 -0
- aiecs/domain/community/agent_adapter.py +469 -0
- aiecs/domain/community/analytics.py +432 -0
- aiecs/domain/community/collaborative_workflow.py +648 -0
- aiecs/domain/community/communication_hub.py +634 -0
- aiecs/domain/community/community_builder.py +320 -0
- aiecs/domain/community/community_integration.py +796 -0
- aiecs/domain/community/community_manager.py +803 -0
- aiecs/domain/community/decision_engine.py +849 -0
- aiecs/domain/community/exceptions.py +231 -0
- aiecs/domain/community/models/__init__.py +33 -0
- aiecs/domain/community/models/community_models.py +234 -0
- aiecs/domain/community/resource_manager.py +461 -0
- aiecs/domain/community/shared_context_manager.py +589 -0
- aiecs/domain/context/__init__.py +40 -10
- aiecs/domain/context/context_engine.py +1910 -0
- aiecs/domain/context/conversation_models.py +87 -53
- aiecs/domain/context/graph_memory.py +582 -0
- aiecs/domain/execution/model.py +12 -4
- aiecs/domain/knowledge_graph/__init__.py +19 -0
- aiecs/domain/knowledge_graph/models/__init__.py +52 -0
- aiecs/domain/knowledge_graph/models/entity.py +148 -0
- aiecs/domain/knowledge_graph/models/evidence.py +178 -0
- aiecs/domain/knowledge_graph/models/inference_rule.py +184 -0
- aiecs/domain/knowledge_graph/models/path.py +171 -0
- aiecs/domain/knowledge_graph/models/path_pattern.py +171 -0
- aiecs/domain/knowledge_graph/models/query.py +261 -0
- aiecs/domain/knowledge_graph/models/query_plan.py +181 -0
- aiecs/domain/knowledge_graph/models/relation.py +202 -0
- aiecs/domain/knowledge_graph/schema/__init__.py +23 -0
- aiecs/domain/knowledge_graph/schema/entity_type.py +131 -0
- aiecs/domain/knowledge_graph/schema/graph_schema.py +253 -0
- aiecs/domain/knowledge_graph/schema/property_schema.py +143 -0
- aiecs/domain/knowledge_graph/schema/relation_type.py +163 -0
- aiecs/domain/knowledge_graph/schema/schema_manager.py +691 -0
- aiecs/domain/knowledge_graph/schema/type_enums.py +209 -0
- aiecs/domain/task/dsl_processor.py +172 -56
- aiecs/domain/task/model.py +20 -8
- aiecs/domain/task/task_context.py +27 -24
- aiecs/infrastructure/__init__.py +0 -2
- aiecs/infrastructure/graph_storage/__init__.py +11 -0
- aiecs/infrastructure/graph_storage/base.py +837 -0
- aiecs/infrastructure/graph_storage/batch_operations.py +458 -0
- aiecs/infrastructure/graph_storage/cache.py +424 -0
- aiecs/infrastructure/graph_storage/distributed.py +223 -0
- aiecs/infrastructure/graph_storage/error_handling.py +380 -0
- aiecs/infrastructure/graph_storage/graceful_degradation.py +294 -0
- aiecs/infrastructure/graph_storage/health_checks.py +378 -0
- aiecs/infrastructure/graph_storage/in_memory.py +1197 -0
- aiecs/infrastructure/graph_storage/index_optimization.py +446 -0
- aiecs/infrastructure/graph_storage/lazy_loading.py +431 -0
- aiecs/infrastructure/graph_storage/metrics.py +344 -0
- aiecs/infrastructure/graph_storage/migration.py +400 -0
- aiecs/infrastructure/graph_storage/pagination.py +483 -0
- aiecs/infrastructure/graph_storage/performance_monitoring.py +456 -0
- aiecs/infrastructure/graph_storage/postgres.py +1563 -0
- aiecs/infrastructure/graph_storage/property_storage.py +353 -0
- aiecs/infrastructure/graph_storage/protocols.py +76 -0
- aiecs/infrastructure/graph_storage/query_optimizer.py +642 -0
- aiecs/infrastructure/graph_storage/schema_cache.py +290 -0
- aiecs/infrastructure/graph_storage/sqlite.py +1373 -0
- aiecs/infrastructure/graph_storage/streaming.py +487 -0
- aiecs/infrastructure/graph_storage/tenant.py +412 -0
- aiecs/infrastructure/messaging/celery_task_manager.py +92 -54
- aiecs/infrastructure/messaging/websocket_manager.py +51 -35
- aiecs/infrastructure/monitoring/__init__.py +22 -0
- aiecs/infrastructure/monitoring/executor_metrics.py +45 -11
- aiecs/infrastructure/monitoring/global_metrics_manager.py +212 -0
- aiecs/infrastructure/monitoring/structured_logger.py +3 -7
- aiecs/infrastructure/monitoring/tracing_manager.py +63 -35
- aiecs/infrastructure/persistence/__init__.py +14 -1
- aiecs/infrastructure/persistence/context_engine_client.py +184 -0
- aiecs/infrastructure/persistence/database_manager.py +67 -43
- aiecs/infrastructure/persistence/file_storage.py +180 -103
- aiecs/infrastructure/persistence/redis_client.py +74 -21
- aiecs/llm/__init__.py +73 -25
- aiecs/llm/callbacks/__init__.py +11 -0
- aiecs/llm/{custom_callbacks.py → callbacks/custom_callbacks.py} +26 -19
- aiecs/llm/client_factory.py +224 -36
- aiecs/llm/client_resolver.py +155 -0
- aiecs/llm/clients/__init__.py +38 -0
- aiecs/llm/clients/base_client.py +324 -0
- aiecs/llm/clients/google_function_calling_mixin.py +457 -0
- aiecs/llm/clients/googleai_client.py +241 -0
- aiecs/llm/clients/openai_client.py +158 -0
- aiecs/llm/clients/openai_compatible_mixin.py +367 -0
- aiecs/llm/clients/vertex_client.py +897 -0
- aiecs/llm/clients/xai_client.py +201 -0
- aiecs/llm/config/__init__.py +51 -0
- aiecs/llm/config/config_loader.py +272 -0
- aiecs/llm/config/config_validator.py +206 -0
- aiecs/llm/config/model_config.py +143 -0
- aiecs/llm/protocols.py +149 -0
- aiecs/llm/utils/__init__.py +10 -0
- aiecs/llm/utils/validate_config.py +89 -0
- aiecs/main.py +140 -121
- aiecs/scripts/aid/VERSION_MANAGEMENT.md +138 -0
- aiecs/scripts/aid/__init__.py +19 -0
- aiecs/scripts/aid/module_checker.py +499 -0
- aiecs/scripts/aid/version_manager.py +235 -0
- aiecs/scripts/{DEPENDENCY_SYSTEM_SUMMARY.md → dependance_check/DEPENDENCY_SYSTEM_SUMMARY.md} +1 -0
- aiecs/scripts/{README_DEPENDENCY_CHECKER.md → dependance_check/README_DEPENDENCY_CHECKER.md} +1 -0
- aiecs/scripts/dependance_check/__init__.py +15 -0
- aiecs/scripts/dependance_check/dependency_checker.py +1835 -0
- aiecs/scripts/{dependency_fixer.py → dependance_check/dependency_fixer.py} +192 -90
- aiecs/scripts/{download_nlp_data.py → dependance_check/download_nlp_data.py} +203 -71
- aiecs/scripts/dependance_patch/__init__.py +7 -0
- aiecs/scripts/dependance_patch/fix_weasel/__init__.py +11 -0
- aiecs/scripts/{fix_weasel_validator.py → dependance_patch/fix_weasel/fix_weasel_validator.py} +21 -14
- aiecs/scripts/{patch_weasel_library.sh → dependance_patch/fix_weasel/patch_weasel_library.sh} +1 -1
- aiecs/scripts/knowledge_graph/__init__.py +3 -0
- aiecs/scripts/knowledge_graph/run_threshold_experiments.py +212 -0
- aiecs/scripts/migrations/multi_tenancy/README.md +142 -0
- aiecs/scripts/tools_develop/README.md +671 -0
- aiecs/scripts/tools_develop/README_CONFIG_CHECKER.md +273 -0
- aiecs/scripts/tools_develop/TOOLS_CONFIG_GUIDE.md +1287 -0
- aiecs/scripts/tools_develop/TOOL_AUTO_DISCOVERY.md +234 -0
- aiecs/scripts/tools_develop/__init__.py +21 -0
- aiecs/scripts/tools_develop/check_all_tools_config.py +548 -0
- aiecs/scripts/tools_develop/check_type_annotations.py +257 -0
- aiecs/scripts/tools_develop/pre-commit-schema-coverage.sh +66 -0
- aiecs/scripts/tools_develop/schema_coverage.py +511 -0
- aiecs/scripts/tools_develop/validate_tool_schemas.py +475 -0
- aiecs/scripts/tools_develop/verify_executor_config_fix.py +98 -0
- aiecs/scripts/tools_develop/verify_tools.py +352 -0
- aiecs/tasks/__init__.py +0 -1
- aiecs/tasks/worker.py +115 -47
- aiecs/tools/__init__.py +194 -72
- aiecs/tools/apisource/__init__.py +99 -0
- aiecs/tools/apisource/intelligence/__init__.py +19 -0
- aiecs/tools/apisource/intelligence/data_fusion.py +632 -0
- aiecs/tools/apisource/intelligence/query_analyzer.py +417 -0
- aiecs/tools/apisource/intelligence/search_enhancer.py +385 -0
- aiecs/tools/apisource/monitoring/__init__.py +9 -0
- aiecs/tools/apisource/monitoring/metrics.py +330 -0
- aiecs/tools/apisource/providers/__init__.py +112 -0
- aiecs/tools/apisource/providers/base.py +671 -0
- aiecs/tools/apisource/providers/census.py +397 -0
- aiecs/tools/apisource/providers/fred.py +535 -0
- aiecs/tools/apisource/providers/newsapi.py +409 -0
- aiecs/tools/apisource/providers/worldbank.py +352 -0
- aiecs/tools/apisource/reliability/__init__.py +12 -0
- aiecs/tools/apisource/reliability/error_handler.py +363 -0
- aiecs/tools/apisource/reliability/fallback_strategy.py +376 -0
- aiecs/tools/apisource/tool.py +832 -0
- aiecs/tools/apisource/utils/__init__.py +9 -0
- aiecs/tools/apisource/utils/validators.py +334 -0
- aiecs/tools/base_tool.py +415 -21
- aiecs/tools/docs/__init__.py +121 -0
- aiecs/tools/docs/ai_document_orchestrator.py +607 -0
- aiecs/tools/docs/ai_document_writer_orchestrator.py +2350 -0
- aiecs/tools/docs/content_insertion_tool.py +1320 -0
- aiecs/tools/docs/document_creator_tool.py +1323 -0
- aiecs/tools/docs/document_layout_tool.py +1160 -0
- aiecs/tools/docs/document_parser_tool.py +1011 -0
- aiecs/tools/docs/document_writer_tool.py +1829 -0
- aiecs/tools/knowledge_graph/__init__.py +17 -0
- aiecs/tools/knowledge_graph/graph_reasoning_tool.py +807 -0
- aiecs/tools/knowledge_graph/graph_search_tool.py +944 -0
- aiecs/tools/knowledge_graph/kg_builder_tool.py +524 -0
- aiecs/tools/langchain_adapter.py +300 -138
- aiecs/tools/schema_generator.py +455 -0
- aiecs/tools/search_tool/__init__.py +100 -0
- aiecs/tools/search_tool/analyzers.py +581 -0
- aiecs/tools/search_tool/cache.py +264 -0
- aiecs/tools/search_tool/constants.py +128 -0
- aiecs/tools/search_tool/context.py +224 -0
- aiecs/tools/search_tool/core.py +778 -0
- aiecs/tools/search_tool/deduplicator.py +119 -0
- aiecs/tools/search_tool/error_handler.py +242 -0
- aiecs/tools/search_tool/metrics.py +343 -0
- aiecs/tools/search_tool/rate_limiter.py +172 -0
- aiecs/tools/search_tool/schemas.py +275 -0
- aiecs/tools/statistics/__init__.py +80 -0
- aiecs/tools/statistics/ai_data_analysis_orchestrator.py +646 -0
- aiecs/tools/statistics/ai_insight_generator_tool.py +508 -0
- aiecs/tools/statistics/ai_report_orchestrator_tool.py +684 -0
- aiecs/tools/statistics/data_loader_tool.py +555 -0
- aiecs/tools/statistics/data_profiler_tool.py +638 -0
- aiecs/tools/statistics/data_transformer_tool.py +580 -0
- aiecs/tools/statistics/data_visualizer_tool.py +498 -0
- aiecs/tools/statistics/model_trainer_tool.py +507 -0
- aiecs/tools/statistics/statistical_analyzer_tool.py +472 -0
- aiecs/tools/task_tools/__init__.py +49 -36
- aiecs/tools/task_tools/chart_tool.py +200 -184
- aiecs/tools/task_tools/classfire_tool.py +268 -267
- aiecs/tools/task_tools/image_tool.py +175 -131
- aiecs/tools/task_tools/office_tool.py +226 -146
- aiecs/tools/task_tools/pandas_tool.py +477 -121
- aiecs/tools/task_tools/report_tool.py +390 -142
- aiecs/tools/task_tools/research_tool.py +149 -79
- aiecs/tools/task_tools/scraper_tool.py +339 -145
- aiecs/tools/task_tools/stats_tool.py +448 -209
- aiecs/tools/temp_file_manager.py +26 -24
- aiecs/tools/tool_executor/__init__.py +18 -16
- aiecs/tools/tool_executor/tool_executor.py +364 -52
- aiecs/utils/LLM_output_structor.py +74 -48
- aiecs/utils/__init__.py +14 -3
- aiecs/utils/base_callback.py +0 -3
- aiecs/utils/cache_provider.py +696 -0
- aiecs/utils/execution_utils.py +50 -31
- aiecs/utils/prompt_loader.py +1 -0
- aiecs/utils/token_usage_repository.py +37 -11
- aiecs/ws/socket_server.py +14 -4
- {aiecs-1.0.1.dist-info → aiecs-1.7.6.dist-info}/METADATA +52 -15
- aiecs-1.7.6.dist-info/RECORD +337 -0
- aiecs-1.7.6.dist-info/entry_points.txt +13 -0
- aiecs/config/registry.py +0 -19
- aiecs/domain/context/content_engine.py +0 -982
- aiecs/llm/base_client.py +0 -99
- aiecs/llm/openai_client.py +0 -125
- aiecs/llm/vertex_client.py +0 -186
- aiecs/llm/xai_client.py +0 -184
- aiecs/scripts/dependency_checker.py +0 -857
- aiecs/scripts/quick_dependency_check.py +0 -269
- aiecs/tools/task_tools/search_api.py +0 -7
- aiecs-1.0.1.dist-info/RECORD +0 -90
- aiecs-1.0.1.dist-info/entry_points.txt +0 -7
- /aiecs/scripts/{setup_nlp_data.sh → dependance_check/setup_nlp_data.sh} +0 -0
- /aiecs/scripts/{README_WEASEL_PATCH.md → dependance_patch/fix_weasel/README_WEASEL_PATCH.md} +0 -0
- /aiecs/scripts/{fix_weasel_validator.sh → dependance_patch/fix_weasel/fix_weasel_validator.sh} +0 -0
- /aiecs/scripts/{run_weasel_patch.sh → dependance_patch/fix_weasel/run_weasel_patch.sh} +0 -0
- {aiecs-1.0.1.dist-info → aiecs-1.7.6.dist-info}/WHEEL +0 -0
- {aiecs-1.0.1.dist-info → aiecs-1.7.6.dist-info}/licenses/LICENSE +0 -0
- {aiecs-1.0.1.dist-info → aiecs-1.7.6.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Evidence Synthesis
|
|
3
|
+
|
|
4
|
+
Combine and synthesize evidence from multiple sources for robust reasoning.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import uuid
|
|
8
|
+
from typing import List, Optional, Dict, Any
|
|
9
|
+
from collections import defaultdict
|
|
10
|
+
from aiecs.domain.knowledge_graph.models.evidence import Evidence
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class EvidenceSynthesizer:
|
|
14
|
+
"""
|
|
15
|
+
Evidence Synthesizer
|
|
16
|
+
|
|
17
|
+
Combines evidence from multiple sources to create more robust conclusions.
|
|
18
|
+
|
|
19
|
+
Features:
|
|
20
|
+
- Merge overlapping evidence
|
|
21
|
+
- Calculate combined confidence
|
|
22
|
+
- Detect contradictions
|
|
23
|
+
- Synthesize explanations
|
|
24
|
+
|
|
25
|
+
Example:
|
|
26
|
+
```python
|
|
27
|
+
synthesizer = EvidenceSynthesizer()
|
|
28
|
+
|
|
29
|
+
# Combine evidence from different sources
|
|
30
|
+
combined = synthesizer.synthesize_evidence([ev1, ev2, ev3])
|
|
31
|
+
|
|
32
|
+
# Get most reliable evidence
|
|
33
|
+
reliable = synthesizer.filter_by_confidence(combined, threshold=0.7)
|
|
34
|
+
```
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def __init__(
|
|
38
|
+
self,
|
|
39
|
+
confidence_threshold: float = 0.5,
|
|
40
|
+
contradiction_threshold: float = 0.3,
|
|
41
|
+
):
|
|
42
|
+
"""
|
|
43
|
+
Initialize evidence synthesizer
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
confidence_threshold: Minimum confidence for evidence
|
|
47
|
+
contradiction_threshold: Threshold for detecting contradictions
|
|
48
|
+
"""
|
|
49
|
+
self.confidence_threshold = confidence_threshold
|
|
50
|
+
self.contradiction_threshold = contradiction_threshold
|
|
51
|
+
|
|
52
|
+
def synthesize_evidence(self, evidence_list: List[Evidence], method: str = "weighted_average") -> List[Evidence]:
|
|
53
|
+
"""
|
|
54
|
+
Synthesize evidence from multiple sources
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
evidence_list: List of evidence to synthesize
|
|
58
|
+
method: Synthesis method ("weighted_average", "max", "voting")
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
Synthesized evidence list
|
|
62
|
+
"""
|
|
63
|
+
if not evidence_list:
|
|
64
|
+
return []
|
|
65
|
+
|
|
66
|
+
# Group evidence by entity overlap
|
|
67
|
+
groups = self._group_overlapping_evidence(evidence_list)
|
|
68
|
+
|
|
69
|
+
# Synthesize each group
|
|
70
|
+
synthesized = []
|
|
71
|
+
for group in groups:
|
|
72
|
+
if len(group) == 1:
|
|
73
|
+
synthesized.append(group[0])
|
|
74
|
+
else:
|
|
75
|
+
combined = self._combine_evidence_group(group, method)
|
|
76
|
+
synthesized.append(combined)
|
|
77
|
+
|
|
78
|
+
return synthesized
|
|
79
|
+
|
|
80
|
+
def _group_overlapping_evidence(self, evidence_list: List[Evidence]) -> List[List[Evidence]]:
|
|
81
|
+
"""
|
|
82
|
+
Group evidence that refers to overlapping entities
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
evidence_list: List of evidence to group
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
List of evidence groups
|
|
89
|
+
"""
|
|
90
|
+
groups = []
|
|
91
|
+
used = set()
|
|
92
|
+
|
|
93
|
+
for i, ev1 in enumerate(evidence_list):
|
|
94
|
+
if i in used:
|
|
95
|
+
continue
|
|
96
|
+
|
|
97
|
+
group = [ev1]
|
|
98
|
+
ev1_entities = set(ev1.get_entity_ids())
|
|
99
|
+
used.add(i)
|
|
100
|
+
|
|
101
|
+
# Find overlapping evidence
|
|
102
|
+
for j, ev2 in enumerate(evidence_list):
|
|
103
|
+
if j <= i or j in used:
|
|
104
|
+
continue
|
|
105
|
+
|
|
106
|
+
ev2_entities = set(ev2.get_entity_ids())
|
|
107
|
+
overlap = ev1_entities & ev2_entities
|
|
108
|
+
|
|
109
|
+
# If significant overlap, add to group
|
|
110
|
+
if len(overlap) > 0:
|
|
111
|
+
group.append(ev2)
|
|
112
|
+
used.add(j)
|
|
113
|
+
|
|
114
|
+
groups.append(group)
|
|
115
|
+
|
|
116
|
+
return groups
|
|
117
|
+
|
|
118
|
+
def _combine_evidence_group(self, group: List[Evidence], method: str) -> Evidence:
|
|
119
|
+
"""
|
|
120
|
+
Combine a group of overlapping evidence
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
group: Group of evidence to combine
|
|
124
|
+
method: Combination method
|
|
125
|
+
|
|
126
|
+
Returns:
|
|
127
|
+
Combined evidence
|
|
128
|
+
"""
|
|
129
|
+
if not group:
|
|
130
|
+
raise ValueError("Cannot combine empty evidence group")
|
|
131
|
+
|
|
132
|
+
if len(group) == 1:
|
|
133
|
+
return group[0]
|
|
134
|
+
|
|
135
|
+
# Collect all entities and relations
|
|
136
|
+
all_entities = []
|
|
137
|
+
all_relations = []
|
|
138
|
+
all_paths = []
|
|
139
|
+
seen_entity_ids = set()
|
|
140
|
+
seen_relation_ids = set()
|
|
141
|
+
|
|
142
|
+
for ev in group:
|
|
143
|
+
for entity in ev.entities:
|
|
144
|
+
if entity.id not in seen_entity_ids:
|
|
145
|
+
all_entities.append(entity)
|
|
146
|
+
seen_entity_ids.add(entity.id)
|
|
147
|
+
|
|
148
|
+
for relation in ev.relations:
|
|
149
|
+
if relation.id not in seen_relation_ids:
|
|
150
|
+
all_relations.append(relation)
|
|
151
|
+
seen_relation_ids.add(relation.id)
|
|
152
|
+
|
|
153
|
+
all_paths.extend(ev.paths)
|
|
154
|
+
|
|
155
|
+
# Calculate combined confidence and relevance
|
|
156
|
+
if method == "weighted_average":
|
|
157
|
+
# Weight by number of supporting evidence
|
|
158
|
+
total_confidence = sum(ev.confidence for ev in group)
|
|
159
|
+
total_relevance = sum(ev.relevance_score for ev in group)
|
|
160
|
+
confidence = total_confidence / len(group)
|
|
161
|
+
relevance = total_relevance / len(group)
|
|
162
|
+
|
|
163
|
+
elif method == "max":
|
|
164
|
+
# Take maximum
|
|
165
|
+
confidence = max(ev.confidence for ev in group)
|
|
166
|
+
relevance = max(ev.relevance_score for ev in group)
|
|
167
|
+
|
|
168
|
+
elif method == "voting":
|
|
169
|
+
# Majority voting with confidence weights
|
|
170
|
+
confidence = sum(ev.confidence for ev in group) / len(group)
|
|
171
|
+
relevance = sum(ev.relevance_score for ev in group) / len(group)
|
|
172
|
+
|
|
173
|
+
else:
|
|
174
|
+
# Default to weighted average
|
|
175
|
+
confidence = sum(ev.confidence for ev in group) / len(group)
|
|
176
|
+
relevance = sum(ev.relevance_score for ev in group) / len(group)
|
|
177
|
+
|
|
178
|
+
# Boost confidence if multiple sources agree
|
|
179
|
+
agreement_boost = min(0.1 * (len(group) - 1), 0.3)
|
|
180
|
+
confidence = min(1.0, confidence + agreement_boost)
|
|
181
|
+
|
|
182
|
+
# Create combined explanation
|
|
183
|
+
sources = list(set(ev.source for ev in group if ev.source))
|
|
184
|
+
explanation = f"Combined from {len(group)} sources: {', '.join(sources[:3])}"
|
|
185
|
+
if len(group) > 1:
|
|
186
|
+
explanation += f"\nAgreement across {len(group)} pieces of evidence increases confidence"
|
|
187
|
+
|
|
188
|
+
# Create synthesized evidence
|
|
189
|
+
combined = Evidence(
|
|
190
|
+
evidence_id=f"synth_{uuid.uuid4().hex[:8]}",
|
|
191
|
+
evidence_type=group[0].evidence_type,
|
|
192
|
+
entities=all_entities,
|
|
193
|
+
relations=all_relations,
|
|
194
|
+
paths=all_paths,
|
|
195
|
+
confidence=confidence,
|
|
196
|
+
relevance_score=relevance,
|
|
197
|
+
explanation=explanation,
|
|
198
|
+
source="synthesis",
|
|
199
|
+
metadata={
|
|
200
|
+
"source_count": len(group),
|
|
201
|
+
"source_evidence_ids": [ev.evidence_id for ev in group],
|
|
202
|
+
"synthesis_method": method,
|
|
203
|
+
},
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
return combined
|
|
207
|
+
|
|
208
|
+
def filter_by_confidence(self, evidence_list: List[Evidence], threshold: Optional[float] = None) -> List[Evidence]:
|
|
209
|
+
"""
|
|
210
|
+
Filter evidence by confidence threshold
|
|
211
|
+
|
|
212
|
+
Args:
|
|
213
|
+
evidence_list: List of evidence to filter
|
|
214
|
+
threshold: Confidence threshold (uses default if None)
|
|
215
|
+
|
|
216
|
+
Returns:
|
|
217
|
+
Filtered evidence list
|
|
218
|
+
"""
|
|
219
|
+
threshold = threshold if threshold is not None else self.confidence_threshold
|
|
220
|
+
return [ev for ev in evidence_list if ev.confidence >= threshold]
|
|
221
|
+
|
|
222
|
+
def detect_contradictions(self, evidence_list: List[Evidence]) -> List[Dict[str, Any]]:
|
|
223
|
+
"""
|
|
224
|
+
Detect contradictions in evidence
|
|
225
|
+
|
|
226
|
+
Args:
|
|
227
|
+
evidence_list: List of evidence to check
|
|
228
|
+
|
|
229
|
+
Returns:
|
|
230
|
+
List of detected contradictions
|
|
231
|
+
"""
|
|
232
|
+
contradictions = []
|
|
233
|
+
|
|
234
|
+
# Group by entity
|
|
235
|
+
entity_evidence: Dict[str, List[Evidence]] = defaultdict(list)
|
|
236
|
+
for ev in evidence_list:
|
|
237
|
+
for entity in ev.entities:
|
|
238
|
+
entity_evidence[entity.id].append(ev)
|
|
239
|
+
|
|
240
|
+
# Check for contradictory claims
|
|
241
|
+
for entity_id, evidence_group in entity_evidence.items():
|
|
242
|
+
if len(evidence_group) < 2:
|
|
243
|
+
continue
|
|
244
|
+
|
|
245
|
+
# Look for low confidence with high relevance (potential
|
|
246
|
+
# contradiction)
|
|
247
|
+
confidences = [ev.confidence for ev in evidence_group]
|
|
248
|
+
if max(confidences) - min(confidences) > self.contradiction_threshold:
|
|
249
|
+
contradictions.append(
|
|
250
|
+
{
|
|
251
|
+
"entity_id": entity_id,
|
|
252
|
+
"evidence_ids": [ev.evidence_id for ev in evidence_group],
|
|
253
|
+
"confidence_range": (
|
|
254
|
+
min(confidences),
|
|
255
|
+
max(confidences),
|
|
256
|
+
),
|
|
257
|
+
"description": f"Conflicting confidence scores for entity {entity_id}",
|
|
258
|
+
}
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
return contradictions
|
|
262
|
+
|
|
263
|
+
def estimate_overall_confidence(self, evidence_list: List[Evidence]) -> float:
|
|
264
|
+
"""
|
|
265
|
+
Estimate overall confidence from evidence list
|
|
266
|
+
|
|
267
|
+
Considers:
|
|
268
|
+
- Individual confidence scores
|
|
269
|
+
- Agreement across evidence
|
|
270
|
+
- Source diversity
|
|
271
|
+
|
|
272
|
+
Args:
|
|
273
|
+
evidence_list: List of evidence
|
|
274
|
+
|
|
275
|
+
Returns:
|
|
276
|
+
Overall confidence score (0-1)
|
|
277
|
+
"""
|
|
278
|
+
if not evidence_list:
|
|
279
|
+
return 0.0
|
|
280
|
+
|
|
281
|
+
# Base confidence (average)
|
|
282
|
+
base_confidence = sum(ev.confidence for ev in evidence_list) / len(evidence_list)
|
|
283
|
+
|
|
284
|
+
# Source diversity bonus
|
|
285
|
+
sources = set(ev.source for ev in evidence_list if ev.source)
|
|
286
|
+
diversity_bonus = min(0.1 * (len(sources) - 1), 0.2)
|
|
287
|
+
|
|
288
|
+
# Agreement bonus (entities appearing in multiple evidence)
|
|
289
|
+
entity_counts: Dict[str, int] = defaultdict(int)
|
|
290
|
+
for ev in evidence_list:
|
|
291
|
+
for entity_id in ev.get_entity_ids():
|
|
292
|
+
entity_counts[entity_id] += 1
|
|
293
|
+
|
|
294
|
+
# Average entity appearance count
|
|
295
|
+
if entity_counts:
|
|
296
|
+
avg_appearances = sum(entity_counts.values()) / len(entity_counts)
|
|
297
|
+
agreement_bonus = min(0.1 * (avg_appearances - 1), 0.15)
|
|
298
|
+
else:
|
|
299
|
+
agreement_bonus = 0.0
|
|
300
|
+
|
|
301
|
+
# Combined confidence
|
|
302
|
+
overall = base_confidence + diversity_bonus + agreement_bonus
|
|
303
|
+
return min(1.0, overall)
|
|
304
|
+
|
|
305
|
+
def rank_by_reliability(self, evidence_list: List[Evidence]) -> List[Evidence]:
|
|
306
|
+
"""
|
|
307
|
+
Rank evidence by reliability
|
|
308
|
+
|
|
309
|
+
Considers:
|
|
310
|
+
- Confidence score
|
|
311
|
+
- Relevance score
|
|
312
|
+
- Source credibility
|
|
313
|
+
|
|
314
|
+
Args:
|
|
315
|
+
evidence_list: List of evidence to rank
|
|
316
|
+
|
|
317
|
+
Returns:
|
|
318
|
+
Ranked evidence list (most reliable first)
|
|
319
|
+
"""
|
|
320
|
+
# Calculate reliability score for each evidence
|
|
321
|
+
scored = []
|
|
322
|
+
for ev in evidence_list:
|
|
323
|
+
# Base score from confidence and relevance
|
|
324
|
+
reliability = (ev.confidence * 0.6) + (ev.relevance_score * 0.4)
|
|
325
|
+
|
|
326
|
+
# Boost for synthesis (already vetted)
|
|
327
|
+
if ev.source == "synthesis":
|
|
328
|
+
reliability *= 1.1
|
|
329
|
+
|
|
330
|
+
# Boost for multiple supporting elements
|
|
331
|
+
element_count = len(ev.entities) + len(ev.relations) + len(ev.paths)
|
|
332
|
+
if element_count > 3:
|
|
333
|
+
reliability *= 1.05
|
|
334
|
+
|
|
335
|
+
reliability = min(1.0, reliability)
|
|
336
|
+
scored.append((ev, reliability))
|
|
337
|
+
|
|
338
|
+
# Sort by reliability (descending)
|
|
339
|
+
scored.sort(key=lambda x: x[1], reverse=True)
|
|
340
|
+
|
|
341
|
+
return [ev for ev, score in scored]
|