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,461 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Community Resource Manager
|
|
3
|
+
|
|
4
|
+
Manages shared resources, knowledge bases, and collaborative tools
|
|
5
|
+
within agent communities.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
from datetime import datetime
|
|
10
|
+
from typing import Dict, List, Any, Optional, Set, TYPE_CHECKING
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from .community_manager import CommunityManager
|
|
14
|
+
from aiecs.domain.context.context_engine import ContextEngine
|
|
15
|
+
import json
|
|
16
|
+
|
|
17
|
+
from .models.community_models import (
|
|
18
|
+
CommunityResource,
|
|
19
|
+
CommunityMember,
|
|
20
|
+
ResourceType,
|
|
21
|
+
)
|
|
22
|
+
from .exceptions import CommunityValidationError as TaskValidationError
|
|
23
|
+
|
|
24
|
+
logger = logging.getLogger(__name__)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ResourceManager:
|
|
28
|
+
"""
|
|
29
|
+
Manager for community resources, knowledge sharing, and collaborative tools.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(
|
|
33
|
+
self,
|
|
34
|
+
community_manager: Optional["CommunityManager"] = None,
|
|
35
|
+
context_engine: Optional["ContextEngine"] = None,
|
|
36
|
+
) -> None:
|
|
37
|
+
"""
|
|
38
|
+
Initialize the resource manager.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
community_manager: Reference to the community manager
|
|
42
|
+
context_engine: Optional context engine for persistent storage
|
|
43
|
+
"""
|
|
44
|
+
self.community_manager = community_manager
|
|
45
|
+
self.context_engine = context_engine
|
|
46
|
+
|
|
47
|
+
# Resource indexing and search
|
|
48
|
+
# tag -> set of resource_ids
|
|
49
|
+
self.resource_index: Dict[str, Set[str]] = {}
|
|
50
|
+
# type -> set of resource_ids
|
|
51
|
+
self.type_index: Dict[ResourceType, Set[str]] = {}
|
|
52
|
+
# owner_id -> set of resource_ids
|
|
53
|
+
self.owner_index: Dict[str, Set[str]] = {}
|
|
54
|
+
|
|
55
|
+
# Knowledge graph for resource relationships
|
|
56
|
+
self.resource_relationships: Dict[str, Dict[str, List[str]]] = {}
|
|
57
|
+
|
|
58
|
+
# Usage analytics
|
|
59
|
+
self.usage_analytics: Dict[str, Dict[str, Any]] = {}
|
|
60
|
+
|
|
61
|
+
logger.info("Resource manager initialized")
|
|
62
|
+
|
|
63
|
+
async def create_knowledge_resource(
|
|
64
|
+
self,
|
|
65
|
+
community_id: str,
|
|
66
|
+
owner_member_id: str,
|
|
67
|
+
title: str,
|
|
68
|
+
content: str,
|
|
69
|
+
knowledge_type: str = "general",
|
|
70
|
+
tags: Optional[List[str]] = None,
|
|
71
|
+
related_resources: Optional[List[str]] = None,
|
|
72
|
+
) -> str:
|
|
73
|
+
"""
|
|
74
|
+
Create a knowledge resource for the community.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
community_id: ID of the community
|
|
78
|
+
owner_member_id: ID of the member creating the resource
|
|
79
|
+
title: Title of the knowledge resource
|
|
80
|
+
content: Knowledge content
|
|
81
|
+
knowledge_type: Type of knowledge (general, expertise, experience, etc.)
|
|
82
|
+
tags: Tags for categorization
|
|
83
|
+
related_resources: IDs of related resources
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
Resource ID
|
|
87
|
+
"""
|
|
88
|
+
resource_content: Dict[str, Any] = {
|
|
89
|
+
"title": title,
|
|
90
|
+
"content": content,
|
|
91
|
+
"knowledge_type": knowledge_type,
|
|
92
|
+
"created_at": datetime.utcnow().isoformat(),
|
|
93
|
+
"version": "1.0",
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if related_resources:
|
|
97
|
+
resource_content["related_resources"] = related_resources
|
|
98
|
+
|
|
99
|
+
if self.community_manager is None:
|
|
100
|
+
raise ValueError("CommunityManager not initialized")
|
|
101
|
+
resource_id = await self.community_manager.create_community_resource(
|
|
102
|
+
community_id=community_id,
|
|
103
|
+
owner_member_id=owner_member_id,
|
|
104
|
+
name=title,
|
|
105
|
+
resource_type=ResourceType.KNOWLEDGE,
|
|
106
|
+
content=resource_content,
|
|
107
|
+
description=f"Knowledge resource: {knowledge_type}",
|
|
108
|
+
tags=tags or [],
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
# Update indexes
|
|
112
|
+
await self._update_resource_indexes(resource_id, tags or [], ResourceType.KNOWLEDGE, owner_member_id)
|
|
113
|
+
|
|
114
|
+
# Create relationships
|
|
115
|
+
if related_resources:
|
|
116
|
+
await self._create_resource_relationships(resource_id, related_resources)
|
|
117
|
+
|
|
118
|
+
logger.info(f"Created knowledge resource: {title} ({resource_id})")
|
|
119
|
+
return resource_id
|
|
120
|
+
|
|
121
|
+
async def create_tool_resource(
|
|
122
|
+
self,
|
|
123
|
+
community_id: str,
|
|
124
|
+
owner_member_id: str,
|
|
125
|
+
tool_name: str,
|
|
126
|
+
tool_config: Dict[str, Any],
|
|
127
|
+
description: str,
|
|
128
|
+
usage_instructions: str,
|
|
129
|
+
tags: Optional[List[str]] = None,
|
|
130
|
+
) -> str:
|
|
131
|
+
"""
|
|
132
|
+
Create a tool resource for community sharing.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
community_id: ID of the community
|
|
136
|
+
owner_member_id: ID of the member creating the resource
|
|
137
|
+
tool_name: Name of the tool
|
|
138
|
+
tool_config: Tool configuration
|
|
139
|
+
description: Tool description
|
|
140
|
+
usage_instructions: Instructions for using the tool
|
|
141
|
+
tags: Tags for categorization
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
Resource ID
|
|
145
|
+
"""
|
|
146
|
+
resource_content = {
|
|
147
|
+
"tool_name": tool_name,
|
|
148
|
+
"tool_config": tool_config,
|
|
149
|
+
"description": description,
|
|
150
|
+
"usage_instructions": usage_instructions,
|
|
151
|
+
"created_at": datetime.utcnow().isoformat(),
|
|
152
|
+
"version": "1.0",
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if self.community_manager is None:
|
|
156
|
+
raise ValueError("CommunityManager not initialized")
|
|
157
|
+
resource_id = await self.community_manager.create_community_resource(
|
|
158
|
+
community_id=community_id,
|
|
159
|
+
owner_member_id=owner_member_id,
|
|
160
|
+
name=tool_name,
|
|
161
|
+
resource_type=ResourceType.TOOL,
|
|
162
|
+
content=resource_content,
|
|
163
|
+
description=description,
|
|
164
|
+
tags=tags or [],
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
# Update indexes
|
|
168
|
+
await self._update_resource_indexes(resource_id, tags or [], ResourceType.TOOL, owner_member_id)
|
|
169
|
+
|
|
170
|
+
logger.info(f"Created tool resource: {tool_name} ({resource_id})")
|
|
171
|
+
return resource_id
|
|
172
|
+
|
|
173
|
+
async def create_experience_resource(
|
|
174
|
+
self,
|
|
175
|
+
community_id: str,
|
|
176
|
+
owner_member_id: str,
|
|
177
|
+
experience_title: str,
|
|
178
|
+
situation: str,
|
|
179
|
+
actions_taken: List[str],
|
|
180
|
+
outcomes: Dict[str, Any],
|
|
181
|
+
lessons_learned: List[str],
|
|
182
|
+
tags: Optional[List[str]] = None,
|
|
183
|
+
) -> str:
|
|
184
|
+
"""
|
|
185
|
+
Create an experience resource for knowledge sharing.
|
|
186
|
+
|
|
187
|
+
Args:
|
|
188
|
+
community_id: ID of the community
|
|
189
|
+
owner_member_id: ID of the member sharing the experience
|
|
190
|
+
experience_title: Title of the experience
|
|
191
|
+
situation: Description of the situation
|
|
192
|
+
actions_taken: List of actions taken
|
|
193
|
+
outcomes: Outcomes and results
|
|
194
|
+
lessons_learned: Key lessons learned
|
|
195
|
+
tags: Tags for categorization
|
|
196
|
+
|
|
197
|
+
Returns:
|
|
198
|
+
Resource ID
|
|
199
|
+
"""
|
|
200
|
+
resource_content = {
|
|
201
|
+
"experience_title": experience_title,
|
|
202
|
+
"situation": situation,
|
|
203
|
+
"actions_taken": actions_taken,
|
|
204
|
+
"outcomes": outcomes,
|
|
205
|
+
"lessons_learned": lessons_learned,
|
|
206
|
+
"created_at": datetime.utcnow().isoformat(),
|
|
207
|
+
"experience_type": "case_study",
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if self.community_manager is None:
|
|
211
|
+
raise ValueError("CommunityManager not initialized")
|
|
212
|
+
resource_id = await self.community_manager.create_community_resource(
|
|
213
|
+
community_id=community_id,
|
|
214
|
+
owner_member_id=owner_member_id,
|
|
215
|
+
name=experience_title,
|
|
216
|
+
resource_type=ResourceType.EXPERIENCE,
|
|
217
|
+
content=resource_content,
|
|
218
|
+
description=f"Experience sharing: {situation[:100]}...",
|
|
219
|
+
tags=tags or [],
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
# Update indexes
|
|
223
|
+
await self._update_resource_indexes(resource_id, tags or [], ResourceType.EXPERIENCE, owner_member_id)
|
|
224
|
+
|
|
225
|
+
logger.info(f"Created experience resource: {experience_title} ({resource_id})")
|
|
226
|
+
return resource_id
|
|
227
|
+
|
|
228
|
+
async def search_resources(
|
|
229
|
+
self,
|
|
230
|
+
community_id: str,
|
|
231
|
+
query: Optional[str] = None,
|
|
232
|
+
resource_type: Optional[ResourceType] = None,
|
|
233
|
+
tags: Optional[List[str]] = None,
|
|
234
|
+
owner_id: Optional[str] = None,
|
|
235
|
+
limit: int = 10,
|
|
236
|
+
) -> List[Dict[str, Any]]:
|
|
237
|
+
"""
|
|
238
|
+
Search for community resources.
|
|
239
|
+
|
|
240
|
+
Args:
|
|
241
|
+
community_id: ID of the community
|
|
242
|
+
query: Text query for searching
|
|
243
|
+
resource_type: Filter by resource type
|
|
244
|
+
tags: Filter by tags
|
|
245
|
+
owner_id: Filter by owner
|
|
246
|
+
limit: Maximum number of results
|
|
247
|
+
|
|
248
|
+
Returns:
|
|
249
|
+
List of matching resources
|
|
250
|
+
"""
|
|
251
|
+
if not self.community_manager:
|
|
252
|
+
raise TaskValidationError("Community manager not available")
|
|
253
|
+
|
|
254
|
+
community = self.community_manager.communities.get(community_id)
|
|
255
|
+
if not community:
|
|
256
|
+
raise TaskValidationError(f"Community not found: {community_id}")
|
|
257
|
+
|
|
258
|
+
# Get candidate resource IDs
|
|
259
|
+
candidate_ids = set(community.shared_resources)
|
|
260
|
+
|
|
261
|
+
# Apply filters
|
|
262
|
+
if resource_type and resource_type in self.type_index:
|
|
263
|
+
candidate_ids &= self.type_index[resource_type]
|
|
264
|
+
|
|
265
|
+
if tags:
|
|
266
|
+
for tag in tags:
|
|
267
|
+
if tag in self.resource_index:
|
|
268
|
+
candidate_ids &= self.resource_index[tag]
|
|
269
|
+
|
|
270
|
+
if owner_id and owner_id in self.owner_index:
|
|
271
|
+
candidate_ids &= self.owner_index[owner_id]
|
|
272
|
+
|
|
273
|
+
# Get resource details and apply text search
|
|
274
|
+
results = []
|
|
275
|
+
for resource_id in candidate_ids:
|
|
276
|
+
resource = self.community_manager.resources.get(resource_id)
|
|
277
|
+
if not resource:
|
|
278
|
+
continue
|
|
279
|
+
|
|
280
|
+
# Text search in resource content
|
|
281
|
+
if query:
|
|
282
|
+
searchable_text = f"{resource.name} {resource.description or ''} {json.dumps(resource.content)}"
|
|
283
|
+
if query.lower() not in searchable_text.lower():
|
|
284
|
+
continue
|
|
285
|
+
|
|
286
|
+
# Add to results
|
|
287
|
+
results.append(
|
|
288
|
+
{
|
|
289
|
+
"resource_id": resource.resource_id,
|
|
290
|
+
"name": resource.name,
|
|
291
|
+
"resource_type": resource.resource_type,
|
|
292
|
+
"description": resource.description,
|
|
293
|
+
"owner_id": resource.owner_id,
|
|
294
|
+
"tags": resource.tags,
|
|
295
|
+
"usage_count": resource.usage_count,
|
|
296
|
+
"rating": resource.rating,
|
|
297
|
+
"created_at": resource.created_at,
|
|
298
|
+
"content_preview": self._get_content_preview(resource.content),
|
|
299
|
+
}
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
if len(results) >= limit:
|
|
303
|
+
break
|
|
304
|
+
|
|
305
|
+
# Sort by relevance (usage count and rating)
|
|
306
|
+
results.sort(key=lambda x: (x["usage_count"], x["rating"]), reverse=True)
|
|
307
|
+
|
|
308
|
+
logger.info(f"Found {len(results)} resources for query: {query}")
|
|
309
|
+
return results
|
|
310
|
+
|
|
311
|
+
async def get_resource_recommendations(
|
|
312
|
+
self,
|
|
313
|
+
community_id: str,
|
|
314
|
+
member_id: str,
|
|
315
|
+
context: Optional[Dict[str, Any]] = None,
|
|
316
|
+
limit: int = 5,
|
|
317
|
+
) -> List[Dict[str, Any]]:
|
|
318
|
+
"""
|
|
319
|
+
Get personalized resource recommendations for a member.
|
|
320
|
+
|
|
321
|
+
Args:
|
|
322
|
+
community_id: ID of the community
|
|
323
|
+
member_id: ID of the member
|
|
324
|
+
context: Optional context for recommendations
|
|
325
|
+
limit: Maximum number of recommendations
|
|
326
|
+
|
|
327
|
+
Returns:
|
|
328
|
+
List of recommended resources
|
|
329
|
+
"""
|
|
330
|
+
if not self.community_manager:
|
|
331
|
+
raise TaskValidationError("Community manager not available")
|
|
332
|
+
|
|
333
|
+
member = self.community_manager.members.get(member_id)
|
|
334
|
+
if not member:
|
|
335
|
+
raise TaskValidationError(f"Member not found: {member_id}")
|
|
336
|
+
|
|
337
|
+
# Get member's specializations and interests
|
|
338
|
+
member_tags = set(member.specializations)
|
|
339
|
+
|
|
340
|
+
# Find resources matching member's interests
|
|
341
|
+
candidate_resources = []
|
|
342
|
+
for tag in member_tags:
|
|
343
|
+
if tag in self.resource_index:
|
|
344
|
+
for resource_id in self.resource_index[tag]:
|
|
345
|
+
resource = self.community_manager.resources.get(resource_id)
|
|
346
|
+
if resource and resource.owner_id != member_id: # Don't recommend own resources
|
|
347
|
+
candidate_resources.append(resource)
|
|
348
|
+
|
|
349
|
+
# Score and rank resources
|
|
350
|
+
scored_resources = []
|
|
351
|
+
for resource in candidate_resources:
|
|
352
|
+
score = self._calculate_recommendation_score(resource, member, context)
|
|
353
|
+
scored_resources.append((score, resource))
|
|
354
|
+
|
|
355
|
+
# Sort by score and return top recommendations
|
|
356
|
+
scored_resources.sort(key=lambda x: x[0], reverse=True)
|
|
357
|
+
|
|
358
|
+
recommendations = []
|
|
359
|
+
for score, resource in scored_resources[:limit]:
|
|
360
|
+
recommendations.append(
|
|
361
|
+
{
|
|
362
|
+
"resource_id": resource.resource_id,
|
|
363
|
+
"name": resource.name,
|
|
364
|
+
"resource_type": resource.resource_type,
|
|
365
|
+
"description": resource.description,
|
|
366
|
+
"recommendation_score": score,
|
|
367
|
+
"tags": resource.tags,
|
|
368
|
+
"usage_count": resource.usage_count,
|
|
369
|
+
"rating": resource.rating,
|
|
370
|
+
}
|
|
371
|
+
)
|
|
372
|
+
|
|
373
|
+
logger.info(f"Generated {len(recommendations)} recommendations for member {member_id}")
|
|
374
|
+
return recommendations
|
|
375
|
+
|
|
376
|
+
def _calculate_recommendation_score(
|
|
377
|
+
self,
|
|
378
|
+
resource: CommunityResource,
|
|
379
|
+
member: CommunityMember,
|
|
380
|
+
context: Optional[Dict[str, Any]] = None,
|
|
381
|
+
) -> float:
|
|
382
|
+
"""Calculate recommendation score for a resource."""
|
|
383
|
+
score = 0.0
|
|
384
|
+
|
|
385
|
+
# Tag matching score
|
|
386
|
+
member_tags = set(member.specializations)
|
|
387
|
+
resource_tags = set(resource.tags)
|
|
388
|
+
tag_overlap = len(member_tags & resource_tags)
|
|
389
|
+
score += tag_overlap * 2.0
|
|
390
|
+
|
|
391
|
+
# Usage popularity score
|
|
392
|
+
score += resource.usage_count * 0.1
|
|
393
|
+
|
|
394
|
+
# Quality score
|
|
395
|
+
score += resource.rating * 1.0
|
|
396
|
+
|
|
397
|
+
# Recency score (newer resources get slight boost)
|
|
398
|
+
days_old = (datetime.utcnow() - resource.created_at).days
|
|
399
|
+
recency_score = max(0, 1.0 - (days_old / 365)) # Decay over a year
|
|
400
|
+
score += recency_score * 0.5
|
|
401
|
+
|
|
402
|
+
return score
|
|
403
|
+
|
|
404
|
+
async def _update_resource_indexes(
|
|
405
|
+
self,
|
|
406
|
+
resource_id: str,
|
|
407
|
+
tags: List[str],
|
|
408
|
+
resource_type: ResourceType,
|
|
409
|
+
owner_id: str,
|
|
410
|
+
) -> None:
|
|
411
|
+
"""Update resource indexes for efficient searching."""
|
|
412
|
+
# Tag index
|
|
413
|
+
for tag in tags:
|
|
414
|
+
if tag not in self.resource_index:
|
|
415
|
+
self.resource_index[tag] = set()
|
|
416
|
+
self.resource_index[tag].add(resource_id)
|
|
417
|
+
|
|
418
|
+
# Type index
|
|
419
|
+
if resource_type not in self.type_index:
|
|
420
|
+
self.type_index[resource_type] = set()
|
|
421
|
+
self.type_index[resource_type].add(resource_id)
|
|
422
|
+
|
|
423
|
+
# Owner index
|
|
424
|
+
if owner_id not in self.owner_index:
|
|
425
|
+
self.owner_index[owner_id] = set()
|
|
426
|
+
self.owner_index[owner_id].add(resource_id)
|
|
427
|
+
|
|
428
|
+
async def _create_resource_relationships(self, resource_id: str, related_resource_ids: List[str]) -> None:
|
|
429
|
+
"""Create relationships between resources."""
|
|
430
|
+
if resource_id not in self.resource_relationships:
|
|
431
|
+
self.resource_relationships[resource_id] = {
|
|
432
|
+
"related_to": [],
|
|
433
|
+
"referenced_by": [],
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
for related_id in related_resource_ids:
|
|
437
|
+
# Add forward relationship
|
|
438
|
+
if related_id not in self.resource_relationships[resource_id]["related_to"]:
|
|
439
|
+
self.resource_relationships[resource_id]["related_to"].append(related_id)
|
|
440
|
+
|
|
441
|
+
# Add backward relationship
|
|
442
|
+
if related_id not in self.resource_relationships:
|
|
443
|
+
self.resource_relationships[related_id] = {
|
|
444
|
+
"related_to": [],
|
|
445
|
+
"referenced_by": [],
|
|
446
|
+
}
|
|
447
|
+
if resource_id not in self.resource_relationships[related_id]["referenced_by"]:
|
|
448
|
+
self.resource_relationships[related_id]["referenced_by"].append(resource_id)
|
|
449
|
+
|
|
450
|
+
def _get_content_preview(self, content: Dict[str, Any], max_length: int = 200) -> str:
|
|
451
|
+
"""Get a preview of resource content."""
|
|
452
|
+
if "content" in content:
|
|
453
|
+
text = str(content["content"])
|
|
454
|
+
elif "description" in content:
|
|
455
|
+
text = str(content["description"])
|
|
456
|
+
else:
|
|
457
|
+
text = str(content)
|
|
458
|
+
|
|
459
|
+
if len(text) > max_length:
|
|
460
|
+
return text[:max_length] + "..."
|
|
461
|
+
return text
|