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,1317 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Document Creator Tool
4
+
5
+ This tool is responsible for creating new documents from templates,
6
+ initializing document structure, and managing document metadata.
7
+
8
+ Key Features:
9
+ 1. Template-based document creation
10
+ 2. Document structure initialization
11
+ 3. Metadata management (title, author, date, etc.)
12
+ 4. Style configuration and presets
13
+ 5. Multi-format support (MD, HTML, DOCX, PDF, etc.)
14
+ """
15
+
16
+ import os
17
+ import json
18
+ import uuid
19
+ import tempfile
20
+ import logging
21
+ from datetime import datetime
22
+ from typing import Dict, Any, List, Optional
23
+ from enum import Enum
24
+
25
+ from pydantic import BaseModel, Field, ConfigDict
26
+
27
+ from aiecs.tools.base_tool import BaseTool
28
+ from aiecs.tools import register_tool
29
+
30
+
31
+ class DocumentType(str, Enum):
32
+ """Supported document types"""
33
+
34
+ REPORT = "report"
35
+ ARTICLE = "article"
36
+ PRESENTATION = "presentation"
37
+ MANUAL = "manual"
38
+ LETTER = "letter"
39
+ PROPOSAL = "proposal"
40
+ ACADEMIC = "academic"
41
+ TECHNICAL = "technical"
42
+ CREATIVE = "creative"
43
+ CUSTOM = "custom"
44
+
45
+
46
+ class DocumentFormat(str, Enum):
47
+ """Supported output formats"""
48
+
49
+ MARKDOWN = "markdown"
50
+ HTML = "html"
51
+ DOCX = "docx"
52
+ PDF = "pdf"
53
+ LATEX = "latex"
54
+ PLAIN_TEXT = "txt"
55
+ JSON = "json"
56
+ XML = "xml"
57
+
58
+
59
+ class TemplateType(str, Enum):
60
+ """Document template types"""
61
+
62
+ BLANK = "blank"
63
+ BUSINESS_REPORT = "business_report"
64
+ TECHNICAL_DOC = "technical_doc"
65
+ ACADEMIC_PAPER = "academic_paper"
66
+ PROJECT_PROPOSAL = "project_proposal"
67
+ USER_MANUAL = "user_manual"
68
+ PRESENTATION = "presentation"
69
+ NEWSLETTER = "newsletter"
70
+ INVOICE = "invoice"
71
+ CUSTOM = "custom"
72
+
73
+
74
+ class StylePreset(str, Enum):
75
+ """Style presets for documents"""
76
+
77
+ DEFAULT = "default"
78
+ CORPORATE = "corporate"
79
+ ACADEMIC = "academic"
80
+ MODERN = "modern"
81
+ CLASSIC = "classic"
82
+ MINIMAL = "minimal"
83
+ COLORFUL = "colorful"
84
+ PROFESSIONAL = "professional"
85
+
86
+
87
+ class DocumentCreatorError(Exception):
88
+ """Base exception for Document Creator errors"""
89
+
90
+
91
+ class TemplateError(DocumentCreatorError):
92
+ """Raised when template operations fail"""
93
+
94
+
95
+ class DocumentCreationError(DocumentCreatorError):
96
+ """Raised when document creation fails"""
97
+
98
+
99
+ @register_tool("document_creator")
100
+ class DocumentCreatorTool(BaseTool):
101
+ """
102
+ Document Creator Tool for creating new documents from templates
103
+
104
+ This tool provides:
105
+ 1. Template management and selection
106
+ 2. Document structure initialization
107
+ 3. Metadata configuration
108
+ 4. Style and format setup
109
+ 5. Multi-format document creation
110
+
111
+ Integrates with:
112
+ - DocumentWriterTool for content writing
113
+ - DocumentLayoutTool for layout configuration
114
+ - ContentInsertionTool for complex content
115
+ """
116
+
117
+ # Configuration schema
118
+ class Config(BaseModel):
119
+ """Configuration for the document creator tool"""
120
+
121
+ model_config = ConfigDict(env_prefix="DOC_CREATOR_")
122
+
123
+ templates_dir: str = Field(
124
+ default=os.path.join(tempfile.gettempdir(), "document_templates"),
125
+ description="Directory for document templates",
126
+ )
127
+ output_dir: str = Field(
128
+ default=os.path.join(tempfile.gettempdir(), "created_documents"),
129
+ description="Directory for created documents",
130
+ )
131
+ default_format: str = Field(default="markdown", description="Default output format")
132
+ default_style: str = Field(default="default", description="Default style preset")
133
+ auto_backup: bool = Field(
134
+ default=True,
135
+ description="Whether to automatically backup created documents",
136
+ )
137
+ include_metadata: bool = Field(
138
+ default=True,
139
+ description="Whether to include metadata in created documents",
140
+ )
141
+ generate_toc: bool = Field(
142
+ default=True,
143
+ description="Whether to generate table of contents automatically",
144
+ )
145
+
146
+ def __init__(self, config: Optional[Dict] = None):
147
+ """Initialize Document Creator Tool with settings"""
148
+ super().__init__(config)
149
+
150
+ # Parse configuration
151
+ self.config = self.Config(**(config or {}))
152
+
153
+ self.logger = logging.getLogger(__name__)
154
+
155
+ # Initialize directories
156
+ self._init_directories()
157
+
158
+ # Initialize templates
159
+ self._init_templates()
160
+
161
+ # Initialize document tracking
162
+ self._documents_created = []
163
+
164
+ def _init_directories(self):
165
+ """Initialize required directories"""
166
+ os.makedirs(self.config.templates_dir, exist_ok=True)
167
+ os.makedirs(self.config.output_dir, exist_ok=True)
168
+
169
+ def _init_templates(self):
170
+ """Initialize built-in templates"""
171
+ self.templates = {
172
+ TemplateType.BLANK: self._get_blank_template(),
173
+ TemplateType.BUSINESS_REPORT: self._get_business_report_template(),
174
+ TemplateType.TECHNICAL_DOC: self._get_technical_doc_template(),
175
+ TemplateType.ACADEMIC_PAPER: self._get_academic_paper_template(),
176
+ TemplateType.PROJECT_PROPOSAL: self._get_project_proposal_template(),
177
+ TemplateType.USER_MANUAL: self._get_user_manual_template(),
178
+ TemplateType.PRESENTATION: self._get_presentation_template(),
179
+ TemplateType.NEWSLETTER: self._get_newsletter_template(),
180
+ TemplateType.INVOICE: self._get_invoice_template(),
181
+ }
182
+
183
+ # Schema definitions
184
+ class CreateDocumentSchema(BaseModel):
185
+ """Schema for create_document operation"""
186
+
187
+ document_type: DocumentType = Field(description="Type of document to create")
188
+ template_type: TemplateType = Field(description="Template to use")
189
+ output_format: DocumentFormat = Field(description="Output format")
190
+ metadata: Dict[str, Any] = Field(description="Document metadata")
191
+ style_preset: Optional[StylePreset] = Field(default=None, description="Style preset")
192
+ output_path: Optional[str] = Field(default=None, description="Custom output path")
193
+
194
+ class CreateFromTemplateSchema(BaseModel):
195
+ """Schema for create_from_template operation"""
196
+
197
+ template_name: str = Field(description="Name of template to use")
198
+ template_variables: Dict[str, Any] = Field(description="Variables to fill in template")
199
+ output_format: DocumentFormat = Field(description="Output format")
200
+ output_path: Optional[str] = Field(default=None, description="Custom output path")
201
+
202
+ class SetupStructureSchema(BaseModel):
203
+ """Schema for setup_document_structure operation"""
204
+
205
+ document_path: str = Field(description="Path to document")
206
+ sections: List[Dict[str, Any]] = Field(description="Document sections configuration")
207
+ generate_toc: bool = Field(default=True, description="Generate table of contents")
208
+ numbering_style: Optional[str] = Field(default=None, description="Section numbering style")
209
+
210
+ class ConfigureMetadataSchema(BaseModel):
211
+ """Schema for configure_metadata operation"""
212
+
213
+ document_path: str = Field(description="Path to document")
214
+ metadata: Dict[str, Any] = Field(description="Metadata to configure")
215
+ format_specific: bool = Field(default=True, description="Use format-specific metadata")
216
+
217
+ def create_document(
218
+ self,
219
+ document_type: DocumentType,
220
+ template_type: TemplateType,
221
+ output_format: DocumentFormat,
222
+ metadata: Dict[str, Any],
223
+ style_preset: Optional[StylePreset] = None,
224
+ output_path: Optional[str] = None,
225
+ ) -> Dict[str, Any]:
226
+ """
227
+ Create a new document from template
228
+
229
+ Args:
230
+ document_type: Type of document to create
231
+ template_type: Template to use
232
+ output_format: Output format for the document
233
+ metadata: Document metadata (title, author, etc.)
234
+ style_preset: Style preset to apply
235
+ output_path: Custom output path
236
+
237
+ Returns:
238
+ Dict containing document creation results
239
+ """
240
+ try:
241
+ start_time = datetime.now()
242
+ document_id = str(uuid.uuid4())
243
+
244
+ self.logger.info(
245
+ f"Creating document {document_id}: {document_type} using {template_type}"
246
+ )
247
+
248
+ # Step 1: Validate and prepare template
249
+ template = self._get_template(template_type)
250
+
251
+ # Step 2: Generate output path
252
+ if not output_path:
253
+ output_path = self._generate_output_path(document_type, output_format, document_id)
254
+
255
+ # Step 3: Process metadata
256
+ processed_metadata = self._process_metadata(metadata, output_format)
257
+
258
+ # Step 4: Apply style preset
259
+ style_config = self._get_style_config(style_preset or self.config.default_style)
260
+
261
+ # Step 5: Create document from template
262
+ document_content = self._create_document_from_template(
263
+ template, processed_metadata, style_config, output_format
264
+ )
265
+
266
+ # Step 6: Write document to file
267
+ self._write_document_file(output_path, document_content, output_format)
268
+
269
+ # Step 7: Track created document
270
+ document_info = {
271
+ "document_id": document_id,
272
+ "document_type": document_type,
273
+ "template_type": template_type,
274
+ "output_format": output_format,
275
+ "output_path": output_path,
276
+ "metadata": processed_metadata,
277
+ "style_preset": style_preset,
278
+ "creation_metadata": {
279
+ "created_at": start_time.isoformat(),
280
+ "file_size": (
281
+ os.path.getsize(output_path) if os.path.exists(output_path) else 0
282
+ ),
283
+ "duration": (datetime.now() - start_time).total_seconds(),
284
+ },
285
+ }
286
+
287
+ self._documents_created.append(document_info)
288
+
289
+ self.logger.info(f"Document {document_id} created successfully at {output_path}")
290
+ return document_info
291
+
292
+ except Exception as e:
293
+ raise DocumentCreationError(f"Failed to create document: {str(e)}")
294
+
295
+ def create_from_template(
296
+ self,
297
+ template_name: str,
298
+ template_variables: Dict[str, Any],
299
+ output_format: DocumentFormat,
300
+ output_path: Optional[str] = None,
301
+ ) -> Dict[str, Any]:
302
+ """
303
+ Create document from custom template with variables
304
+
305
+ Args:
306
+ template_name: Name of template file
307
+ template_variables: Variables to substitute in template
308
+ output_format: Output format
309
+ output_path: Custom output path
310
+
311
+ Returns:
312
+ Dict containing creation results
313
+ """
314
+ try:
315
+ # Load custom template
316
+ template_path = os.path.join(self.config.templates_dir, template_name)
317
+ if not os.path.exists(template_path):
318
+ raise TemplateError(f"Template not found: {template_name}")
319
+
320
+ with open(template_path, "r", encoding="utf-8") as f:
321
+ template_content = f.read()
322
+
323
+ # Process template variables
324
+ processed_content = self._process_template_variables(
325
+ template_content, template_variables
326
+ )
327
+
328
+ # Generate output path if not provided
329
+ if not output_path:
330
+ output_path = self._generate_output_path("custom", output_format, str(uuid.uuid4()))
331
+
332
+ # Write processed content
333
+ self._write_document_file(output_path, processed_content, output_format)
334
+
335
+ return {
336
+ "template_name": template_name,
337
+ "output_path": output_path,
338
+ "output_format": output_format,
339
+ "variables_used": template_variables,
340
+ "creation_time": datetime.now().isoformat(),
341
+ }
342
+
343
+ except Exception as e:
344
+ raise DocumentCreationError(f"Failed to create from template: {str(e)}")
345
+
346
+ def setup_document_structure(
347
+ self,
348
+ document_path: str,
349
+ sections: List[Dict[str, Any]],
350
+ generate_toc: bool = True,
351
+ numbering_style: Optional[str] = None,
352
+ ) -> Dict[str, Any]:
353
+ """
354
+ Setup document structure with sections and headers
355
+
356
+ Args:
357
+ document_path: Path to document
358
+ sections: List of section configurations
359
+ generate_toc: Whether to generate table of contents
360
+ numbering_style: Section numbering style
361
+
362
+ Returns:
363
+ Dict containing structure setup results
364
+ """
365
+ try:
366
+ self.logger.info(f"Setting up structure for document: {document_path}")
367
+
368
+ # Read existing document
369
+ if os.path.exists(document_path):
370
+ with open(document_path, "r", encoding="utf-8") as f:
371
+ content = f.read()
372
+ else:
373
+ content = ""
374
+
375
+ # Generate structure
376
+ structure_content = self._generate_document_structure(
377
+ sections, generate_toc, numbering_style
378
+ )
379
+
380
+ # Combine with existing content
381
+ final_content = self._combine_structure_with_content(structure_content, content)
382
+
383
+ # Write back to file
384
+ with open(document_path, "w", encoding="utf-8") as f:
385
+ f.write(final_content)
386
+
387
+ return {
388
+ "document_path": document_path,
389
+ "sections_created": len(sections),
390
+ "toc_generated": generate_toc,
391
+ "numbering_style": numbering_style,
392
+ "structure_setup_time": datetime.now().isoformat(),
393
+ }
394
+
395
+ except Exception as e:
396
+ raise DocumentCreationError(f"Failed to setup document structure: {str(e)}")
397
+
398
+ def configure_metadata(
399
+ self,
400
+ document_path: str,
401
+ metadata: Dict[str, Any],
402
+ format_specific: bool = True,
403
+ ) -> Dict[str, Any]:
404
+ """
405
+ Configure document metadata
406
+
407
+ Args:
408
+ document_path: Path to document
409
+ metadata: Metadata to configure
410
+ format_specific: Use format-specific metadata syntax
411
+
412
+ Returns:
413
+ Dict containing metadata configuration results
414
+ """
415
+ try:
416
+ # Detect document format
417
+ file_format = self._detect_document_format(document_path)
418
+
419
+ # Generate metadata content
420
+ if format_specific:
421
+ metadata_content = self._generate_format_specific_metadata(metadata, file_format)
422
+ else:
423
+ metadata_content = self._generate_generic_metadata(metadata)
424
+
425
+ # Insert metadata into document
426
+ self._insert_metadata_into_document(document_path, metadata_content, file_format)
427
+
428
+ return {
429
+ "document_path": document_path,
430
+ "metadata_configured": metadata,
431
+ "format": file_format,
432
+ "format_specific": format_specific,
433
+ "configuration_time": datetime.now().isoformat(),
434
+ }
435
+
436
+ except Exception as e:
437
+ raise DocumentCreationError(f"Failed to configure metadata: {str(e)}")
438
+
439
+ def list_templates(self) -> Dict[str, Any]:
440
+ """
441
+ List available document templates
442
+
443
+ Returns:
444
+ Dict containing available templates
445
+ """
446
+ built_in_templates = list(self.templates.keys())
447
+
448
+ # Scan for custom templates
449
+ custom_templates = []
450
+ if os.path.exists(self.config.templates_dir):
451
+ for file in os.listdir(self.config.templates_dir):
452
+ if file.endswith((".md", ".html", ".txt", ".json")):
453
+ custom_templates.append(file)
454
+
455
+ return {
456
+ "built_in_templates": [t.value for t in built_in_templates],
457
+ "custom_templates": custom_templates,
458
+ "templates_directory": self.config.templates_dir,
459
+ "total_templates": len(built_in_templates) + len(custom_templates),
460
+ }
461
+
462
+ def get_template_info(self, template_type: TemplateType) -> Dict[str, Any]:
463
+ """
464
+ Get information about a specific template
465
+
466
+ Args:
467
+ template_type: Type of template
468
+
469
+ Returns:
470
+ Dict containing template information
471
+ """
472
+ if template_type not in self.templates:
473
+ raise TemplateError(f"Template not found: {template_type}")
474
+
475
+ template = self.templates[template_type]
476
+
477
+ return {
478
+ "template_type": template_type.value,
479
+ "name": template.get("name", ""),
480
+ "description": template.get("description", ""),
481
+ "sections": template.get("sections", []),
482
+ "variables": template.get("variables", []),
483
+ "supported_formats": template.get("supported_formats", []),
484
+ "style_presets": template.get("style_presets", []),
485
+ }
486
+
487
+ def get_created_documents(self) -> List[Dict[str, Any]]:
488
+ """
489
+ Get list of documents created in this session
490
+
491
+ Returns:
492
+ List of created document information
493
+ """
494
+ return self._documents_created.copy()
495
+
496
+ # Template definitions
497
+ def _get_blank_template(self) -> Dict[str, Any]:
498
+ """Get blank document template"""
499
+ return {
500
+ "name": "Blank Document",
501
+ "description": "Empty document with basic structure",
502
+ "content": "",
503
+ "sections": [],
504
+ "variables": [],
505
+ "supported_formats": ["markdown", "html", "txt", "docx"],
506
+ "metadata_template": {
507
+ "title": "New Document",
508
+ "author": "Author",
509
+ "date": datetime.now().strftime("%Y-%m-%d"),
510
+ },
511
+ }
512
+
513
+ def _get_business_report_template(self) -> Dict[str, Any]:
514
+ """Get business report template"""
515
+ return {
516
+ "name": "Business Report",
517
+ "description": "Professional business report template",
518
+ "content": """# {title}
519
+
520
+ **Date:** {date}
521
+ **Author:** {author}
522
+ **Department:** {department}
523
+
524
+ ## Executive Summary
525
+
526
+ {executive_summary}
527
+
528
+ ## Introduction
529
+
530
+ {introduction}
531
+
532
+ ## Analysis
533
+
534
+ ### Key Findings
535
+
536
+ {key_findings}
537
+
538
+ ### Data Analysis
539
+
540
+ {data_analysis}
541
+
542
+ ## Recommendations
543
+
544
+ {recommendations}
545
+
546
+ ## Conclusion
547
+
548
+ {conclusion}
549
+
550
+ ## Appendices
551
+
552
+ {appendices}
553
+ """,
554
+ "sections": [
555
+ {"name": "Executive Summary", "level": 2, "required": True},
556
+ {"name": "Introduction", "level": 2, "required": True},
557
+ {"name": "Analysis", "level": 2, "required": True},
558
+ {"name": "Recommendations", "level": 2, "required": True},
559
+ {"name": "Conclusion", "level": 2, "required": True},
560
+ ],
561
+ "variables": [
562
+ "title",
563
+ "date",
564
+ "author",
565
+ "department",
566
+ "executive_summary",
567
+ "introduction",
568
+ "key_findings",
569
+ "data_analysis",
570
+ "recommendations",
571
+ "conclusion",
572
+ "appendices",
573
+ ],
574
+ "supported_formats": ["markdown", "html", "docx", "pdf"],
575
+ "style_presets": ["corporate", "professional", "modern"],
576
+ }
577
+
578
+ def _get_technical_doc_template(self) -> Dict[str, Any]:
579
+ """Get technical documentation template"""
580
+ return {
581
+ "name": "Technical Documentation",
582
+ "description": "Technical documentation with code examples",
583
+ "content": """# {title}
584
+
585
+ **Version:** {version}
586
+ **Last Updated:** {date}
587
+ **Author:** {author}
588
+
589
+ ## Overview
590
+
591
+ {overview}
592
+
593
+ ## Prerequisites
594
+
595
+ {prerequisites}
596
+
597
+ ## Installation
598
+
599
+ {installation}
600
+
601
+ ## Configuration
602
+
603
+ {configuration}
604
+
605
+ ## Usage
606
+
607
+ {usage}
608
+
609
+ ## API Reference
610
+
611
+ {api_reference}
612
+
613
+ ## Examples
614
+
615
+ {examples}
616
+
617
+ ## Troubleshooting
618
+
619
+ {troubleshooting}
620
+
621
+ ## Changelog
622
+
623
+ {changelog}
624
+ """,
625
+ "sections": [
626
+ {"name": "Overview", "level": 2, "required": True},
627
+ {"name": "Prerequisites", "level": 2, "required": False},
628
+ {"name": "Installation", "level": 2, "required": True},
629
+ {"name": "Configuration", "level": 2, "required": False},
630
+ {"name": "Usage", "level": 2, "required": True},
631
+ {"name": "API Reference", "level": 2, "required": False},
632
+ {"name": "Examples", "level": 2, "required": True},
633
+ {"name": "Troubleshooting", "level": 2, "required": False},
634
+ ],
635
+ "variables": [
636
+ "title",
637
+ "version",
638
+ "date",
639
+ "author",
640
+ "overview",
641
+ "prerequisites",
642
+ "installation",
643
+ "configuration",
644
+ "usage",
645
+ "api_reference",
646
+ "examples",
647
+ "troubleshooting",
648
+ "changelog",
649
+ ],
650
+ "supported_formats": ["markdown", "html", "pdf"],
651
+ "style_presets": ["technical", "modern", "minimal"],
652
+ }
653
+
654
+ def _get_academic_paper_template(self) -> Dict[str, Any]:
655
+ """Get academic paper template"""
656
+ return {
657
+ "name": "Academic Paper",
658
+ "description": "Academic research paper template",
659
+ "content": """# {title}
660
+
661
+ **Author:** {author}
662
+ **Institution:** {institution}
663
+ **Email:** {email}
664
+ **Date:** {date}
665
+
666
+ ## Abstract
667
+
668
+ {abstract}
669
+
670
+ **Keywords:** {keywords}
671
+
672
+ ## 1. Introduction
673
+
674
+ {introduction}
675
+
676
+ ## 2. Literature Review
677
+
678
+ {literature_review}
679
+
680
+ ## 3. Methodology
681
+
682
+ {methodology}
683
+
684
+ ## 4. Results
685
+
686
+ {results}
687
+
688
+ ## 5. Discussion
689
+
690
+ {discussion}
691
+
692
+ ## 6. Conclusion
693
+
694
+ {conclusion}
695
+
696
+ ## References
697
+
698
+ {references}
699
+
700
+ ## Appendices
701
+
702
+ {appendices}
703
+ """,
704
+ "sections": [
705
+ {"name": "Abstract", "level": 2, "required": True},
706
+ {"name": "Introduction", "level": 2, "required": True},
707
+ {"name": "Literature Review", "level": 2, "required": True},
708
+ {"name": "Methodology", "level": 2, "required": True},
709
+ {"name": "Results", "level": 2, "required": True},
710
+ {"name": "Discussion", "level": 2, "required": True},
711
+ {"name": "Conclusion", "level": 2, "required": True},
712
+ {"name": "References", "level": 2, "required": True},
713
+ ],
714
+ "variables": [
715
+ "title",
716
+ "author",
717
+ "institution",
718
+ "email",
719
+ "date",
720
+ "abstract",
721
+ "keywords",
722
+ "introduction",
723
+ "literature_review",
724
+ "methodology",
725
+ "results",
726
+ "discussion",
727
+ "conclusion",
728
+ "references",
729
+ "appendices",
730
+ ],
731
+ "supported_formats": ["markdown", "latex", "pdf"],
732
+ "style_presets": ["academic", "classic", "formal"],
733
+ }
734
+
735
+ def _get_project_proposal_template(self) -> Dict[str, Any]:
736
+ """Get project proposal template"""
737
+ return {
738
+ "name": "Project Proposal",
739
+ "description": "Project proposal and planning template",
740
+ "content": """# {project_name}
741
+
742
+ **Proposal Date:** {date}
743
+ **Project Manager:** {project_manager}
744
+ **Department:** {department}
745
+ **Budget:** {budget}
746
+
747
+ ## Project Overview
748
+
749
+ {project_overview}
750
+
751
+ ## Objectives
752
+
753
+ {objectives}
754
+
755
+ ## Scope
756
+
757
+ ### In Scope
758
+ {in_scope}
759
+
760
+ ### Out of Scope
761
+ {out_scope}
762
+
763
+ ## Timeline
764
+
765
+ {timeline}
766
+
767
+ ## Resources Required
768
+
769
+ {resources}
770
+
771
+ ## Budget Breakdown
772
+
773
+ {budget_breakdown}
774
+
775
+ ## Risk Assessment
776
+
777
+ {risk_assessment}
778
+
779
+ ## Success Criteria
780
+
781
+ {success_criteria}
782
+
783
+ ## Next Steps
784
+
785
+ {next_steps}
786
+ """,
787
+ "variables": [
788
+ "project_name",
789
+ "date",
790
+ "project_manager",
791
+ "department",
792
+ "budget",
793
+ "project_overview",
794
+ "objectives",
795
+ "in_scope",
796
+ "out_scope",
797
+ "timeline",
798
+ "resources",
799
+ "budget_breakdown",
800
+ "risk_assessment",
801
+ "success_criteria",
802
+ "next_steps",
803
+ ],
804
+ "supported_formats": ["markdown", "html", "docx", "pdf"],
805
+ "style_presets": ["professional", "corporate", "modern"],
806
+ }
807
+
808
+ def _get_user_manual_template(self) -> Dict[str, Any]:
809
+ """Get user manual template"""
810
+ return {
811
+ "name": "User Manual",
812
+ "description": "User manual and guide template",
813
+ "content": """# {product_name} User Manual
814
+
815
+ **Version:** {version}
816
+ **Date:** {date}
817
+ **Support:** {support_contact}
818
+
819
+ ## Table of Contents
820
+
821
+ 1. [Getting Started](#getting-started)
822
+ 2. [Basic Features](#basic-features)
823
+ 3. [Advanced Features](#advanced-features)
824
+ 4. [Troubleshooting](#troubleshooting)
825
+ 5. [FAQ](#faq)
826
+
827
+ ## Getting Started
828
+
829
+ {getting_started}
830
+
831
+ ## Basic Features
832
+
833
+ {basic_features}
834
+
835
+ ## Advanced Features
836
+
837
+ {advanced_features}
838
+
839
+ ## Troubleshooting
840
+
841
+ {troubleshooting}
842
+
843
+ ## FAQ
844
+
845
+ {faq}
846
+
847
+ ## Contact Support
848
+
849
+ {support_info}
850
+ """,
851
+ "variables": [
852
+ "product_name",
853
+ "version",
854
+ "date",
855
+ "support_contact",
856
+ "getting_started",
857
+ "basic_features",
858
+ "advanced_features",
859
+ "troubleshooting",
860
+ "faq",
861
+ "support_info",
862
+ ],
863
+ "supported_formats": ["markdown", "html", "pdf"],
864
+ "style_presets": ["user-friendly", "modern", "minimal"],
865
+ }
866
+
867
+ def _get_presentation_template(self) -> Dict[str, Any]:
868
+ """Get presentation template"""
869
+ return {
870
+ "name": "Presentation",
871
+ "description": "Slide presentation template",
872
+ "content": """# {title}
873
+
874
+ ---
875
+
876
+ ## Slide 1: Title Slide
877
+
878
+ ### {title}
879
+ **Presenter:** {presenter}
880
+ **Date:** {date}
881
+ **Organization:** {organization}
882
+
883
+ ---
884
+
885
+ ## Slide 2: Agenda
886
+
887
+ {agenda}
888
+
889
+ ---
890
+
891
+ ## Slide 3: Introduction
892
+
893
+ {introduction}
894
+
895
+ ---
896
+
897
+ ## Slide 4: Main Content
898
+
899
+ {main_content}
900
+
901
+ ---
902
+
903
+ ## Slide 5: Conclusion
904
+
905
+ {conclusion}
906
+
907
+ ---
908
+
909
+ ## Slide 6: Questions
910
+
911
+ {questions}
912
+
913
+ ---
914
+
915
+ ## Slide 7: Thank You
916
+
917
+ **Contact Information:**
918
+ {contact_info}
919
+ """,
920
+ "variables": [
921
+ "title",
922
+ "presenter",
923
+ "date",
924
+ "organization",
925
+ "agenda",
926
+ "introduction",
927
+ "main_content",
928
+ "conclusion",
929
+ "questions",
930
+ "contact_info",
931
+ ],
932
+ "supported_formats": ["markdown", "html"],
933
+ "style_presets": ["presentation", "modern", "colorful"],
934
+ }
935
+
936
+ def _get_newsletter_template(self) -> Dict[str, Any]:
937
+ """Get newsletter template"""
938
+ return {
939
+ "name": "Newsletter",
940
+ "description": "Newsletter and bulletin template",
941
+ "content": """# {newsletter_name}
942
+
943
+ **Issue #{issue_number}** | {date}
944
+
945
+ ## Headlines
946
+
947
+ {headlines}
948
+
949
+ ## Feature Article
950
+
951
+ {feature_article}
952
+
953
+ ## News Briefs
954
+
955
+ {news_briefs}
956
+
957
+ ## Upcoming Events
958
+
959
+ {upcoming_events}
960
+
961
+ ## Community Spotlight
962
+
963
+ {community_spotlight}
964
+
965
+ ## Contact Us
966
+
967
+ {contact_info}
968
+ """,
969
+ "variables": [
970
+ "newsletter_name",
971
+ "issue_number",
972
+ "date",
973
+ "headlines",
974
+ "feature_article",
975
+ "news_briefs",
976
+ "upcoming_events",
977
+ "community_spotlight",
978
+ "contact_info",
979
+ ],
980
+ "supported_formats": ["markdown", "html"],
981
+ "style_presets": ["newsletter", "colorful", "modern"],
982
+ }
983
+
984
+ def _get_invoice_template(self) -> Dict[str, Any]:
985
+ """Get invoice template"""
986
+ return {
987
+ "name": "Invoice",
988
+ "description": "Business invoice template",
989
+ "content": """# INVOICE
990
+
991
+ **Invoice #:** {invoice_number}
992
+ **Date:** {date}
993
+ **Due Date:** {due_date}
994
+
995
+ ## Bill To:
996
+ {client_info}
997
+
998
+ ## Bill From:
999
+ {company_info}
1000
+
1001
+ ## Items
1002
+
1003
+ {items_table}
1004
+
1005
+ ## Summary
1006
+
1007
+ **Subtotal:** {subtotal}
1008
+ **Tax:** {tax}
1009
+ **Total:** {total}
1010
+
1011
+ ## Payment Terms
1012
+
1013
+ {payment_terms}
1014
+
1015
+ ## Notes
1016
+
1017
+ {notes}
1018
+ """,
1019
+ "variables": [
1020
+ "invoice_number",
1021
+ "date",
1022
+ "due_date",
1023
+ "client_info",
1024
+ "company_info",
1025
+ "items_table",
1026
+ "subtotal",
1027
+ "tax",
1028
+ "total",
1029
+ "payment_terms",
1030
+ "notes",
1031
+ ],
1032
+ "supported_formats": ["markdown", "html", "pdf"],
1033
+ "style_presets": ["professional", "corporate", "minimal"],
1034
+ }
1035
+
1036
+ # Helper methods
1037
+ def _get_template(self, template_type: TemplateType) -> Dict[str, Any]:
1038
+ """Get template by type"""
1039
+ if template_type not in self.templates:
1040
+ raise TemplateError(f"Template not found: {template_type}")
1041
+ return self.templates[template_type]
1042
+
1043
+ def _generate_output_path(
1044
+ self,
1045
+ document_type: str,
1046
+ output_format: DocumentFormat,
1047
+ document_id: str,
1048
+ ) -> str:
1049
+ """Generate output path for document"""
1050
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
1051
+ filename = f"{document_type}_{timestamp}_{document_id[:8]}.{output_format.value}"
1052
+ return os.path.join(self.config.output_dir, filename)
1053
+
1054
+ def _process_metadata(
1055
+ self, metadata: Dict[str, Any], output_format: DocumentFormat
1056
+ ) -> Dict[str, Any]:
1057
+ """Process and validate metadata"""
1058
+ processed = metadata.copy()
1059
+
1060
+ # Add default metadata if missing
1061
+ if "date" not in processed:
1062
+ processed["date"] = datetime.now().strftime("%Y-%m-%d")
1063
+ if "created_by" not in processed:
1064
+ processed["created_by"] = "AIECS Document Creator"
1065
+ if "format" not in processed:
1066
+ processed["format"] = output_format.value
1067
+
1068
+ return processed
1069
+
1070
+ def _get_style_config(self, style_preset: StylePreset) -> Dict[str, Any]:
1071
+ """Get style configuration for preset"""
1072
+ style_configs = {
1073
+ StylePreset.DEFAULT: {
1074
+ "font_family": "Arial",
1075
+ "font_size": 12,
1076
+ "colors": {"primary": "#000000"},
1077
+ },
1078
+ StylePreset.CORPORATE: {
1079
+ "font_family": "Calibri",
1080
+ "font_size": 11,
1081
+ "colors": {"primary": "#2E5D92"},
1082
+ },
1083
+ StylePreset.ACADEMIC: {
1084
+ "font_family": "Times New Roman",
1085
+ "font_size": 12,
1086
+ "colors": {"primary": "#000000"},
1087
+ },
1088
+ StylePreset.MODERN: {
1089
+ "font_family": "Helvetica",
1090
+ "font_size": 11,
1091
+ "colors": {"primary": "#333333"},
1092
+ },
1093
+ StylePreset.CLASSIC: {
1094
+ "font_family": "Georgia",
1095
+ "font_size": 12,
1096
+ "colors": {"primary": "#1a1a1a"},
1097
+ },
1098
+ StylePreset.MINIMAL: {
1099
+ "font_family": "Arial",
1100
+ "font_size": 10,
1101
+ "colors": {"primary": "#444444"},
1102
+ },
1103
+ StylePreset.COLORFUL: {
1104
+ "font_family": "Verdana",
1105
+ "font_size": 11,
1106
+ "colors": {"primary": "#2E8B57"},
1107
+ },
1108
+ StylePreset.PROFESSIONAL: {
1109
+ "font_family": "Segoe UI",
1110
+ "font_size": 11,
1111
+ "colors": {"primary": "#2F4F4F"},
1112
+ },
1113
+ }
1114
+ return style_configs.get(style_preset, style_configs[StylePreset.DEFAULT])
1115
+
1116
+ def _create_document_from_template(
1117
+ self,
1118
+ template: Dict[str, Any],
1119
+ metadata: Dict[str, Any],
1120
+ style_config: Dict[str, Any],
1121
+ output_format: DocumentFormat,
1122
+ ) -> str:
1123
+ """Create document content from template"""
1124
+ content = template.get("content", "")
1125
+
1126
+ # Apply metadata to template
1127
+ if content and template.get("variables"):
1128
+ # Replace template variables with metadata values
1129
+ for var in template["variables"]:
1130
+ placeholder = f"{{{var}}}"
1131
+ value = metadata.get(var, f"[{var}]")
1132
+ content = content.replace(placeholder, str(value))
1133
+
1134
+ # Add metadata header if required
1135
+ if self.config.include_metadata:
1136
+ metadata_header = self._generate_metadata_header(metadata, output_format)
1137
+ content = metadata_header + "\n\n" + content
1138
+
1139
+ return content
1140
+
1141
+ def _generate_metadata_header(
1142
+ self, metadata: Dict[str, Any], output_format: DocumentFormat
1143
+ ) -> str:
1144
+ """Generate metadata header for document"""
1145
+ if output_format == DocumentFormat.MARKDOWN:
1146
+ return "---\n" + "\n".join([f"{k}: {v}" for k, v in metadata.items()]) + "\n---"
1147
+ elif output_format == DocumentFormat.HTML:
1148
+ meta_tags = "\n".join([f'<meta name="{k}" content="{v}">' for k, v in metadata.items()])
1149
+ return f"<!-- Document Metadata -->\n{meta_tags}\n<!-- End Metadata -->"
1150
+ else:
1151
+ return "# Document Metadata\n" + "\n".join([f"{k}: {v}" for k, v in metadata.items()])
1152
+
1153
+ def _write_document_file(self, output_path: str, content: str, output_format: DocumentFormat):
1154
+ """Write document content to file"""
1155
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
1156
+
1157
+ if output_format in [
1158
+ DocumentFormat.MARKDOWN,
1159
+ DocumentFormat.HTML,
1160
+ DocumentFormat.PLAIN_TEXT,
1161
+ DocumentFormat.LATEX,
1162
+ ]:
1163
+ with open(output_path, "w", encoding="utf-8") as f:
1164
+ f.write(content)
1165
+ elif output_format == DocumentFormat.JSON:
1166
+ with open(output_path, "w", encoding="utf-8") as f:
1167
+ json.dump({"content": content}, f, indent=2, ensure_ascii=False)
1168
+ else:
1169
+ # For other formats, write as text for now
1170
+ with open(output_path, "w", encoding="utf-8") as f:
1171
+ f.write(content)
1172
+
1173
+ def _process_template_variables(self, template_content: str, variables: Dict[str, Any]) -> str:
1174
+ """Process template variables in content"""
1175
+ result = template_content
1176
+ for key, value in variables.items():
1177
+ placeholder = f"{{{key}}}"
1178
+ result = result.replace(placeholder, str(value))
1179
+ return result
1180
+
1181
+ def _generate_document_structure(
1182
+ self,
1183
+ sections: List[Dict[str, Any]],
1184
+ generate_toc: bool,
1185
+ numbering_style: Optional[str],
1186
+ ) -> str:
1187
+ """Generate document structure from sections"""
1188
+ structure_parts = []
1189
+
1190
+ # Generate table of contents
1191
+ if generate_toc:
1192
+ toc = self._generate_table_of_contents(sections, numbering_style)
1193
+ structure_parts.append(toc)
1194
+
1195
+ # Generate section headers
1196
+ for i, section in enumerate(sections, 1):
1197
+ level = section.get("level", 2)
1198
+ title = section.get("title", f"Section {i}")
1199
+
1200
+ if numbering_style == "numeric":
1201
+ header = f"{'#' * level} {i}. {title}"
1202
+ elif numbering_style == "alpha":
1203
+ alpha = chr(ord("A") + i - 1) if i <= 26 else f"Section{i}"
1204
+ header = f"{'#' * level} {alpha}. {title}"
1205
+ else:
1206
+ header = f"{'#' * level} {title}"
1207
+
1208
+ structure_parts.append(header)
1209
+ structure_parts.append("") # Empty line
1210
+
1211
+ # Add placeholder content
1212
+ placeholder = section.get("placeholder", f"Content for {title} goes here...")
1213
+ structure_parts.append(placeholder)
1214
+ structure_parts.append("") # Empty line
1215
+
1216
+ return "\n".join(structure_parts)
1217
+
1218
+ def _generate_table_of_contents(
1219
+ self, sections: List[Dict[str, Any]], numbering_style: Optional[str]
1220
+ ) -> str:
1221
+ """Generate table of contents"""
1222
+ toc_parts = ["# Table of Contents", ""]
1223
+
1224
+ for i, section in enumerate(sections, 1):
1225
+ title = section.get("title", f"Section {i}")
1226
+ level = section.get("level", 2)
1227
+ indent = " " * (level - 1)
1228
+
1229
+ if numbering_style == "numeric":
1230
+ toc_line = f"{indent}- {i}. {title}"
1231
+ elif numbering_style == "alpha":
1232
+ alpha = chr(ord("A") + i - 1) if i <= 26 else f"Section{i}"
1233
+ toc_line = f"{indent}- {alpha}. {title}"
1234
+ else:
1235
+ toc_line = f"{indent}- {title}"
1236
+
1237
+ toc_parts.append(toc_line)
1238
+
1239
+ toc_parts.extend(["", "---", ""])
1240
+ return "\n".join(toc_parts)
1241
+
1242
+ def _combine_structure_with_content(self, structure: str, existing_content: str) -> str:
1243
+ """Combine generated structure with existing content"""
1244
+ if not existing_content.strip():
1245
+ return structure
1246
+
1247
+ # If existing content has structure markers, replace them
1248
+ if "# Table of Contents" in existing_content:
1249
+ # Replace existing structure
1250
+ lines = existing_content.split("\n")
1251
+ content_start = -1
1252
+ for i, line in enumerate(lines):
1253
+ if line.startswith("---") and i > 0:
1254
+ content_start = i + 1
1255
+ break
1256
+
1257
+ if content_start > 0:
1258
+ existing_body = "\n".join(lines[content_start:])
1259
+ return structure + "\n" + existing_body
1260
+
1261
+ return structure + "\n\n" + existing_content
1262
+
1263
+ def _detect_document_format(self, document_path: str) -> DocumentFormat:
1264
+ """Detect document format from file extension"""
1265
+ ext = os.path.splitext(document_path)[1].lower()
1266
+ format_map = {
1267
+ ".md": DocumentFormat.MARKDOWN,
1268
+ ".markdown": DocumentFormat.MARKDOWN,
1269
+ ".html": DocumentFormat.HTML,
1270
+ ".htm": DocumentFormat.HTML,
1271
+ ".txt": DocumentFormat.PLAIN_TEXT,
1272
+ ".json": DocumentFormat.JSON,
1273
+ ".xml": DocumentFormat.XML,
1274
+ ".tex": DocumentFormat.LATEX,
1275
+ ".docx": DocumentFormat.DOCX,
1276
+ ".pdf": DocumentFormat.PDF,
1277
+ }
1278
+ return format_map.get(ext, DocumentFormat.PLAIN_TEXT)
1279
+
1280
+ def _generate_format_specific_metadata(
1281
+ self, metadata: Dict[str, Any], file_format: DocumentFormat
1282
+ ) -> str:
1283
+ """Generate format-specific metadata"""
1284
+ if file_format == DocumentFormat.MARKDOWN:
1285
+ return "---\n" + "\n".join([f"{k}: {v}" for k, v in metadata.items()]) + "\n---"
1286
+ elif file_format == DocumentFormat.HTML:
1287
+ meta_tags = "\n".join([f'<meta name="{k}" content="{v}">' for k, v in metadata.items()])
1288
+ return f"<head>\n{meta_tags}\n</head>"
1289
+ elif file_format == DocumentFormat.LATEX:
1290
+ return "\n".join([f"\\{k}{{{v}}}" for k, v in metadata.items()])
1291
+ else:
1292
+ return self._generate_generic_metadata(metadata)
1293
+
1294
+ def _generate_generic_metadata(self, metadata: Dict[str, Any]) -> str:
1295
+ """Generate generic metadata"""
1296
+ return "% " + "\n% ".join([f"{k}: {v}" for k, v in metadata.items()])
1297
+
1298
+ def _insert_metadata_into_document(
1299
+ self,
1300
+ document_path: str,
1301
+ metadata_content: str,
1302
+ file_format: DocumentFormat,
1303
+ ):
1304
+ """Insert metadata into document"""
1305
+ with open(document_path, "r", encoding="utf-8") as f:
1306
+ content = f.read()
1307
+
1308
+ # Insert metadata at the beginning
1309
+ if file_format == DocumentFormat.HTML and "<head>" in content:
1310
+ # Insert into existing head section
1311
+ content = content.replace("<head>", f"<head>\n{metadata_content}")
1312
+ else:
1313
+ # Insert at the beginning
1314
+ content = metadata_content + "\n\n" + content
1315
+
1316
+ with open(document_path, "w", encoding="utf-8") as f:
1317
+ f.write(content)