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,603 @@
1
+ """
2
+ Shared Context Manager
3
+
4
+ Manages shared memory and context for agents in a community,
5
+ with support for versioning, conflict resolution, and real-time streaming.
6
+ """
7
+
8
+ import logging
9
+ import asyncio
10
+ from datetime import datetime
11
+ from typing import Dict, List, Any, Optional, Set, Callable
12
+ from enum import Enum
13
+ from collections import defaultdict
14
+ import uuid
15
+ import copy
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+
20
+ class ContextScope(str, Enum):
21
+ """Scope levels for shared context."""
22
+
23
+ COMMUNITY = "community"
24
+ SESSION = "session"
25
+ TASK = "task"
26
+ AGENT = "agent"
27
+
28
+
29
+ class ConflictResolutionStrategy(str, Enum):
30
+ """Strategies for resolving context conflicts."""
31
+
32
+ LAST_WRITE_WINS = "last_write_wins"
33
+ FIRST_WRITE_WINS = "first_write_wins"
34
+ MERGE = "merge"
35
+ MANUAL = "manual"
36
+ TIMESTAMP_BASED = "timestamp_based"
37
+
38
+
39
+ class ContextVersion:
40
+ """Represents a version of context data."""
41
+
42
+ def __init__(
43
+ self,
44
+ context_id: str,
45
+ data: Dict[str, Any],
46
+ version_number: int,
47
+ author_id: str,
48
+ parent_version: Optional[int] = None,
49
+ ):
50
+ """
51
+ Initialize a context version.
52
+
53
+ Args:
54
+ context_id: ID of the context
55
+ data: Context data
56
+ version_number: Version number
57
+ author_id: ID of the author who created this version
58
+ parent_version: Optional parent version number
59
+ """
60
+ self.context_id = context_id
61
+ self.data = copy.deepcopy(data)
62
+ self.version_number = version_number
63
+ self.author_id = author_id
64
+ self.parent_version = parent_version
65
+ self.timestamp = datetime.utcnow()
66
+ self.metadata: Dict[str, Any] = {}
67
+
68
+
69
+ class SharedContext:
70
+ """Represents a shared context in the community."""
71
+
72
+ def __init__(
73
+ self,
74
+ context_id: str,
75
+ scope: ContextScope,
76
+ owner_id: str,
77
+ initial_data: Optional[Dict[str, Any]] = None,
78
+ ):
79
+ """
80
+ Initialize a shared context.
81
+
82
+ Args:
83
+ context_id: Unique context identifier
84
+ scope: Scope level of the context
85
+ owner_id: ID of the context owner
86
+ initial_data: Optional initial data
87
+ """
88
+ self.context_id = context_id
89
+ self.scope = scope
90
+ self.owner_id = owner_id
91
+ self.current_version = 0
92
+ self.versions: List[ContextVersion] = []
93
+ self.data = initial_data or {}
94
+ self.access_control: Set[str] = {owner_id} # IDs with access
95
+ self.subscribers: Set[str] = set() # IDs subscribed to updates
96
+ self.created_at = datetime.utcnow()
97
+ self.updated_at = datetime.utcnow()
98
+ self.metadata: Dict[str, Any] = {}
99
+
100
+ # Create initial version
101
+ if initial_data:
102
+ self._create_version(initial_data, owner_id)
103
+
104
+ def _create_version(self, data: Dict[str, Any], author_id: str) -> ContextVersion:
105
+ """Create a new version of the context."""
106
+ version = ContextVersion(
107
+ self.context_id,
108
+ data,
109
+ self.current_version + 1,
110
+ author_id,
111
+ self.current_version if self.current_version > 0 else None,
112
+ )
113
+ self.versions.append(version)
114
+ self.current_version = version.version_number
115
+ self.data = copy.deepcopy(data)
116
+ self.updated_at = datetime.utcnow()
117
+ return version
118
+
119
+
120
+ class SharedContextManager:
121
+ """
122
+ Manager for shared contexts in agent communities.
123
+ Provides versioning, conflict resolution, and streaming capabilities.
124
+ """
125
+
126
+ def __init__(
127
+ self,
128
+ default_conflict_strategy: ConflictResolutionStrategy = ConflictResolutionStrategy.LAST_WRITE_WINS,
129
+ ):
130
+ """
131
+ Initialize the shared context manager.
132
+
133
+ Args:
134
+ default_conflict_strategy: Default strategy for conflict resolution
135
+ """
136
+ self.contexts: Dict[str, SharedContext] = {}
137
+ self.default_conflict_strategy = default_conflict_strategy
138
+
139
+ # Scope-based indexes
140
+ self.community_contexts: Dict[str, Set[str]] = defaultdict(set)
141
+ self.session_contexts: Dict[str, Set[str]] = defaultdict(set)
142
+ self.task_contexts: Dict[str, Set[str]] = defaultdict(set)
143
+ self.agent_contexts: Dict[str, Set[str]] = defaultdict(set)
144
+
145
+ # Update callbacks for streaming
146
+ self.update_callbacks: Dict[str, List[Callable]] = defaultdict(list)
147
+
148
+ logger.info("Shared context manager initialized")
149
+
150
+ async def create_context(
151
+ self,
152
+ scope: ContextScope,
153
+ owner_id: str,
154
+ scope_id: str,
155
+ initial_data: Optional[Dict[str, Any]] = None,
156
+ access_control: Optional[Set[str]] = None,
157
+ ) -> str:
158
+ """
159
+ Create a new shared context.
160
+
161
+ Args:
162
+ scope: Scope level of the context
163
+ owner_id: ID of the context owner
164
+ scope_id: ID of the scope (community_id, session_id, task_id, or agent_id)
165
+ initial_data: Optional initial data
166
+ access_control: Optional set of agent IDs with access
167
+
168
+ Returns:
169
+ Context ID
170
+ """
171
+ context_id = str(uuid.uuid4())
172
+ context = SharedContext(context_id, scope, owner_id, initial_data)
173
+
174
+ if access_control:
175
+ context.access_control = access_control
176
+
177
+ self.contexts[context_id] = context
178
+
179
+ # Add to scope index
180
+ if scope == ContextScope.COMMUNITY:
181
+ self.community_contexts[scope_id].add(context_id)
182
+ elif scope == ContextScope.SESSION:
183
+ self.session_contexts[scope_id].add(context_id)
184
+ elif scope == ContextScope.TASK:
185
+ self.task_contexts[scope_id].add(context_id)
186
+ elif scope == ContextScope.AGENT:
187
+ self.agent_contexts[scope_id].add(context_id)
188
+
189
+ logger.info(f"Created {scope.value} context {context_id}")
190
+ return context_id
191
+
192
+ async def get_context(
193
+ self, context_id: str, requester_id: str, version: Optional[int] = None
194
+ ) -> Optional[Dict[str, Any]]:
195
+ """
196
+ Get context data.
197
+
198
+ Args:
199
+ context_id: ID of the context
200
+ requester_id: ID of the requester
201
+ version: Optional specific version to retrieve
202
+
203
+ Returns:
204
+ Context data or None if not found/unauthorized
205
+ """
206
+ context = self.contexts.get(context_id)
207
+ if not context:
208
+ return None
209
+
210
+ # Check access control
211
+ if requester_id not in context.access_control:
212
+ logger.warning(f"Access denied for {requester_id} to context {context_id}")
213
+ return None
214
+
215
+ # Return specific version or current
216
+ if version is not None:
217
+ for v in context.versions:
218
+ if v.version_number == version:
219
+ return copy.deepcopy(v.data)
220
+ return None
221
+
222
+ return copy.deepcopy(context.data)
223
+
224
+ async def update_context(
225
+ self,
226
+ context_id: str,
227
+ updater_id: str,
228
+ updates: Dict[str, Any],
229
+ conflict_strategy: Optional[ConflictResolutionStrategy] = None,
230
+ create_version: bool = True,
231
+ ) -> bool:
232
+ """
233
+ Update context data with conflict resolution.
234
+
235
+ Args:
236
+ context_id: ID of the context
237
+ updater_id: ID of the updater
238
+ updates: Data updates
239
+ conflict_strategy: Optional conflict resolution strategy
240
+ create_version: Whether to create a new version
241
+
242
+ Returns:
243
+ True if update was successful
244
+ """
245
+ context = self.contexts.get(context_id)
246
+ if not context:
247
+ logger.error(f"Context {context_id} not found")
248
+ return False
249
+
250
+ # Check access control
251
+ if updater_id not in context.access_control:
252
+ logger.warning(f"Access denied for {updater_id} to update context {context_id}")
253
+ return False
254
+
255
+ # Apply updates with conflict resolution
256
+ strategy = conflict_strategy or self.default_conflict_strategy
257
+ merged_data = await self._resolve_conflicts(
258
+ context.data, updates, strategy, context, updater_id
259
+ )
260
+
261
+ # Create new version if requested
262
+ if create_version:
263
+ context._create_version(merged_data, updater_id)
264
+ else:
265
+ context.data = merged_data
266
+ context.updated_at = datetime.utcnow()
267
+
268
+ # Notify subscribers via streaming
269
+ await self._notify_subscribers(context_id, merged_data, updater_id)
270
+
271
+ logger.debug(f"Updated context {context_id} by {updater_id}")
272
+ return True
273
+
274
+ async def _resolve_conflicts(
275
+ self,
276
+ current_data: Dict[str, Any],
277
+ updates: Dict[str, Any],
278
+ strategy: ConflictResolutionStrategy,
279
+ context: SharedContext,
280
+ updater_id: str,
281
+ ) -> Dict[str, Any]:
282
+ """Resolve conflicts between current data and updates."""
283
+ if strategy == ConflictResolutionStrategy.LAST_WRITE_WINS:
284
+ # Simply apply updates over current data
285
+ merged = copy.deepcopy(current_data)
286
+ merged.update(updates)
287
+ return merged
288
+
289
+ elif strategy == ConflictResolutionStrategy.FIRST_WRITE_WINS:
290
+ # Only add new keys, don't override existing
291
+ merged = copy.deepcopy(current_data)
292
+ for key, value in updates.items():
293
+ if key not in merged:
294
+ merged[key] = value
295
+ return merged
296
+
297
+ elif strategy == ConflictResolutionStrategy.MERGE:
298
+ # Intelligent merge based on data types
299
+ merged = copy.deepcopy(current_data)
300
+ for key, new_value in updates.items():
301
+ if key in merged:
302
+ current_value = merged[key]
303
+ # Merge lists
304
+ if isinstance(current_value, list) and isinstance(new_value, list):
305
+ merged[key] = current_value + [
306
+ item for item in new_value if item not in current_value
307
+ ]
308
+ # Merge dicts
309
+ elif isinstance(current_value, dict) and isinstance(new_value, dict):
310
+ merged[key] = {**current_value, **new_value}
311
+ # Otherwise, last write wins
312
+ else:
313
+ merged[key] = new_value
314
+ else:
315
+ merged[key] = new_value
316
+ return merged
317
+
318
+ elif strategy == ConflictResolutionStrategy.TIMESTAMP_BASED:
319
+ # Use timestamps to determine which update wins
320
+ merged = copy.deepcopy(current_data)
321
+ current_time = datetime.utcnow()
322
+ for key, value in updates.items():
323
+ if key not in merged or context.updated_at < current_time:
324
+ merged[key] = value
325
+ return merged
326
+
327
+ else: # MANUAL
328
+ # Return updates as-is and log conflict for manual resolution
329
+ logger.warning(f"Manual conflict resolution required for context {context.context_id}")
330
+ return copy.deepcopy(updates)
331
+
332
+ async def subscribe_to_context(
333
+ self,
334
+ context_id: str,
335
+ subscriber_id: str,
336
+ callback: Optional[Callable] = None,
337
+ ) -> bool:
338
+ """
339
+ Subscribe to context updates (streaming).
340
+
341
+ Args:
342
+ context_id: ID of the context
343
+ subscriber_id: ID of the subscriber
344
+ callback: Optional callback for updates
345
+
346
+ Returns:
347
+ True if subscription was successful
348
+ """
349
+ context = self.contexts.get(context_id)
350
+ if not context:
351
+ return False
352
+
353
+ # Check access control
354
+ if subscriber_id not in context.access_control:
355
+ logger.warning(
356
+ f"Access denied for {subscriber_id} to subscribe to context {context_id}"
357
+ )
358
+ return False
359
+
360
+ context.subscribers.add(subscriber_id)
361
+
362
+ if callback:
363
+ self.update_callbacks[context_id].append(callback)
364
+
365
+ logger.debug(f"Agent {subscriber_id} subscribed to context {context_id}")
366
+ return True
367
+
368
+ async def unsubscribe_from_context(
369
+ self,
370
+ context_id: str,
371
+ subscriber_id: str,
372
+ callback: Optional[Callable] = None,
373
+ ) -> bool:
374
+ """
375
+ Unsubscribe from context updates.
376
+
377
+ Args:
378
+ context_id: ID of the context
379
+ subscriber_id: ID of the subscriber
380
+ callback: Optional callback to remove
381
+
382
+ Returns:
383
+ True if unsubscription was successful
384
+ """
385
+ context = self.contexts.get(context_id)
386
+ if not context:
387
+ return False
388
+
389
+ context.subscribers.discard(subscriber_id)
390
+
391
+ if callback and context_id in self.update_callbacks:
392
+ if callback in self.update_callbacks[context_id]:
393
+ self.update_callbacks[context_id].remove(callback)
394
+
395
+ logger.debug(f"Agent {subscriber_id} unsubscribed from context {context_id}")
396
+ return True
397
+
398
+ async def _notify_subscribers(
399
+ self, context_id: str, updated_data: Dict[str, Any], updater_id: str
400
+ ) -> None:
401
+ """Notify subscribers of context updates."""
402
+ context = self.contexts.get(context_id)
403
+ if not context:
404
+ return
405
+
406
+ update_notification = {
407
+ "context_id": context_id,
408
+ "updater_id": updater_id,
409
+ "data": copy.deepcopy(updated_data),
410
+ "version": context.current_version,
411
+ "timestamp": datetime.utcnow().isoformat(),
412
+ }
413
+
414
+ # Execute callbacks
415
+ if context_id in self.update_callbacks:
416
+ for callback in self.update_callbacks[context_id]:
417
+ try:
418
+ if asyncio.iscoroutinefunction(callback):
419
+ await callback(update_notification)
420
+ else:
421
+ callback(update_notification)
422
+ except Exception as e:
423
+ logger.error(f"Error executing context update callback: {e}")
424
+
425
+ async def grant_access(self, context_id: str, granter_id: str, grantee_id: str) -> bool:
426
+ """
427
+ Grant access to a context.
428
+
429
+ Args:
430
+ context_id: ID of the context
431
+ granter_id: ID of the agent granting access (must be owner)
432
+ grantee_id: ID of the agent being granted access
433
+
434
+ Returns:
435
+ True if access was granted
436
+ """
437
+ context = self.contexts.get(context_id)
438
+ if not context:
439
+ return False
440
+
441
+ # Only owner can grant access
442
+ if granter_id != context.owner_id:
443
+ logger.warning(f"Only owner can grant access to context {context_id}")
444
+ return False
445
+
446
+ context.access_control.add(grantee_id)
447
+ logger.info(f"Granted access to {grantee_id} for context {context_id}")
448
+ return True
449
+
450
+ async def revoke_access(self, context_id: str, revoker_id: str, revokee_id: str) -> bool:
451
+ """
452
+ Revoke access to a context.
453
+
454
+ Args:
455
+ context_id: ID of the context
456
+ revoker_id: ID of the agent revoking access (must be owner)
457
+ revokee_id: ID of the agent losing access
458
+
459
+ Returns:
460
+ True if access was revoked
461
+ """
462
+ context = self.contexts.get(context_id)
463
+ if not context:
464
+ return False
465
+
466
+ # Only owner can revoke access
467
+ if revoker_id != context.owner_id:
468
+ logger.warning(f"Only owner can revoke access to context {context_id}")
469
+ return False
470
+
471
+ # Can't revoke owner's access
472
+ if revokee_id == context.owner_id:
473
+ logger.warning("Cannot revoke owner's access to context")
474
+ return False
475
+
476
+ context.access_control.discard(revokee_id)
477
+ context.subscribers.discard(revokee_id)
478
+ logger.info(f"Revoked access from {revokee_id} for context {context_id}")
479
+ return True
480
+
481
+ async def get_version_history(
482
+ self, context_id: str, requester_id: str
483
+ ) -> Optional[List[Dict[str, Any]]]:
484
+ """
485
+ Get version history for a context.
486
+
487
+ Args:
488
+ context_id: ID of the context
489
+ requester_id: ID of the requester
490
+
491
+ Returns:
492
+ List of version information or None if unauthorized
493
+ """
494
+ context = self.contexts.get(context_id)
495
+ if not context:
496
+ return None
497
+
498
+ # Check access control
499
+ if requester_id not in context.access_control:
500
+ return None
501
+
502
+ history = []
503
+ for version in context.versions:
504
+ history.append(
505
+ {
506
+ "version_number": version.version_number,
507
+ "author_id": version.author_id,
508
+ "timestamp": version.timestamp.isoformat(),
509
+ "parent_version": version.parent_version,
510
+ "metadata": version.metadata,
511
+ }
512
+ )
513
+
514
+ return history
515
+
516
+ async def rollback_to_version(
517
+ self, context_id: str, requester_id: str, target_version: int
518
+ ) -> bool:
519
+ """
520
+ Rollback context to a previous version.
521
+
522
+ Args:
523
+ context_id: ID of the context
524
+ requester_id: ID of the requester (must be owner)
525
+ target_version: Version number to rollback to
526
+
527
+ Returns:
528
+ True if rollback was successful
529
+ """
530
+ context = self.contexts.get(context_id)
531
+ if not context:
532
+ return False
533
+
534
+ # Only owner can rollback
535
+ if requester_id != context.owner_id:
536
+ logger.warning(f"Only owner can rollback context {context_id}")
537
+ return False
538
+
539
+ # Find target version
540
+ target = None
541
+ for version in context.versions:
542
+ if version.version_number == target_version:
543
+ target = version
544
+ break
545
+
546
+ if not target:
547
+ logger.error(f"Version {target_version} not found for context {context_id}")
548
+ return False
549
+
550
+ # Create new version based on target (rollback is a new version)
551
+ context._create_version(target.data, requester_id)
552
+ context.metadata["rollback"] = {
553
+ "from_version": context.current_version - 1,
554
+ "to_version": target_version,
555
+ "timestamp": datetime.utcnow().isoformat(),
556
+ }
557
+
558
+ # Notify subscribers
559
+ await self._notify_subscribers(context_id, context.data, requester_id)
560
+
561
+ logger.info(f"Rolled back context {context_id} to version {target_version}")
562
+ return True
563
+
564
+ def get_contexts_by_scope(self, scope: ContextScope, scope_id: str) -> List[str]:
565
+ """
566
+ Get all contexts for a specific scope.
567
+
568
+ Args:
569
+ scope: Scope level
570
+ scope_id: ID of the scope
571
+
572
+ Returns:
573
+ List of context IDs
574
+ """
575
+ if scope == ContextScope.COMMUNITY:
576
+ return list(self.community_contexts.get(scope_id, set()))
577
+ elif scope == ContextScope.SESSION:
578
+ return list(self.session_contexts.get(scope_id, set()))
579
+ elif scope == ContextScope.TASK:
580
+ return list(self.task_contexts.get(scope_id, set()))
581
+ elif scope == ContextScope.AGENT:
582
+ return list(self.agent_contexts.get(scope_id, set()))
583
+ return []
584
+
585
+ def get_statistics(self) -> Dict[str, Any]:
586
+ """
587
+ Get context manager statistics.
588
+
589
+ Returns:
590
+ Statistics dictionary
591
+ """
592
+ total_versions = sum(len(ctx.versions) for ctx in self.contexts.values())
593
+ total_subscribers = sum(len(ctx.subscribers) for ctx in self.contexts.values())
594
+
595
+ return {
596
+ "total_contexts": len(self.contexts),
597
+ "total_versions": total_versions,
598
+ "total_subscribers": total_subscribers,
599
+ "community_contexts": sum(len(s) for s in self.community_contexts.values()),
600
+ "session_contexts": sum(len(s) for s in self.session_contexts.values()),
601
+ "task_contexts": sum(len(s) for s in self.task_contexts.values()),
602
+ "agent_contexts": sum(len(s) for s in self.agent_contexts.values()),
603
+ }
@@ -0,0 +1,58 @@
1
+ """
2
+ Context Management Domain
3
+
4
+ This module provides advanced context and session management capabilities
5
+ for the Python middleware application.
6
+
7
+ Components:
8
+ - ContextEngine: Advanced context and session management with Redis backend
9
+ - Integration with TaskContext for enhanced functionality
10
+ - Support for BaseServiceCheckpointer and LangGraph workflows
11
+
12
+ Usage:
13
+ # For creating ContextEngine instances directly:
14
+ from aiecs.domain.context import ContextEngine
15
+ engine = ContextEngine(use_existing_redis=True)
16
+ await engine.initialize()
17
+
18
+ # For using the global singleton instance (recommended):
19
+ from aiecs.infrastructure.persistence import (
20
+ get_context_engine,
21
+ initialize_context_engine,
22
+ close_context_engine
23
+ )
24
+
25
+ # The global instance is automatically initialized in main.py lifespan
26
+ context_engine = get_context_engine()
27
+ if context_engine:
28
+ await context_engine.add_conversation_message(...)
29
+
30
+ Architecture Note:
31
+ - This package contains DOMAIN layer classes (business logic)
32
+ - Global instance management is in INFRASTRUCTURE layer:
33
+ aiecs.infrastructure.persistence.context_engine_client
34
+ - This separation follows Clean Architecture / DDD principles
35
+ """
36
+
37
+ from .context_engine import ContextEngine, SessionMetrics, ConversationMessage
38
+ from .conversation_models import (
39
+ ConversationParticipant,
40
+ ConversationSession,
41
+ AgentCommunicationMessage,
42
+ create_session_key,
43
+ validate_conversation_isolation_pattern,
44
+ )
45
+ from .graph_memory import GraphMemoryMixin, ContextEngineWithGraph
46
+
47
+ __all__ = [
48
+ "ContextEngine",
49
+ "SessionMetrics",
50
+ "ConversationMessage",
51
+ "ConversationParticipant",
52
+ "ConversationSession",
53
+ "AgentCommunicationMessage",
54
+ "create_session_key",
55
+ "validate_conversation_isolation_pattern",
56
+ "GraphMemoryMixin",
57
+ "ContextEngineWithGraph",
58
+ ]