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,694 @@
1
+ """
2
+ AI Report Orchestrator Tool - AI-powered comprehensive report generation
3
+
4
+ This tool provides advanced report generation with:
5
+ - Automated analysis report creation
6
+ - Multiple report types and formats
7
+ - Integration with analysis results
8
+ - Visualization embedding
9
+ - Export to multiple formats
10
+ """
11
+
12
+ import os
13
+ import logging
14
+ import tempfile
15
+ from typing import Dict, Any, List, Optional
16
+ from enum import Enum
17
+ from datetime import datetime
18
+
19
+ from pydantic import BaseModel, Field, ConfigDict
20
+
21
+ from aiecs.tools.base_tool import BaseTool
22
+ from aiecs.tools import register_tool
23
+
24
+
25
+ class ReportType(str, Enum):
26
+ """Types of reports"""
27
+
28
+ EXECUTIVE_SUMMARY = "executive_summary"
29
+ TECHNICAL_REPORT = "technical_report"
30
+ BUSINESS_REPORT = "business_report"
31
+ RESEARCH_PAPER = "research_paper"
32
+ DATA_QUALITY_REPORT = "data_quality_report"
33
+
34
+
35
+ class ReportFormat(str, Enum):
36
+ """Report output formats"""
37
+
38
+ MARKDOWN = "markdown"
39
+ HTML = "html"
40
+ PDF = "pdf"
41
+ WORD = "word"
42
+ JSON = "json"
43
+
44
+
45
+ class ReportOrchestratorError(Exception):
46
+ """Base exception for Report Orchestrator errors"""
47
+
48
+
49
+ class ReportGenerationError(ReportOrchestratorError):
50
+ """Raised when report generation fails"""
51
+
52
+
53
+ @register_tool("ai_report_orchestrator")
54
+ class AIReportOrchestratorTool(BaseTool):
55
+ """
56
+ AI-powered analysis report generator that can:
57
+ 1. Generate comprehensive analysis reports
58
+ 2. Customize report structure and style
59
+ 3. Include visualizations and tables
60
+ 4. Export to multiple formats
61
+ 5. Integrate analysis results and insights
62
+
63
+ Integrates with report_tool for document generation.
64
+ """
65
+
66
+ # Configuration schema
67
+ class Config(BaseModel):
68
+ """Configuration for the AI report orchestrator tool"""
69
+
70
+ model_config = ConfigDict(env_prefix="AI_REPORT_ORCHESTRATOR_")
71
+
72
+ default_report_type: str = Field(
73
+ default="business_report",
74
+ description="Default report type to generate",
75
+ )
76
+ default_format: str = Field(default="markdown", description="Default report output format")
77
+ output_directory: str = Field(
78
+ default=tempfile.gettempdir(),
79
+ description="Directory for report output files",
80
+ )
81
+ include_code: bool = Field(
82
+ default=False,
83
+ description="Whether to include code snippets in reports",
84
+ )
85
+ include_visualizations: bool = Field(
86
+ default=True,
87
+ description="Whether to include visualizations in reports",
88
+ )
89
+ max_insights_per_report: int = Field(
90
+ default=20,
91
+ description="Maximum number of insights to include per report",
92
+ )
93
+
94
+ def __init__(self, config: Optional[Dict[str, Any]] = None):
95
+ """Initialize AI Report Orchestrator Tool"""
96
+ super().__init__(config)
97
+
98
+ # Parse configuration
99
+ self.config = self.Config(**(config or {}))
100
+
101
+ self.logger = logging.getLogger(__name__)
102
+ if not self.logger.handlers:
103
+ handler = logging.StreamHandler()
104
+ handler.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(message)s"))
105
+ self.logger.addHandler(handler)
106
+ self.logger.setLevel(logging.INFO)
107
+
108
+ self._init_external_tools()
109
+
110
+ # Ensure output directory exists
111
+ os.makedirs(self.config.output_directory, exist_ok=True)
112
+
113
+ def _init_external_tools(self):
114
+ """Initialize external task tools"""
115
+ self.external_tools = {}
116
+
117
+ # Initialize ReportTool for document generation
118
+ try:
119
+ from aiecs.tools.task_tools.report_tool import ReportTool
120
+
121
+ self.external_tools["report"] = ReportTool()
122
+ self.logger.info("ReportTool initialized successfully")
123
+ except ImportError:
124
+ self.logger.warning("ReportTool not available")
125
+ self.external_tools["report"] = None
126
+
127
+ # Schema definitions
128
+ class GenerateReportSchema(BaseModel):
129
+ """Schema for generate_report operation"""
130
+
131
+ analysis_results: Dict[str, Any] = Field(description="Analysis results to include")
132
+ insights: Optional[Dict[str, Any]] = Field(default=None, description="Generated insights")
133
+ report_type: ReportType = Field(
134
+ default=ReportType.BUSINESS_REPORT, description="Type of report"
135
+ )
136
+ output_format: ReportFormat = Field(
137
+ default=ReportFormat.MARKDOWN, description="Output format"
138
+ )
139
+ title: Optional[str] = Field(default=None, description="Report title")
140
+ include_code: bool = Field(default=False, description="Include code snippets")
141
+
142
+ class FormatReportSchema(BaseModel):
143
+ """Schema for format_report operation"""
144
+
145
+ report_content: str = Field(description="Report content to format")
146
+ output_format: ReportFormat = Field(description="Desired output format")
147
+ output_path: Optional[str] = Field(default=None, description="Output file path")
148
+
149
+ class ExportReportSchema(BaseModel):
150
+ """Schema for export_report operation"""
151
+
152
+ report_content: str = Field(description="Report content")
153
+ output_format: ReportFormat = Field(description="Export format")
154
+ output_path: str = Field(description="Output file path")
155
+
156
+ def generate_report(
157
+ self,
158
+ analysis_results: Dict[str, Any],
159
+ insights: Optional[Dict[str, Any]] = None,
160
+ report_type: ReportType = ReportType.BUSINESS_REPORT,
161
+ output_format: ReportFormat = ReportFormat.MARKDOWN,
162
+ title: Optional[str] = None,
163
+ include_code: bool = False,
164
+ ) -> Dict[str, Any]:
165
+ """
166
+ Generate comprehensive analysis report.
167
+
168
+ Args:
169
+ analysis_results: Results from data analysis
170
+ insights: Generated insights to include
171
+ report_type: Type of report to generate
172
+ output_format: Output format
173
+ title: Report title
174
+ include_code: Whether to include code snippets
175
+
176
+ Returns:
177
+ Dict containing:
178
+ - report_content: Generated report content
179
+ - sections: Report sections
180
+ - export_path: Path to exported report
181
+ - metadata: Report metadata
182
+ """
183
+ try:
184
+ self.logger.info(
185
+ f"Generating {report_type.value} report in {output_format.value} format"
186
+ )
187
+
188
+ # Generate report title
189
+ if title is None:
190
+ title = self._generate_title(report_type, analysis_results)
191
+
192
+ # Build report sections
193
+ sections = self._build_report_sections(
194
+ analysis_results, insights, report_type, include_code
195
+ )
196
+
197
+ # Compile report content
198
+ report_content = self._compile_report(title, sections, report_type)
199
+
200
+ # Format report for output format
201
+ formatted_content = self._format_content(report_content, output_format)
202
+
203
+ # Export report
204
+ export_path = self._export_report(formatted_content, output_format, title)
205
+
206
+ # Generate metadata
207
+ metadata = {
208
+ "generated_at": datetime.now().isoformat(),
209
+ "report_type": report_type.value,
210
+ "output_format": output_format.value,
211
+ "sections_count": len(sections),
212
+ "word_count": len(report_content.split()),
213
+ }
214
+
215
+ return {
216
+ "report_content": report_content,
217
+ "sections": {s["title"]: s["content"] for s in sections},
218
+ "export_path": export_path,
219
+ "metadata": metadata,
220
+ "title": title,
221
+ }
222
+
223
+ except Exception as e:
224
+ self.logger.error(f"Error generating report: {e}")
225
+ raise ReportGenerationError(f"Report generation failed: {e}")
226
+
227
+ def format_report(
228
+ self,
229
+ report_content: str,
230
+ output_format: ReportFormat,
231
+ output_path: Optional[str] = None,
232
+ ) -> Dict[str, Any]:
233
+ """
234
+ Format report content to specified format.
235
+
236
+ Args:
237
+ report_content: Report content to format
238
+ output_format: Desired output format
239
+ output_path: Optional output file path
240
+
241
+ Returns:
242
+ Dict containing formatted report info
243
+ """
244
+ try:
245
+ formatted_content = self._format_content(report_content, output_format)
246
+
247
+ if output_path:
248
+ with open(output_path, "w", encoding="utf-8") as f:
249
+ f.write(formatted_content)
250
+ export_path = output_path
251
+ else:
252
+ export_path = self._export_report(formatted_content, output_format, "report")
253
+
254
+ return {
255
+ "formatted_content": formatted_content,
256
+ "output_format": output_format.value,
257
+ "export_path": export_path,
258
+ }
259
+
260
+ except Exception as e:
261
+ self.logger.error(f"Error formatting report: {e}")
262
+ raise ReportGenerationError(f"Report formatting failed: {e}")
263
+
264
+ def export_report(
265
+ self,
266
+ report_content: str,
267
+ output_format: ReportFormat,
268
+ output_path: str,
269
+ ) -> Dict[str, Any]:
270
+ """
271
+ Export report to file.
272
+
273
+ Args:
274
+ report_content: Report content
275
+ output_format: Export format
276
+ output_path: Output file path
277
+
278
+ Returns:
279
+ Dict containing export information
280
+ """
281
+ try:
282
+ formatted_content = self._format_content(report_content, output_format)
283
+
284
+ with open(output_path, "w", encoding="utf-8") as f:
285
+ f.write(formatted_content)
286
+
287
+ file_size = os.path.getsize(output_path)
288
+
289
+ return {
290
+ "export_path": output_path,
291
+ "format": output_format.value,
292
+ "file_size_bytes": file_size,
293
+ "success": True,
294
+ }
295
+
296
+ except Exception as e:
297
+ self.logger.error(f"Error exporting report: {e}")
298
+ raise ReportGenerationError(f"Report export failed: {e}")
299
+
300
+ # Internal report generation methods
301
+
302
+ def _generate_title(self, report_type: ReportType, analysis_results: Dict[str, Any]) -> str:
303
+ """Generate appropriate report title"""
304
+ if report_type == ReportType.EXECUTIVE_SUMMARY:
305
+ return "Executive Summary: Data Analysis Report"
306
+ elif report_type == ReportType.TECHNICAL_REPORT:
307
+ return "Technical Data Analysis Report"
308
+ elif report_type == ReportType.BUSINESS_REPORT:
309
+ return "Business Intelligence Report"
310
+ elif report_type == ReportType.RESEARCH_PAPER:
311
+ return "Data Analysis Research Paper"
312
+ elif report_type == ReportType.DATA_QUALITY_REPORT:
313
+ return "Data Quality Assessment Report"
314
+ else:
315
+ return "Data Analysis Report"
316
+
317
+ def _build_report_sections(
318
+ self,
319
+ analysis_results: Dict[str, Any],
320
+ insights: Optional[Dict[str, Any]],
321
+ report_type: ReportType,
322
+ include_code: bool,
323
+ ) -> List[Dict[str, str]]:
324
+ """Build report sections based on type"""
325
+ sections = []
326
+
327
+ # Executive Summary (for all report types)
328
+ sections.append(
329
+ {
330
+ "title": "Executive Summary",
331
+ "content": self._generate_executive_summary(analysis_results, insights),
332
+ }
333
+ )
334
+
335
+ # Methodology section (for technical and research reports)
336
+ if report_type in [
337
+ ReportType.TECHNICAL_REPORT,
338
+ ReportType.RESEARCH_PAPER,
339
+ ]:
340
+ sections.append(
341
+ {
342
+ "title": "Methodology",
343
+ "content": self._generate_methodology_section(analysis_results),
344
+ }
345
+ )
346
+
347
+ # Data Overview
348
+ sections.append(
349
+ {
350
+ "title": "Data Overview",
351
+ "content": self._generate_data_overview(analysis_results),
352
+ }
353
+ )
354
+
355
+ # Findings section
356
+ sections.append(
357
+ {
358
+ "title": "Key Findings",
359
+ "content": self._generate_findings_section(analysis_results, insights),
360
+ }
361
+ )
362
+
363
+ # Statistical Analysis (for technical reports)
364
+ if (
365
+ report_type == ReportType.TECHNICAL_REPORT
366
+ and "statistical_analysis" in analysis_results
367
+ ):
368
+ sections.append(
369
+ {
370
+ "title": "Statistical Analysis",
371
+ "content": self._generate_statistics_section(
372
+ analysis_results.get("statistical_analysis", {})
373
+ ),
374
+ }
375
+ )
376
+
377
+ # Insights section
378
+ if insights:
379
+ sections.append(
380
+ {
381
+ "title": "Insights and Patterns",
382
+ "content": self._generate_insights_section(insights),
383
+ }
384
+ )
385
+
386
+ # Recommendations
387
+ sections.append(
388
+ {
389
+ "title": "Recommendations",
390
+ "content": self._generate_recommendations_section(analysis_results, insights),
391
+ }
392
+ )
393
+
394
+ # Conclusion
395
+ sections.append(
396
+ {
397
+ "title": "Conclusion",
398
+ "content": self._generate_conclusion(analysis_results, insights),
399
+ }
400
+ )
401
+
402
+ # Appendix (if code included)
403
+ if include_code:
404
+ sections.append(
405
+ {
406
+ "title": "Appendix: Technical Details",
407
+ "content": self._generate_appendix(analysis_results),
408
+ }
409
+ )
410
+
411
+ return sections
412
+
413
+ def _generate_executive_summary(
414
+ self,
415
+ analysis_results: Dict[str, Any],
416
+ insights: Optional[Dict[str, Any]],
417
+ ) -> str:
418
+ """Generate executive summary"""
419
+ lines = []
420
+
421
+ # Get data profile if available
422
+ data_profile = analysis_results.get("data_profile", {})
423
+ summary = data_profile.get("summary", {})
424
+
425
+ if summary:
426
+ lines.append(
427
+ f"This report presents a comprehensive analysis of a dataset containing {summary.get('rows', 'N/A')} rows and {summary.get('columns', 'N/A')} columns."
428
+ )
429
+
430
+ missing_pct = summary.get("missing_percentage", 0)
431
+ if missing_pct > 0:
432
+ lines.append(f"The dataset has {missing_pct:.2f}% missing values.")
433
+
434
+ # Add insight summary
435
+ if insights and "summary" in insights:
436
+ lines.append(f"\n{insights['summary']}")
437
+
438
+ # Add key metrics
439
+ if insights and "priority_insights" in insights:
440
+ top_insights = insights["priority_insights"][:3]
441
+ if top_insights:
442
+ lines.append("\nKey highlights:")
443
+ for i, insight in enumerate(top_insights, 1):
444
+ lines.append(f"{i}. {insight.get('title', 'Insight')}")
445
+
446
+ return "\n".join(lines) if lines else "Analysis completed successfully."
447
+
448
+ def _generate_methodology_section(self, analysis_results: Dict[str, Any]) -> str:
449
+ """Generate methodology section"""
450
+ lines = [
451
+ "The analysis was conducted using a systematic approach:",
452
+ "",
453
+ "1. **Data Loading**: Data was loaded and validated for quality",
454
+ "2. **Data Profiling**: Comprehensive statistical profiling was performed",
455
+ "3. **Data Transformation**: Necessary transformations and cleaning were applied",
456
+ "4. **Statistical Analysis**: Various statistical tests and analyses were conducted",
457
+ "5. **Insight Generation**: Patterns, trends, and anomalies were identified",
458
+ "6. **Visualization**: Key findings were visualized for clarity",
459
+ ]
460
+
461
+ return "\n".join(lines)
462
+
463
+ def _generate_data_overview(self, analysis_results: Dict[str, Any]) -> str:
464
+ """Generate data overview section"""
465
+ lines = []
466
+
467
+ data_profile = analysis_results.get("data_profile", {})
468
+ summary = data_profile.get("summary", {})
469
+
470
+ if summary:
471
+ lines.append("**Dataset Characteristics:**")
472
+ lines.append(f"- Total Records: {summary.get('rows', 'N/A')}")
473
+ lines.append(f"- Total Columns: {summary.get('columns', 'N/A')}")
474
+ lines.append(f"- Numeric Columns: {summary.get('numeric_columns', 'N/A')}")
475
+ lines.append(f"- Categorical Columns: {summary.get('categorical_columns', 'N/A')}")
476
+ lines.append(f"- Missing Values: {summary.get('missing_percentage', 0):.2f}%")
477
+ lines.append(f"- Duplicate Rows: {summary.get('duplicate_rows', 0)}")
478
+ else:
479
+ lines.append("Data overview not available.")
480
+
481
+ return "\n".join(lines)
482
+
483
+ def _generate_findings_section(
484
+ self,
485
+ analysis_results: Dict[str, Any],
486
+ insights: Optional[Dict[str, Any]],
487
+ ) -> str:
488
+ """Generate findings section"""
489
+ lines = []
490
+
491
+ # Extract findings from analysis results
492
+ if "findings" in analysis_results:
493
+ findings = analysis_results["findings"]
494
+ for i, finding in enumerate(findings[:10], 1):
495
+ lines.append(
496
+ f"{i}. **{finding.get('title', 'Finding')}**: {finding.get('description', 'No description')}"
497
+ )
498
+
499
+ # Add insights if available
500
+ if insights and "insights" in insights:
501
+ insight_list = insights["insights"][: self.config.max_insights_per_report]
502
+ if insight_list and not lines:
503
+ lines.append("**Key Insights:**")
504
+ for insight in insight_list:
505
+ lines.append(
506
+ f"- {insight.get('title', 'Insight')}: {insight.get('description', '')}"
507
+ )
508
+
509
+ return "\n".join(lines) if lines else "No significant findings to report."
510
+
511
+ def _generate_statistics_section(self, stats_results: Dict[str, Any]) -> str:
512
+ """Generate statistics section"""
513
+ lines = ["**Statistical Analysis Results:**", ""]
514
+
515
+ if "correlation_matrix" in stats_results:
516
+ lines.append(
517
+ "Correlation analysis was performed to identify relationships between variables."
518
+ )
519
+
520
+ if "hypothesis_tests" in stats_results:
521
+ lines.append("Hypothesis testing was conducted to validate statistical significance.")
522
+
523
+ return "\n".join(lines)
524
+
525
+ def _generate_insights_section(self, insights: Dict[str, Any]) -> str:
526
+ """Generate insights section"""
527
+ lines = []
528
+
529
+ insights.get("insights", [])
530
+ priority_insights = insights.get("priority_insights", [])
531
+
532
+ if priority_insights:
533
+ lines.append("**Priority Insights:**")
534
+ for i, insight in enumerate(priority_insights, 1):
535
+ title = insight.get("title", "Insight")
536
+ description = insight.get("description", "")
537
+ confidence = insight.get("confidence", 0)
538
+ impact = insight.get("impact", "medium")
539
+
540
+ lines.append(f"\n{i}. **{title}** (Confidence: {confidence:.0%}, Impact: {impact})")
541
+ lines.append(f" {description}")
542
+
543
+ if "recommendation" in insight:
544
+ lines.append(f" *Recommendation: {insight['recommendation']}*")
545
+
546
+ return "\n".join(lines) if lines else "No insights generated."
547
+
548
+ def _generate_recommendations_section(
549
+ self,
550
+ analysis_results: Dict[str, Any],
551
+ insights: Optional[Dict[str, Any]],
552
+ ) -> str:
553
+ """Generate recommendations section"""
554
+ lines = []
555
+
556
+ # Get recommendations from analysis results
557
+ if "recommendations" in analysis_results:
558
+ recs = analysis_results["recommendations"]
559
+ for i, rec in enumerate(recs[:10], 1):
560
+ action = rec.get("action", "Action")
561
+ reason = rec.get("reason", "")
562
+ priority = rec.get("priority", "medium")
563
+ lines.append(f"{i}. **{action}** (Priority: {priority})")
564
+ if reason:
565
+ lines.append(f" {reason}")
566
+
567
+ # Get recommendations from data profiler
568
+ data_profile = analysis_results.get("data_profile", {})
569
+ if "recommendations" in data_profile:
570
+ if not lines:
571
+ lines.append("**Data Quality Recommendations:**")
572
+ for rec in data_profile["recommendations"][:5]:
573
+ lines.append(f"- {rec.get('action', 'Action')}: {rec.get('reason', '')}")
574
+
575
+ return "\n".join(lines) if lines else "No specific recommendations at this time."
576
+
577
+ def _generate_conclusion(
578
+ self,
579
+ analysis_results: Dict[str, Any],
580
+ insights: Optional[Dict[str, Any]],
581
+ ) -> str:
582
+ """Generate conclusion"""
583
+ lines = []
584
+
585
+ lines.append("This comprehensive analysis has provided valuable insights into the dataset.")
586
+
587
+ if insights:
588
+ total_insights = insights.get("total_insights", 0)
589
+ lines.append(
590
+ f"A total of {total_insights} insights were generated through systematic analysis."
591
+ )
592
+
593
+ lines.append(
594
+ "\nThe findings and recommendations presented in this report should be carefully considered in the context of your specific business objectives and constraints."
595
+ )
596
+
597
+ return "\n".join(lines)
598
+
599
+ def _generate_appendix(self, analysis_results: Dict[str, Any]) -> str:
600
+ """Generate appendix with technical details"""
601
+ lines = [
602
+ "**Technical Details:**",
603
+ "",
604
+ "This section contains technical information about the analysis process.",
605
+ "",
606
+ "Analysis was performed using the AIECS Data Analysis Orchestrator framework.",
607
+ ]
608
+
609
+ return "\n".join(lines)
610
+
611
+ def _compile_report(
612
+ self,
613
+ title: str,
614
+ sections: List[Dict[str, str]],
615
+ report_type: ReportType,
616
+ ) -> str:
617
+ """Compile report sections into final document"""
618
+ lines = [
619
+ f"# {title}",
620
+ "",
621
+ f"*Report Type: {report_type.value.replace('_', ' ').title()}*",
622
+ f"*Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}*",
623
+ "",
624
+ "---",
625
+ "",
626
+ ]
627
+
628
+ for section in sections:
629
+ lines.append(f"## {section['title']}")
630
+ lines.append("")
631
+ lines.append(section["content"])
632
+ lines.append("")
633
+ lines.append("---")
634
+ lines.append("")
635
+
636
+ return "\n".join(lines)
637
+
638
+ def _format_content(self, content: str, output_format: ReportFormat) -> str:
639
+ """Format content for specified output format"""
640
+ if output_format == ReportFormat.MARKDOWN:
641
+ return content
642
+ elif output_format == ReportFormat.HTML:
643
+ return self._markdown_to_html(content)
644
+ elif output_format == ReportFormat.JSON:
645
+ return self._content_to_json(content)
646
+ else:
647
+ # For PDF and Word, return markdown (would need additional
648
+ # libraries for conversion)
649
+ self.logger.warning(
650
+ f"Format {output_format.value} not fully implemented, returning markdown"
651
+ )
652
+ return content
653
+
654
+ def _markdown_to_html(self, markdown_content: str) -> str:
655
+ """Convert markdown to HTML (basic implementation)"""
656
+ html = markdown_content
657
+ # Basic conversions
658
+ html = html.replace("# ", "<h1>").replace("\n", "</h1>\n", 1)
659
+ html = html.replace("## ", "<h2>").replace("\n", "</h2>\n")
660
+ html = html.replace("**", "<strong>").replace("**", "</strong>")
661
+ html = html.replace("*", "<em>").replace("*", "</em>")
662
+ html = f"<html><body>{html}</body></html>"
663
+ return html
664
+
665
+ def _content_to_json(self, content: str) -> str:
666
+ """Convert content to JSON format"""
667
+ import json
668
+
669
+ return json.dumps({"content": content, "format": "markdown"}, indent=2)
670
+
671
+ def _export_report(self, content: str, output_format: ReportFormat, title: str) -> str:
672
+ """Export report to file"""
673
+ # Generate filename
674
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
675
+ safe_title = title.replace(" ", "_").replace(":", "").lower()
676
+
677
+ extension_map = {
678
+ ReportFormat.MARKDOWN: ".md",
679
+ ReportFormat.HTML: ".html",
680
+ ReportFormat.PDF: ".pdf",
681
+ ReportFormat.WORD: ".docx",
682
+ ReportFormat.JSON: ".json",
683
+ }
684
+
685
+ extension = extension_map.get(output_format, ".txt")
686
+ filename = f"{safe_title}_{timestamp}{extension}"
687
+ filepath = os.path.join(self.config.output_directory, filename)
688
+
689
+ # Write file
690
+ with open(filepath, "w", encoding="utf-8") as f:
691
+ f.write(content)
692
+
693
+ self.logger.info(f"Report exported to: {filepath}")
694
+ return filepath