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.
- aiecs/__init__.py +1 -1
- aiecs/aiecs_client.py +1 -1
- aiecs/config/config.py +38 -0
- aiecs/domain/__init__.py +95 -0
- aiecs/domain/community/__init__.py +159 -0
- aiecs/domain/community/agent_adapter.py +516 -0
- aiecs/domain/community/analytics.py +465 -0
- aiecs/domain/community/collaborative_workflow.py +99 -7
- aiecs/domain/community/communication_hub.py +649 -0
- aiecs/domain/community/community_builder.py +322 -0
- aiecs/domain/community/community_integration.py +365 -12
- aiecs/domain/community/community_manager.py +481 -5
- aiecs/domain/community/decision_engine.py +459 -13
- aiecs/domain/community/exceptions.py +238 -0
- aiecs/domain/community/models/__init__.py +36 -0
- aiecs/domain/community/resource_manager.py +1 -1
- aiecs/domain/community/shared_context_manager.py +621 -0
- aiecs/domain/context/context_engine.py +37 -33
- aiecs/infrastructure/monitoring/__init__.py +22 -0
- aiecs/infrastructure/monitoring/global_metrics_manager.py +207 -0
- aiecs/infrastructure/persistence/file_storage.py +41 -28
- aiecs/llm/__init__.py +44 -7
- aiecs/llm/callbacks/__init__.py +12 -0
- aiecs/llm/{custom_callbacks.py → callbacks/custom_callbacks.py} +1 -1
- aiecs/llm/client_factory.py +23 -6
- aiecs/llm/clients/__init__.py +35 -0
- aiecs/llm/{base_client.py → clients/base_client.py} +73 -1
- aiecs/llm/{googleai_client.py → clients/googleai_client.py} +19 -15
- aiecs/llm/{openai_client.py → clients/openai_client.py} +9 -14
- aiecs/llm/{vertex_client.py → clients/vertex_client.py} +15 -15
- aiecs/llm/{xai_client.py → clients/xai_client.py} +36 -50
- aiecs/llm/config/__init__.py +54 -0
- aiecs/llm/config/config_loader.py +275 -0
- aiecs/llm/config/config_validator.py +237 -0
- aiecs/llm/config/model_config.py +132 -0
- aiecs/llm/utils/__init__.py +11 -0
- aiecs/llm/utils/validate_config.py +91 -0
- aiecs/main.py +32 -2
- aiecs/scripts/aid/VERSION_MANAGEMENT.md +97 -0
- aiecs/scripts/aid/__init__.py +15 -0
- aiecs/scripts/aid/version_manager.py +224 -0
- aiecs/scripts/dependance_check/download_nlp_data.py +1 -0
- aiecs/tools/__init__.py +23 -23
- aiecs/tools/docs/__init__.py +5 -2
- aiecs/tools/docs/ai_document_orchestrator.py +39 -26
- aiecs/tools/docs/ai_document_writer_orchestrator.py +61 -38
- aiecs/tools/docs/content_insertion_tool.py +48 -28
- aiecs/tools/docs/document_creator_tool.py +47 -29
- aiecs/tools/docs/document_layout_tool.py +35 -20
- aiecs/tools/docs/document_parser_tool.py +56 -36
- aiecs/tools/docs/document_writer_tool.py +115 -62
- aiecs/tools/schema_generator.py +56 -56
- aiecs/tools/statistics/__init__.py +82 -0
- aiecs/tools/statistics/ai_data_analysis_orchestrator.py +581 -0
- aiecs/tools/statistics/ai_insight_generator_tool.py +473 -0
- aiecs/tools/statistics/ai_report_orchestrator_tool.py +629 -0
- aiecs/tools/statistics/data_loader_tool.py +518 -0
- aiecs/tools/statistics/data_profiler_tool.py +599 -0
- aiecs/tools/statistics/data_transformer_tool.py +531 -0
- aiecs/tools/statistics/data_visualizer_tool.py +460 -0
- aiecs/tools/statistics/model_trainer_tool.py +470 -0
- aiecs/tools/statistics/statistical_analyzer_tool.py +426 -0
- aiecs/tools/task_tools/chart_tool.py +2 -1
- aiecs/tools/task_tools/image_tool.py +43 -43
- aiecs/tools/task_tools/office_tool.py +39 -36
- aiecs/tools/task_tools/pandas_tool.py +37 -33
- aiecs/tools/task_tools/report_tool.py +67 -56
- aiecs/tools/task_tools/research_tool.py +32 -31
- aiecs/tools/task_tools/scraper_tool.py +53 -46
- aiecs/tools/task_tools/search_tool.py +1123 -0
- aiecs/tools/task_tools/stats_tool.py +20 -15
- aiecs/tools/tool_executor/__init__.py +2 -2
- aiecs/tools/tool_executor/tool_executor.py +3 -3
- {aiecs-1.1.0.dist-info → aiecs-1.2.1.dist-info}/METADATA +5 -1
- aiecs-1.2.1.dist-info/RECORD +144 -0
- {aiecs-1.1.0.dist-info → aiecs-1.2.1.dist-info}/entry_points.txt +1 -0
- aiecs/tools/task_tools/search_api.py +0 -7
- aiecs-1.1.0.dist-info/RECORD +0 -114
- {aiecs-1.1.0.dist-info → aiecs-1.2.1.dist-info}/WHEEL +0 -0
- {aiecs-1.1.0.dist-info → aiecs-1.2.1.dist-info}/licenses/LICENSE +0 -0
- {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
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
158
|
-
|
|
159
|
-
|
|
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.
|
|
179
|
-
os.makedirs(self.
|
|
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.
|
|
807
|
-
asset_path = os.path.join(self.
|
|
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.
|
|
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.
|
|
882
|
-
asset_path = os.path.join(self.
|
|
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.
|
|
1146
|
-
filepath = os.path.join(self.
|
|
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.
|
|
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
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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.
|
|
156
|
-
os.makedirs(self.
|
|
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.
|
|
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.
|
|
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.
|
|
427
|
-
for file in os.listdir(self.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|