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