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,490 @@
1
+ """
2
+ Hybrid Agent
3
+
4
+ Agent implementation combining LLM reasoning with tool execution capabilities.
5
+ Implements the ReAct (Reasoning + Acting) pattern.
6
+ """
7
+
8
+ import logging
9
+ from typing import Dict, List, Any, Optional
10
+ from datetime import datetime
11
+
12
+ from aiecs.llm import BaseLLMClient, LLMMessage
13
+ from aiecs.tools import get_tool, BaseTool
14
+
15
+ from .base_agent import BaseAIAgent
16
+ from .models import AgentType, AgentConfiguration
17
+ from .exceptions import TaskExecutionError, ToolAccessDeniedError
18
+
19
+ logger = logging.getLogger(__name__)
20
+
21
+
22
+ class HybridAgent(BaseAIAgent):
23
+ """
24
+ Hybrid agent combining LLM reasoning with tool execution.
25
+
26
+ Implements ReAct pattern: Reason → Act → Observe loop.
27
+ """
28
+
29
+ def __init__(
30
+ self,
31
+ agent_id: str,
32
+ name: str,
33
+ llm_client: BaseLLMClient,
34
+ tools: List[str],
35
+ config: AgentConfiguration,
36
+ description: Optional[str] = None,
37
+ version: str = "1.0.0",
38
+ max_iterations: int = 10,
39
+ ):
40
+ """
41
+ Initialize Hybrid agent.
42
+
43
+ Args:
44
+ agent_id: Unique agent identifier
45
+ name: Agent name
46
+ llm_client: LLM client for reasoning
47
+ tools: List of tool names
48
+ config: Agent configuration
49
+ description: Optional description
50
+ version: Agent version
51
+ max_iterations: Maximum ReAct iterations
52
+ """
53
+ super().__init__(
54
+ agent_id=agent_id,
55
+ name=name,
56
+ agent_type=AgentType.DEVELOPER, # Can be adjusted based on use case
57
+ config=config,
58
+ description=description or "Hybrid agent with LLM reasoning and tool execution",
59
+ version=version,
60
+ )
61
+
62
+ self.llm_client = llm_client
63
+ self._available_tools = tools
64
+ self._max_iterations = max_iterations
65
+ self._tool_instances: Dict[str, BaseTool] = {}
66
+ self._system_prompt: Optional[str] = None
67
+ self._conversation_history: List[LLMMessage] = []
68
+
69
+ logger.info(
70
+ f"HybridAgent initialized: {agent_id} with LLM ({llm_client.provider_name}) "
71
+ f"and tools: {', '.join(tools)}"
72
+ )
73
+
74
+ async def _initialize(self) -> None:
75
+ """Initialize Hybrid agent - build system prompt and load tools."""
76
+ # Build system prompt
77
+ self._system_prompt = self._build_system_prompt()
78
+
79
+ # Load tool instances
80
+ for tool_name in self._available_tools:
81
+ try:
82
+ self._tool_instances[tool_name] = get_tool(tool_name)
83
+ logger.debug(f"HybridAgent {self.agent_id} loaded tool: {tool_name}")
84
+ except Exception as e:
85
+ logger.warning(f"Failed to load tool {tool_name}: {e}")
86
+
87
+ logger.info(
88
+ f"HybridAgent {self.agent_id} initialized with {len(self._tool_instances)} tools"
89
+ )
90
+
91
+ async def _shutdown(self) -> None:
92
+ """Shutdown Hybrid agent."""
93
+ self._conversation_history.clear()
94
+ self._tool_instances.clear()
95
+
96
+ if hasattr(self.llm_client, "close"):
97
+ await self.llm_client.close()
98
+
99
+ logger.info(f"HybridAgent {self.agent_id} shut down")
100
+
101
+ def _build_system_prompt(self) -> str:
102
+ """Build system prompt including tool descriptions."""
103
+ parts = []
104
+
105
+ # Add goal and backstory
106
+ if self._config.goal:
107
+ parts.append(f"Goal: {self._config.goal}")
108
+
109
+ if self._config.backstory:
110
+ parts.append(f"Background: {self._config.backstory}")
111
+
112
+ # Add ReAct instructions
113
+ parts.append(
114
+ "You are a reasoning agent that can use tools to complete tasks. "
115
+ "Follow the ReAct pattern:\n"
116
+ "1. THOUGHT: Analyze the task and decide what to do\n"
117
+ "2. ACTION: Use a tool if needed, or provide final answer\n"
118
+ "3. OBSERVATION: Review the tool result and continue reasoning\n\n"
119
+ "When you need to use a tool, respond with:\n"
120
+ "TOOL: <tool_name>\n"
121
+ "OPERATION: <operation_name>\n"
122
+ "PARAMETERS: <json_parameters>\n\n"
123
+ "When you have the final answer, respond with:\n"
124
+ "FINAL ANSWER: <your_answer>"
125
+ )
126
+
127
+ # Add available tools
128
+ if self._available_tools:
129
+ parts.append(f"\nAvailable tools: {', '.join(self._available_tools)}")
130
+
131
+ if self._config.domain_knowledge:
132
+ parts.append(f"\nDomain Knowledge: {self._config.domain_knowledge}")
133
+
134
+ return "\n\n".join(parts)
135
+
136
+ async def execute_task(self, task: Dict[str, Any], context: Dict[str, Any]) -> Dict[str, Any]:
137
+ """
138
+ Execute a task using ReAct loop.
139
+
140
+ Args:
141
+ task: Task specification with 'description' or 'prompt'
142
+ context: Execution context
143
+
144
+ Returns:
145
+ Execution result with 'output', 'reasoning_steps', 'tool_calls'
146
+
147
+ Raises:
148
+ TaskExecutionError: If task execution fails
149
+ """
150
+ start_time = datetime.utcnow()
151
+
152
+ try:
153
+ # Extract task description
154
+ task_description = task.get("description") or task.get("prompt") or task.get("task")
155
+ if not task_description:
156
+ raise TaskExecutionError(
157
+ "Task must contain 'description', 'prompt', or 'task' field",
158
+ agent_id=self.agent_id,
159
+ )
160
+
161
+ # Transition to busy state
162
+ self._transition_state(self.state.__class__.BUSY)
163
+ self._current_task_id = task.get("task_id")
164
+
165
+ # Execute ReAct loop
166
+ result = await self._react_loop(task_description, context)
167
+
168
+ # Calculate execution time
169
+ execution_time = (datetime.utcnow() - start_time).total_seconds()
170
+
171
+ # Update metrics
172
+ self.update_metrics(
173
+ execution_time=execution_time,
174
+ success=True,
175
+ tokens_used=result.get("total_tokens"),
176
+ tool_calls=result.get("tool_calls_count", 0),
177
+ )
178
+
179
+ # Transition back to active
180
+ self._transition_state(self.state.__class__.ACTIVE)
181
+ self._current_task_id = None
182
+ self.last_active_at = datetime.utcnow()
183
+
184
+ return {
185
+ "success": True,
186
+ "output": result.get("final_answer"),
187
+ "reasoning_steps": result.get("steps"),
188
+ "tool_calls_count": result.get("tool_calls_count"),
189
+ "iterations": result.get("iterations"),
190
+ "execution_time": execution_time,
191
+ "timestamp": datetime.utcnow().isoformat(),
192
+ }
193
+
194
+ except Exception as e:
195
+ logger.error(f"Task execution failed for {self.agent_id}: {e}")
196
+
197
+ # Update metrics for failure
198
+ execution_time = (datetime.utcnow() - start_time).total_seconds()
199
+ self.update_metrics(execution_time=execution_time, success=False)
200
+
201
+ # Transition to error state
202
+ self._transition_state(self.state.__class__.ERROR)
203
+ self._current_task_id = None
204
+
205
+ raise TaskExecutionError(
206
+ f"Task execution failed: {str(e)}",
207
+ agent_id=self.agent_id,
208
+ task_id=task.get("task_id"),
209
+ )
210
+
211
+ async def process_message(
212
+ self, message: str, sender_id: Optional[str] = None
213
+ ) -> Dict[str, Any]:
214
+ """
215
+ Process an incoming message using ReAct loop.
216
+
217
+ Args:
218
+ message: Message content
219
+ sender_id: Optional sender identifier
220
+
221
+ Returns:
222
+ Response dictionary with 'response', 'reasoning_steps'
223
+ """
224
+ try:
225
+ # Build task from message
226
+ task = {
227
+ "description": message,
228
+ "task_id": f"msg_{datetime.utcnow().timestamp()}",
229
+ }
230
+
231
+ # Execute as task
232
+ result = await self.execute_task(task, {"sender_id": sender_id})
233
+
234
+ return {
235
+ "response": result.get("output"),
236
+ "reasoning_steps": result.get("reasoning_steps"),
237
+ "timestamp": result.get("timestamp"),
238
+ }
239
+
240
+ except Exception as e:
241
+ logger.error(f"Message processing failed for {self.agent_id}: {e}")
242
+ raise
243
+
244
+ async def _react_loop(self, task: str, context: Dict[str, Any]) -> Dict[str, Any]:
245
+ """
246
+ Execute ReAct loop: Reason → Act → Observe.
247
+
248
+ Args:
249
+ task: Task description
250
+ context: Context dictionary
251
+
252
+ Returns:
253
+ Result dictionary with 'final_answer', 'steps', 'iterations'
254
+ """
255
+ steps = []
256
+ tool_calls_count = 0
257
+ total_tokens = 0
258
+
259
+ # Build initial messages
260
+ messages = self._build_initial_messages(task, context)
261
+
262
+ for iteration in range(self._max_iterations):
263
+ logger.debug(f"HybridAgent {self.agent_id} - ReAct iteration {iteration + 1}")
264
+
265
+ # THINK: LLM reasons about next action
266
+ response = await self.llm_client.generate_text(
267
+ messages=messages,
268
+ model=self._config.llm_model,
269
+ temperature=self._config.temperature,
270
+ max_tokens=self._config.max_tokens,
271
+ )
272
+
273
+ thought = response.content
274
+ total_tokens += getattr(response, "total_tokens", 0)
275
+
276
+ steps.append(
277
+ {
278
+ "type": "thought",
279
+ "content": thought,
280
+ "iteration": iteration + 1,
281
+ }
282
+ )
283
+
284
+ # Check if final answer
285
+ if "FINAL ANSWER:" in thought:
286
+ final_answer = self._extract_final_answer(thought)
287
+ return {
288
+ "final_answer": final_answer,
289
+ "steps": steps,
290
+ "iterations": iteration + 1,
291
+ "tool_calls_count": tool_calls_count,
292
+ "total_tokens": total_tokens,
293
+ }
294
+
295
+ # Check if tool call
296
+ if "TOOL:" in thought:
297
+ # ACT: Execute tool
298
+ try:
299
+ tool_info = self._parse_tool_call(thought)
300
+ tool_result = await self._execute_tool(
301
+ tool_info["tool"],
302
+ tool_info.get("operation"),
303
+ tool_info.get("parameters", {}),
304
+ )
305
+ tool_calls_count += 1
306
+
307
+ steps.append(
308
+ {
309
+ "type": "action",
310
+ "tool": tool_info["tool"],
311
+ "operation": tool_info.get("operation"),
312
+ "parameters": tool_info.get("parameters"),
313
+ "iteration": iteration + 1,
314
+ }
315
+ )
316
+
317
+ # OBSERVE: Add tool result to conversation
318
+ observation = f"OBSERVATION: Tool '{tool_info['tool']}' returned: {tool_result}"
319
+ steps.append(
320
+ {
321
+ "type": "observation",
322
+ "content": observation,
323
+ "iteration": iteration + 1,
324
+ }
325
+ )
326
+
327
+ # Add to messages for next iteration
328
+ messages.append(LLMMessage(role="assistant", content=thought))
329
+ messages.append(LLMMessage(role="user", content=observation))
330
+
331
+ except Exception as e:
332
+ error_msg = f"OBSERVATION: Tool execution failed: {str(e)}"
333
+ steps.append(
334
+ {
335
+ "type": "observation",
336
+ "content": error_msg,
337
+ "iteration": iteration + 1,
338
+ "error": True,
339
+ }
340
+ )
341
+ messages.append(LLMMessage(role="assistant", content=thought))
342
+ messages.append(LLMMessage(role="user", content=error_msg))
343
+
344
+ else:
345
+ # LLM didn't provide clear action - treat as final answer
346
+ return {
347
+ "final_answer": thought,
348
+ "steps": steps,
349
+ "iterations": iteration + 1,
350
+ "tool_calls_count": tool_calls_count,
351
+ "total_tokens": total_tokens,
352
+ }
353
+
354
+ # Max iterations reached
355
+ logger.warning(f"HybridAgent {self.agent_id} reached max iterations")
356
+ return {
357
+ "final_answer": "Max iterations reached. Unable to complete task fully.",
358
+ "steps": steps,
359
+ "iterations": self._max_iterations,
360
+ "tool_calls_count": tool_calls_count,
361
+ "total_tokens": total_tokens,
362
+ "max_iterations_reached": True,
363
+ }
364
+
365
+ def _build_initial_messages(self, task: str, context: Dict[str, Any]) -> List[LLMMessage]:
366
+ """Build initial messages for ReAct loop."""
367
+ messages = []
368
+
369
+ # Add system prompt
370
+ if self._system_prompt:
371
+ messages.append(LLMMessage(role="system", content=self._system_prompt))
372
+
373
+ # Add context if provided
374
+ if context:
375
+ context_str = self._format_context(context)
376
+ if context_str:
377
+ messages.append(
378
+ LLMMessage(
379
+ role="system",
380
+ content=f"Additional Context:\n{context_str}",
381
+ )
382
+ )
383
+
384
+ # Add task
385
+ messages.append(LLMMessage(role="user", content=f"Task: {task}"))
386
+
387
+ return messages
388
+
389
+ def _format_context(self, context: Dict[str, Any]) -> str:
390
+ """Format context dictionary as string."""
391
+ relevant_fields = []
392
+ for key, value in context.items():
393
+ if not key.startswith("_") and value is not None:
394
+ relevant_fields.append(f"{key}: {value}")
395
+ return "\n".join(relevant_fields) if relevant_fields else ""
396
+
397
+ def _extract_final_answer(self, thought: str) -> str:
398
+ """Extract final answer from thought."""
399
+ if "FINAL ANSWER:" in thought:
400
+ return thought.split("FINAL ANSWER:", 1)[1].strip()
401
+ return thought
402
+
403
+ def _parse_tool_call(self, thought: str) -> Dict[str, Any]:
404
+ """
405
+ Parse tool call from LLM thought.
406
+
407
+ Expected format:
408
+ TOOL: <tool_name>
409
+ OPERATION: <operation_name>
410
+ PARAMETERS: <json_parameters>
411
+
412
+ Args:
413
+ thought: LLM thought containing tool call
414
+
415
+ Returns:
416
+ Dictionary with 'tool', 'operation', 'parameters'
417
+ """
418
+ import json
419
+
420
+ result = {}
421
+
422
+ # Extract tool
423
+ if "TOOL:" in thought:
424
+ tool_line = [line for line in thought.split("\n") if line.startswith("TOOL:")][0]
425
+ result["tool"] = tool_line.split("TOOL:", 1)[1].strip()
426
+
427
+ # Extract operation (optional)
428
+ if "OPERATION:" in thought:
429
+ op_line = [line for line in thought.split("\n") if line.startswith("OPERATION:")][0]
430
+ result["operation"] = op_line.split("OPERATION:", 1)[1].strip()
431
+
432
+ # Extract parameters (optional)
433
+ if "PARAMETERS:" in thought:
434
+ param_line = [line for line in thought.split("\n") if line.startswith("PARAMETERS:")][0]
435
+ param_str = param_line.split("PARAMETERS:", 1)[1].strip()
436
+ try:
437
+ result["parameters"] = json.loads(param_str)
438
+ except json.JSONDecodeError:
439
+ logger.warning(f"Failed to parse parameters: {param_str}")
440
+ result["parameters"] = {}
441
+
442
+ return result
443
+
444
+ async def _execute_tool(
445
+ self,
446
+ tool_name: str,
447
+ operation: Optional[str],
448
+ parameters: Dict[str, Any],
449
+ ) -> Any:
450
+ """Execute a tool operation."""
451
+ # Check access
452
+ if tool_name not in self._available_tools:
453
+ raise ToolAccessDeniedError(self.agent_id, tool_name)
454
+
455
+ tool = self._tool_instances.get(tool_name)
456
+ if not tool:
457
+ raise ValueError(f"Tool {tool_name} not loaded")
458
+
459
+ # Execute tool
460
+ if operation:
461
+ result = await tool.run_async(operation, **parameters)
462
+ else:
463
+ if hasattr(tool, "run_async"):
464
+ result = await tool.run_async(**parameters)
465
+ else:
466
+ raise ValueError(f"Tool {tool_name} requires operation to be specified")
467
+
468
+ return result
469
+
470
+ def get_available_tools(self) -> List[str]:
471
+ """Get list of available tools."""
472
+ return self._available_tools.copy()
473
+
474
+ @classmethod
475
+ def from_dict(cls, data: Dict[str, Any]) -> "HybridAgent":
476
+ """
477
+ Deserialize HybridAgent from dictionary.
478
+
479
+ Note: LLM client must be provided separately.
480
+
481
+ Args:
482
+ data: Dictionary representation
483
+
484
+ Returns:
485
+ HybridAgent instance
486
+ """
487
+ raise NotImplementedError(
488
+ "HybridAgent.from_dict requires LLM client to be provided separately. "
489
+ "Use constructor instead."
490
+ )
@@ -0,0 +1,26 @@
1
+ """
2
+ Integration Module
3
+
4
+ Integration adapters for external systems.
5
+ """
6
+
7
+ from .context_engine_adapter import ContextEngineAdapter
8
+ from .retry_policy import EnhancedRetryPolicy, ErrorClassifier, ErrorType
9
+ from .role_config import RoleConfiguration, load_role_config
10
+ from .context_compressor import (
11
+ ContextCompressor,
12
+ compress_messages,
13
+ CompressionStrategy,
14
+ )
15
+
16
+ __all__ = [
17
+ "ContextEngineAdapter",
18
+ "EnhancedRetryPolicy",
19
+ "ErrorClassifier",
20
+ "ErrorType",
21
+ "RoleConfiguration",
22
+ "load_role_config",
23
+ "ContextCompressor",
24
+ "compress_messages",
25
+ "CompressionStrategy",
26
+ ]