aiecs 1.0.8__py3-none-any.whl → 1.2.0__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.

Potentially problematic release.


This version of aiecs might be problematic. Click here for more details.

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