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.
Files changed (302) hide show
  1. aiecs/__init__.py +72 -0
  2. aiecs/__main__.py +41 -0
  3. aiecs/aiecs_client.py +469 -0
  4. aiecs/application/__init__.py +10 -0
  5. aiecs/application/executors/__init__.py +10 -0
  6. aiecs/application/executors/operation_executor.py +363 -0
  7. aiecs/application/knowledge_graph/__init__.py +7 -0
  8. aiecs/application/knowledge_graph/builder/__init__.py +37 -0
  9. aiecs/application/knowledge_graph/builder/document_builder.py +375 -0
  10. aiecs/application/knowledge_graph/builder/graph_builder.py +356 -0
  11. aiecs/application/knowledge_graph/builder/schema_mapping.py +531 -0
  12. aiecs/application/knowledge_graph/builder/structured_pipeline.py +443 -0
  13. aiecs/application/knowledge_graph/builder/text_chunker.py +319 -0
  14. aiecs/application/knowledge_graph/extractors/__init__.py +27 -0
  15. aiecs/application/knowledge_graph/extractors/base.py +100 -0
  16. aiecs/application/knowledge_graph/extractors/llm_entity_extractor.py +327 -0
  17. aiecs/application/knowledge_graph/extractors/llm_relation_extractor.py +349 -0
  18. aiecs/application/knowledge_graph/extractors/ner_entity_extractor.py +244 -0
  19. aiecs/application/knowledge_graph/fusion/__init__.py +23 -0
  20. aiecs/application/knowledge_graph/fusion/entity_deduplicator.py +387 -0
  21. aiecs/application/knowledge_graph/fusion/entity_linker.py +343 -0
  22. aiecs/application/knowledge_graph/fusion/knowledge_fusion.py +580 -0
  23. aiecs/application/knowledge_graph/fusion/relation_deduplicator.py +189 -0
  24. aiecs/application/knowledge_graph/pattern_matching/__init__.py +21 -0
  25. aiecs/application/knowledge_graph/pattern_matching/pattern_matcher.py +344 -0
  26. aiecs/application/knowledge_graph/pattern_matching/query_executor.py +378 -0
  27. aiecs/application/knowledge_graph/profiling/__init__.py +12 -0
  28. aiecs/application/knowledge_graph/profiling/query_plan_visualizer.py +199 -0
  29. aiecs/application/knowledge_graph/profiling/query_profiler.py +223 -0
  30. aiecs/application/knowledge_graph/reasoning/__init__.py +27 -0
  31. aiecs/application/knowledge_graph/reasoning/evidence_synthesis.py +347 -0
  32. aiecs/application/knowledge_graph/reasoning/inference_engine.py +504 -0
  33. aiecs/application/knowledge_graph/reasoning/logic_form_parser.py +167 -0
  34. aiecs/application/knowledge_graph/reasoning/logic_parser/__init__.py +79 -0
  35. aiecs/application/knowledge_graph/reasoning/logic_parser/ast_builder.py +513 -0
  36. aiecs/application/knowledge_graph/reasoning/logic_parser/ast_nodes.py +630 -0
  37. aiecs/application/knowledge_graph/reasoning/logic_parser/ast_validator.py +654 -0
  38. aiecs/application/knowledge_graph/reasoning/logic_parser/error_handler.py +477 -0
  39. aiecs/application/knowledge_graph/reasoning/logic_parser/parser.py +390 -0
  40. aiecs/application/knowledge_graph/reasoning/logic_parser/query_context.py +217 -0
  41. aiecs/application/knowledge_graph/reasoning/logic_query_integration.py +169 -0
  42. aiecs/application/knowledge_graph/reasoning/query_planner.py +872 -0
  43. aiecs/application/knowledge_graph/reasoning/reasoning_engine.py +554 -0
  44. aiecs/application/knowledge_graph/retrieval/__init__.py +19 -0
  45. aiecs/application/knowledge_graph/retrieval/retrieval_strategies.py +596 -0
  46. aiecs/application/knowledge_graph/search/__init__.py +59 -0
  47. aiecs/application/knowledge_graph/search/hybrid_search.py +423 -0
  48. aiecs/application/knowledge_graph/search/reranker.py +295 -0
  49. aiecs/application/knowledge_graph/search/reranker_strategies.py +553 -0
  50. aiecs/application/knowledge_graph/search/text_similarity.py +398 -0
  51. aiecs/application/knowledge_graph/traversal/__init__.py +15 -0
  52. aiecs/application/knowledge_graph/traversal/enhanced_traversal.py +329 -0
  53. aiecs/application/knowledge_graph/traversal/path_scorer.py +269 -0
  54. aiecs/application/knowledge_graph/validators/__init__.py +13 -0
  55. aiecs/application/knowledge_graph/validators/relation_validator.py +189 -0
  56. aiecs/application/knowledge_graph/visualization/__init__.py +11 -0
  57. aiecs/application/knowledge_graph/visualization/graph_visualizer.py +321 -0
  58. aiecs/common/__init__.py +9 -0
  59. aiecs/common/knowledge_graph/__init__.py +17 -0
  60. aiecs/common/knowledge_graph/runnable.py +484 -0
  61. aiecs/config/__init__.py +16 -0
  62. aiecs/config/config.py +498 -0
  63. aiecs/config/graph_config.py +137 -0
  64. aiecs/config/registry.py +23 -0
  65. aiecs/core/__init__.py +46 -0
  66. aiecs/core/interface/__init__.py +34 -0
  67. aiecs/core/interface/execution_interface.py +152 -0
  68. aiecs/core/interface/storage_interface.py +171 -0
  69. aiecs/domain/__init__.py +289 -0
  70. aiecs/domain/agent/__init__.py +189 -0
  71. aiecs/domain/agent/base_agent.py +697 -0
  72. aiecs/domain/agent/exceptions.py +103 -0
  73. aiecs/domain/agent/graph_aware_mixin.py +559 -0
  74. aiecs/domain/agent/hybrid_agent.py +490 -0
  75. aiecs/domain/agent/integration/__init__.py +26 -0
  76. aiecs/domain/agent/integration/context_compressor.py +222 -0
  77. aiecs/domain/agent/integration/context_engine_adapter.py +252 -0
  78. aiecs/domain/agent/integration/retry_policy.py +219 -0
  79. aiecs/domain/agent/integration/role_config.py +213 -0
  80. aiecs/domain/agent/knowledge_aware_agent.py +646 -0
  81. aiecs/domain/agent/lifecycle.py +296 -0
  82. aiecs/domain/agent/llm_agent.py +300 -0
  83. aiecs/domain/agent/memory/__init__.py +12 -0
  84. aiecs/domain/agent/memory/conversation.py +197 -0
  85. aiecs/domain/agent/migration/__init__.py +14 -0
  86. aiecs/domain/agent/migration/conversion.py +160 -0
  87. aiecs/domain/agent/migration/legacy_wrapper.py +90 -0
  88. aiecs/domain/agent/models.py +317 -0
  89. aiecs/domain/agent/observability.py +407 -0
  90. aiecs/domain/agent/persistence.py +289 -0
  91. aiecs/domain/agent/prompts/__init__.py +29 -0
  92. aiecs/domain/agent/prompts/builder.py +161 -0
  93. aiecs/domain/agent/prompts/formatters.py +189 -0
  94. aiecs/domain/agent/prompts/template.py +255 -0
  95. aiecs/domain/agent/registry.py +260 -0
  96. aiecs/domain/agent/tool_agent.py +257 -0
  97. aiecs/domain/agent/tools/__init__.py +12 -0
  98. aiecs/domain/agent/tools/schema_generator.py +221 -0
  99. aiecs/domain/community/__init__.py +155 -0
  100. aiecs/domain/community/agent_adapter.py +477 -0
  101. aiecs/domain/community/analytics.py +481 -0
  102. aiecs/domain/community/collaborative_workflow.py +642 -0
  103. aiecs/domain/community/communication_hub.py +645 -0
  104. aiecs/domain/community/community_builder.py +320 -0
  105. aiecs/domain/community/community_integration.py +800 -0
  106. aiecs/domain/community/community_manager.py +813 -0
  107. aiecs/domain/community/decision_engine.py +879 -0
  108. aiecs/domain/community/exceptions.py +225 -0
  109. aiecs/domain/community/models/__init__.py +33 -0
  110. aiecs/domain/community/models/community_models.py +268 -0
  111. aiecs/domain/community/resource_manager.py +457 -0
  112. aiecs/domain/community/shared_context_manager.py +603 -0
  113. aiecs/domain/context/__init__.py +58 -0
  114. aiecs/domain/context/context_engine.py +989 -0
  115. aiecs/domain/context/conversation_models.py +354 -0
  116. aiecs/domain/context/graph_memory.py +467 -0
  117. aiecs/domain/execution/__init__.py +12 -0
  118. aiecs/domain/execution/model.py +57 -0
  119. aiecs/domain/knowledge_graph/__init__.py +19 -0
  120. aiecs/domain/knowledge_graph/models/__init__.py +52 -0
  121. aiecs/domain/knowledge_graph/models/entity.py +130 -0
  122. aiecs/domain/knowledge_graph/models/evidence.py +194 -0
  123. aiecs/domain/knowledge_graph/models/inference_rule.py +186 -0
  124. aiecs/domain/knowledge_graph/models/path.py +179 -0
  125. aiecs/domain/knowledge_graph/models/path_pattern.py +173 -0
  126. aiecs/domain/knowledge_graph/models/query.py +272 -0
  127. aiecs/domain/knowledge_graph/models/query_plan.py +187 -0
  128. aiecs/domain/knowledge_graph/models/relation.py +136 -0
  129. aiecs/domain/knowledge_graph/schema/__init__.py +23 -0
  130. aiecs/domain/knowledge_graph/schema/entity_type.py +135 -0
  131. aiecs/domain/knowledge_graph/schema/graph_schema.py +271 -0
  132. aiecs/domain/knowledge_graph/schema/property_schema.py +155 -0
  133. aiecs/domain/knowledge_graph/schema/relation_type.py +171 -0
  134. aiecs/domain/knowledge_graph/schema/schema_manager.py +496 -0
  135. aiecs/domain/knowledge_graph/schema/type_enums.py +205 -0
  136. aiecs/domain/task/__init__.py +13 -0
  137. aiecs/domain/task/dsl_processor.py +613 -0
  138. aiecs/domain/task/model.py +62 -0
  139. aiecs/domain/task/task_context.py +268 -0
  140. aiecs/infrastructure/__init__.py +24 -0
  141. aiecs/infrastructure/graph_storage/__init__.py +11 -0
  142. aiecs/infrastructure/graph_storage/base.py +601 -0
  143. aiecs/infrastructure/graph_storage/batch_operations.py +449 -0
  144. aiecs/infrastructure/graph_storage/cache.py +429 -0
  145. aiecs/infrastructure/graph_storage/distributed.py +226 -0
  146. aiecs/infrastructure/graph_storage/error_handling.py +390 -0
  147. aiecs/infrastructure/graph_storage/graceful_degradation.py +306 -0
  148. aiecs/infrastructure/graph_storage/health_checks.py +378 -0
  149. aiecs/infrastructure/graph_storage/in_memory.py +514 -0
  150. aiecs/infrastructure/graph_storage/index_optimization.py +483 -0
  151. aiecs/infrastructure/graph_storage/lazy_loading.py +410 -0
  152. aiecs/infrastructure/graph_storage/metrics.py +357 -0
  153. aiecs/infrastructure/graph_storage/migration.py +413 -0
  154. aiecs/infrastructure/graph_storage/pagination.py +471 -0
  155. aiecs/infrastructure/graph_storage/performance_monitoring.py +466 -0
  156. aiecs/infrastructure/graph_storage/postgres.py +871 -0
  157. aiecs/infrastructure/graph_storage/query_optimizer.py +635 -0
  158. aiecs/infrastructure/graph_storage/schema_cache.py +290 -0
  159. aiecs/infrastructure/graph_storage/sqlite.py +623 -0
  160. aiecs/infrastructure/graph_storage/streaming.py +495 -0
  161. aiecs/infrastructure/messaging/__init__.py +13 -0
  162. aiecs/infrastructure/messaging/celery_task_manager.py +383 -0
  163. aiecs/infrastructure/messaging/websocket_manager.py +298 -0
  164. aiecs/infrastructure/monitoring/__init__.py +34 -0
  165. aiecs/infrastructure/monitoring/executor_metrics.py +174 -0
  166. aiecs/infrastructure/monitoring/global_metrics_manager.py +213 -0
  167. aiecs/infrastructure/monitoring/structured_logger.py +48 -0
  168. aiecs/infrastructure/monitoring/tracing_manager.py +410 -0
  169. aiecs/infrastructure/persistence/__init__.py +24 -0
  170. aiecs/infrastructure/persistence/context_engine_client.py +187 -0
  171. aiecs/infrastructure/persistence/database_manager.py +333 -0
  172. aiecs/infrastructure/persistence/file_storage.py +754 -0
  173. aiecs/infrastructure/persistence/redis_client.py +220 -0
  174. aiecs/llm/__init__.py +86 -0
  175. aiecs/llm/callbacks/__init__.py +11 -0
  176. aiecs/llm/callbacks/custom_callbacks.py +264 -0
  177. aiecs/llm/client_factory.py +420 -0
  178. aiecs/llm/clients/__init__.py +33 -0
  179. aiecs/llm/clients/base_client.py +193 -0
  180. aiecs/llm/clients/googleai_client.py +181 -0
  181. aiecs/llm/clients/openai_client.py +131 -0
  182. aiecs/llm/clients/vertex_client.py +437 -0
  183. aiecs/llm/clients/xai_client.py +184 -0
  184. aiecs/llm/config/__init__.py +51 -0
  185. aiecs/llm/config/config_loader.py +275 -0
  186. aiecs/llm/config/config_validator.py +236 -0
  187. aiecs/llm/config/model_config.py +151 -0
  188. aiecs/llm/utils/__init__.py +10 -0
  189. aiecs/llm/utils/validate_config.py +91 -0
  190. aiecs/main.py +363 -0
  191. aiecs/scripts/__init__.py +3 -0
  192. aiecs/scripts/aid/VERSION_MANAGEMENT.md +97 -0
  193. aiecs/scripts/aid/__init__.py +19 -0
  194. aiecs/scripts/aid/version_manager.py +215 -0
  195. aiecs/scripts/dependance_check/DEPENDENCY_SYSTEM_SUMMARY.md +242 -0
  196. aiecs/scripts/dependance_check/README_DEPENDENCY_CHECKER.md +310 -0
  197. aiecs/scripts/dependance_check/__init__.py +17 -0
  198. aiecs/scripts/dependance_check/dependency_checker.py +938 -0
  199. aiecs/scripts/dependance_check/dependency_fixer.py +391 -0
  200. aiecs/scripts/dependance_check/download_nlp_data.py +396 -0
  201. aiecs/scripts/dependance_check/quick_dependency_check.py +270 -0
  202. aiecs/scripts/dependance_check/setup_nlp_data.sh +217 -0
  203. aiecs/scripts/dependance_patch/__init__.py +7 -0
  204. aiecs/scripts/dependance_patch/fix_weasel/README_WEASEL_PATCH.md +126 -0
  205. aiecs/scripts/dependance_patch/fix_weasel/__init__.py +11 -0
  206. aiecs/scripts/dependance_patch/fix_weasel/fix_weasel_validator.py +128 -0
  207. aiecs/scripts/dependance_patch/fix_weasel/fix_weasel_validator.sh +82 -0
  208. aiecs/scripts/dependance_patch/fix_weasel/patch_weasel_library.sh +188 -0
  209. aiecs/scripts/dependance_patch/fix_weasel/run_weasel_patch.sh +41 -0
  210. aiecs/scripts/tools_develop/README.md +449 -0
  211. aiecs/scripts/tools_develop/TOOL_AUTO_DISCOVERY.md +234 -0
  212. aiecs/scripts/tools_develop/__init__.py +21 -0
  213. aiecs/scripts/tools_develop/check_type_annotations.py +259 -0
  214. aiecs/scripts/tools_develop/validate_tool_schemas.py +422 -0
  215. aiecs/scripts/tools_develop/verify_tools.py +356 -0
  216. aiecs/tasks/__init__.py +1 -0
  217. aiecs/tasks/worker.py +172 -0
  218. aiecs/tools/__init__.py +299 -0
  219. aiecs/tools/apisource/__init__.py +99 -0
  220. aiecs/tools/apisource/intelligence/__init__.py +19 -0
  221. aiecs/tools/apisource/intelligence/data_fusion.py +381 -0
  222. aiecs/tools/apisource/intelligence/query_analyzer.py +413 -0
  223. aiecs/tools/apisource/intelligence/search_enhancer.py +388 -0
  224. aiecs/tools/apisource/monitoring/__init__.py +9 -0
  225. aiecs/tools/apisource/monitoring/metrics.py +303 -0
  226. aiecs/tools/apisource/providers/__init__.py +115 -0
  227. aiecs/tools/apisource/providers/base.py +664 -0
  228. aiecs/tools/apisource/providers/census.py +401 -0
  229. aiecs/tools/apisource/providers/fred.py +564 -0
  230. aiecs/tools/apisource/providers/newsapi.py +412 -0
  231. aiecs/tools/apisource/providers/worldbank.py +357 -0
  232. aiecs/tools/apisource/reliability/__init__.py +12 -0
  233. aiecs/tools/apisource/reliability/error_handler.py +375 -0
  234. aiecs/tools/apisource/reliability/fallback_strategy.py +391 -0
  235. aiecs/tools/apisource/tool.py +850 -0
  236. aiecs/tools/apisource/utils/__init__.py +9 -0
  237. aiecs/tools/apisource/utils/validators.py +338 -0
  238. aiecs/tools/base_tool.py +201 -0
  239. aiecs/tools/docs/__init__.py +121 -0
  240. aiecs/tools/docs/ai_document_orchestrator.py +599 -0
  241. aiecs/tools/docs/ai_document_writer_orchestrator.py +2403 -0
  242. aiecs/tools/docs/content_insertion_tool.py +1333 -0
  243. aiecs/tools/docs/document_creator_tool.py +1317 -0
  244. aiecs/tools/docs/document_layout_tool.py +1166 -0
  245. aiecs/tools/docs/document_parser_tool.py +994 -0
  246. aiecs/tools/docs/document_writer_tool.py +1818 -0
  247. aiecs/tools/knowledge_graph/__init__.py +17 -0
  248. aiecs/tools/knowledge_graph/graph_reasoning_tool.py +734 -0
  249. aiecs/tools/knowledge_graph/graph_search_tool.py +923 -0
  250. aiecs/tools/knowledge_graph/kg_builder_tool.py +476 -0
  251. aiecs/tools/langchain_adapter.py +542 -0
  252. aiecs/tools/schema_generator.py +275 -0
  253. aiecs/tools/search_tool/__init__.py +100 -0
  254. aiecs/tools/search_tool/analyzers.py +589 -0
  255. aiecs/tools/search_tool/cache.py +260 -0
  256. aiecs/tools/search_tool/constants.py +128 -0
  257. aiecs/tools/search_tool/context.py +216 -0
  258. aiecs/tools/search_tool/core.py +749 -0
  259. aiecs/tools/search_tool/deduplicator.py +123 -0
  260. aiecs/tools/search_tool/error_handler.py +271 -0
  261. aiecs/tools/search_tool/metrics.py +371 -0
  262. aiecs/tools/search_tool/rate_limiter.py +178 -0
  263. aiecs/tools/search_tool/schemas.py +277 -0
  264. aiecs/tools/statistics/__init__.py +80 -0
  265. aiecs/tools/statistics/ai_data_analysis_orchestrator.py +643 -0
  266. aiecs/tools/statistics/ai_insight_generator_tool.py +505 -0
  267. aiecs/tools/statistics/ai_report_orchestrator_tool.py +694 -0
  268. aiecs/tools/statistics/data_loader_tool.py +564 -0
  269. aiecs/tools/statistics/data_profiler_tool.py +658 -0
  270. aiecs/tools/statistics/data_transformer_tool.py +573 -0
  271. aiecs/tools/statistics/data_visualizer_tool.py +495 -0
  272. aiecs/tools/statistics/model_trainer_tool.py +487 -0
  273. aiecs/tools/statistics/statistical_analyzer_tool.py +459 -0
  274. aiecs/tools/task_tools/__init__.py +86 -0
  275. aiecs/tools/task_tools/chart_tool.py +732 -0
  276. aiecs/tools/task_tools/classfire_tool.py +922 -0
  277. aiecs/tools/task_tools/image_tool.py +447 -0
  278. aiecs/tools/task_tools/office_tool.py +684 -0
  279. aiecs/tools/task_tools/pandas_tool.py +635 -0
  280. aiecs/tools/task_tools/report_tool.py +635 -0
  281. aiecs/tools/task_tools/research_tool.py +392 -0
  282. aiecs/tools/task_tools/scraper_tool.py +715 -0
  283. aiecs/tools/task_tools/stats_tool.py +688 -0
  284. aiecs/tools/temp_file_manager.py +130 -0
  285. aiecs/tools/tool_executor/__init__.py +37 -0
  286. aiecs/tools/tool_executor/tool_executor.py +881 -0
  287. aiecs/utils/LLM_output_structor.py +445 -0
  288. aiecs/utils/__init__.py +34 -0
  289. aiecs/utils/base_callback.py +47 -0
  290. aiecs/utils/cache_provider.py +695 -0
  291. aiecs/utils/execution_utils.py +184 -0
  292. aiecs/utils/logging.py +1 -0
  293. aiecs/utils/prompt_loader.py +14 -0
  294. aiecs/utils/token_usage_repository.py +323 -0
  295. aiecs/ws/__init__.py +0 -0
  296. aiecs/ws/socket_server.py +52 -0
  297. aiecs-1.5.1.dist-info/METADATA +608 -0
  298. aiecs-1.5.1.dist-info/RECORD +302 -0
  299. aiecs-1.5.1.dist-info/WHEEL +5 -0
  300. aiecs-1.5.1.dist-info/entry_points.txt +10 -0
  301. aiecs-1.5.1.dist-info/licenses/LICENSE +225 -0
  302. aiecs-1.5.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,130 @@
1
+ """
2
+ Entity Domain Model
3
+
4
+ Represents a node/entity in the knowledge graph with properties and embeddings.
5
+ """
6
+
7
+ from typing import Any, Optional
8
+ from datetime import datetime
9
+ from pydantic import BaseModel, Field, field_validator
10
+ import numpy as np
11
+
12
+
13
+ class Entity(BaseModel):
14
+ """
15
+ Knowledge Graph Entity
16
+
17
+ Represents a node in the knowledge graph with:
18
+ - Unique identifier
19
+ - Entity type (e.g., "Person", "Company", "Product")
20
+ - Properties (arbitrary key-value data)
21
+ - Optional vector embedding for semantic search
22
+ - Metadata (timestamps, source info)
23
+
24
+ Example:
25
+ ```python
26
+ entity = Entity(
27
+ id="person_001",
28
+ entity_type="Person",
29
+ properties={
30
+ "name": "John Doe",
31
+ "age": 30,
32
+ "occupation": "Software Engineer"
33
+ }
34
+ )
35
+ ```
36
+ """
37
+
38
+ id: str = Field(..., description="Unique identifier for the entity")
39
+
40
+ entity_type: str = Field(..., description="Type of the entity (e.g., 'Person', 'Company')")
41
+
42
+ properties: dict[str, Any] = Field(
43
+ default_factory=dict,
44
+ description="Arbitrary properties associated with the entity",
45
+ )
46
+
47
+ embedding: Optional[list[float]] = Field(
48
+ default=None, description="Vector embedding for semantic search"
49
+ )
50
+
51
+ created_at: datetime = Field(
52
+ default_factory=datetime.utcnow,
53
+ description="Timestamp when entity was created",
54
+ )
55
+
56
+ updated_at: datetime = Field(
57
+ default_factory=datetime.utcnow,
58
+ description="Timestamp when entity was last updated",
59
+ )
60
+
61
+ source: Optional[str] = Field(
62
+ default=None,
63
+ description="Source of the entity data (e.g., document ID)",
64
+ )
65
+
66
+ class Config:
67
+ json_encoders = {datetime: lambda v: v.isoformat()}
68
+ # Allow arbitrary types for numpy arrays if needed
69
+ arbitrary_types_allowed = True
70
+
71
+ @field_validator("embedding")
72
+ @classmethod
73
+ def validate_embedding(cls, v: Optional[list[float]]) -> Optional[list[float]]:
74
+ """Validate embedding is a list of floats"""
75
+ if v is not None:
76
+ if not isinstance(v, list):
77
+ raise ValueError("Embedding must be a list of floats")
78
+ if not all(isinstance(x, (int, float)) for x in v):
79
+ raise ValueError("All embedding values must be numeric")
80
+ return v
81
+
82
+ def get_embedding_vector(self) -> Optional[np.ndarray]:
83
+ """
84
+ Get embedding as numpy array
85
+
86
+ Returns:
87
+ numpy array of embedding or None if no embedding
88
+ """
89
+ if self.embedding is None:
90
+ return None
91
+ return np.array(self.embedding, dtype=np.float32)
92
+
93
+ def set_embedding_vector(self, vector: np.ndarray) -> None:
94
+ """
95
+ Set embedding from numpy array
96
+
97
+ Args:
98
+ vector: Numpy array of embedding values
99
+ """
100
+ self.embedding = vector.tolist()
101
+
102
+ def get_property(self, key: str, default: Any = None) -> Any:
103
+ """
104
+ Get a specific property value
105
+
106
+ Args:
107
+ key: Property key
108
+ default: Default value if key not found
109
+
110
+ Returns:
111
+ Property value or default
112
+ """
113
+ return self.properties.get(key, default)
114
+
115
+ def set_property(self, key: str, value: Any) -> None:
116
+ """
117
+ Set a property value
118
+
119
+ Args:
120
+ key: Property key
121
+ value: Property value
122
+ """
123
+ self.properties[key] = value
124
+ self.updated_at = datetime.utcnow()
125
+
126
+ def __str__(self) -> str:
127
+ return f"Entity(id={self.id}, type={self.entity_type})"
128
+
129
+ def __repr__(self) -> str:
130
+ return f"Entity(id='{self.id}', entity_type='{self.entity_type}', properties={len(self.properties)} keys)"
@@ -0,0 +1,194 @@
1
+ """
2
+ Evidence Domain Models
3
+
4
+ Models for representing evidence from reasoning processes.
5
+ """
6
+
7
+ from typing import List, Optional, Dict, Any
8
+ from enum import Enum
9
+ from pydantic import BaseModel, Field
10
+ from aiecs.domain.knowledge_graph.models.entity import Entity
11
+ from aiecs.domain.knowledge_graph.models.relation import Relation
12
+ from aiecs.domain.knowledge_graph.models.path import Path
13
+
14
+
15
+ class EvidenceType(str, Enum):
16
+ """Types of evidence"""
17
+
18
+ ENTITY = "entity" # Single entity
19
+ RELATION = "relation" # Single relation
20
+ PATH = "path" # Complete path
21
+ SUBGRAPH = "subgraph" # Subgraph fragment
22
+
23
+
24
+ class Evidence(BaseModel):
25
+ """
26
+ Evidence from Reasoning
27
+
28
+ Represents a piece of evidence collected during reasoning,
29
+ with confidence scoring and provenance tracking.
30
+
31
+ Attributes:
32
+ evidence_id: Unique identifier for this evidence
33
+ evidence_type: Type of evidence (entity, relation, path, etc.)
34
+ entities: Entities involved in this evidence
35
+ relations: Relations involved in this evidence
36
+ paths: Paths involved in this evidence (for path-based evidence)
37
+ confidence: Confidence score (0-1, higher = more confident)
38
+ relevance_score: Relevance to the query (0-1)
39
+ explanation: Human-readable explanation of this evidence
40
+ source: Source of this evidence (e.g., "traversal", "vector_search")
41
+ metadata: Additional metadata
42
+
43
+ Example:
44
+ ```python
45
+ evidence = Evidence(
46
+ evidence_id="ev_001",
47
+ evidence_type=EvidenceType.PATH,
48
+ entities=[alice, bob, company],
49
+ relations=[knows_rel, works_at_rel],
50
+ paths=[path],
51
+ confidence=0.9,
52
+ relevance_score=0.85,
53
+ explanation="Alice knows Bob who works at Company X",
54
+ source="multi_hop_traversal"
55
+ )
56
+ ```
57
+ """
58
+
59
+ evidence_id: str = Field(..., description="Unique identifier for this evidence")
60
+
61
+ evidence_type: EvidenceType = Field(..., description="Type of evidence")
62
+
63
+ entities: List[Entity] = Field(
64
+ default_factory=list, description="Entities involved in this evidence"
65
+ )
66
+
67
+ relations: List[Relation] = Field(
68
+ default_factory=list, description="Relations involved in this evidence"
69
+ )
70
+
71
+ paths: List[Path] = Field(default_factory=list, description="Paths involved in this evidence")
72
+
73
+ confidence: float = Field(
74
+ default=1.0,
75
+ ge=0.0,
76
+ le=1.0,
77
+ description="Confidence score (0-1, higher = more confident)",
78
+ )
79
+
80
+ relevance_score: float = Field(
81
+ default=0.5, ge=0.0, le=1.0, description="Relevance to the query (0-1)"
82
+ )
83
+
84
+ explanation: str = Field(default="", description="Human-readable explanation of this evidence")
85
+
86
+ source: str = Field(default="", description="Source of this evidence (e.g., query step ID)")
87
+
88
+ metadata: Dict[str, Any] = Field(default_factory=dict, description="Additional metadata")
89
+
90
+ @property
91
+ def combined_score(self) -> float:
92
+ """Get combined score (confidence * relevance)"""
93
+ return self.confidence * self.relevance_score
94
+
95
+ def get_entity_ids(self) -> List[str]:
96
+ """Get list of all entity IDs in evidence"""
97
+ return [entity.id for entity in self.entities]
98
+
99
+ def __str__(self) -> str:
100
+ return (
101
+ f"Evidence(type={self.evidence_type}, "
102
+ f"score={self.combined_score:.2f}, "
103
+ f"entities={len(self.entities)})"
104
+ )
105
+
106
+
107
+ class ReasoningResult(BaseModel):
108
+ """
109
+ Result of Reasoning Process
110
+
111
+ Contains evidence collected, answer generated, and reasoning trace.
112
+
113
+ Attributes:
114
+ query: Original query that was answered
115
+ evidence: List of evidence pieces collected
116
+ answer: Generated answer (if applicable)
117
+ confidence: Overall confidence in the answer (0-1)
118
+ reasoning_trace: Human-readable trace of reasoning steps
119
+ execution_time_ms: Time taken to perform reasoning
120
+ metadata: Additional metadata
121
+
122
+ Example:
123
+ ```python
124
+ result = ReasoningResult(
125
+ query="What companies does Alice know people at?",
126
+ evidence=[ev1, ev2, ev3],
127
+ answer="Alice knows people at Company X and Company Y",
128
+ confidence=0.87,
129
+ reasoning_trace="Step 1: Find Alice\nStep 2: Find people Alice knows\n...",
130
+ execution_time_ms=125.5
131
+ )
132
+ ```
133
+ """
134
+
135
+ query: str = Field(..., description="Original query that was answered")
136
+
137
+ evidence: List[Evidence] = Field(
138
+ default_factory=list, description="List of evidence pieces collected"
139
+ )
140
+
141
+ answer: Optional[str] = Field(default=None, description="Generated answer (if applicable)")
142
+
143
+ confidence: float = Field(
144
+ default=0.0,
145
+ ge=0.0,
146
+ le=1.0,
147
+ description="Overall confidence in the answer (0-1)",
148
+ )
149
+
150
+ reasoning_trace: List[str] = Field(
151
+ default_factory=list, description="List of reasoning steps taken"
152
+ )
153
+
154
+ execution_time_ms: Optional[float] = Field(
155
+ default=None, ge=0.0, description="Time taken to perform reasoning"
156
+ )
157
+
158
+ metadata: Dict[str, Any] = Field(default_factory=dict, description="Additional metadata")
159
+
160
+ @property
161
+ def evidence_count(self) -> int:
162
+ """Get number of evidence pieces"""
163
+ return len(self.evidence)
164
+
165
+ @property
166
+ def has_answer(self) -> bool:
167
+ """Check if result has an answer"""
168
+ return self.answer is not None and len(self.answer) > 0
169
+
170
+ def get_top_evidence(self, n: int = 5) -> List[Evidence]:
171
+ """
172
+ Get top N evidence pieces by combined score
173
+
174
+ Args:
175
+ n: Number of evidence pieces to return
176
+
177
+ Returns:
178
+ Top N evidence pieces
179
+ """
180
+ sorted_evidence = sorted(self.evidence, key=lambda e: e.combined_score, reverse=True)
181
+ return sorted_evidence[:n]
182
+
183
+ def get_trace_string(self) -> str:
184
+ """Get reasoning trace as a single string"""
185
+ return "\n".join(self.reasoning_trace)
186
+
187
+ def __str__(self) -> str:
188
+ parts = [
189
+ f"ReasoningResult(evidence={self.evidence_count}",
190
+ f"confidence={self.confidence:.2f})",
191
+ ]
192
+ if self.has_answer:
193
+ parts.insert(1, f"answer={self.answer[:50]}...")
194
+ return " ".join(parts)
@@ -0,0 +1,186 @@
1
+ """
2
+ Inference Rule Domain Models
3
+
4
+ Models for representing logical inference rules.
5
+ """
6
+
7
+ from typing import List, Dict, Any
8
+ from enum import Enum
9
+ from pydantic import BaseModel, Field
10
+ from aiecs.domain.knowledge_graph.models.relation import Relation
11
+
12
+
13
+ class RuleType(str, Enum):
14
+ """Types of inference rules"""
15
+
16
+ TRANSITIVE = "transitive" # A->B, B->C => A->C
17
+ SYMMETRIC = "symmetric" # A->B => B->A
18
+ REFLEXIVE = "reflexive" # A => A->A
19
+ CUSTOM = "custom" # User-defined rule
20
+
21
+
22
+ class InferenceRule(BaseModel):
23
+ """
24
+ Inference Rule
25
+
26
+ Represents a logical rule for inferring new relations from existing ones.
27
+
28
+ Attributes:
29
+ rule_id: Unique identifier for this rule
30
+ rule_type: Type of rule (transitive, symmetric, etc.)
31
+ relation_type: Relation type this rule applies to
32
+ description: Human-readable description
33
+ enabled: Whether this rule is enabled
34
+ confidence_decay: How much confidence decreases with each inference step (0-1)
35
+ metadata: Additional metadata
36
+
37
+ Example:
38
+ ```python
39
+ rule = InferenceRule(
40
+ rule_id="rule_001",
41
+ rule_type=RuleType.TRANSITIVE,
42
+ relation_type="WORKS_FOR",
43
+ description="If A works for B and B works for C, then A works for C",
44
+ confidence_decay=0.1
45
+ )
46
+ ```
47
+ """
48
+
49
+ rule_id: str = Field(..., description="Unique identifier for this rule")
50
+
51
+ rule_type: RuleType = Field(..., description="Type of inference rule")
52
+
53
+ relation_type: str = Field(..., description="Relation type this rule applies to")
54
+
55
+ description: str = Field(default="", description="Human-readable description of the rule")
56
+
57
+ enabled: bool = Field(default=True, description="Whether this rule is enabled")
58
+
59
+ confidence_decay: float = Field(
60
+ default=0.1,
61
+ ge=0.0,
62
+ le=1.0,
63
+ description="Confidence decay per inference step (0-1)",
64
+ )
65
+
66
+ metadata: Dict[str, Any] = Field(default_factory=dict, description="Additional metadata")
67
+
68
+ def can_apply(self, relation: Relation) -> bool:
69
+ """
70
+ Check if this rule can apply to a given relation
71
+
72
+ Args:
73
+ relation: Relation to check
74
+
75
+ Returns:
76
+ True if rule can apply
77
+ """
78
+ if not self.enabled:
79
+ return False
80
+ return relation.relation_type == self.relation_type
81
+
82
+
83
+ class InferenceStep(BaseModel):
84
+ """
85
+ Single Inference Step
86
+
87
+ Represents one step in an inference chain, tracking what was inferred
88
+ and how.
89
+
90
+ Attributes:
91
+ step_id: Unique identifier for this step
92
+ inferred_relation: The relation that was inferred
93
+ source_relations: Relations used to infer this one
94
+ rule: The rule that was applied
95
+ confidence: Confidence in this inference (0-1)
96
+ explanation: Human-readable explanation
97
+
98
+ Example:
99
+ ```python
100
+ step = InferenceStep(
101
+ step_id="step_001",
102
+ inferred_relation=inferred_rel,
103
+ source_relations=[rel1, rel2],
104
+ rule=rule,
105
+ confidence=0.9,
106
+ explanation="Inferred from transitive rule"
107
+ )
108
+ ```
109
+ """
110
+
111
+ step_id: str = Field(..., description="Unique identifier for this step")
112
+
113
+ inferred_relation: Relation = Field(..., description="The relation that was inferred")
114
+
115
+ source_relations: List[Relation] = Field(..., description="Relations used to infer this one")
116
+
117
+ rule: InferenceRule = Field(..., description="The rule that was applied")
118
+
119
+ confidence: float = Field(..., ge=0.0, le=1.0, description="Confidence in this inference (0-1)")
120
+
121
+ explanation: str = Field(default="", description="Human-readable explanation of the inference")
122
+
123
+ metadata: Dict[str, Any] = Field(default_factory=dict, description="Additional metadata")
124
+
125
+
126
+ class InferenceResult(BaseModel):
127
+ """
128
+ Inference Result
129
+
130
+ Contains the results of applying inference rules.
131
+
132
+ Attributes:
133
+ inferred_relations: List of relations that were inferred
134
+ inference_steps: List of inference steps taken
135
+ total_steps: Total number of inference steps
136
+ confidence: Overall confidence in the results
137
+ explanation: Human-readable explanation
138
+
139
+ Example:
140
+ ```python
141
+ result = InferenceResult(
142
+ inferred_relations=[rel1, rel2],
143
+ inference_steps=[step1, step2],
144
+ total_steps=2,
145
+ confidence=0.85,
146
+ explanation="Inferred 2 relations using transitive rule"
147
+ )
148
+ ```
149
+ """
150
+
151
+ inferred_relations: List[Relation] = Field(
152
+ default_factory=list,
153
+ description="List of relations that were inferred",
154
+ )
155
+
156
+ inference_steps: List[InferenceStep] = Field(
157
+ default_factory=list, description="List of inference steps taken"
158
+ )
159
+
160
+ total_steps: int = Field(default=0, ge=0, description="Total number of inference steps")
161
+
162
+ confidence: float = Field(
163
+ default=1.0,
164
+ ge=0.0,
165
+ le=1.0,
166
+ description="Overall confidence in the results",
167
+ )
168
+
169
+ explanation: str = Field(default="", description="Human-readable explanation")
170
+
171
+ metadata: Dict[str, Any] = Field(default_factory=dict, description="Additional metadata")
172
+
173
+ @property
174
+ def has_results(self) -> bool:
175
+ """Check if any relations were inferred"""
176
+ return len(self.inferred_relations) > 0
177
+
178
+ def get_explanation_string(self) -> str:
179
+ """Get explanation as a single string"""
180
+ if not self.explanation:
181
+ return f"Inferred {len(self.inferred_relations)} relations in {self.total_steps} steps"
182
+ return self.explanation
183
+
184
+ def get_step_explanations(self) -> List[str]:
185
+ """Get explanations for each step"""
186
+ return [step.explanation for step in self.inference_steps]
@@ -0,0 +1,179 @@
1
+ """
2
+ Path Domain Model
3
+
4
+ Represents a path through the knowledge graph (sequence of entities and relations).
5
+ """
6
+
7
+ from typing import List, Optional
8
+ from pydantic import BaseModel, Field, field_validator
9
+ from aiecs.domain.knowledge_graph.models.entity import Entity
10
+ from aiecs.domain.knowledge_graph.models.relation import Relation
11
+
12
+
13
+ class Path(BaseModel):
14
+ """
15
+ Knowledge Graph Path
16
+
17
+ Represents a path through the knowledge graph as a sequence of entities
18
+ connected by relations. Paths are results of graph traversal operations.
19
+
20
+ Attributes:
21
+ nodes: Sequence of entities in the path
22
+ edges: Sequence of relations connecting the entities
23
+ score: Optional relevance score for the path
24
+ length: Number of hops in the path
25
+
26
+ Example:
27
+ ```python
28
+ path = Path(
29
+ nodes=[entity1, entity2, entity3],
30
+ edges=[relation1_2, relation2_3],
31
+ score=0.85
32
+ )
33
+ ```
34
+
35
+ Invariants:
36
+ - len(edges) == len(nodes) - 1 (for a valid path)
37
+ - edges[i].source_id == nodes[i].id
38
+ - edges[i].target_id == nodes[i+1].id
39
+ """
40
+
41
+ nodes: List[Entity] = Field(..., min_length=1, description="Sequence of entities in the path")
42
+
43
+ edges: List[Relation] = Field(
44
+ default_factory=list,
45
+ description="Sequence of relations connecting entities",
46
+ )
47
+
48
+ score: Optional[float] = Field(
49
+ default=None,
50
+ ge=0.0,
51
+ le=1.0,
52
+ description="Relevance score for the path (0.0-1.0)",
53
+ )
54
+
55
+ class Config:
56
+ arbitrary_types_allowed = True
57
+
58
+ @field_validator("edges")
59
+ @classmethod
60
+ def validate_path_structure(cls, v: List[Relation], info) -> List[Relation]:
61
+ """Validate that edges match nodes structure"""
62
+ nodes = info.data.get("nodes", [])
63
+ if not nodes:
64
+ return v
65
+
66
+ # Check edge count
67
+ if len(v) != len(nodes) - 1:
68
+ if len(v) > 0: # Only raise error if edges are provided
69
+ raise ValueError(
70
+ f"Number of edges ({len(v)}) must be len(nodes) - 1 ({len(nodes) - 1})"
71
+ )
72
+
73
+ # Validate edge connectivity (if we have edges)
74
+ for i, edge in enumerate(v):
75
+ if i < len(nodes) - 1:
76
+ expected_source = nodes[i].id
77
+ expected_target = nodes[i + 1].id
78
+
79
+ if edge.source_id != expected_source:
80
+ raise ValueError(
81
+ f"Edge {i} source_id ({edge.source_id}) doesn't match "
82
+ f"node {i} id ({expected_source})"
83
+ )
84
+
85
+ if edge.target_id != expected_target:
86
+ raise ValueError(
87
+ f"Edge {i} target_id ({edge.target_id}) doesn't match "
88
+ f"node {i+1} id ({expected_target})"
89
+ )
90
+
91
+ return v
92
+
93
+ @property
94
+ def length(self) -> int:
95
+ """
96
+ Get path length (number of hops)
97
+
98
+ Returns:
99
+ Number of edges in the path
100
+ """
101
+ return len(self.edges)
102
+
103
+ @property
104
+ def start_entity(self) -> Entity:
105
+ """
106
+ Get the starting entity of the path
107
+
108
+ Returns:
109
+ First entity in the path
110
+ """
111
+ return self.nodes[0]
112
+
113
+ @property
114
+ def end_entity(self) -> Entity:
115
+ """
116
+ Get the ending entity of the path
117
+
118
+ Returns:
119
+ Last entity in the path
120
+ """
121
+ return self.nodes[-1]
122
+
123
+ def get_entity_ids(self) -> List[str]:
124
+ """
125
+ Get list of entity IDs in the path
126
+
127
+ Returns:
128
+ List of entity IDs
129
+ """
130
+ return [node.id for node in self.nodes]
131
+
132
+ def get_relation_types(self) -> List[str]:
133
+ """
134
+ Get list of relation types in the path
135
+
136
+ Returns:
137
+ List of relation types
138
+ """
139
+ return [edge.relation_type for edge in self.edges]
140
+
141
+ def contains_entity(self, entity_id: str) -> bool:
142
+ """
143
+ Check if path contains a specific entity
144
+
145
+ Args:
146
+ entity_id: Entity ID to check
147
+
148
+ Returns:
149
+ True if entity is in the path
150
+ """
151
+ return entity_id in self.get_entity_ids()
152
+
153
+ def contains_relation_type(self, relation_type: str) -> bool:
154
+ """
155
+ Check if path contains a specific relation type
156
+
157
+ Args:
158
+ relation_type: Relation type to check
159
+
160
+ Returns:
161
+ True if relation type is in the path
162
+ """
163
+ return relation_type in self.get_relation_types()
164
+
165
+ def __str__(self) -> str:
166
+ if not self.edges:
167
+ return f"Path({self.nodes[0]})"
168
+
169
+ path_str = str(self.nodes[0].id)
170
+ for edge, node in zip(self.edges, self.nodes[1:]):
171
+ path_str += f" -[{edge.relation_type}]-> {node.id}"
172
+
173
+ if self.score is not None:
174
+ path_str += f" (score={self.score:.3f})"
175
+
176
+ return f"Path({path_str})"
177
+
178
+ def __repr__(self) -> str:
179
+ return f"Path(length={self.length}, nodes={len(self.nodes)}, score={self.score})"