aiecs 1.0.1__py3-none-any.whl → 1.7.17__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 +435 -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 +3949 -0
- aiecs/domain/agent/exceptions.py +99 -0
- aiecs/domain/agent/graph_aware_mixin.py +569 -0
- aiecs/domain/agent/hybrid_agent.py +1731 -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 +894 -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 +377 -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 +230 -37
- aiecs/llm/client_resolver.py +155 -0
- aiecs/llm/clients/__init__.py +38 -0
- aiecs/llm/clients/base_client.py +328 -0
- aiecs/llm/clients/google_function_calling_mixin.py +415 -0
- aiecs/llm/clients/googleai_client.py +314 -0
- aiecs/llm/clients/openai_client.py +158 -0
- aiecs/llm/clients/openai_compatible_mixin.py +367 -0
- aiecs/llm/clients/vertex_client.py +1186 -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 +1464 -0
- aiecs/tools/docs/document_layout_tool.py +1160 -0
- aiecs/tools/docs/document_parser_tool.py +1016 -0
- aiecs/tools/docs/document_writer_tool.py +2008 -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 +220 -141
- 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.17.dist-info}/METADATA +52 -15
- aiecs-1.7.17.dist-info/RECORD +337 -0
- aiecs-1.7.17.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.17.dist-info}/WHEEL +0 -0
- {aiecs-1.0.1.dist-info → aiecs-1.7.17.dist-info}/licenses/LICENSE +0 -0
- {aiecs-1.0.1.dist-info → aiecs-1.7.17.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Knowledge Graph Configuration
|
|
3
|
+
|
|
4
|
+
Configuration settings for knowledge graph storage and operations.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from enum import Enum
|
|
8
|
+
from pydantic import Field
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class GraphStorageBackend(str, Enum):
|
|
12
|
+
"""Available graph storage backends"""
|
|
13
|
+
|
|
14
|
+
INMEMORY = "inmemory"
|
|
15
|
+
SQLITE = "sqlite"
|
|
16
|
+
POSTGRESQL = "postgresql"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class KnowledgeGraphConfig:
|
|
20
|
+
"""
|
|
21
|
+
Knowledge Graph Configuration
|
|
22
|
+
|
|
23
|
+
This class provides configuration settings for knowledge graph operations.
|
|
24
|
+
It integrates with AIECS Settings through environment variables.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
# Storage backend selection
|
|
28
|
+
backend: GraphStorageBackend = Field(
|
|
29
|
+
default=GraphStorageBackend.INMEMORY,
|
|
30
|
+
description="Graph storage backend to use",
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
# SQLite configuration (for file-based persistence)
|
|
34
|
+
sqlite_db_path: str = Field(
|
|
35
|
+
default="./storage/knowledge_graph.db",
|
|
36
|
+
description="Path to SQLite database file",
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
# In-memory configuration
|
|
40
|
+
inmemory_max_nodes: int = Field(
|
|
41
|
+
default=100000,
|
|
42
|
+
description="Maximum number of nodes for in-memory storage",
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
# Vector search configuration
|
|
46
|
+
vector_dimension: int = Field(
|
|
47
|
+
default=1536,
|
|
48
|
+
description="Dimension of embedding vectors (default for OpenAI ada-002)",
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
# Query configuration
|
|
52
|
+
default_search_limit: int = Field(
|
|
53
|
+
default=10,
|
|
54
|
+
description="Default number of results to return in searches",
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
max_traversal_depth: int = Field(default=5, description="Maximum depth for graph traversal queries")
|
|
58
|
+
|
|
59
|
+
# Cache configuration
|
|
60
|
+
enable_query_cache: bool = Field(default=True, description="Enable caching of query results")
|
|
61
|
+
|
|
62
|
+
cache_ttl_seconds: int = Field(
|
|
63
|
+
default=300,
|
|
64
|
+
description="Time-to-live for cached query results (seconds)",
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
# Feature flags for new capabilities
|
|
68
|
+
enable_runnable_pattern: bool = Field(
|
|
69
|
+
default=True,
|
|
70
|
+
description="Enable Runnable pattern for composable graph operations",
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
enable_knowledge_fusion: bool = Field(
|
|
74
|
+
default=True,
|
|
75
|
+
description="Enable knowledge fusion for cross-document entity merging",
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
enable_reranking: bool = Field(
|
|
79
|
+
default=True,
|
|
80
|
+
description="Enable result reranking for improved search relevance",
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
enable_logical_queries: bool = Field(
|
|
84
|
+
default=True,
|
|
85
|
+
description="Enable logical query parsing for structured queries",
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
enable_structured_import: bool = Field(default=True, description="Enable structured data import (CSV/JSON)")
|
|
89
|
+
|
|
90
|
+
# Knowledge Fusion configuration
|
|
91
|
+
fusion_similarity_threshold: float = Field(
|
|
92
|
+
default=0.85,
|
|
93
|
+
description="Similarity threshold for entity fusion (0.0-1.0)",
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
fusion_conflict_resolution: str = Field(
|
|
97
|
+
default="most_complete",
|
|
98
|
+
description="Conflict resolution strategy: most_complete, most_recent, most_confident, longest, keep_all",
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
# Reranking configuration
|
|
102
|
+
reranking_default_strategy: str = Field(
|
|
103
|
+
default="hybrid",
|
|
104
|
+
description="Default reranking strategy: text, semantic, structural, hybrid",
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
reranking_top_k: int = Field(default=100, description="Top-K results to fetch before reranking")
|
|
108
|
+
|
|
109
|
+
# Schema cache configuration
|
|
110
|
+
enable_schema_cache: bool = Field(
|
|
111
|
+
default=True,
|
|
112
|
+
description="Enable schema caching for improved performance",
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
schema_cache_ttl_seconds: int = Field(default=3600, description="Time-to-live for cached schemas (seconds)")
|
|
116
|
+
|
|
117
|
+
# Query optimization configuration
|
|
118
|
+
enable_query_optimization: bool = Field(
|
|
119
|
+
default=True,
|
|
120
|
+
description="Enable query optimization for better performance",
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
query_optimization_strategy: str = Field(
|
|
124
|
+
default="balanced",
|
|
125
|
+
description="Query optimization strategy: cost, latency, balanced",
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def get_graph_config() -> KnowledgeGraphConfig:
|
|
130
|
+
"""Get knowledge graph configuration singleton"""
|
|
131
|
+
return KnowledgeGraphConfig()
|
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Configuration loader for tool configurations.
|
|
3
|
+
|
|
4
|
+
This module provides a singleton configuration loader that loads and manages
|
|
5
|
+
tool configurations from YAML files and .env files with support for
|
|
6
|
+
sensitive credential separation and runtime configuration management.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import logging
|
|
10
|
+
import os
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import Any, Dict, Optional, Type, Union
|
|
13
|
+
import yaml
|
|
14
|
+
from threading import Lock
|
|
15
|
+
from dotenv import load_dotenv
|
|
16
|
+
from pydantic import BaseModel, ValidationError
|
|
17
|
+
|
|
18
|
+
logger = logging.getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ToolConfigLoader:
|
|
22
|
+
"""
|
|
23
|
+
Singleton configuration loader for tools.
|
|
24
|
+
|
|
25
|
+
Supports:
|
|
26
|
+
- Loading sensitive configuration from .env files (via dotenv)
|
|
27
|
+
- Loading runtime configuration from YAML files
|
|
28
|
+
- Configuration merging with precedence order
|
|
29
|
+
- Schema validation against tool's Pydantic Config class
|
|
30
|
+
- Config directory discovery (walking up directory tree)
|
|
31
|
+
- Thread-safe access
|
|
32
|
+
- Caching for performance
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
_instance: Optional["ToolConfigLoader"] = None
|
|
36
|
+
_lock = Lock()
|
|
37
|
+
_config_lock = Lock()
|
|
38
|
+
_initialized: bool = False
|
|
39
|
+
|
|
40
|
+
def __new__(cls):
|
|
41
|
+
"""Ensure singleton instance"""
|
|
42
|
+
if cls._instance is None:
|
|
43
|
+
with cls._lock:
|
|
44
|
+
if cls._instance is None:
|
|
45
|
+
cls._instance = super().__new__(cls)
|
|
46
|
+
cls._instance._initialized = False
|
|
47
|
+
return cls._instance
|
|
48
|
+
|
|
49
|
+
def __init__(self) -> None:
|
|
50
|
+
"""Initialize the configuration loader"""
|
|
51
|
+
if self._initialized:
|
|
52
|
+
return
|
|
53
|
+
|
|
54
|
+
self._config_path: Optional[Path] = None
|
|
55
|
+
self._cached_config_dir: Optional[Path] = None
|
|
56
|
+
self._initialized = True
|
|
57
|
+
logger.info("ToolConfigLoader initialized")
|
|
58
|
+
|
|
59
|
+
def find_config_directory(self) -> Optional[Path]:
|
|
60
|
+
"""
|
|
61
|
+
Discover config/ directory in project.
|
|
62
|
+
|
|
63
|
+
Search order:
|
|
64
|
+
1. Custom config path set via set_config_path()
|
|
65
|
+
2. Settings tool_config_path (if available)
|
|
66
|
+
3. Environment variable TOOL_CONFIG_PATH
|
|
67
|
+
4. Walk up directory tree from current working directory
|
|
68
|
+
5. Check aiecs/config/ directory
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
Path to config directory if found, None otherwise
|
|
72
|
+
"""
|
|
73
|
+
# Check if custom path was set
|
|
74
|
+
if self._config_path:
|
|
75
|
+
if self._config_path.is_dir():
|
|
76
|
+
return self._config_path
|
|
77
|
+
elif self._config_path.is_file():
|
|
78
|
+
return self._config_path.parent
|
|
79
|
+
|
|
80
|
+
# Check if config directory was already cached
|
|
81
|
+
if self._cached_config_dir and self._cached_config_dir.exists():
|
|
82
|
+
return self._cached_config_dir
|
|
83
|
+
|
|
84
|
+
# Check settings (if available)
|
|
85
|
+
try:
|
|
86
|
+
from aiecs.config.config import get_settings
|
|
87
|
+
|
|
88
|
+
settings = get_settings()
|
|
89
|
+
if hasattr(settings, "tool_config_path") and settings.tool_config_path:
|
|
90
|
+
path = Path(settings.tool_config_path)
|
|
91
|
+
if path.exists():
|
|
92
|
+
logger.info(f"Using tool config path from settings: {path}")
|
|
93
|
+
self._cached_config_dir = path if path.is_dir() else path.parent
|
|
94
|
+
return self._cached_config_dir
|
|
95
|
+
except Exception as e:
|
|
96
|
+
logger.debug(f"Could not load settings: {e}")
|
|
97
|
+
|
|
98
|
+
# Check environment variable
|
|
99
|
+
env_path = os.environ.get("TOOL_CONFIG_PATH")
|
|
100
|
+
if env_path:
|
|
101
|
+
path = Path(env_path)
|
|
102
|
+
if path.exists():
|
|
103
|
+
logger.info(f"Using tool config path from environment: {path}")
|
|
104
|
+
self._cached_config_dir = path if path.is_dir() else path.parent
|
|
105
|
+
return self._cached_config_dir
|
|
106
|
+
|
|
107
|
+
# Walk up directory tree from current working directory
|
|
108
|
+
current_dir = Path.cwd()
|
|
109
|
+
while current_dir != current_dir.parent: # Stop at root
|
|
110
|
+
config_dir = current_dir / "config"
|
|
111
|
+
if config_dir.exists() and config_dir.is_dir():
|
|
112
|
+
logger.info(f"Found config directory: {config_dir}")
|
|
113
|
+
self._cached_config_dir = config_dir
|
|
114
|
+
return config_dir
|
|
115
|
+
current_dir = current_dir.parent
|
|
116
|
+
|
|
117
|
+
# Check aiecs/config/ directory as fallback
|
|
118
|
+
aiecs_config_dir = Path(__file__).parent.parent / "config"
|
|
119
|
+
if aiecs_config_dir.exists() and aiecs_config_dir.is_dir():
|
|
120
|
+
logger.info(f"Using aiecs config directory: {aiecs_config_dir}")
|
|
121
|
+
self._cached_config_dir = aiecs_config_dir
|
|
122
|
+
return aiecs_config_dir
|
|
123
|
+
|
|
124
|
+
logger.debug("No config directory found")
|
|
125
|
+
return None
|
|
126
|
+
|
|
127
|
+
def load_env_config(self) -> Dict[str, Any]:
|
|
128
|
+
"""
|
|
129
|
+
Load sensitive configuration from .env files via dotenv.
|
|
130
|
+
|
|
131
|
+
Supports multiple .env files in order:
|
|
132
|
+
1. .env (base)
|
|
133
|
+
2. .env.local (local overrides)
|
|
134
|
+
3. .env.production (production overrides, if NODE_ENV=production)
|
|
135
|
+
|
|
136
|
+
Returns:
|
|
137
|
+
Dictionary of environment variables loaded from .env files
|
|
138
|
+
"""
|
|
139
|
+
config_dir = self.find_config_directory()
|
|
140
|
+
env_vars = {}
|
|
141
|
+
|
|
142
|
+
# Determine base directory for .env files
|
|
143
|
+
if config_dir:
|
|
144
|
+
base_dir = config_dir.parent if (config_dir / "tools").exists() else config_dir
|
|
145
|
+
else:
|
|
146
|
+
base_dir = Path.cwd()
|
|
147
|
+
|
|
148
|
+
# Load .env files in order (later files override earlier ones)
|
|
149
|
+
env_files = [".env"]
|
|
150
|
+
if os.environ.get("NODE_ENV") == "production":
|
|
151
|
+
env_files.append(".env.production")
|
|
152
|
+
else:
|
|
153
|
+
env_files.append(".env.local")
|
|
154
|
+
|
|
155
|
+
for env_file in env_files:
|
|
156
|
+
env_path = base_dir / env_file
|
|
157
|
+
if env_path.exists():
|
|
158
|
+
try:
|
|
159
|
+
load_dotenv(env_path, override=False) # Don't override already loaded vars
|
|
160
|
+
logger.debug(f"Loaded environment variables from {env_path}")
|
|
161
|
+
except Exception as e:
|
|
162
|
+
logger.warning(f"Failed to load {env_path}: {e}")
|
|
163
|
+
|
|
164
|
+
# Return all environment variables (dotenv loads them into os.environ)
|
|
165
|
+
# We return empty dict here since dotenv modifies os.environ directly
|
|
166
|
+
# The actual env vars will be picked up by BaseSettings or os.getenv()
|
|
167
|
+
return {}
|
|
168
|
+
|
|
169
|
+
def load_yaml_config(self, tool_name: str) -> Dict[str, Any]:
|
|
170
|
+
"""
|
|
171
|
+
Load runtime configuration from YAML files.
|
|
172
|
+
|
|
173
|
+
Loads from:
|
|
174
|
+
1. Tool-specific: config/tools/{tool_name}.yaml
|
|
175
|
+
2. Global: config/tools.yaml
|
|
176
|
+
|
|
177
|
+
Tool-specific config takes precedence over global config.
|
|
178
|
+
|
|
179
|
+
Args:
|
|
180
|
+
tool_name: Name of the tool (e.g., "DocumentParserTool")
|
|
181
|
+
|
|
182
|
+
Returns:
|
|
183
|
+
Dictionary of configuration values from YAML files
|
|
184
|
+
"""
|
|
185
|
+
config_dir = self.find_config_directory()
|
|
186
|
+
if not config_dir:
|
|
187
|
+
logger.debug("No config directory found, skipping YAML config loading")
|
|
188
|
+
return {}
|
|
189
|
+
|
|
190
|
+
merged_config = {}
|
|
191
|
+
|
|
192
|
+
# Load global config first (lower precedence)
|
|
193
|
+
global_config_path = config_dir / "tools.yaml"
|
|
194
|
+
if global_config_path.exists():
|
|
195
|
+
try:
|
|
196
|
+
with open(global_config_path, "r", encoding="utf-8") as f:
|
|
197
|
+
global_data = yaml.safe_load(f)
|
|
198
|
+
if global_data:
|
|
199
|
+
# Support tool-specific sections in global config
|
|
200
|
+
if isinstance(global_data, dict):
|
|
201
|
+
# If there's a tools section, look for tool-specific config
|
|
202
|
+
if "tools" in global_data and isinstance(global_data["tools"], dict):
|
|
203
|
+
# Global defaults
|
|
204
|
+
merged_config.update(global_data.get("defaults", {}))
|
|
205
|
+
else:
|
|
206
|
+
# Flat global config
|
|
207
|
+
merged_config.update(global_data)
|
|
208
|
+
logger.debug(f"Loaded global config from {global_config_path}")
|
|
209
|
+
except yaml.YAMLError as e:
|
|
210
|
+
logger.warning(f"Invalid YAML in {global_config_path}: {e}. Skipping.")
|
|
211
|
+
except Exception as e:
|
|
212
|
+
logger.warning(f"Failed to load {global_config_path}: {e}. Skipping.")
|
|
213
|
+
|
|
214
|
+
# Load tool-specific config (higher precedence)
|
|
215
|
+
# Try multiple locations:
|
|
216
|
+
# 1. config/tools/{tool_name}.yaml (standard location)
|
|
217
|
+
# 2. config/{tool_name}.yaml (direct in config_dir, for custom paths)
|
|
218
|
+
tools_dir = config_dir / "tools"
|
|
219
|
+
search_dirs = []
|
|
220
|
+
if tools_dir.exists() and tools_dir.is_dir():
|
|
221
|
+
search_dirs.append(tools_dir)
|
|
222
|
+
# Also search directly in config_dir for custom path structures
|
|
223
|
+
search_dirs.append(config_dir)
|
|
224
|
+
|
|
225
|
+
# Try multiple naming conventions for tool config files
|
|
226
|
+
# 1. {tool_name}.yaml (e.g., image.yaml)
|
|
227
|
+
# 2. {tool_name}_tool.yaml (e.g., image_tool.yaml)
|
|
228
|
+
# 3. {ToolName}.yaml (e.g., ImageTool.yaml)
|
|
229
|
+
possible_names = [
|
|
230
|
+
f"{tool_name}.yaml",
|
|
231
|
+
f"{tool_name}_tool.yaml",
|
|
232
|
+
]
|
|
233
|
+
# Also try with capitalized class name if tool_name is lowercase
|
|
234
|
+
if tool_name.islower():
|
|
235
|
+
class_name = tool_name.replace("_", "").title() + "Tool"
|
|
236
|
+
possible_names.append(f"{class_name}.yaml")
|
|
237
|
+
|
|
238
|
+
tool_config_path = None
|
|
239
|
+
for search_dir in search_dirs:
|
|
240
|
+
for name in possible_names:
|
|
241
|
+
candidate_path = search_dir / name
|
|
242
|
+
if candidate_path.exists():
|
|
243
|
+
tool_config_path = candidate_path
|
|
244
|
+
break
|
|
245
|
+
if tool_config_path:
|
|
246
|
+
break
|
|
247
|
+
|
|
248
|
+
if tool_config_path:
|
|
249
|
+
try:
|
|
250
|
+
with open(tool_config_path, "r", encoding="utf-8") as f:
|
|
251
|
+
tool_data = yaml.safe_load(f)
|
|
252
|
+
if tool_data:
|
|
253
|
+
# Merge tool-specific config (overrides global)
|
|
254
|
+
merged_config.update(tool_data)
|
|
255
|
+
logger.debug(f"Loaded tool-specific config from {tool_config_path}")
|
|
256
|
+
except yaml.YAMLError as e:
|
|
257
|
+
logger.warning(f"Invalid YAML in {tool_config_path}: {e}. Skipping.")
|
|
258
|
+
except Exception as e:
|
|
259
|
+
logger.warning(f"Failed to load {tool_config_path}: {e}. Skipping.")
|
|
260
|
+
|
|
261
|
+
return merged_config
|
|
262
|
+
|
|
263
|
+
def merge_config(
|
|
264
|
+
self,
|
|
265
|
+
explicit_config: Optional[Dict[str, Any]] = None,
|
|
266
|
+
yaml_config: Optional[Dict[str, Any]] = None,
|
|
267
|
+
env_config: Optional[Dict[str, Any]] = None,
|
|
268
|
+
defaults: Optional[Dict[str, Any]] = None,
|
|
269
|
+
) -> Dict[str, Any]:
|
|
270
|
+
"""
|
|
271
|
+
Merge configurations according to precedence order.
|
|
272
|
+
|
|
273
|
+
Precedence (highest to lowest):
|
|
274
|
+
1. Explicit config dict
|
|
275
|
+
2. YAML config
|
|
276
|
+
3. Environment variables
|
|
277
|
+
4. Defaults
|
|
278
|
+
|
|
279
|
+
Args:
|
|
280
|
+
explicit_config: Explicit configuration dict (highest priority)
|
|
281
|
+
yaml_config: Configuration from YAML files
|
|
282
|
+
env_config: Configuration from environment variables
|
|
283
|
+
defaults: Default configuration values (lowest priority)
|
|
284
|
+
|
|
285
|
+
Returns:
|
|
286
|
+
Merged configuration dictionary
|
|
287
|
+
"""
|
|
288
|
+
merged = {}
|
|
289
|
+
|
|
290
|
+
# Start with defaults (lowest priority)
|
|
291
|
+
if defaults:
|
|
292
|
+
merged.update(defaults)
|
|
293
|
+
|
|
294
|
+
# Add environment variables (dotenv loads them into os.environ)
|
|
295
|
+
# Note: We don't merge env_config here since dotenv modifies os.environ
|
|
296
|
+
# Environment variables will be picked up by BaseSettings automatically
|
|
297
|
+
|
|
298
|
+
# Add YAML config
|
|
299
|
+
if yaml_config:
|
|
300
|
+
merged.update(yaml_config)
|
|
301
|
+
|
|
302
|
+
# Add explicit config (highest priority)
|
|
303
|
+
if explicit_config:
|
|
304
|
+
merged.update(explicit_config)
|
|
305
|
+
|
|
306
|
+
return merged
|
|
307
|
+
|
|
308
|
+
def validate_config(self, config_dict: Dict[str, Any], config_schema: Type[BaseModel]) -> Dict[str, Any]:
|
|
309
|
+
"""
|
|
310
|
+
Validate merged config against tool's Pydantic schema.
|
|
311
|
+
|
|
312
|
+
Args:
|
|
313
|
+
config_dict: Configuration dictionary to validate
|
|
314
|
+
config_schema: Pydantic model class for validation
|
|
315
|
+
|
|
316
|
+
Returns:
|
|
317
|
+
Validated configuration dictionary
|
|
318
|
+
|
|
319
|
+
Raises:
|
|
320
|
+
ValidationError: If configuration is invalid
|
|
321
|
+
"""
|
|
322
|
+
try:
|
|
323
|
+
# Create instance of config schema to validate
|
|
324
|
+
config_instance = config_schema(**config_dict)
|
|
325
|
+
# Convert back to dict (handles aliases, validators, etc.)
|
|
326
|
+
return config_instance.model_dump()
|
|
327
|
+
except ValidationError as e:
|
|
328
|
+
error_messages = []
|
|
329
|
+
for error in e.errors():
|
|
330
|
+
field = " -> ".join(str(loc) for loc in error["loc"])
|
|
331
|
+
error_messages.append(f"{field}: {error['msg']}")
|
|
332
|
+
raise ValidationError(
|
|
333
|
+
f"Tool configuration validation failed:\n" + "\n".join(error_messages),
|
|
334
|
+
e.model,
|
|
335
|
+
) from e
|
|
336
|
+
|
|
337
|
+
def load_tool_config(
|
|
338
|
+
self,
|
|
339
|
+
tool_name: str,
|
|
340
|
+
config_schema: Optional[Type[BaseModel]] = None,
|
|
341
|
+
explicit_config: Optional[Dict[str, Any]] = None,
|
|
342
|
+
) -> Dict[str, Any]:
|
|
343
|
+
"""
|
|
344
|
+
Main entry point for loading tool configuration.
|
|
345
|
+
|
|
346
|
+
Loads, merges, and validates configuration from all sources:
|
|
347
|
+
1. Explicit config dict (highest priority)
|
|
348
|
+
2. YAML config files (tool-specific and global)
|
|
349
|
+
3. Environment variables (via dotenv)
|
|
350
|
+
4. Tool defaults (lowest priority)
|
|
351
|
+
|
|
352
|
+
Args:
|
|
353
|
+
tool_name: Name of the tool (e.g., "DocumentParserTool")
|
|
354
|
+
config_schema: Optional Pydantic model class for validation
|
|
355
|
+
explicit_config: Optional explicit configuration dict (overrides everything)
|
|
356
|
+
|
|
357
|
+
Returns:
|
|
358
|
+
Merged and validated configuration dictionary
|
|
359
|
+
|
|
360
|
+
Raises:
|
|
361
|
+
ValidationError: If config_schema is provided and validation fails
|
|
362
|
+
"""
|
|
363
|
+
with self._config_lock:
|
|
364
|
+
# Load environment variables from .env files
|
|
365
|
+
self.load_env_config()
|
|
366
|
+
|
|
367
|
+
# Load YAML configuration
|
|
368
|
+
yaml_config = self.load_yaml_config(tool_name)
|
|
369
|
+
|
|
370
|
+
# Get defaults from config schema if available
|
|
371
|
+
defaults = {}
|
|
372
|
+
if config_schema:
|
|
373
|
+
try:
|
|
374
|
+
# Create instance with no args to get defaults
|
|
375
|
+
default_instance = config_schema()
|
|
376
|
+
defaults = default_instance.model_dump(exclude_unset=True)
|
|
377
|
+
except Exception:
|
|
378
|
+
# Schema might require some fields, that's okay
|
|
379
|
+
pass
|
|
380
|
+
|
|
381
|
+
# Merge configurations according to precedence
|
|
382
|
+
merged_config = self.merge_config(
|
|
383
|
+
explicit_config=explicit_config,
|
|
384
|
+
yaml_config=yaml_config,
|
|
385
|
+
defaults=defaults,
|
|
386
|
+
)
|
|
387
|
+
|
|
388
|
+
# Validate against schema if provided
|
|
389
|
+
if config_schema:
|
|
390
|
+
merged_config = self.validate_config(merged_config, config_schema)
|
|
391
|
+
|
|
392
|
+
logger.debug(f"Loaded config for {tool_name}: {len(merged_config)} keys")
|
|
393
|
+
return merged_config
|
|
394
|
+
|
|
395
|
+
def set_config_path(self, path: Optional[Union[str, Path]] = None) -> None:
|
|
396
|
+
"""
|
|
397
|
+
Set custom config path.
|
|
398
|
+
|
|
399
|
+
Args:
|
|
400
|
+
path: Path to config directory or file. If None, resets to auto-discovery.
|
|
401
|
+
"""
|
|
402
|
+
if path is None:
|
|
403
|
+
self._config_path = None
|
|
404
|
+
# Clear cached config directory to force re-discovery
|
|
405
|
+
self._cached_config_dir = None
|
|
406
|
+
logger.info("Reset config path to auto-discovery")
|
|
407
|
+
else:
|
|
408
|
+
self._config_path = Path(path)
|
|
409
|
+
# Clear cached config directory to force re-discovery
|
|
410
|
+
self._cached_config_dir = None
|
|
411
|
+
logger.info(f"Set custom config path: {self._config_path}")
|
|
412
|
+
|
|
413
|
+
def get_config_path(self) -> Optional[Path]:
|
|
414
|
+
"""
|
|
415
|
+
Get current config path.
|
|
416
|
+
|
|
417
|
+
Returns:
|
|
418
|
+
Path to config directory if set, None otherwise
|
|
419
|
+
"""
|
|
420
|
+
return self._config_path or self._cached_config_dir
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
# Global singleton instance
|
|
424
|
+
_loader = ToolConfigLoader()
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
def get_tool_config_loader() -> ToolConfigLoader:
|
|
428
|
+
"""
|
|
429
|
+
Get the global tool configuration loader instance.
|
|
430
|
+
|
|
431
|
+
Returns:
|
|
432
|
+
ToolConfigLoader: Global singleton instance
|
|
433
|
+
"""
|
|
434
|
+
return _loader
|
|
435
|
+
|
aiecs/core/__init__.py
CHANGED
|
@@ -4,6 +4,7 @@ Core module for the Python middleware application.
|
|
|
4
4
|
This module provides the core interfaces and abstractions including:
|
|
5
5
|
- Execution interfaces
|
|
6
6
|
- Core abstractions
|
|
7
|
+
- Service registry (no dependencies, safe to import anywhere)
|
|
7
8
|
"""
|
|
8
9
|
|
|
9
10
|
# Core interfaces
|
|
@@ -12,7 +13,7 @@ from .interface.execution_interface import (
|
|
|
12
13
|
IToolProvider,
|
|
13
14
|
IToolExecutor,
|
|
14
15
|
ICacheProvider,
|
|
15
|
-
IOperationExecutor
|
|
16
|
+
IOperationExecutor,
|
|
16
17
|
)
|
|
17
18
|
|
|
18
19
|
from .interface.storage_interface import (
|
|
@@ -21,23 +22,38 @@ from .interface.storage_interface import (
|
|
|
21
22
|
ICheckpointStorage,
|
|
22
23
|
ITaskContextStorage,
|
|
23
24
|
IStorageBackend,
|
|
24
|
-
ICheckpointerBackend
|
|
25
|
+
ICheckpointerBackend,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
# Service registry (zero dependencies, safe for module-level imports)
|
|
29
|
+
from .registry import (
|
|
30
|
+
AI_SERVICE_REGISTRY,
|
|
31
|
+
register_ai_service,
|
|
32
|
+
get_ai_service,
|
|
33
|
+
list_registered_services,
|
|
34
|
+
clear_registry,
|
|
25
35
|
)
|
|
26
36
|
|
|
27
37
|
__all__ = [
|
|
28
38
|
# Execution interfaces
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
39
|
+
"ExecutionInterface",
|
|
40
|
+
"IToolProvider",
|
|
41
|
+
"IToolExecutor",
|
|
42
|
+
"ICacheProvider",
|
|
43
|
+
"IOperationExecutor",
|
|
34
44
|
# Storage interfaces
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
45
|
+
"ISessionStorage",
|
|
46
|
+
"IConversationStorage",
|
|
47
|
+
"ICheckpointStorage",
|
|
48
|
+
"ITaskContextStorage",
|
|
49
|
+
"IStorageBackend",
|
|
50
|
+
"ICheckpointerBackend",
|
|
51
|
+
# Service registry
|
|
52
|
+
"AI_SERVICE_REGISTRY",
|
|
53
|
+
"register_ai_service",
|
|
54
|
+
"get_ai_service",
|
|
55
|
+
"list_registered_services",
|
|
56
|
+
"clear_registry",
|
|
41
57
|
]
|
|
42
58
|
|
|
43
59
|
# Version information
|
aiecs/core/interface/__init__.py
CHANGED
|
@@ -5,7 +5,7 @@ from .execution_interface import (
|
|
|
5
5
|
IToolProvider,
|
|
6
6
|
IToolExecutor,
|
|
7
7
|
ICacheProvider,
|
|
8
|
-
IOperationExecutor
|
|
8
|
+
IOperationExecutor,
|
|
9
9
|
)
|
|
10
10
|
|
|
11
11
|
from .storage_interface import (
|
|
@@ -14,7 +14,7 @@ from .storage_interface import (
|
|
|
14
14
|
ICheckpointStorage,
|
|
15
15
|
ITaskContextStorage,
|
|
16
16
|
IStorageBackend,
|
|
17
|
-
ICheckpointerBackend
|
|
17
|
+
ICheckpointerBackend,
|
|
18
18
|
)
|
|
19
19
|
|
|
20
20
|
__all__ = [
|