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,296 @@
1
+ """
2
+ Agent Lifecycle Management
3
+
4
+ Manages agent lifecycle transitions and state management.
5
+ """
6
+
7
+ import logging
8
+ from typing import Dict, Any, Optional, List
9
+
10
+ from .base_agent import BaseAIAgent
11
+ from .models import AgentState
12
+ from .registry import AgentRegistry, get_global_registry
13
+ from .exceptions import (
14
+ AgentInitializationError,
15
+ )
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+
20
+ class AgentLifecycleManager:
21
+ """
22
+ Manages agent lifecycle: creation, initialization, activation, deactivation, shutdown.
23
+
24
+ Ensures proper state transitions and coordinates with registry.
25
+ """
26
+
27
+ def __init__(self, registry: Optional[AgentRegistry] = None):
28
+ """
29
+ Initialize lifecycle manager.
30
+
31
+ Args:
32
+ registry: Optional custom registry (uses global if not provided)
33
+ """
34
+ self.registry = registry or get_global_registry()
35
+ logger.info("AgentLifecycleManager initialized")
36
+
37
+ async def create_and_initialize(self, agent: BaseAIAgent) -> BaseAIAgent:
38
+ """
39
+ Register and initialize an agent.
40
+
41
+ Args:
42
+ agent: Agent to initialize
43
+
44
+ Returns:
45
+ Initialized agent
46
+
47
+ Raises:
48
+ AgentInitializationError: If initialization fails
49
+ """
50
+ try:
51
+ # Register agent
52
+ self.registry.register(agent)
53
+ logger.info(f"Agent {agent.agent_id} registered")
54
+
55
+ # Initialize agent
56
+ await agent.initialize()
57
+ logger.info(f"Agent {agent.agent_id} initialized")
58
+
59
+ return agent
60
+
61
+ except Exception as e:
62
+ logger.error(f"Failed to create and initialize agent {agent.agent_id}: {e}")
63
+
64
+ # Cleanup on failure
65
+ try:
66
+ if self.registry.exists(agent.agent_id):
67
+ self.registry.unregister(agent.agent_id)
68
+ except Exception as cleanup_error:
69
+ logger.error(f"Cleanup failed: {cleanup_error}")
70
+
71
+ raise AgentInitializationError(
72
+ f"Agent initialization failed: {str(e)}",
73
+ agent_id=agent.agent_id,
74
+ )
75
+
76
+ async def activate(self, agent_id: str) -> None:
77
+ """
78
+ Activate an agent.
79
+
80
+ Args:
81
+ agent_id: Agent identifier
82
+
83
+ Raises:
84
+ AgentNotFoundError: If agent not found
85
+ InvalidStateTransitionError: If activation not allowed
86
+ """
87
+ agent = self.registry.get(agent_id)
88
+
89
+ try:
90
+ await agent.activate()
91
+ logger.info(f"Agent {agent_id} activated")
92
+ except Exception as e:
93
+ logger.error(f"Failed to activate agent {agent_id}: {e}")
94
+ raise
95
+
96
+ async def deactivate(self, agent_id: str) -> None:
97
+ """
98
+ Deactivate an agent.
99
+
100
+ Args:
101
+ agent_id: Agent identifier
102
+
103
+ Raises:
104
+ AgentNotFoundError: If agent not found
105
+ InvalidStateTransitionError: If deactivation not allowed
106
+ """
107
+ agent = self.registry.get(agent_id)
108
+
109
+ try:
110
+ await agent.deactivate()
111
+ logger.info(f"Agent {agent_id} deactivated")
112
+ except Exception as e:
113
+ logger.error(f"Failed to deactivate agent {agent_id}: {e}")
114
+ raise
115
+
116
+ async def shutdown(self, agent_id: str, unregister: bool = True) -> None:
117
+ """
118
+ Shutdown an agent.
119
+
120
+ Args:
121
+ agent_id: Agent identifier
122
+ unregister: Whether to unregister after shutdown
123
+
124
+ Raises:
125
+ AgentNotFoundError: If agent not found
126
+ """
127
+ agent = self.registry.get(agent_id)
128
+
129
+ try:
130
+ await agent.shutdown()
131
+ logger.info(f"Agent {agent_id} shut down")
132
+
133
+ if unregister:
134
+ self.registry.unregister(agent_id)
135
+ logger.info(f"Agent {agent_id} unregistered")
136
+
137
+ except Exception as e:
138
+ logger.error(f"Failed to shutdown agent {agent_id}: {e}")
139
+ raise
140
+
141
+ async def restart(self, agent_id: str) -> None:
142
+ """
143
+ Restart an agent (deactivate → initialize → activate).
144
+
145
+ Args:
146
+ agent_id: Agent identifier
147
+
148
+ Raises:
149
+ AgentNotFoundError: If agent not found
150
+ """
151
+ agent = self.registry.get(agent_id)
152
+
153
+ try:
154
+ # Deactivate
155
+ if agent.state in [AgentState.ACTIVE, AgentState.BUSY]:
156
+ await agent.deactivate()
157
+
158
+ # Re-initialize
159
+ await agent.initialize()
160
+
161
+ # Re-activate
162
+ await agent.activate()
163
+
164
+ logger.info(f"Agent {agent_id} restarted")
165
+
166
+ except Exception as e:
167
+ logger.error(f"Failed to restart agent {agent_id}: {e}")
168
+ raise
169
+
170
+ async def shutdown_all(self) -> Dict[str, Any]:
171
+ """
172
+ Shutdown all registered agents.
173
+
174
+ Returns:
175
+ Dictionary with shutdown results
176
+ """
177
+ results = {
178
+ "success": [],
179
+ "failed": [],
180
+ "total": self.registry.count(),
181
+ }
182
+
183
+ agents = self.registry.list_all()
184
+
185
+ for agent in agents:
186
+ try:
187
+ await self.shutdown(agent.agent_id, unregister=True)
188
+ results["success"].append(agent.agent_id)
189
+ except Exception as e:
190
+ logger.error(f"Failed to shutdown agent {agent.agent_id}: {e}")
191
+ results["failed"].append(
192
+ {
193
+ "agent_id": agent.agent_id,
194
+ "error": str(e),
195
+ }
196
+ )
197
+
198
+ logger.info(
199
+ f"Shutdown all agents: {len(results['success'])} succeeded, "
200
+ f"{len(results['failed'])} failed"
201
+ )
202
+
203
+ return results
204
+
205
+ def get_agent_status(self, agent_id: str) -> Dict[str, Any]:
206
+ """
207
+ Get agent status information.
208
+
209
+ Args:
210
+ agent_id: Agent identifier
211
+
212
+ Returns:
213
+ Status dictionary
214
+
215
+ Raises:
216
+ AgentNotFoundError: If agent not found
217
+ """
218
+ agent = self.registry.get(agent_id)
219
+
220
+ return {
221
+ "agent_id": agent.agent_id,
222
+ "name": agent.name,
223
+ "type": agent.agent_type.value,
224
+ "state": agent.state.value,
225
+ "version": agent.version,
226
+ "created_at": (agent.created_at.isoformat() if agent.created_at else None),
227
+ "last_active_at": (agent.last_active_at.isoformat() if agent.last_active_at else None),
228
+ "current_task_id": agent._current_task_id,
229
+ "metrics": {
230
+ "total_tasks_executed": agent.get_metrics().total_tasks_executed,
231
+ "successful_tasks": agent.get_metrics().successful_tasks,
232
+ "failed_tasks": agent.get_metrics().failed_tasks,
233
+ "average_execution_time": agent.get_metrics().average_execution_time,
234
+ "total_tool_calls": agent.get_metrics().total_tool_calls,
235
+ },
236
+ }
237
+
238
+ def list_agent_statuses(
239
+ self, agent_type: Optional[str] = None, state: Optional[str] = None
240
+ ) -> "List[Dict[str, Any]]":
241
+ """
242
+ List agent statuses with optional filtering.
243
+
244
+ Args:
245
+ agent_type: Optional filter by agent type
246
+ state: Optional filter by state
247
+
248
+ Returns:
249
+ List of status dictionaries
250
+ """
251
+ agents = self.registry.list_all()
252
+
253
+ # Filter by type
254
+ if agent_type:
255
+ from .models import AgentType
256
+
257
+ try:
258
+ type_enum = AgentType(agent_type)
259
+ agents = [a for a in agents if a.agent_type == type_enum]
260
+ except ValueError:
261
+ logger.warning(f"Invalid agent type: {agent_type}")
262
+
263
+ # Filter by state
264
+ if state:
265
+ from .models import AgentState
266
+
267
+ try:
268
+ state_enum = AgentState(state)
269
+ agents = [a for a in agents if a.state == state_enum]
270
+ except ValueError:
271
+ logger.warning(f"Invalid state: {state}")
272
+
273
+ return [self.get_agent_status(a.agent_id) for a in agents]
274
+
275
+
276
+ # Global lifecycle manager
277
+ _global_lifecycle_manager: Optional[AgentLifecycleManager] = None
278
+
279
+
280
+ def get_global_lifecycle_manager() -> AgentLifecycleManager:
281
+ """
282
+ Get or create global lifecycle manager.
283
+
284
+ Returns:
285
+ Global AgentLifecycleManager instance
286
+ """
287
+ global _global_lifecycle_manager
288
+ if _global_lifecycle_manager is None:
289
+ _global_lifecycle_manager = AgentLifecycleManager()
290
+ return _global_lifecycle_manager
291
+
292
+
293
+ def reset_global_lifecycle_manager() -> None:
294
+ """Reset global lifecycle manager (primarily for testing)."""
295
+ global _global_lifecycle_manager
296
+ _global_lifecycle_manager = None
@@ -0,0 +1,300 @@
1
+ """
2
+ LLM Agent
3
+
4
+ Agent implementation powered by LLM for text generation and reasoning.
5
+ """
6
+
7
+ import logging
8
+ from typing import Dict, List, Any, Optional
9
+ from datetime import datetime
10
+
11
+ from aiecs.llm import BaseLLMClient, LLMMessage
12
+
13
+ from .base_agent import BaseAIAgent
14
+ from .models import AgentType, AgentConfiguration
15
+ from .exceptions import TaskExecutionError
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+
20
+ class LLMAgent(BaseAIAgent):
21
+ """
22
+ LLM-powered agent for text generation and reasoning.
23
+
24
+ This agent uses an LLM client to process tasks and generate responses.
25
+ """
26
+
27
+ def __init__(
28
+ self,
29
+ agent_id: str,
30
+ name: str,
31
+ llm_client: BaseLLMClient,
32
+ config: AgentConfiguration,
33
+ description: Optional[str] = None,
34
+ version: str = "1.0.0",
35
+ ):
36
+ """
37
+ Initialize LLM agent.
38
+
39
+ Args:
40
+ agent_id: Unique agent identifier
41
+ name: Agent name
42
+ llm_client: LLM client instance
43
+ config: Agent configuration
44
+ description: Optional description
45
+ version: Agent version
46
+ """
47
+ super().__init__(
48
+ agent_id=agent_id,
49
+ name=name,
50
+ agent_type=AgentType.CONVERSATIONAL,
51
+ config=config,
52
+ description=description or "LLM-powered conversational agent",
53
+ version=version,
54
+ )
55
+
56
+ self.llm_client = llm_client
57
+ self._system_prompt: Optional[str] = None
58
+ self._conversation_history: List[LLMMessage] = []
59
+
60
+ logger.info(f"LLMAgent initialized: {agent_id} with client {llm_client.provider_name}")
61
+
62
+ async def _initialize(self) -> None:
63
+ """Initialize LLM agent."""
64
+ # Build system prompt
65
+ self._system_prompt = self._build_system_prompt()
66
+ logger.debug(f"LLMAgent {self.agent_id} initialized with system prompt")
67
+
68
+ async def _shutdown(self) -> None:
69
+ """Shutdown LLM agent."""
70
+ # Clear conversation history
71
+ self._conversation_history.clear()
72
+
73
+ # Close LLM client if it has a close method
74
+ if hasattr(self.llm_client, "close"):
75
+ await self.llm_client.close()
76
+
77
+ logger.info(f"LLMAgent {self.agent_id} shut down")
78
+
79
+ def _build_system_prompt(self) -> str:
80
+ """Build system prompt from configuration."""
81
+ parts = []
82
+
83
+ if self._config.goal:
84
+ parts.append(f"Goal: {self._config.goal}")
85
+
86
+ if self._config.backstory:
87
+ parts.append(f"Background: {self._config.backstory}")
88
+
89
+ if self._config.domain_knowledge:
90
+ parts.append(f"Domain Knowledge: {self._config.domain_knowledge}")
91
+
92
+ if self._config.reasoning_guidance:
93
+ parts.append(f"Reasoning Approach: {self._config.reasoning_guidance}")
94
+
95
+ if not parts:
96
+ return "You are a helpful AI assistant."
97
+
98
+ return "\n\n".join(parts)
99
+
100
+ async def execute_task(self, task: Dict[str, Any], context: Dict[str, Any]) -> Dict[str, Any]:
101
+ """
102
+ Execute a task using the LLM.
103
+
104
+ Args:
105
+ task: Task specification with 'description' or 'prompt'
106
+ context: Execution context
107
+
108
+ Returns:
109
+ Execution result with 'output', 'reasoning', 'tokens_used'
110
+
111
+ Raises:
112
+ TaskExecutionError: If task execution fails
113
+ """
114
+ start_time = datetime.utcnow()
115
+
116
+ try:
117
+ # Extract task description
118
+ task_description = task.get("description") or task.get("prompt") or task.get("task")
119
+ if not task_description:
120
+ raise TaskExecutionError(
121
+ "Task must contain 'description', 'prompt', or 'task' field",
122
+ agent_id=self.agent_id,
123
+ )
124
+
125
+ # Transition to busy state
126
+ self._transition_state(self.state.__class__.BUSY)
127
+ self._current_task_id = task.get("task_id")
128
+
129
+ # Build messages
130
+ messages = self._build_messages(task_description, context)
131
+
132
+ # Call LLM
133
+ response = await self.llm_client.generate_text(
134
+ messages=messages,
135
+ model=self._config.llm_model,
136
+ temperature=self._config.temperature,
137
+ max_tokens=self._config.max_tokens,
138
+ )
139
+
140
+ # Extract result
141
+ output = response.content
142
+
143
+ # Store in conversation history if enabled
144
+ if self._config.memory_enabled:
145
+ self._conversation_history.append(LLMMessage(role="user", content=task_description))
146
+ self._conversation_history.append(LLMMessage(role="assistant", content=output))
147
+
148
+ # Calculate execution time
149
+ execution_time = (datetime.utcnow() - start_time).total_seconds()
150
+
151
+ # Update metrics
152
+ self.update_metrics(
153
+ execution_time=execution_time,
154
+ success=True,
155
+ tokens_used=getattr(response, "total_tokens", None),
156
+ )
157
+
158
+ # Transition back to active
159
+ self._transition_state(self.state.__class__.ACTIVE)
160
+ self._current_task_id = None
161
+ self.last_active_at = datetime.utcnow()
162
+
163
+ return {
164
+ "success": True,
165
+ "output": output,
166
+ "provider": response.provider,
167
+ "model": response.model,
168
+ "tokens_used": getattr(response, "total_tokens", None),
169
+ "execution_time": execution_time,
170
+ "timestamp": datetime.utcnow().isoformat(),
171
+ }
172
+
173
+ except Exception as e:
174
+ logger.error(f"Task execution failed for {self.agent_id}: {e}")
175
+
176
+ # Update metrics for failure
177
+ execution_time = (datetime.utcnow() - start_time).total_seconds()
178
+ self.update_metrics(execution_time=execution_time, success=False)
179
+
180
+ # Transition to error state
181
+ self._transition_state(self.state.__class__.ERROR)
182
+ self._current_task_id = None
183
+
184
+ raise TaskExecutionError(
185
+ f"Task execution failed: {str(e)}",
186
+ agent_id=self.agent_id,
187
+ task_id=task.get("task_id"),
188
+ )
189
+
190
+ async def process_message(
191
+ self, message: str, sender_id: Optional[str] = None
192
+ ) -> Dict[str, Any]:
193
+ """
194
+ Process an incoming message.
195
+
196
+ Args:
197
+ message: Message content
198
+ sender_id: Optional sender identifier
199
+
200
+ Returns:
201
+ Response dictionary with 'response', 'tokens_used'
202
+ """
203
+ try:
204
+ # Build task from message
205
+ task = {
206
+ "description": message,
207
+ "task_id": f"msg_{datetime.utcnow().timestamp()}",
208
+ }
209
+
210
+ # Execute as task
211
+ result = await self.execute_task(task, {"sender_id": sender_id})
212
+
213
+ return {
214
+ "response": result.get("output"),
215
+ "tokens_used": result.get("tokens_used"),
216
+ "timestamp": result.get("timestamp"),
217
+ }
218
+
219
+ except Exception as e:
220
+ logger.error(f"Message processing failed for {self.agent_id}: {e}")
221
+ raise
222
+
223
+ def _build_messages(self, user_message: str, context: Dict[str, Any]) -> List[LLMMessage]:
224
+ """
225
+ Build LLM messages from task and context.
226
+
227
+ Args:
228
+ user_message: User message
229
+ context: Context dictionary
230
+
231
+ Returns:
232
+ List of LLM messages
233
+ """
234
+ messages = []
235
+
236
+ # Add system prompt
237
+ if self._system_prompt:
238
+ messages.append(LLMMessage(role="system", content=self._system_prompt))
239
+
240
+ # Add conversation history if available and memory enabled
241
+ if self._config.memory_enabled and self._conversation_history:
242
+ # Limit history to prevent token overflow
243
+ max_history = 10 # Keep last 10 exchanges
244
+ messages.extend(self._conversation_history[-max_history:])
245
+
246
+ # Add additional context if provided
247
+ if context:
248
+ context_str = self._format_context(context)
249
+ if context_str:
250
+ messages.append(
251
+ LLMMessage(
252
+ role="system",
253
+ content=f"Additional Context:\n{context_str}",
254
+ )
255
+ )
256
+
257
+ # Add user message
258
+ messages.append(LLMMessage(role="user", content=user_message))
259
+
260
+ return messages
261
+
262
+ def _format_context(self, context: Dict[str, Any]) -> str:
263
+ """Format context dictionary as string."""
264
+ relevant_fields = []
265
+
266
+ # Filter out internal fields
267
+ for key, value in context.items():
268
+ if not key.startswith("_") and value is not None:
269
+ relevant_fields.append(f"{key}: {value}")
270
+
271
+ return "\n".join(relevant_fields) if relevant_fields else ""
272
+
273
+ def clear_conversation_history(self) -> None:
274
+ """Clear conversation history."""
275
+ self._conversation_history.clear()
276
+ logger.info(f"LLMAgent {self.agent_id} conversation history cleared")
277
+
278
+ def get_conversation_history(self) -> List[Dict[str, str]]:
279
+ """Get conversation history."""
280
+ return [{"role": msg.role, "content": msg.content} for msg in self._conversation_history]
281
+
282
+ @classmethod
283
+ def from_dict(cls, data: Dict[str, Any]) -> "LLMAgent":
284
+ """
285
+ Deserialize LLMAgent from dictionary.
286
+
287
+ Note: LLM client must be provided separately as it cannot be serialized.
288
+
289
+ Args:
290
+ data: Dictionary representation
291
+
292
+ Returns:
293
+ LLMAgent instance
294
+ """
295
+ # This is a placeholder - actual implementation would require
296
+ # providing the LLM client separately
297
+ raise NotImplementedError(
298
+ "LLMAgent.from_dict requires LLM client to be provided separately. "
299
+ "Use constructor instead."
300
+ )
@@ -0,0 +1,12 @@
1
+ """
2
+ Agent Memory Module
3
+
4
+ Conversation memory and history management.
5
+ """
6
+
7
+ from .conversation import ConversationMemory, Session
8
+
9
+ __all__ = [
10
+ "ConversationMemory",
11
+ "Session",
12
+ ]