aiecs 1.5.1__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.
- aiecs/__init__.py +72 -0
- aiecs/__main__.py +41 -0
- aiecs/aiecs_client.py +469 -0
- aiecs/application/__init__.py +10 -0
- aiecs/application/executors/__init__.py +10 -0
- aiecs/application/executors/operation_executor.py +363 -0
- aiecs/application/knowledge_graph/__init__.py +7 -0
- aiecs/application/knowledge_graph/builder/__init__.py +37 -0
- aiecs/application/knowledge_graph/builder/document_builder.py +375 -0
- aiecs/application/knowledge_graph/builder/graph_builder.py +356 -0
- aiecs/application/knowledge_graph/builder/schema_mapping.py +531 -0
- aiecs/application/knowledge_graph/builder/structured_pipeline.py +443 -0
- aiecs/application/knowledge_graph/builder/text_chunker.py +319 -0
- aiecs/application/knowledge_graph/extractors/__init__.py +27 -0
- aiecs/application/knowledge_graph/extractors/base.py +100 -0
- aiecs/application/knowledge_graph/extractors/llm_entity_extractor.py +327 -0
- aiecs/application/knowledge_graph/extractors/llm_relation_extractor.py +349 -0
- aiecs/application/knowledge_graph/extractors/ner_entity_extractor.py +244 -0
- aiecs/application/knowledge_graph/fusion/__init__.py +23 -0
- aiecs/application/knowledge_graph/fusion/entity_deduplicator.py +387 -0
- aiecs/application/knowledge_graph/fusion/entity_linker.py +343 -0
- aiecs/application/knowledge_graph/fusion/knowledge_fusion.py +580 -0
- aiecs/application/knowledge_graph/fusion/relation_deduplicator.py +189 -0
- aiecs/application/knowledge_graph/pattern_matching/__init__.py +21 -0
- aiecs/application/knowledge_graph/pattern_matching/pattern_matcher.py +344 -0
- aiecs/application/knowledge_graph/pattern_matching/query_executor.py +378 -0
- aiecs/application/knowledge_graph/profiling/__init__.py +12 -0
- aiecs/application/knowledge_graph/profiling/query_plan_visualizer.py +199 -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 +347 -0
- aiecs/application/knowledge_graph/reasoning/inference_engine.py +504 -0
- aiecs/application/knowledge_graph/reasoning/logic_form_parser.py +167 -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 +630 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/ast_validator.py +654 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/error_handler.py +477 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/parser.py +390 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/query_context.py +217 -0
- aiecs/application/knowledge_graph/reasoning/logic_query_integration.py +169 -0
- aiecs/application/knowledge_graph/reasoning/query_planner.py +872 -0
- aiecs/application/knowledge_graph/reasoning/reasoning_engine.py +554 -0
- aiecs/application/knowledge_graph/retrieval/__init__.py +19 -0
- aiecs/application/knowledge_graph/retrieval/retrieval_strategies.py +596 -0
- aiecs/application/knowledge_graph/search/__init__.py +59 -0
- aiecs/application/knowledge_graph/search/hybrid_search.py +423 -0
- aiecs/application/knowledge_graph/search/reranker.py +295 -0
- aiecs/application/knowledge_graph/search/reranker_strategies.py +553 -0
- aiecs/application/knowledge_graph/search/text_similarity.py +398 -0
- aiecs/application/knowledge_graph/traversal/__init__.py +15 -0
- aiecs/application/knowledge_graph/traversal/enhanced_traversal.py +329 -0
- aiecs/application/knowledge_graph/traversal/path_scorer.py +269 -0
- aiecs/application/knowledge_graph/validators/__init__.py +13 -0
- aiecs/application/knowledge_graph/validators/relation_validator.py +189 -0
- aiecs/application/knowledge_graph/visualization/__init__.py +11 -0
- aiecs/application/knowledge_graph/visualization/graph_visualizer.py +321 -0
- aiecs/common/__init__.py +9 -0
- aiecs/common/knowledge_graph/__init__.py +17 -0
- aiecs/common/knowledge_graph/runnable.py +484 -0
- aiecs/config/__init__.py +16 -0
- aiecs/config/config.py +498 -0
- aiecs/config/graph_config.py +137 -0
- aiecs/config/registry.py +23 -0
- aiecs/core/__init__.py +46 -0
- aiecs/core/interface/__init__.py +34 -0
- aiecs/core/interface/execution_interface.py +152 -0
- aiecs/core/interface/storage_interface.py +171 -0
- aiecs/domain/__init__.py +289 -0
- aiecs/domain/agent/__init__.py +189 -0
- aiecs/domain/agent/base_agent.py +697 -0
- aiecs/domain/agent/exceptions.py +103 -0
- aiecs/domain/agent/graph_aware_mixin.py +559 -0
- aiecs/domain/agent/hybrid_agent.py +490 -0
- aiecs/domain/agent/integration/__init__.py +26 -0
- aiecs/domain/agent/integration/context_compressor.py +222 -0
- aiecs/domain/agent/integration/context_engine_adapter.py +252 -0
- aiecs/domain/agent/integration/retry_policy.py +219 -0
- aiecs/domain/agent/integration/role_config.py +213 -0
- aiecs/domain/agent/knowledge_aware_agent.py +646 -0
- aiecs/domain/agent/lifecycle.py +296 -0
- aiecs/domain/agent/llm_agent.py +300 -0
- aiecs/domain/agent/memory/__init__.py +12 -0
- aiecs/domain/agent/memory/conversation.py +197 -0
- aiecs/domain/agent/migration/__init__.py +14 -0
- aiecs/domain/agent/migration/conversion.py +160 -0
- aiecs/domain/agent/migration/legacy_wrapper.py +90 -0
- aiecs/domain/agent/models.py +317 -0
- aiecs/domain/agent/observability.py +407 -0
- aiecs/domain/agent/persistence.py +289 -0
- aiecs/domain/agent/prompts/__init__.py +29 -0
- aiecs/domain/agent/prompts/builder.py +161 -0
- aiecs/domain/agent/prompts/formatters.py +189 -0
- aiecs/domain/agent/prompts/template.py +255 -0
- aiecs/domain/agent/registry.py +260 -0
- aiecs/domain/agent/tool_agent.py +257 -0
- aiecs/domain/agent/tools/__init__.py +12 -0
- aiecs/domain/agent/tools/schema_generator.py +221 -0
- aiecs/domain/community/__init__.py +155 -0
- aiecs/domain/community/agent_adapter.py +477 -0
- aiecs/domain/community/analytics.py +481 -0
- aiecs/domain/community/collaborative_workflow.py +642 -0
- aiecs/domain/community/communication_hub.py +645 -0
- aiecs/domain/community/community_builder.py +320 -0
- aiecs/domain/community/community_integration.py +800 -0
- aiecs/domain/community/community_manager.py +813 -0
- aiecs/domain/community/decision_engine.py +879 -0
- aiecs/domain/community/exceptions.py +225 -0
- aiecs/domain/community/models/__init__.py +33 -0
- aiecs/domain/community/models/community_models.py +268 -0
- aiecs/domain/community/resource_manager.py +457 -0
- aiecs/domain/community/shared_context_manager.py +603 -0
- aiecs/domain/context/__init__.py +58 -0
- aiecs/domain/context/context_engine.py +989 -0
- aiecs/domain/context/conversation_models.py +354 -0
- aiecs/domain/context/graph_memory.py +467 -0
- aiecs/domain/execution/__init__.py +12 -0
- aiecs/domain/execution/model.py +57 -0
- aiecs/domain/knowledge_graph/__init__.py +19 -0
- aiecs/domain/knowledge_graph/models/__init__.py +52 -0
- aiecs/domain/knowledge_graph/models/entity.py +130 -0
- aiecs/domain/knowledge_graph/models/evidence.py +194 -0
- aiecs/domain/knowledge_graph/models/inference_rule.py +186 -0
- aiecs/domain/knowledge_graph/models/path.py +179 -0
- aiecs/domain/knowledge_graph/models/path_pattern.py +173 -0
- aiecs/domain/knowledge_graph/models/query.py +272 -0
- aiecs/domain/knowledge_graph/models/query_plan.py +187 -0
- aiecs/domain/knowledge_graph/models/relation.py +136 -0
- aiecs/domain/knowledge_graph/schema/__init__.py +23 -0
- aiecs/domain/knowledge_graph/schema/entity_type.py +135 -0
- aiecs/domain/knowledge_graph/schema/graph_schema.py +271 -0
- aiecs/domain/knowledge_graph/schema/property_schema.py +155 -0
- aiecs/domain/knowledge_graph/schema/relation_type.py +171 -0
- aiecs/domain/knowledge_graph/schema/schema_manager.py +496 -0
- aiecs/domain/knowledge_graph/schema/type_enums.py +205 -0
- aiecs/domain/task/__init__.py +13 -0
- aiecs/domain/task/dsl_processor.py +613 -0
- aiecs/domain/task/model.py +62 -0
- aiecs/domain/task/task_context.py +268 -0
- aiecs/infrastructure/__init__.py +24 -0
- aiecs/infrastructure/graph_storage/__init__.py +11 -0
- aiecs/infrastructure/graph_storage/base.py +601 -0
- aiecs/infrastructure/graph_storage/batch_operations.py +449 -0
- aiecs/infrastructure/graph_storage/cache.py +429 -0
- aiecs/infrastructure/graph_storage/distributed.py +226 -0
- aiecs/infrastructure/graph_storage/error_handling.py +390 -0
- aiecs/infrastructure/graph_storage/graceful_degradation.py +306 -0
- aiecs/infrastructure/graph_storage/health_checks.py +378 -0
- aiecs/infrastructure/graph_storage/in_memory.py +514 -0
- aiecs/infrastructure/graph_storage/index_optimization.py +483 -0
- aiecs/infrastructure/graph_storage/lazy_loading.py +410 -0
- aiecs/infrastructure/graph_storage/metrics.py +357 -0
- aiecs/infrastructure/graph_storage/migration.py +413 -0
- aiecs/infrastructure/graph_storage/pagination.py +471 -0
- aiecs/infrastructure/graph_storage/performance_monitoring.py +466 -0
- aiecs/infrastructure/graph_storage/postgres.py +871 -0
- aiecs/infrastructure/graph_storage/query_optimizer.py +635 -0
- aiecs/infrastructure/graph_storage/schema_cache.py +290 -0
- aiecs/infrastructure/graph_storage/sqlite.py +623 -0
- aiecs/infrastructure/graph_storage/streaming.py +495 -0
- aiecs/infrastructure/messaging/__init__.py +13 -0
- aiecs/infrastructure/messaging/celery_task_manager.py +383 -0
- aiecs/infrastructure/messaging/websocket_manager.py +298 -0
- aiecs/infrastructure/monitoring/__init__.py +34 -0
- aiecs/infrastructure/monitoring/executor_metrics.py +174 -0
- aiecs/infrastructure/monitoring/global_metrics_manager.py +213 -0
- aiecs/infrastructure/monitoring/structured_logger.py +48 -0
- aiecs/infrastructure/monitoring/tracing_manager.py +410 -0
- aiecs/infrastructure/persistence/__init__.py +24 -0
- aiecs/infrastructure/persistence/context_engine_client.py +187 -0
- aiecs/infrastructure/persistence/database_manager.py +333 -0
- aiecs/infrastructure/persistence/file_storage.py +754 -0
- aiecs/infrastructure/persistence/redis_client.py +220 -0
- aiecs/llm/__init__.py +86 -0
- aiecs/llm/callbacks/__init__.py +11 -0
- aiecs/llm/callbacks/custom_callbacks.py +264 -0
- aiecs/llm/client_factory.py +420 -0
- aiecs/llm/clients/__init__.py +33 -0
- aiecs/llm/clients/base_client.py +193 -0
- aiecs/llm/clients/googleai_client.py +181 -0
- aiecs/llm/clients/openai_client.py +131 -0
- aiecs/llm/clients/vertex_client.py +437 -0
- aiecs/llm/clients/xai_client.py +184 -0
- aiecs/llm/config/__init__.py +51 -0
- aiecs/llm/config/config_loader.py +275 -0
- aiecs/llm/config/config_validator.py +236 -0
- aiecs/llm/config/model_config.py +151 -0
- aiecs/llm/utils/__init__.py +10 -0
- aiecs/llm/utils/validate_config.py +91 -0
- aiecs/main.py +363 -0
- aiecs/scripts/__init__.py +3 -0
- aiecs/scripts/aid/VERSION_MANAGEMENT.md +97 -0
- aiecs/scripts/aid/__init__.py +19 -0
- aiecs/scripts/aid/version_manager.py +215 -0
- aiecs/scripts/dependance_check/DEPENDENCY_SYSTEM_SUMMARY.md +242 -0
- aiecs/scripts/dependance_check/README_DEPENDENCY_CHECKER.md +310 -0
- aiecs/scripts/dependance_check/__init__.py +17 -0
- aiecs/scripts/dependance_check/dependency_checker.py +938 -0
- aiecs/scripts/dependance_check/dependency_fixer.py +391 -0
- aiecs/scripts/dependance_check/download_nlp_data.py +396 -0
- aiecs/scripts/dependance_check/quick_dependency_check.py +270 -0
- aiecs/scripts/dependance_check/setup_nlp_data.sh +217 -0
- aiecs/scripts/dependance_patch/__init__.py +7 -0
- aiecs/scripts/dependance_patch/fix_weasel/README_WEASEL_PATCH.md +126 -0
- aiecs/scripts/dependance_patch/fix_weasel/__init__.py +11 -0
- aiecs/scripts/dependance_patch/fix_weasel/fix_weasel_validator.py +128 -0
- aiecs/scripts/dependance_patch/fix_weasel/fix_weasel_validator.sh +82 -0
- aiecs/scripts/dependance_patch/fix_weasel/patch_weasel_library.sh +188 -0
- aiecs/scripts/dependance_patch/fix_weasel/run_weasel_patch.sh +41 -0
- aiecs/scripts/tools_develop/README.md +449 -0
- aiecs/scripts/tools_develop/TOOL_AUTO_DISCOVERY.md +234 -0
- aiecs/scripts/tools_develop/__init__.py +21 -0
- aiecs/scripts/tools_develop/check_type_annotations.py +259 -0
- aiecs/scripts/tools_develop/validate_tool_schemas.py +422 -0
- aiecs/scripts/tools_develop/verify_tools.py +356 -0
- aiecs/tasks/__init__.py +1 -0
- aiecs/tasks/worker.py +172 -0
- aiecs/tools/__init__.py +299 -0
- aiecs/tools/apisource/__init__.py +99 -0
- aiecs/tools/apisource/intelligence/__init__.py +19 -0
- aiecs/tools/apisource/intelligence/data_fusion.py +381 -0
- aiecs/tools/apisource/intelligence/query_analyzer.py +413 -0
- aiecs/tools/apisource/intelligence/search_enhancer.py +388 -0
- aiecs/tools/apisource/monitoring/__init__.py +9 -0
- aiecs/tools/apisource/monitoring/metrics.py +303 -0
- aiecs/tools/apisource/providers/__init__.py +115 -0
- aiecs/tools/apisource/providers/base.py +664 -0
- aiecs/tools/apisource/providers/census.py +401 -0
- aiecs/tools/apisource/providers/fred.py +564 -0
- aiecs/tools/apisource/providers/newsapi.py +412 -0
- aiecs/tools/apisource/providers/worldbank.py +357 -0
- aiecs/tools/apisource/reliability/__init__.py +12 -0
- aiecs/tools/apisource/reliability/error_handler.py +375 -0
- aiecs/tools/apisource/reliability/fallback_strategy.py +391 -0
- aiecs/tools/apisource/tool.py +850 -0
- aiecs/tools/apisource/utils/__init__.py +9 -0
- aiecs/tools/apisource/utils/validators.py +338 -0
- aiecs/tools/base_tool.py +201 -0
- aiecs/tools/docs/__init__.py +121 -0
- aiecs/tools/docs/ai_document_orchestrator.py +599 -0
- aiecs/tools/docs/ai_document_writer_orchestrator.py +2403 -0
- aiecs/tools/docs/content_insertion_tool.py +1333 -0
- aiecs/tools/docs/document_creator_tool.py +1317 -0
- aiecs/tools/docs/document_layout_tool.py +1166 -0
- aiecs/tools/docs/document_parser_tool.py +994 -0
- aiecs/tools/docs/document_writer_tool.py +1818 -0
- aiecs/tools/knowledge_graph/__init__.py +17 -0
- aiecs/tools/knowledge_graph/graph_reasoning_tool.py +734 -0
- aiecs/tools/knowledge_graph/graph_search_tool.py +923 -0
- aiecs/tools/knowledge_graph/kg_builder_tool.py +476 -0
- aiecs/tools/langchain_adapter.py +542 -0
- aiecs/tools/schema_generator.py +275 -0
- aiecs/tools/search_tool/__init__.py +100 -0
- aiecs/tools/search_tool/analyzers.py +589 -0
- aiecs/tools/search_tool/cache.py +260 -0
- aiecs/tools/search_tool/constants.py +128 -0
- aiecs/tools/search_tool/context.py +216 -0
- aiecs/tools/search_tool/core.py +749 -0
- aiecs/tools/search_tool/deduplicator.py +123 -0
- aiecs/tools/search_tool/error_handler.py +271 -0
- aiecs/tools/search_tool/metrics.py +371 -0
- aiecs/tools/search_tool/rate_limiter.py +178 -0
- aiecs/tools/search_tool/schemas.py +277 -0
- aiecs/tools/statistics/__init__.py +80 -0
- aiecs/tools/statistics/ai_data_analysis_orchestrator.py +643 -0
- aiecs/tools/statistics/ai_insight_generator_tool.py +505 -0
- aiecs/tools/statistics/ai_report_orchestrator_tool.py +694 -0
- aiecs/tools/statistics/data_loader_tool.py +564 -0
- aiecs/tools/statistics/data_profiler_tool.py +658 -0
- aiecs/tools/statistics/data_transformer_tool.py +573 -0
- aiecs/tools/statistics/data_visualizer_tool.py +495 -0
- aiecs/tools/statistics/model_trainer_tool.py +487 -0
- aiecs/tools/statistics/statistical_analyzer_tool.py +459 -0
- aiecs/tools/task_tools/__init__.py +86 -0
- aiecs/tools/task_tools/chart_tool.py +732 -0
- aiecs/tools/task_tools/classfire_tool.py +922 -0
- aiecs/tools/task_tools/image_tool.py +447 -0
- aiecs/tools/task_tools/office_tool.py +684 -0
- aiecs/tools/task_tools/pandas_tool.py +635 -0
- aiecs/tools/task_tools/report_tool.py +635 -0
- aiecs/tools/task_tools/research_tool.py +392 -0
- aiecs/tools/task_tools/scraper_tool.py +715 -0
- aiecs/tools/task_tools/stats_tool.py +688 -0
- aiecs/tools/temp_file_manager.py +130 -0
- aiecs/tools/tool_executor/__init__.py +37 -0
- aiecs/tools/tool_executor/tool_executor.py +881 -0
- aiecs/utils/LLM_output_structor.py +445 -0
- aiecs/utils/__init__.py +34 -0
- aiecs/utils/base_callback.py +47 -0
- aiecs/utils/cache_provider.py +695 -0
- aiecs/utils/execution_utils.py +184 -0
- aiecs/utils/logging.py +1 -0
- aiecs/utils/prompt_loader.py +14 -0
- aiecs/utils/token_usage_repository.py +323 -0
- aiecs/ws/__init__.py +0 -0
- aiecs/ws/socket_server.py +52 -0
- aiecs-1.5.1.dist-info/METADATA +608 -0
- aiecs-1.5.1.dist-info/RECORD +302 -0
- aiecs-1.5.1.dist-info/WHEEL +5 -0
- aiecs-1.5.1.dist-info/entry_points.txt +10 -0
- aiecs-1.5.1.dist-info/licenses/LICENSE +225 -0
- aiecs-1.5.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Relation Domain Model
|
|
3
|
+
|
|
4
|
+
Represents an edge/relationship between two entities in the knowledge graph.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Any, Optional
|
|
8
|
+
from datetime import datetime
|
|
9
|
+
from pydantic import BaseModel, Field, field_validator
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Relation(BaseModel):
|
|
13
|
+
"""
|
|
14
|
+
Knowledge Graph Relation
|
|
15
|
+
|
|
16
|
+
Represents a directed edge between two entities in the knowledge graph.
|
|
17
|
+
|
|
18
|
+
Attributes:
|
|
19
|
+
id: Unique identifier for the relation
|
|
20
|
+
relation_type: Type of relation (e.g., "WORKS_FOR", "KNOWS")
|
|
21
|
+
source_id: ID of the source entity
|
|
22
|
+
target_id: ID of the target entity
|
|
23
|
+
properties: Additional properties of the relation
|
|
24
|
+
weight: Optional weight/strength of the relation (0.0-1.0)
|
|
25
|
+
created_at: Creation timestamp
|
|
26
|
+
source: Source of the relation data
|
|
27
|
+
|
|
28
|
+
Example:
|
|
29
|
+
```python
|
|
30
|
+
relation = Relation(
|
|
31
|
+
id="rel_001",
|
|
32
|
+
relation_type="WORKS_FOR",
|
|
33
|
+
source_id="person_001",
|
|
34
|
+
target_id="company_001",
|
|
35
|
+
properties={"role": "Engineer", "since": "2020-01-01"},
|
|
36
|
+
weight=1.0
|
|
37
|
+
)
|
|
38
|
+
```
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
id: str = Field(..., description="Unique identifier for the relation")
|
|
42
|
+
|
|
43
|
+
relation_type: str = Field(..., description="Type of the relation (e.g., 'WORKS_FOR', 'KNOWS')")
|
|
44
|
+
|
|
45
|
+
source_id: str = Field(..., description="ID of the source entity")
|
|
46
|
+
|
|
47
|
+
target_id: str = Field(..., description="ID of the target entity")
|
|
48
|
+
|
|
49
|
+
properties: dict[str, Any] = Field(
|
|
50
|
+
default_factory=dict,
|
|
51
|
+
description="Additional properties of the relation",
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
weight: float = Field(
|
|
55
|
+
default=1.0,
|
|
56
|
+
ge=0.0,
|
|
57
|
+
le=1.0,
|
|
58
|
+
description="Weight/strength of the relation (0.0-1.0)",
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
created_at: datetime = Field(
|
|
62
|
+
default_factory=datetime.utcnow,
|
|
63
|
+
description="Timestamp when relation was created",
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
source: Optional[str] = Field(default=None, description="Source of the relation data")
|
|
67
|
+
|
|
68
|
+
class Config:
|
|
69
|
+
json_encoders = {datetime: lambda v: v.isoformat()}
|
|
70
|
+
|
|
71
|
+
@field_validator("source_id", "target_id")
|
|
72
|
+
@classmethod
|
|
73
|
+
def validate_entity_ids(cls, v: str) -> str:
|
|
74
|
+
"""Validate entity IDs are non-empty"""
|
|
75
|
+
if not v or not v.strip():
|
|
76
|
+
raise ValueError("Entity IDs must be non-empty strings")
|
|
77
|
+
return v
|
|
78
|
+
|
|
79
|
+
@field_validator("source_id")
|
|
80
|
+
@classmethod
|
|
81
|
+
def validate_no_self_loop(cls, v: str, info) -> str:
|
|
82
|
+
"""Prevent self-loops (optional validation)"""
|
|
83
|
+
# Note: We allow self-loops for now, but this validator can be enabled if needed
|
|
84
|
+
# if info.data.get('target_id') and v == info.data['target_id']:
|
|
85
|
+
# raise ValueError("Self-loops are not allowed (source_id == target_id)")
|
|
86
|
+
return v
|
|
87
|
+
|
|
88
|
+
def get_property(self, key: str, default: Any = None) -> Any:
|
|
89
|
+
"""
|
|
90
|
+
Get a specific property value
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
key: Property key
|
|
94
|
+
default: Default value if key not found
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
Property value or default
|
|
98
|
+
"""
|
|
99
|
+
return self.properties.get(key, default)
|
|
100
|
+
|
|
101
|
+
def set_property(self, key: str, value: Any) -> None:
|
|
102
|
+
"""
|
|
103
|
+
Set a property value
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
key: Property key
|
|
107
|
+
value: Property value
|
|
108
|
+
"""
|
|
109
|
+
self.properties[key] = value
|
|
110
|
+
|
|
111
|
+
def reverse(self) -> "Relation":
|
|
112
|
+
"""
|
|
113
|
+
Create a reversed relation (swap source and target)
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
New Relation with swapped source and target
|
|
117
|
+
"""
|
|
118
|
+
return Relation(
|
|
119
|
+
id=f"{self.id}_reversed",
|
|
120
|
+
relation_type=f"{self.relation_type}_REVERSE",
|
|
121
|
+
source_id=self.target_id,
|
|
122
|
+
target_id=self.source_id,
|
|
123
|
+
properties=self.properties.copy(),
|
|
124
|
+
weight=self.weight,
|
|
125
|
+
created_at=self.created_at,
|
|
126
|
+
source=self.source,
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
def __str__(self) -> str:
|
|
130
|
+
return f"Relation({self.source_id} -[{self.relation_type}]-> {self.target_id})"
|
|
131
|
+
|
|
132
|
+
def __repr__(self) -> str:
|
|
133
|
+
return (
|
|
134
|
+
f"Relation(id='{self.id}', type='{self.relation_type}', "
|
|
135
|
+
f"source='{self.source_id}', target='{self.target_id}', weight={self.weight})"
|
|
136
|
+
)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Knowledge Graph Schema Management
|
|
3
|
+
|
|
4
|
+
Schema definitions for entity types, relation types, and properties.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from aiecs.domain.knowledge_graph.schema.property_schema import (
|
|
8
|
+
PropertySchema,
|
|
9
|
+
PropertyType,
|
|
10
|
+
)
|
|
11
|
+
from aiecs.domain.knowledge_graph.schema.entity_type import EntityType
|
|
12
|
+
from aiecs.domain.knowledge_graph.schema.relation_type import RelationType
|
|
13
|
+
from aiecs.domain.knowledge_graph.schema.graph_schema import GraphSchema
|
|
14
|
+
from aiecs.domain.knowledge_graph.schema.schema_manager import SchemaManager
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"PropertySchema",
|
|
18
|
+
"PropertyType",
|
|
19
|
+
"EntityType",
|
|
20
|
+
"RelationType",
|
|
21
|
+
"GraphSchema",
|
|
22
|
+
"SchemaManager",
|
|
23
|
+
]
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Entity Type Schema Definition
|
|
3
|
+
|
|
4
|
+
Defines the schema for entity types in the knowledge graph.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Dict, List, Optional, Any
|
|
8
|
+
from pydantic import BaseModel, Field
|
|
9
|
+
from aiecs.domain.knowledge_graph.schema.property_schema import PropertySchema
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class EntityType(BaseModel):
|
|
13
|
+
"""
|
|
14
|
+
Entity Type Schema
|
|
15
|
+
|
|
16
|
+
Defines the schema for a type of entity in the knowledge graph,
|
|
17
|
+
including its properties and constraints.
|
|
18
|
+
|
|
19
|
+
Attributes:
|
|
20
|
+
name: Entity type name (e.g., "Person", "Company")
|
|
21
|
+
description: Human-readable description
|
|
22
|
+
properties: Dictionary of property schemas
|
|
23
|
+
parent_type: Optional parent entity type for inheritance
|
|
24
|
+
is_abstract: Whether this is an abstract type (cannot be instantiated)
|
|
25
|
+
|
|
26
|
+
Example:
|
|
27
|
+
```python
|
|
28
|
+
person_type = EntityType(
|
|
29
|
+
name="Person",
|
|
30
|
+
description="A person entity",
|
|
31
|
+
properties={
|
|
32
|
+
"name": PropertySchema(name="name", property_type=PropertyType.STRING, required=True),
|
|
33
|
+
"age": PropertySchema(name="age", property_type=PropertyType.INTEGER),
|
|
34
|
+
}
|
|
35
|
+
)
|
|
36
|
+
```
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
name: str = Field(..., description="Entity type name (must be unique)")
|
|
40
|
+
|
|
41
|
+
description: Optional[str] = Field(
|
|
42
|
+
default=None,
|
|
43
|
+
description="Human-readable description of this entity type",
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
properties: Dict[str, PropertySchema] = Field(
|
|
47
|
+
default_factory=dict,
|
|
48
|
+
description="Dictionary of property schemas (key=property name)",
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
parent_type: Optional[str] = Field(
|
|
52
|
+
default=None, description="Parent entity type name for inheritance"
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
is_abstract: bool = Field(
|
|
56
|
+
default=False,
|
|
57
|
+
description="Whether this is an abstract type (cannot be instantiated)",
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
class Config:
|
|
61
|
+
arbitrary_types_allowed = True
|
|
62
|
+
|
|
63
|
+
def add_property(self, prop: PropertySchema) -> None:
|
|
64
|
+
"""
|
|
65
|
+
Add a property to this entity type
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
prop: Property schema to add
|
|
69
|
+
"""
|
|
70
|
+
self.properties[prop.name] = prop
|
|
71
|
+
|
|
72
|
+
def remove_property(self, property_name: str) -> None:
|
|
73
|
+
"""
|
|
74
|
+
Remove a property from this entity type
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
property_name: Name of property to remove
|
|
78
|
+
"""
|
|
79
|
+
if property_name in self.properties:
|
|
80
|
+
del self.properties[property_name]
|
|
81
|
+
|
|
82
|
+
def get_property(self, property_name: str) -> Optional[PropertySchema]:
|
|
83
|
+
"""
|
|
84
|
+
Get a property schema by name
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
property_name: Name of property to get
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
Property schema or None if not found
|
|
91
|
+
"""
|
|
92
|
+
return self.properties.get(property_name)
|
|
93
|
+
|
|
94
|
+
def validate_properties(self, properties: Dict[str, Any]) -> bool:
|
|
95
|
+
"""
|
|
96
|
+
Validate a dictionary of properties against this schema
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
properties: Dictionary of properties to validate
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
True if all properties are valid
|
|
103
|
+
|
|
104
|
+
Raises:
|
|
105
|
+
ValueError: If validation fails
|
|
106
|
+
"""
|
|
107
|
+
# Check required properties
|
|
108
|
+
for prop_name, prop_schema in self.properties.items():
|
|
109
|
+
if prop_schema.required and prop_name not in properties:
|
|
110
|
+
raise ValueError(
|
|
111
|
+
f"Required property '{prop_name}' missing for entity type '{self.name}'"
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
# Validate each provided property
|
|
115
|
+
for prop_name, prop_value in properties.items():
|
|
116
|
+
if prop_name in self.properties:
|
|
117
|
+
prop_schema = self.properties[prop_name]
|
|
118
|
+
prop_schema.validate_value(prop_value)
|
|
119
|
+
|
|
120
|
+
return True
|
|
121
|
+
|
|
122
|
+
def get_required_properties(self) -> List[str]:
|
|
123
|
+
"""
|
|
124
|
+
Get list of required property names
|
|
125
|
+
|
|
126
|
+
Returns:
|
|
127
|
+
List of required property names
|
|
128
|
+
"""
|
|
129
|
+
return [prop.name for prop in self.properties.values() if prop.required]
|
|
130
|
+
|
|
131
|
+
def __str__(self) -> str:
|
|
132
|
+
return f"EntityType(name='{self.name}', properties={len(self.properties)})"
|
|
133
|
+
|
|
134
|
+
def __repr__(self) -> str:
|
|
135
|
+
return self.__str__()
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Graph Schema Container
|
|
3
|
+
|
|
4
|
+
Container for all entity types and relation types in the knowledge graph.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Dict, List, Optional
|
|
8
|
+
from pydantic import BaseModel, Field
|
|
9
|
+
from aiecs.domain.knowledge_graph.schema.entity_type import EntityType
|
|
10
|
+
from aiecs.domain.knowledge_graph.schema.relation_type import RelationType
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class GraphSchema(BaseModel):
|
|
14
|
+
"""
|
|
15
|
+
Knowledge Graph Schema
|
|
16
|
+
|
|
17
|
+
Container for all entity types and relation types in the knowledge graph.
|
|
18
|
+
Provides methods for schema management and validation.
|
|
19
|
+
|
|
20
|
+
Attributes:
|
|
21
|
+
version: Schema version identifier
|
|
22
|
+
entity_types: Dictionary of entity type schemas
|
|
23
|
+
relation_types: Dictionary of relation type schemas
|
|
24
|
+
description: Human-readable description of the schema
|
|
25
|
+
|
|
26
|
+
Example:
|
|
27
|
+
```python
|
|
28
|
+
schema = GraphSchema(
|
|
29
|
+
version="1.0",
|
|
30
|
+
description="Company knowledge graph schema"
|
|
31
|
+
)
|
|
32
|
+
schema.add_entity_type(person_type)
|
|
33
|
+
schema.add_entity_type(company_type)
|
|
34
|
+
schema.add_relation_type(works_for_type)
|
|
35
|
+
```
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
version: str = Field(default="1.0", description="Schema version identifier")
|
|
39
|
+
|
|
40
|
+
entity_types: Dict[str, EntityType] = Field(
|
|
41
|
+
default_factory=dict,
|
|
42
|
+
description="Dictionary of entity type schemas (key=type name)",
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
relation_types: Dict[str, RelationType] = Field(
|
|
46
|
+
default_factory=dict,
|
|
47
|
+
description="Dictionary of relation type schemas (key=type name)",
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
description: Optional[str] = Field(
|
|
51
|
+
default=None, description="Human-readable description of this schema"
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
class Config:
|
|
55
|
+
arbitrary_types_allowed = True
|
|
56
|
+
|
|
57
|
+
# Entity Type Management
|
|
58
|
+
|
|
59
|
+
def add_entity_type(self, entity_type: EntityType) -> None:
|
|
60
|
+
"""
|
|
61
|
+
Add an entity type to the schema
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
entity_type: Entity type to add
|
|
65
|
+
|
|
66
|
+
Raises:
|
|
67
|
+
ValueError: If entity type already exists
|
|
68
|
+
"""
|
|
69
|
+
if entity_type.name in self.entity_types:
|
|
70
|
+
raise ValueError(f"Entity type '{entity_type.name}' already exists in schema")
|
|
71
|
+
self.entity_types[entity_type.name] = entity_type
|
|
72
|
+
|
|
73
|
+
def update_entity_type(self, entity_type: EntityType) -> None:
|
|
74
|
+
"""
|
|
75
|
+
Update an existing entity type
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
entity_type: Updated entity type
|
|
79
|
+
|
|
80
|
+
Raises:
|
|
81
|
+
ValueError: If entity type doesn't exist
|
|
82
|
+
"""
|
|
83
|
+
if entity_type.name not in self.entity_types:
|
|
84
|
+
raise ValueError(f"Entity type '{entity_type.name}' not found in schema")
|
|
85
|
+
self.entity_types[entity_type.name] = entity_type
|
|
86
|
+
|
|
87
|
+
def delete_entity_type(self, type_name: str) -> None:
|
|
88
|
+
"""
|
|
89
|
+
Delete an entity type from the schema
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
type_name: Name of entity type to delete
|
|
93
|
+
|
|
94
|
+
Raises:
|
|
95
|
+
ValueError: If entity type doesn't exist or is in use
|
|
96
|
+
"""
|
|
97
|
+
if type_name not in self.entity_types:
|
|
98
|
+
raise ValueError(f"Entity type '{type_name}' not found in schema")
|
|
99
|
+
|
|
100
|
+
# Check if any relation types reference this entity type
|
|
101
|
+
for rel_type in self.relation_types.values():
|
|
102
|
+
if rel_type.source_entity_types and type_name in rel_type.source_entity_types:
|
|
103
|
+
raise ValueError(
|
|
104
|
+
f"Cannot delete entity type '{type_name}': "
|
|
105
|
+
f"referenced by relation '{rel_type.name}' as source"
|
|
106
|
+
)
|
|
107
|
+
if rel_type.target_entity_types and type_name in rel_type.target_entity_types:
|
|
108
|
+
raise ValueError(
|
|
109
|
+
f"Cannot delete entity type '{type_name}': "
|
|
110
|
+
f"referenced by relation '{rel_type.name}' as target"
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
del self.entity_types[type_name]
|
|
114
|
+
|
|
115
|
+
def get_entity_type(self, type_name: str) -> Optional[EntityType]:
|
|
116
|
+
"""
|
|
117
|
+
Get an entity type by name
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
type_name: Name of entity type
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
Entity type or None if not found
|
|
124
|
+
"""
|
|
125
|
+
return self.entity_types.get(type_name)
|
|
126
|
+
|
|
127
|
+
def has_entity_type(self, type_name: str) -> bool:
|
|
128
|
+
"""
|
|
129
|
+
Check if entity type exists
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
type_name: Name of entity type
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
True if entity type exists
|
|
136
|
+
"""
|
|
137
|
+
return type_name in self.entity_types
|
|
138
|
+
|
|
139
|
+
# Relation Type Management
|
|
140
|
+
|
|
141
|
+
def add_relation_type(self, relation_type: RelationType) -> None:
|
|
142
|
+
"""
|
|
143
|
+
Add a relation type to the schema
|
|
144
|
+
|
|
145
|
+
Args:
|
|
146
|
+
relation_type: Relation type to add
|
|
147
|
+
|
|
148
|
+
Raises:
|
|
149
|
+
ValueError: If relation type already exists
|
|
150
|
+
"""
|
|
151
|
+
if relation_type.name in self.relation_types:
|
|
152
|
+
raise ValueError(f"Relation type '{relation_type.name}' already exists in schema")
|
|
153
|
+
self.relation_types[relation_type.name] = relation_type
|
|
154
|
+
|
|
155
|
+
def update_relation_type(self, relation_type: RelationType) -> None:
|
|
156
|
+
"""
|
|
157
|
+
Update an existing relation type
|
|
158
|
+
|
|
159
|
+
Args:
|
|
160
|
+
relation_type: Updated relation type
|
|
161
|
+
|
|
162
|
+
Raises:
|
|
163
|
+
ValueError: If relation type doesn't exist
|
|
164
|
+
"""
|
|
165
|
+
if relation_type.name not in self.relation_types:
|
|
166
|
+
raise ValueError(f"Relation type '{relation_type.name}' not found in schema")
|
|
167
|
+
self.relation_types[relation_type.name] = relation_type
|
|
168
|
+
|
|
169
|
+
def delete_relation_type(self, type_name: str) -> None:
|
|
170
|
+
"""
|
|
171
|
+
Delete a relation type from the schema
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
type_name: Name of relation type to delete
|
|
175
|
+
|
|
176
|
+
Raises:
|
|
177
|
+
ValueError: If relation type doesn't exist
|
|
178
|
+
"""
|
|
179
|
+
if type_name not in self.relation_types:
|
|
180
|
+
raise ValueError(f"Relation type '{type_name}' not found in schema")
|
|
181
|
+
del self.relation_types[type_name]
|
|
182
|
+
|
|
183
|
+
def get_relation_type(self, type_name: str) -> Optional[RelationType]:
|
|
184
|
+
"""
|
|
185
|
+
Get a relation type by name
|
|
186
|
+
|
|
187
|
+
Args:
|
|
188
|
+
type_name: Name of relation type
|
|
189
|
+
|
|
190
|
+
Returns:
|
|
191
|
+
Relation type or None if not found
|
|
192
|
+
"""
|
|
193
|
+
return self.relation_types.get(type_name)
|
|
194
|
+
|
|
195
|
+
def has_relation_type(self, type_name: str) -> bool:
|
|
196
|
+
"""
|
|
197
|
+
Check if relation type exists
|
|
198
|
+
|
|
199
|
+
Args:
|
|
200
|
+
type_name: Name of relation type
|
|
201
|
+
|
|
202
|
+
Returns:
|
|
203
|
+
True if relation type exists
|
|
204
|
+
"""
|
|
205
|
+
return type_name in self.relation_types
|
|
206
|
+
|
|
207
|
+
# Schema Queries
|
|
208
|
+
|
|
209
|
+
def get_entity_type_names(self) -> List[str]:
|
|
210
|
+
"""Get list of all entity type names"""
|
|
211
|
+
return list(self.entity_types.keys())
|
|
212
|
+
|
|
213
|
+
def get_relation_type_names(self) -> List[str]:
|
|
214
|
+
"""Get list of all relation type names"""
|
|
215
|
+
return list(self.relation_types.keys())
|
|
216
|
+
|
|
217
|
+
def get_entity_types_with_property(self, property_name: str) -> List[EntityType]:
|
|
218
|
+
"""
|
|
219
|
+
Get all entity types that have a specific property
|
|
220
|
+
|
|
221
|
+
Args:
|
|
222
|
+
property_name: Name of property to search for
|
|
223
|
+
|
|
224
|
+
Returns:
|
|
225
|
+
List of entity types with that property
|
|
226
|
+
"""
|
|
227
|
+
return [
|
|
228
|
+
entity_type
|
|
229
|
+
for entity_type in self.entity_types.values()
|
|
230
|
+
if property_name in entity_type.properties
|
|
231
|
+
]
|
|
232
|
+
|
|
233
|
+
def get_relation_types_for_entities(
|
|
234
|
+
self, source_type: str, target_type: str
|
|
235
|
+
) -> List[RelationType]:
|
|
236
|
+
"""
|
|
237
|
+
Get all relation types allowed between two entity types
|
|
238
|
+
|
|
239
|
+
Args:
|
|
240
|
+
source_type: Source entity type name
|
|
241
|
+
target_type: Target entity type name
|
|
242
|
+
|
|
243
|
+
Returns:
|
|
244
|
+
List of allowed relation types
|
|
245
|
+
"""
|
|
246
|
+
allowed_relations = []
|
|
247
|
+
|
|
248
|
+
for rel_type in self.relation_types.values():
|
|
249
|
+
# Check if source type is allowed
|
|
250
|
+
if rel_type.source_entity_types is not None:
|
|
251
|
+
if source_type not in rel_type.source_entity_types:
|
|
252
|
+
continue
|
|
253
|
+
|
|
254
|
+
# Check if target type is allowed
|
|
255
|
+
if rel_type.target_entity_types is not None:
|
|
256
|
+
if target_type not in rel_type.target_entity_types:
|
|
257
|
+
continue
|
|
258
|
+
|
|
259
|
+
allowed_relations.append(rel_type)
|
|
260
|
+
|
|
261
|
+
return allowed_relations
|
|
262
|
+
|
|
263
|
+
def __str__(self) -> str:
|
|
264
|
+
return (
|
|
265
|
+
f"GraphSchema(version='{self.version}', "
|
|
266
|
+
f"entity_types={len(self.entity_types)}, "
|
|
267
|
+
f"relation_types={len(self.relation_types)})"
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
def __repr__(self) -> str:
|
|
271
|
+
return self.__str__()
|