aiecs 1.1.0__py3-none-any.whl → 1.2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

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 +1 -1
  3. aiecs/config/config.py +38 -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/context_engine.py +37 -33
  19. aiecs/infrastructure/monitoring/__init__.py +22 -0
  20. aiecs/infrastructure/monitoring/global_metrics_manager.py +207 -0
  21. aiecs/infrastructure/persistence/file_storage.py +41 -28
  22. aiecs/llm/__init__.py +44 -7
  23. aiecs/llm/callbacks/__init__.py +12 -0
  24. aiecs/llm/{custom_callbacks.py → callbacks/custom_callbacks.py} +1 -1
  25. aiecs/llm/client_factory.py +23 -6
  26. aiecs/llm/clients/__init__.py +35 -0
  27. aiecs/llm/{base_client.py → clients/base_client.py} +73 -1
  28. aiecs/llm/{googleai_client.py → clients/googleai_client.py} +19 -15
  29. aiecs/llm/{openai_client.py → clients/openai_client.py} +9 -14
  30. aiecs/llm/{vertex_client.py → clients/vertex_client.py} +15 -15
  31. aiecs/llm/{xai_client.py → clients/xai_client.py} +36 -50
  32. aiecs/llm/config/__init__.py +54 -0
  33. aiecs/llm/config/config_loader.py +275 -0
  34. aiecs/llm/config/config_validator.py +237 -0
  35. aiecs/llm/config/model_config.py +132 -0
  36. aiecs/llm/utils/__init__.py +11 -0
  37. aiecs/llm/utils/validate_config.py +91 -0
  38. aiecs/main.py +32 -2
  39. aiecs/scripts/aid/VERSION_MANAGEMENT.md +97 -0
  40. aiecs/scripts/aid/__init__.py +15 -0
  41. aiecs/scripts/aid/version_manager.py +224 -0
  42. aiecs/scripts/dependance_check/download_nlp_data.py +1 -0
  43. aiecs/tools/__init__.py +23 -23
  44. aiecs/tools/docs/__init__.py +5 -2
  45. aiecs/tools/docs/ai_document_orchestrator.py +39 -26
  46. aiecs/tools/docs/ai_document_writer_orchestrator.py +61 -38
  47. aiecs/tools/docs/content_insertion_tool.py +48 -28
  48. aiecs/tools/docs/document_creator_tool.py +47 -29
  49. aiecs/tools/docs/document_layout_tool.py +35 -20
  50. aiecs/tools/docs/document_parser_tool.py +56 -36
  51. aiecs/tools/docs/document_writer_tool.py +115 -62
  52. aiecs/tools/schema_generator.py +56 -56
  53. aiecs/tools/statistics/__init__.py +82 -0
  54. aiecs/tools/statistics/ai_data_analysis_orchestrator.py +581 -0
  55. aiecs/tools/statistics/ai_insight_generator_tool.py +473 -0
  56. aiecs/tools/statistics/ai_report_orchestrator_tool.py +629 -0
  57. aiecs/tools/statistics/data_loader_tool.py +518 -0
  58. aiecs/tools/statistics/data_profiler_tool.py +599 -0
  59. aiecs/tools/statistics/data_transformer_tool.py +531 -0
  60. aiecs/tools/statistics/data_visualizer_tool.py +460 -0
  61. aiecs/tools/statistics/model_trainer_tool.py +470 -0
  62. aiecs/tools/statistics/statistical_analyzer_tool.py +426 -0
  63. aiecs/tools/task_tools/chart_tool.py +2 -1
  64. aiecs/tools/task_tools/image_tool.py +43 -43
  65. aiecs/tools/task_tools/office_tool.py +39 -36
  66. aiecs/tools/task_tools/pandas_tool.py +37 -33
  67. aiecs/tools/task_tools/report_tool.py +67 -56
  68. aiecs/tools/task_tools/research_tool.py +32 -31
  69. aiecs/tools/task_tools/scraper_tool.py +53 -46
  70. aiecs/tools/task_tools/search_tool.py +1123 -0
  71. aiecs/tools/task_tools/stats_tool.py +20 -15
  72. aiecs/tools/tool_executor/__init__.py +2 -2
  73. aiecs/tools/tool_executor/tool_executor.py +3 -3
  74. {aiecs-1.1.0.dist-info → aiecs-1.2.1.dist-info}/METADATA +5 -1
  75. aiecs-1.2.1.dist-info/RECORD +144 -0
  76. {aiecs-1.1.0.dist-info → aiecs-1.2.1.dist-info}/entry_points.txt +1 -0
  77. aiecs/tools/task_tools/search_api.py +0 -7
  78. aiecs-1.1.0.dist-info/RECORD +0 -114
  79. {aiecs-1.1.0.dist-info → aiecs-1.2.1.dist-info}/WHEEL +0 -0
  80. {aiecs-1.1.0.dist-info → aiecs-1.2.1.dist-info}/licenses/LICENSE +0 -0
  81. {aiecs-1.1.0.dist-info → aiecs-1.2.1.dist-info}/top_level.txt +0 -0
@@ -6,7 +6,6 @@ from enum import Enum
6
6
  from datetime import datetime
7
7
 
8
8
  from pydantic import BaseModel, Field, ValidationError, ConfigDict
9
- from pydantic_settings import BaseSettings
10
9
 
11
10
  from aiecs.tools.base_tool import BaseTool
12
11
  from aiecs.tools import register_tool
@@ -31,16 +30,6 @@ class AIProvider(str, Enum):
31
30
  LOCAL = "local"
32
31
 
33
32
 
34
- class OrchestratorSettings(BaseSettings):
35
- """Configuration for AI Document Orchestrator"""
36
- default_ai_provider: AIProvider = AIProvider.OPENAI
37
- max_chunk_size: int = 4000 # For AI processing
38
- max_concurrent_requests: int = 5
39
- default_temperature: float = 0.1
40
- max_tokens: int = 2000
41
- timeout: int = 60
42
-
43
- model_config = ConfigDict(env_prefix="AI_DOC_ORCHESTRATOR_")
44
33
 
45
34
 
46
35
  class AIDocumentOrchestratorError(Exception):
@@ -73,18 +62,42 @@ class AIDocumentOrchestrator(BaseTool):
73
62
  - Existing AIECS infrastructure
74
63
  """
75
64
 
65
+ # Configuration schema
66
+ class Config(BaseModel):
67
+ """Configuration for the AI document orchestrator tool"""
68
+ model_config = ConfigDict(env_prefix="AI_DOC_ORCHESTRATOR_")
69
+
70
+ default_ai_provider: str = Field(
71
+ default="openai",
72
+ description="Default AI provider to use"
73
+ )
74
+ max_chunk_size: int = Field(
75
+ default=4000,
76
+ description="Maximum chunk size for AI processing"
77
+ )
78
+ max_concurrent_requests: int = Field(
79
+ default=5,
80
+ description="Maximum concurrent AI requests"
81
+ )
82
+ default_temperature: float = Field(
83
+ default=0.1,
84
+ description="Default temperature for AI model"
85
+ )
86
+ max_tokens: int = Field(
87
+ default=2000,
88
+ description="Maximum tokens for AI response"
89
+ )
90
+ timeout: int = Field(
91
+ default=60,
92
+ description="Timeout in seconds for AI operations"
93
+ )
94
+
76
95
  def __init__(self, config: Optional[Dict] = None):
77
96
  """Initialize AI Document Orchestrator with settings"""
78
97
  super().__init__(config)
79
- # Initialize settings with config if provided
80
- if config:
81
- try:
82
- # For BaseSettings, use dictionary unpacking
83
- self.settings = OrchestratorSettings(**config)
84
- except ValidationError as e:
85
- raise ValueError(f"Invalid settings: {e}")
86
- else:
87
- self.settings = OrchestratorSettings()
98
+
99
+ # Parse configuration
100
+ self.config = self.Config(**(config or {}))
88
101
 
89
102
  self.logger = logging.getLogger(__name__)
90
103
 
@@ -212,7 +225,7 @@ class AIDocumentOrchestrator(BaseTool):
212
225
  ai_result = self._process_with_ai(
213
226
  content,
214
227
  processing_mode,
215
- ai_provider or self.settings.default_ai_provider,
228
+ ai_provider or self.config.default_ai_provider,
216
229
  processing_params or {},
217
230
  ai_params or {}
218
231
  )
@@ -221,7 +234,7 @@ class AIDocumentOrchestrator(BaseTool):
221
234
  result = {
222
235
  "source": source,
223
236
  "processing_mode": processing_mode,
224
- "ai_provider": ai_provider or self.settings.default_ai_provider,
237
+ "ai_provider": ai_provider or self.config.default_ai_provider,
225
238
  "document_info": {
226
239
  "type": parsed_result.get("document_type"),
227
240
  "detection_confidence": parsed_result.get("detection_confidence"),
@@ -282,7 +295,7 @@ class AIDocumentOrchestrator(BaseTool):
282
295
  """
283
296
  try:
284
297
  start_time = datetime.now()
285
- max_concurrent = max_concurrent or self.settings.max_concurrent_requests
298
+ max_concurrent = max_concurrent or self.config.max_concurrent_requests
286
299
 
287
300
  # Process documents in batches
288
301
  results = asyncio.run(self._batch_process_async(
@@ -293,7 +306,7 @@ class AIDocumentOrchestrator(BaseTool):
293
306
  batch_result = {
294
307
  "sources": sources,
295
308
  "processing_mode": processing_mode,
296
- "ai_provider": ai_provider or self.settings.default_ai_provider,
309
+ "ai_provider": ai_provider or self.config.default_ai_provider,
297
310
  "total_documents": len(sources),
298
311
  "successful_documents": len([r for r in results if r.get("status") == "success"]),
299
312
  "failed_documents": len([r for r in results if r.get("status") == "error"]),
@@ -341,7 +354,7 @@ class AIDocumentOrchestrator(BaseTool):
341
354
  # Process with AI
342
355
  ai_result = self._call_ai_provider(
343
356
  prompt,
344
- ai_provider or self.settings.default_ai_provider,
357
+ ai_provider or self.config.default_ai_provider,
345
358
  {}
346
359
  )
347
360
 
@@ -380,7 +393,7 @@ class AIDocumentOrchestrator(BaseTool):
380
393
  text_content = str(content)
381
394
 
382
395
  # Chunk content if too large
383
- max_size = self.settings.max_chunk_size
396
+ max_size = self.config.max_chunk_size
384
397
  if len(text_content) > max_size:
385
398
  # For now, truncate - could implement smart chunking
386
399
  text_content = text_content[:max_size] + "\n\n[Content truncated...]"
@@ -6,8 +6,7 @@ from typing import Dict, Any, List, Optional, Union, Callable
6
6
  from enum import Enum
7
7
  from datetime import datetime
8
8
 
9
- from pydantic import BaseModel, Field, ValidationError
10
- from pydantic_settings import BaseSettings
9
+ from pydantic import BaseModel, Field, ValidationError, ConfigDict
11
10
 
12
11
  from aiecs.tools.base_tool import BaseTool
13
12
  from aiecs.tools import register_tool
@@ -52,25 +51,6 @@ class AIProvider(str, Enum):
52
51
  LOCAL = "local"
53
52
 
54
53
 
55
- class WriterOrchestratorSettings(BaseSettings):
56
- """Configuration for AI Document Writer Orchestrator"""
57
- default_ai_provider: AIProvider = AIProvider.OPENAI
58
- max_content_length: int = 50000 # Maximum content length for AI generation
59
- max_concurrent_writes: int = 5
60
- default_temperature: float = 0.3
61
- max_tokens: int = 4000
62
- timeout: int = 60
63
-
64
- # Draft and review settings
65
- enable_draft_mode: bool = True
66
- enable_content_review: bool = True
67
- auto_backup_on_ai_write: bool = True
68
-
69
- # Directory settings
70
- temp_dir: str = tempfile.gettempdir()
71
-
72
- class Config:
73
- env_prefix = "AI_DOC_WRITER_"
74
54
 
75
55
 
76
56
  class AIDocumentWriterOrchestratorError(Exception):
@@ -104,15 +84,58 @@ class AIDocumentWriterOrchestrator(BaseTool):
104
84
  - Existing AIECS infrastructure
105
85
  """
106
86
 
87
+ # Configuration schema
88
+ class Config(BaseModel):
89
+ """Configuration for the AI document writer orchestrator tool"""
90
+ model_config = ConfigDict(env_prefix="AI_DOC_WRITER_")
91
+
92
+ default_ai_provider: str = Field(
93
+ default="openai",
94
+ description="Default AI provider to use"
95
+ )
96
+ max_content_length: int = Field(
97
+ default=50000,
98
+ description="Maximum content length for AI generation"
99
+ )
100
+ max_concurrent_writes: int = Field(
101
+ default=5,
102
+ description="Maximum concurrent write operations"
103
+ )
104
+ default_temperature: float = Field(
105
+ default=0.3,
106
+ description="Default temperature for AI model"
107
+ )
108
+ max_tokens: int = Field(
109
+ default=4000,
110
+ description="Maximum tokens for AI response"
111
+ )
112
+ timeout: int = Field(
113
+ default=60,
114
+ description="Timeout in seconds for AI operations"
115
+ )
116
+ enable_draft_mode: bool = Field(
117
+ default=True,
118
+ description="Whether to enable draft mode"
119
+ )
120
+ enable_content_review: bool = Field(
121
+ default=True,
122
+ description="Whether to enable content review"
123
+ )
124
+ auto_backup_on_ai_write: bool = Field(
125
+ default=True,
126
+ description="Whether to automatically backup before AI writes"
127
+ )
128
+ temp_dir: str = Field(
129
+ default=tempfile.gettempdir(),
130
+ description="Temporary directory for processing"
131
+ )
132
+
107
133
  def __init__(self, config: Optional[Dict] = None):
108
134
  """Initialize AI Document Writer Orchestrator with settings"""
109
135
  super().__init__(config)
110
- self.settings = WriterOrchestratorSettings()
111
- if config:
112
- try:
113
- self.settings = self.settings.model_validate({**self.settings.model_dump(), **config})
114
- except ValidationError as e:
115
- raise ValueError(f"Invalid settings: {e}")
136
+
137
+ # Parse configuration
138
+ self.config = self.Config(**(config or {}))
116
139
 
117
140
  self.logger = logging.getLogger(__name__)
118
141
 
@@ -328,7 +351,7 @@ class AIDocumentWriterOrchestrator(BaseTool):
328
351
  content_requirements,
329
352
  generation_mode,
330
353
  document_format,
331
- ai_provider or self.settings.default_ai_provider,
354
+ ai_provider or self.config.default_ai_provider,
332
355
  generation_params or {}
333
356
  )
334
357
 
@@ -363,7 +386,7 @@ class AIDocumentWriterOrchestrator(BaseTool):
363
386
  "generation_mode": generation_mode,
364
387
  "document_format": document_format,
365
388
  "write_strategy": write_strategy,
366
- "ai_provider": ai_provider or self.settings.default_ai_provider,
389
+ "ai_provider": ai_provider or self.config.default_ai_provider,
367
390
  "ai_result": ai_result,
368
391
  "write_result": write_result,
369
392
  "post_process_result": post_process_result,
@@ -431,14 +454,14 @@ class AIDocumentWriterOrchestrator(BaseTool):
431
454
  ai_result = self._enhance_content_with_ai(
432
455
  existing_content,
433
456
  enhancement_goals,
434
- ai_provider or self.settings.default_ai_provider
457
+ ai_provider or self.config.default_ai_provider
435
458
  )
436
459
 
437
460
  # Step 3: Write enhanced content
438
461
  target = target_path or source_path
439
462
  write_mode = "overwrite" if target == source_path else "create"
440
463
 
441
- if self.settings.auto_backup_on_ai_write and target == source_path:
464
+ if self.config.auto_backup_on_ai_write and target == source_path:
442
465
  write_mode = "backup_write"
443
466
 
444
467
  write_result = self.document_writer.write_document(
@@ -486,7 +509,7 @@ class AIDocumentWriterOrchestrator(BaseTool):
486
509
  try:
487
510
  start_time = datetime.now()
488
511
  batch_id = f"batch_ai_write_{int(start_time.timestamp())}"
489
- max_concurrent = max_concurrent or self.settings.max_concurrent_writes
512
+ max_concurrent = max_concurrent or self.config.max_concurrent_writes
490
513
 
491
514
  self.logger.info(f"Starting batch AI write {batch_id}: {len(write_requests)} requests")
492
515
 
@@ -568,7 +591,7 @@ class AIDocumentWriterOrchestrator(BaseTool):
568
591
  edit_operation,
569
592
  edit_instructions,
570
593
  analysis_result,
571
- ai_provider or self.settings.default_ai_provider
594
+ ai_provider or self.config.default_ai_provider
572
595
  )
573
596
 
574
597
  # Step 4: Execute editing operations
@@ -1454,7 +1477,7 @@ Please provide a detailed editing plan with:
1454
1477
  item.get('requirements', ''),
1455
1478
  ContentGenerationMode.GENERATE,
1456
1479
  'markdown',
1457
- self.settings.default_ai_provider,
1480
+ self.config.default_ai_provider,
1458
1481
  item.get('generation_params', {})
1459
1482
  )
1460
1483
 
@@ -1634,7 +1657,7 @@ Please provide a detailed editing plan with:
1634
1657
  analysis_prompt,
1635
1658
  ContentGenerationMode.GENERATE,
1636
1659
  'markdown',
1637
- self.settings.default_ai_provider,
1660
+ self.config.default_ai_provider,
1638
1661
  {}
1639
1662
  )
1640
1663
 
@@ -1781,7 +1804,7 @@ Please provide a detailed editing plan with:
1781
1804
  """
1782
1805
  try:
1783
1806
  # Load template
1784
- template_file = os.path.join(self.settings.temp_dir, f"template_{template_name}.json")
1807
+ template_file = os.path.join(self.config.temp_dir, f"template_{template_name}.json")
1785
1808
  with open(template_file, 'r') as f:
1786
1809
  import json
1787
1810
  template_info = json.load(f)
@@ -1798,7 +1821,7 @@ Please provide a detailed editing plan with:
1798
1821
  f"Template: {template_name}",
1799
1822
  ContentGenerationMode.TEMPLATE_FILL,
1800
1823
  "txt",
1801
- self.settings.default_ai_provider,
1824
+ self.config.default_ai_provider,
1802
1825
  {
1803
1826
  "template": template_info["content"],
1804
1827
  "data": template_data
@@ -2189,7 +2212,7 @@ Please provide a detailed editing plan with:
2189
2212
 
2190
2213
  # Log operation
2191
2214
  try:
2192
- log_file = os.path.join(self.settings.temp_dir, "ai_write_operations.log")
2215
+ log_file = os.path.join(self.config.temp_dir, "ai_write_operations.log")
2193
2216
  with open(log_file, "a") as f:
2194
2217
  import json
2195
2218
  f.write(json.dumps(post_process_info) + "\n")
@@ -24,8 +24,7 @@ from typing import Dict, Any, List, Optional, Union, Tuple
24
24
  from enum import Enum
25
25
  from pathlib import Path
26
26
 
27
- from pydantic import BaseModel, Field, ValidationError
28
- from pydantic_settings import BaseSettings
27
+ from pydantic import BaseModel, Field, ValidationError, ConfigDict
29
28
 
30
29
  from aiecs.tools.base_tool import BaseTool
31
30
  from aiecs.tools import register_tool
@@ -97,18 +96,6 @@ class InsertionPosition(str, Enum):
97
96
  INLINE = "inline"
98
97
 
99
98
 
100
- class ContentInsertionSettings(BaseSettings):
101
- """Configuration for ContentInsertionTool"""
102
- temp_dir: str = os.path.join(tempfile.gettempdir(), 'content_insertion')
103
- assets_dir: str = os.path.join(tempfile.gettempdir(), 'document_assets')
104
- max_image_size: int = 10 * 1024 * 1024 # 10MB
105
- max_chart_size: Tuple[int, int] = (1200, 800) # pixels
106
- default_image_format: str = "png"
107
- optimize_images: bool = True
108
- auto_resize: bool = True
109
-
110
- class Config:
111
- env_prefix = "CONTENT_INSERT_"
112
99
 
113
100
 
114
101
  class ContentInsertionError(Exception):
@@ -151,13 +138,46 @@ class ContentInsertionTool(BaseTool):
151
138
  - DocumentWriterTool for content placement
152
139
  """
153
140
 
141
+ # Configuration schema
142
+ class Config(BaseModel):
143
+ """Configuration for the content insertion tool"""
144
+ model_config = ConfigDict(env_prefix="CONTENT_INSERT_")
145
+
146
+ temp_dir: str = Field(
147
+ default=os.path.join(tempfile.gettempdir(), 'content_insertion'),
148
+ description="Temporary directory for content processing"
149
+ )
150
+ assets_dir: str = Field(
151
+ default=os.path.join(tempfile.gettempdir(), 'document_assets'),
152
+ description="Directory for document assets"
153
+ )
154
+ max_image_size: int = Field(
155
+ default=10 * 1024 * 1024,
156
+ description="Maximum image size in bytes"
157
+ )
158
+ max_chart_size: Tuple[int, int] = Field(
159
+ default=(1200, 800),
160
+ description="Maximum chart size in pixels (width, height)"
161
+ )
162
+ default_image_format: str = Field(
163
+ default="png",
164
+ description="Default image format for generated content"
165
+ )
166
+ optimize_images: bool = Field(
167
+ default=True,
168
+ description="Whether to optimize images automatically"
169
+ )
170
+ auto_resize: bool = Field(
171
+ default=True,
172
+ description="Whether to automatically resize content to fit"
173
+ )
174
+
154
175
  def __init__(self, config: Optional[Dict] = None):
155
176
  """Initialize Content Insertion Tool with settings"""
156
177
  super().__init__(config)
157
- try:
158
- self.settings = ContentInsertionSettings(**(config or {}))
159
- except ValidationError as e:
160
- raise ValueError(f"Invalid settings: {e}")
178
+
179
+ # Parse configuration
180
+ self.config = self.Config(**(config or {}))
161
181
 
162
182
  self.logger = logging.getLogger(__name__)
163
183
 
@@ -175,8 +195,8 @@ class ContentInsertionTool(BaseTool):
175
195
 
176
196
  def _init_directories(self):
177
197
  """Initialize required directories"""
178
- os.makedirs(self.settings.temp_dir, exist_ok=True)
179
- os.makedirs(self.settings.assets_dir, exist_ok=True)
198
+ os.makedirs(self.config.temp_dir, exist_ok=True)
199
+ os.makedirs(self.config.assets_dir, exist_ok=True)
180
200
 
181
201
  def _init_external_tools(self):
182
202
  """Initialize external tools for content generation"""
@@ -803,14 +823,14 @@ class ContentInsertionTool(BaseTool):
803
823
  raise ChartInsertionError("Chart file not found")
804
824
 
805
825
  # Copy chart to assets directory
806
- chart_filename = f"chart_{uuid.uuid4().hex[:8]}.{self.settings.default_image_format}"
807
- asset_path = os.path.join(self.settings.assets_dir, chart_filename)
826
+ chart_filename = f"chart_{uuid.uuid4().hex[:8]}.{self.config.default_image_format}"
827
+ asset_path = os.path.join(self.config.assets_dir, chart_filename)
808
828
 
809
829
  import shutil
810
830
  shutil.copy2(chart_file, asset_path)
811
831
 
812
832
  # Optimize if needed
813
- if self.settings.optimize_images and 'image' in self.external_tools:
833
+ if self.config.optimize_images and 'image' in self.external_tools:
814
834
  self._optimize_image(asset_path)
815
835
 
816
836
  return {
@@ -878,8 +898,8 @@ class ContentInsertionTool(BaseTool):
878
898
  image_file = image_source
879
899
 
880
900
  # Copy to assets directory
881
- image_filename = f"image_{uuid.uuid4().hex[:8]}.{self.settings.default_image_format}"
882
- asset_path = os.path.join(self.settings.assets_dir, image_filename)
901
+ image_filename = f"image_{uuid.uuid4().hex[:8]}.{self.config.default_image_format}"
902
+ asset_path = os.path.join(self.config.assets_dir, image_filename)
883
903
 
884
904
  import shutil
885
905
  shutil.copy2(image_file, asset_path)
@@ -1142,8 +1162,8 @@ class ContentInsertionTool(BaseTool):
1142
1162
  """Download image from URL"""
1143
1163
  import urllib.request
1144
1164
 
1145
- filename = f"downloaded_{uuid.uuid4().hex[:8]}.{self.settings.default_image_format}"
1146
- filepath = os.path.join(self.settings.temp_dir, filename)
1165
+ filename = f"downloaded_{uuid.uuid4().hex[:8]}.{self.config.default_image_format}"
1166
+ filepath = os.path.join(self.config.temp_dir, filename)
1147
1167
 
1148
1168
  urllib.request.urlretrieve(url, filepath)
1149
1169
  return filepath
@@ -1160,7 +1180,7 @@ class ContentInsertionTool(BaseTool):
1160
1180
  image_data = base64.b64decode(data)
1161
1181
 
1162
1182
  filename = f"base64_{uuid.uuid4().hex[:8]}.{format_info}"
1163
- filepath = os.path.join(self.settings.temp_dir, filename)
1183
+ filepath = os.path.join(self.config.temp_dir, filename)
1164
1184
 
1165
1185
  with open(filepath, 'wb') as f:
1166
1186
  f.write(image_data)
@@ -23,8 +23,7 @@ from typing import Dict, Any, List, Optional, Union
23
23
  from enum import Enum
24
24
  from pathlib import Path
25
25
 
26
- from pydantic import BaseModel, Field, ValidationError
27
- from pydantic_settings import BaseSettings
26
+ from pydantic import BaseModel, Field, ValidationError, ConfigDict
28
27
 
29
28
  from aiecs.tools.base_tool import BaseTool
30
29
  from aiecs.tools import register_tool
@@ -82,18 +81,6 @@ class StylePreset(str, Enum):
82
81
  PROFESSIONAL = "professional"
83
82
 
84
83
 
85
- class DocumentCreatorSettings(BaseSettings):
86
- """Configuration for DocumentCreatorTool"""
87
- templates_dir: str = os.path.join(tempfile.gettempdir(), 'document_templates')
88
- output_dir: str = os.path.join(tempfile.gettempdir(), 'created_documents')
89
- default_format: DocumentFormat = DocumentFormat.MARKDOWN
90
- default_style: StylePreset = StylePreset.DEFAULT
91
- auto_backup: bool = True
92
- include_metadata: bool = True
93
- generate_toc: bool = True
94
-
95
- class Config:
96
- env_prefix = "DOC_CREATOR_"
97
84
 
98
85
 
99
86
  class DocumentCreatorError(Exception):
@@ -129,15 +116,46 @@ class DocumentCreatorTool(BaseTool):
129
116
  - ContentInsertionTool for complex content
130
117
  """
131
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
+
132
153
  def __init__(self, config: Optional[Dict] = None):
133
154
  """Initialize Document Creator Tool with settings"""
134
155
  super().__init__(config)
135
- self.settings = DocumentCreatorSettings()
136
- if config:
137
- try:
138
- self.settings = self.settings.model_validate({**self.settings.model_dump(), **config})
139
- except ValidationError as e:
140
- raise ValueError(f"Invalid settings: {e}")
156
+
157
+ # Parse configuration
158
+ self.config = self.Config(**(config or {}))
141
159
 
142
160
  self.logger = logging.getLogger(__name__)
143
161
 
@@ -152,8 +170,8 @@ class DocumentCreatorTool(BaseTool):
152
170
 
153
171
  def _init_directories(self):
154
172
  """Initialize required directories"""
155
- os.makedirs(self.settings.templates_dir, exist_ok=True)
156
- os.makedirs(self.settings.output_dir, exist_ok=True)
173
+ os.makedirs(self.config.templates_dir, exist_ok=True)
174
+ os.makedirs(self.config.output_dir, exist_ok=True)
157
175
 
158
176
  def _init_templates(self):
159
177
  """Initialize built-in templates"""
@@ -237,7 +255,7 @@ class DocumentCreatorTool(BaseTool):
237
255
  processed_metadata = self._process_metadata(metadata, output_format)
238
256
 
239
257
  # Step 4: Apply style preset
240
- style_config = self._get_style_config(style_preset or self.settings.default_style)
258
+ style_config = self._get_style_config(style_preset or self.config.default_style)
241
259
 
242
260
  # Step 5: Create document from template
243
261
  document_content = self._create_document_from_template(
@@ -293,7 +311,7 @@ class DocumentCreatorTool(BaseTool):
293
311
  """
294
312
  try:
295
313
  # Load custom template
296
- template_path = os.path.join(self.settings.templates_dir, template_name)
314
+ template_path = os.path.join(self.config.templates_dir, template_name)
297
315
  if not os.path.exists(template_path):
298
316
  raise TemplateError(f"Template not found: {template_name}")
299
317
 
@@ -423,15 +441,15 @@ class DocumentCreatorTool(BaseTool):
423
441
 
424
442
  # Scan for custom templates
425
443
  custom_templates = []
426
- if os.path.exists(self.settings.templates_dir):
427
- for file in os.listdir(self.settings.templates_dir):
444
+ if os.path.exists(self.config.templates_dir):
445
+ for file in os.listdir(self.config.templates_dir):
428
446
  if file.endswith(('.md', '.html', '.txt', '.json')):
429
447
  custom_templates.append(file)
430
448
 
431
449
  return {
432
450
  "built_in_templates": [t.value for t in built_in_templates],
433
451
  "custom_templates": custom_templates,
434
- "templates_directory": self.settings.templates_dir,
452
+ "templates_directory": self.config.templates_dir,
435
453
  "total_templates": len(built_in_templates) + len(custom_templates)
436
454
  }
437
455
 
@@ -952,7 +970,7 @@ class DocumentCreatorTool(BaseTool):
952
970
  """Generate output path for document"""
953
971
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
954
972
  filename = f"{document_type}_{timestamp}_{document_id[:8]}.{output_format.value}"
955
- return os.path.join(self.settings.output_dir, filename)
973
+ return os.path.join(self.config.output_dir, filename)
956
974
 
957
975
  def _process_metadata(self, metadata: Dict[str, Any], output_format: DocumentFormat) -> Dict[str, Any]:
958
976
  """Process and validate metadata"""
@@ -996,7 +1014,7 @@ class DocumentCreatorTool(BaseTool):
996
1014
  content = content.replace(placeholder, str(value))
997
1015
 
998
1016
  # Add metadata header if required
999
- if self.settings.include_metadata:
1017
+ if self.config.include_metadata:
1000
1018
  metadata_header = self._generate_metadata_header(metadata, output_format)
1001
1019
  content = metadata_header + "\n\n" + content
1002
1020