wrd 0.1.41__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.
- dune/__init__.py +31 -0
- dune/__main__.py +6 -0
- dune/config_generator.py +414 -0
- dune/genconfig.py +146 -0
- dune/interactive_dune.py +272 -0
- dune/interactive_mapper.py +599 -0
- dune/llm_analyzer.py +197 -0
- dune/processor_engine.py +114 -0
- dune/smart_env_manager.py +573 -0
- dune/task_validator.py +324 -0
- wrd-0.1.41.dist-info/LICENSE +201 -0
- wrd-0.1.41.dist-info/METADATA +501 -0
- wrd-0.1.41.dist-info/RECORD +15 -0
- wrd-0.1.41.dist-info/WHEEL +4 -0
- wrd-0.1.41.dist-info/entry_points.txt +3 -0
dune/__init__.py
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
"""
|
2
|
+
Dune - Dynamiczny procesor danych z automatycznym wykrywaniem bibliotek.
|
3
|
+
|
4
|
+
Ten moduł zapewnia narzędzia do przetwarzania danych z automatycznym wykrywaniem
|
5
|
+
i wykorzystaniem odpowiednich bibliotek w zależności od typu danych wejściowych.
|
6
|
+
|
7
|
+
Główne komponenty:
|
8
|
+
- config_generator: Generowanie konfiguracji YAML z żądań w języku naturalnym
|
9
|
+
- interactive_mapper: Interaktywne mapowanie zadań do bibliotek
|
10
|
+
- processor_engine: Główny silnik przetwarzania danych
|
11
|
+
- smart_env_manager: Zarządzanie zmiennymi środowiskowymi
|
12
|
+
- task_validator: Walidacja konfiguracji zadań
|
13
|
+
"""
|
14
|
+
|
15
|
+
__version__ = "0.1.1"
|
16
|
+
|
17
|
+
# Eksport głównych klas i funkcji
|
18
|
+
from .config_generator import ConfigGenerator
|
19
|
+
from .interactive_mapper import InteractiveMapper
|
20
|
+
from .processor_engine import ProcessorEngine
|
21
|
+
from .smart_env_manager import SmartEnvManager
|
22
|
+
from .task_validator import TaskValidator
|
23
|
+
|
24
|
+
__all__ = [
|
25
|
+
'ConfigGenerator',
|
26
|
+
'InteractiveMapper',
|
27
|
+
'ProcessorEngine',
|
28
|
+
'SmartEnvManager',
|
29
|
+
'TaskValidator',
|
30
|
+
'__version__',
|
31
|
+
]
|
dune/__main__.py
ADDED
dune/config_generator.py
ADDED
@@ -0,0 +1,414 @@
|
|
1
|
+
"""
|
2
|
+
Generator konfiguracji YAML na podstawie żądań w języku naturalnym.
|
3
|
+
"""
|
4
|
+
|
5
|
+
import yaml
|
6
|
+
import re
|
7
|
+
from typing import Dict, List, Any, Optional
|
8
|
+
from datetime import datetime
|
9
|
+
from loguru import logger
|
10
|
+
|
11
|
+
|
12
|
+
class ConfigGenerator:
|
13
|
+
"""Generator konfiguracji zadań na podstawie NLP."""
|
14
|
+
|
15
|
+
def __init__(self, llm_analyzer=None):
|
16
|
+
self.llm_analyzer = llm_analyzer
|
17
|
+
self.templates = self._load_templates()
|
18
|
+
|
19
|
+
def _load_templates(self) -> Dict[str, Any]:
|
20
|
+
"""Ładuje szablony konfiguracji dla różnych typów zadań."""
|
21
|
+
return {
|
22
|
+
"email_processing": {
|
23
|
+
"runtime": {
|
24
|
+
"python_packages": {
|
25
|
+
"required": ["imaplib2", "email-validator", "python-dotenv", "loguru"],
|
26
|
+
"optional": ["beautifulsoup4", "chardet"]
|
27
|
+
},
|
28
|
+
"environment": {
|
29
|
+
"required": ["IMAP_SERVER", "IMAP_USERNAME", "IMAP_PASSWORD"],
|
30
|
+
"optional": ["IMAP_PORT", "IMAP_USE_SSL", "OUTPUT_DIR"]
|
31
|
+
}
|
32
|
+
},
|
33
|
+
"services": {
|
34
|
+
"dependencies": [{
|
35
|
+
"name": "imap-server",
|
36
|
+
"type": "imap",
|
37
|
+
"required": True,
|
38
|
+
"connection": {
|
39
|
+
"host": "${IMAP_SERVER}",
|
40
|
+
"port": "${IMAP_PORT:-143}",
|
41
|
+
"ssl": "${IMAP_USE_SSL:-false}"
|
42
|
+
},
|
43
|
+
"health_check": {
|
44
|
+
"type": "tcp_connect",
|
45
|
+
"timeout": "10s"
|
46
|
+
}
|
47
|
+
}]
|
48
|
+
}
|
49
|
+
},
|
50
|
+
|
51
|
+
"database_processing": {
|
52
|
+
"runtime": {
|
53
|
+
"python_packages": {
|
54
|
+
"required": ["sqlalchemy", "pandas", "python-dotenv"],
|
55
|
+
"optional": ["psycopg2-binary", "pymysql", "cx_Oracle"]
|
56
|
+
},
|
57
|
+
"environment": {
|
58
|
+
"required": ["DATABASE_URL"],
|
59
|
+
"optional": ["DB_POOL_SIZE", "DB_TIMEOUT"]
|
60
|
+
}
|
61
|
+
},
|
62
|
+
"services": {
|
63
|
+
"dependencies": [{
|
64
|
+
"name": "database",
|
65
|
+
"type": "sql",
|
66
|
+
"required": True,
|
67
|
+
"connection": {
|
68
|
+
"url": "${DATABASE_URL}"
|
69
|
+
},
|
70
|
+
"health_check": {
|
71
|
+
"type": "sql_query",
|
72
|
+
"query": "SELECT 1",
|
73
|
+
"timeout": "30s"
|
74
|
+
}
|
75
|
+
}]
|
76
|
+
}
|
77
|
+
},
|
78
|
+
|
79
|
+
"file_processing": {
|
80
|
+
"runtime": {
|
81
|
+
"python_packages": {
|
82
|
+
"required": ["pandas", "openpyxl", "python-dotenv"],
|
83
|
+
"optional": ["xlrd", "chardet", "python-magic"]
|
84
|
+
},
|
85
|
+
"environment": {
|
86
|
+
"required": ["INPUT_DIR", "OUTPUT_DIR"],
|
87
|
+
"optional": ["FILE_PATTERN", "ENCODING"]
|
88
|
+
}
|
89
|
+
}
|
90
|
+
},
|
91
|
+
|
92
|
+
"web_scraping": {
|
93
|
+
"runtime": {
|
94
|
+
"python_packages": {
|
95
|
+
"required": ["requests", "beautifulsoup4", "selenium", "python-dotenv"],
|
96
|
+
"optional": ["scrapy", "lxml", "html5lib"]
|
97
|
+
},
|
98
|
+
"environment": {
|
99
|
+
"required": ["TARGET_URL"],
|
100
|
+
"optional": ["USER_AGENT", "REQUEST_DELAY", "PROXY_URL"]
|
101
|
+
}
|
102
|
+
}
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
def generate_config_from_nlp(self, natural_request: str) -> Dict[str, Any]:
|
107
|
+
"""Generuje konfigurację YAML na podstawie żądania w języku naturalnym."""
|
108
|
+
|
109
|
+
logger.info("🔄 Analizowanie żądania w celu wygenerowania konfiguracji...")
|
110
|
+
|
111
|
+
# Wykryj typ zadania
|
112
|
+
task_type = self._detect_task_type(natural_request)
|
113
|
+
logger.info(f"🎯 Wykryty typ zadania: {task_type}")
|
114
|
+
|
115
|
+
# Wyodrębnij wymagania
|
116
|
+
requirements = self._extract_requirements(natural_request)
|
117
|
+
|
118
|
+
# Wykryj potrzebne pakiety
|
119
|
+
packages = self._detect_required_packages(natural_request, task_type)
|
120
|
+
|
121
|
+
# Wykryj zmienne środowiskowe
|
122
|
+
env_vars = self._detect_environment_variables(natural_request, task_type)
|
123
|
+
|
124
|
+
# Wykryj usługi
|
125
|
+
services = self._detect_services(natural_request, task_type)
|
126
|
+
|
127
|
+
# Wygeneruj podstawową konfigurację
|
128
|
+
config = self._build_base_config(
|
129
|
+
natural_request, task_type, requirements,
|
130
|
+
packages, env_vars, services
|
131
|
+
)
|
132
|
+
|
133
|
+
return config
|
134
|
+
|
135
|
+
def _detect_task_type(self, request: str) -> str:
|
136
|
+
"""Wykrywa typ zadania na podstawie słów kluczowych."""
|
137
|
+
|
138
|
+
request_lower = request.lower()
|
139
|
+
|
140
|
+
# Mapa słów kluczowych do typów zadań
|
141
|
+
keywords_map = {
|
142
|
+
"email_processing": ["email", "imap", "pop3", "skrzynka", "wiadomość", "poczta"],
|
143
|
+
"database_processing": ["baza danych", "sql", "tabela", "rekord", "zapytanie"],
|
144
|
+
"file_processing": ["plik", "csv", "excel", "json", "xml", "folder"],
|
145
|
+
"web_scraping": ["strona", "scraping", "pobierz z internetu", "www", "http"],
|
146
|
+
"api_processing": ["api", "endpoint", "rest", "json api", "webhook"],
|
147
|
+
"data_analysis": ["analiza", "wykres", "statystyki", "raport", "dashboard"]
|
148
|
+
}
|
149
|
+
|
150
|
+
# Zlicz dopasowania dla każdego typu
|
151
|
+
scores = {}
|
152
|
+
for task_type, keywords in keywords_map.items():
|
153
|
+
score = sum(1 for keyword in keywords if keyword in request_lower)
|
154
|
+
if score > 0:
|
155
|
+
scores[task_type] = score
|
156
|
+
|
157
|
+
# Zwróć typ z najwyższym wynikiem
|
158
|
+
if scores:
|
159
|
+
return max(scores, key=scores.get)
|
160
|
+
|
161
|
+
return "generic_processing"
|
162
|
+
|
163
|
+
def _extract_requirements(self, request: str) -> List[str]:
|
164
|
+
"""Wyodrębnia wymagania funkcjonalne z żądania."""
|
165
|
+
|
166
|
+
requirements = []
|
167
|
+
request_lower = request.lower()
|
168
|
+
|
169
|
+
# Mapa wzorców do wymagań
|
170
|
+
patterns = {
|
171
|
+
r"pobierz.*email|pobierz.*wiadomoś": "download_emails",
|
172
|
+
r"zapisz.*folder|organizuj.*folder": "organize_files",
|
173
|
+
r"połącz.*imap|łącz.*imap": "connect_imap",
|
174
|
+
r"filtruj.*dat|sortuj.*dat": "filter_by_date",
|
175
|
+
r"utwórz.*raport|generuj.*raport": "generate_report",
|
176
|
+
r"analizuj.*treść": "analyze_content",
|
177
|
+
r"wyślij.*email": "send_email",
|
178
|
+
r"pobierz.*załącznik": "download_attachments"
|
179
|
+
}
|
180
|
+
|
181
|
+
for pattern, requirement in patterns.items():
|
182
|
+
if re.search(pattern, request_lower):
|
183
|
+
requirements.append(requirement)
|
184
|
+
|
185
|
+
return requirements if requirements else ["process_data"]
|
186
|
+
|
187
|
+
def _detect_required_packages(self, request: str, task_type: str) -> Dict[str, List[str]]:
|
188
|
+
"""Wykrywa wymagane pakiety Python."""
|
189
|
+
|
190
|
+
# Pobierz bazowe pakiety dla typu zadania
|
191
|
+
base_template = self.templates.get(task_type, {})
|
192
|
+
packages = base_template.get("runtime", {}).get("python_packages", {
|
193
|
+
"required": ["python-dotenv", "loguru"],
|
194
|
+
"optional": []
|
195
|
+
}).copy()
|
196
|
+
|
197
|
+
request_lower = request.lower()
|
198
|
+
|
199
|
+
# Dodatkowe pakiety na podstawie kontekstu
|
200
|
+
additional_packages = {
|
201
|
+
"pandas": ["csv", "excel", "dataframe", "tabela"],
|
202
|
+
"requests": ["http", "api", "pobierz z internetu"],
|
203
|
+
"beautifulsoup4": ["html", "scraping", "parsuj"],
|
204
|
+
"sqlalchemy": ["sql", "baza danych"],
|
205
|
+
"matplotlib": ["wykres", "chart", "plot"],
|
206
|
+
"numpy": ["obliczenia", "matematyka", "array"],
|
207
|
+
"opencv-python": ["obraz", "zdjęcie", "cv2"],
|
208
|
+
"pillow": ["pil", "image", "grafika"]
|
209
|
+
}
|
210
|
+
|
211
|
+
for package, keywords in additional_packages.items():
|
212
|
+
if any(keyword in request_lower for keyword in keywords):
|
213
|
+
if package not in packages["required"]:
|
214
|
+
packages["optional"].append(package)
|
215
|
+
|
216
|
+
return packages
|
217
|
+
|
218
|
+
def _detect_environment_variables(self, request: str, task_type: str) -> Dict[str, List[str]]:
|
219
|
+
"""Wykrywa potrzebne zmienne środowiskowe."""
|
220
|
+
|
221
|
+
# Pobierz bazowe zmienne dla typu zadania
|
222
|
+
base_template = self.templates.get(task_type, {})
|
223
|
+
env_vars = base_template.get("runtime", {}).get("environment", {
|
224
|
+
"required": [],
|
225
|
+
"optional": ["OUTPUT_DIR"]
|
226
|
+
}).copy()
|
227
|
+
|
228
|
+
request_lower = request.lower()
|
229
|
+
|
230
|
+
# Dodatkowe zmienne na podstawie kontekstu
|
231
|
+
additional_vars = {
|
232
|
+
"API_KEY": ["api", "klucz", "token"],
|
233
|
+
"DATABASE_URL": ["baza danych", "sql"],
|
234
|
+
"WEBHOOK_URL": ["webhook", "callback"],
|
235
|
+
"PROXY_URL": ["proxy", "pośrednik"],
|
236
|
+
"TIMEOUT": ["timeout", "czas", "oczekiwanie"]
|
237
|
+
}
|
238
|
+
|
239
|
+
for var, keywords in additional_vars.items():
|
240
|
+
if any(keyword in request_lower for keyword in keywords):
|
241
|
+
if var not in env_vars["required"]:
|
242
|
+
env_vars["optional"].append(var)
|
243
|
+
|
244
|
+
return env_vars
|
245
|
+
|
246
|
+
def _detect_services(self, request: str, task_type: str) -> Dict[str, Any]:
|
247
|
+
"""Wykrywa wymagane usługi zewnętrzne."""
|
248
|
+
|
249
|
+
# Pobierz bazowe usługi dla typu zadania
|
250
|
+
base_template = self.templates.get(task_type, {})
|
251
|
+
services = base_template.get("services", {
|
252
|
+
"dependencies": [],
|
253
|
+
"managed_services": []
|
254
|
+
}).copy()
|
255
|
+
|
256
|
+
request_lower = request.lower()
|
257
|
+
|
258
|
+
# Dodatkowe usługi na podstawie kontekstu
|
259
|
+
if "redis" in request_lower:
|
260
|
+
services["dependencies"].append({
|
261
|
+
"name": "redis",
|
262
|
+
"type": "cache",
|
263
|
+
"required": False,
|
264
|
+
"connection": {"host": "${REDIS_HOST:-localhost}", "port": "6379"},
|
265
|
+
"health_check": {"type": "tcp_connect", "timeout": "5s"}
|
266
|
+
})
|
267
|
+
|
268
|
+
if "elasticsearch" in request_lower:
|
269
|
+
services["dependencies"].append({
|
270
|
+
"name": "elasticsearch",
|
271
|
+
"type": "search",
|
272
|
+
"required": False,
|
273
|
+
"connection": {"url": "${ELASTICSEARCH_URL:-http://localhost:9200}"},
|
274
|
+
"health_check": {"type": "http_get", "endpoint": "/_cluster/health", "timeout": "10s"}
|
275
|
+
})
|
276
|
+
|
277
|
+
return services
|
278
|
+
|
279
|
+
def _build_base_config(self, request: str, task_type: str, requirements: List[str],
|
280
|
+
packages: Dict[str, List[str]], env_vars: Dict[str, List[str]],
|
281
|
+
services: Dict[str, Any]) -> Dict[str, Any]:
|
282
|
+
"""Buduje podstawową konfigurację."""
|
283
|
+
|
284
|
+
# Wygeneruj nazwę zadania
|
285
|
+
task_name = self._generate_task_name(request, task_type)
|
286
|
+
|
287
|
+
config = {
|
288
|
+
"apiVersion": "dune.io/v1",
|
289
|
+
"kind": "TaskConfiguration",
|
290
|
+
"metadata": {
|
291
|
+
"name": task_name,
|
292
|
+
"description": request[:200] + "..." if len(request) > 200 else request,
|
293
|
+
"version": "1.0",
|
294
|
+
"created": datetime.now().isoformat() + "Z",
|
295
|
+
"tags": [task_type, "auto-generated"]
|
296
|
+
},
|
297
|
+
"task": {
|
298
|
+
"natural_language": request,
|
299
|
+
"requirements": requirements,
|
300
|
+
"expected_output": {
|
301
|
+
"type": "file_structure",
|
302
|
+
"pattern": "output/**/*"
|
303
|
+
}
|
304
|
+
},
|
305
|
+
"runtime": {
|
306
|
+
"type": "docker",
|
307
|
+
"base_image": "python:3.11-slim",
|
308
|
+
"python_packages": packages,
|
309
|
+
"environment": env_vars
|
310
|
+
},
|
311
|
+
"services": services,
|
312
|
+
"validation": {
|
313
|
+
"pre_execution": [
|
314
|
+
{"type": "service_connectivity",
|
315
|
+
"services": [dep["name"] for dep in services.get("dependencies", []) if dep.get("required")]},
|
316
|
+
{"type": "environment_variables", "required": env_vars.get("required", [])},
|
317
|
+
{"type": "file_permissions", "paths": ["${OUTPUT_DIR:-./output}"],
|
318
|
+
"permissions": ["read", "write"]},
|
319
|
+
{"type": "disk_space", "minimum": "100MB", "path": "${OUTPUT_DIR:-./output}"}
|
320
|
+
],
|
321
|
+
"post_execution": [
|
322
|
+
{"type": "output_verification", "expected_files": {"pattern": "output/**/*", "minimum_count": 1}},
|
323
|
+
{"type": "directory_structure", "expected": ["output"]}
|
324
|
+
]
|
325
|
+
},
|
326
|
+
"monitoring": {
|
327
|
+
"logs": {
|
328
|
+
"level": "${LOG_LEVEL:-INFO}",
|
329
|
+
"destinations": [
|
330
|
+
{"type": "file", "path": "logs/task-execution.log"},
|
331
|
+
{"type": "stdout", "format": "json"}
|
332
|
+
]
|
333
|
+
},
|
334
|
+
"metrics": [
|
335
|
+
{"name": "execution_time", "type": "histogram", "description": "Czas wykonania zadania"},
|
336
|
+
{"name": "errors_count", "type": "counter", "description": "Liczba błędów"}
|
337
|
+
]
|
338
|
+
},
|
339
|
+
"security": {
|
340
|
+
"network": {
|
341
|
+
"allowed_outbound": ["*:80", "*:443"],
|
342
|
+
"blocked_outbound": ["*:22", "*:3389"]
|
343
|
+
},
|
344
|
+
"filesystem": {
|
345
|
+
"read_only_paths": ["/etc", "/usr"],
|
346
|
+
"writable_paths": ["${OUTPUT_DIR:-./output}", "/tmp", "logs/"]
|
347
|
+
}
|
348
|
+
},
|
349
|
+
"pipeline": {
|
350
|
+
"stages": [
|
351
|
+
{"name": "validation", "type": "validation", "config": {"run_pre_execution_checks": True}},
|
352
|
+
{"name": "environment_setup", "type": "setup",
|
353
|
+
"config": {"install_packages": True, "create_directories": True}},
|
354
|
+
{"name": "llm_analysis", "type": "llm_processing",
|
355
|
+
"config": {"analyze_natural_language": True, "generate_code": True}},
|
356
|
+
{"name": "task_execution", "type": "execution",
|
357
|
+
"config": {"run_generated_code": True, "capture_output": True}},
|
358
|
+
{"name": "post_validation", "type": "validation", "config": {"run_post_execution_checks": True}},
|
359
|
+
{"name": "cleanup", "type": "cleanup", "config": {"remove_temp_files": True}}
|
360
|
+
]
|
361
|
+
},
|
362
|
+
"environments": {
|
363
|
+
"development": {
|
364
|
+
"managed_services_enabled": True,
|
365
|
+
"log_level": "DEBUG",
|
366
|
+
"validation_strict": False
|
367
|
+
},
|
368
|
+
"testing": {
|
369
|
+
"managed_services_enabled": True,
|
370
|
+
"log_level": "INFO",
|
371
|
+
"validation_strict": True
|
372
|
+
},
|
373
|
+
"production": {
|
374
|
+
"managed_services_enabled": False,
|
375
|
+
"log_level": "WARNING",
|
376
|
+
"validation_strict": True,
|
377
|
+
"security_enhanced": True
|
378
|
+
}
|
379
|
+
}
|
380
|
+
}
|
381
|
+
|
382
|
+
return config
|
383
|
+
|
384
|
+
def _generate_task_name(self, request: str, task_type: str) -> str:
|
385
|
+
"""Generuje nazwę zadania na podstawie żądania."""
|
386
|
+
|
387
|
+
# Wyciągnij kluczowe słowa
|
388
|
+
words = re.findall(r'\b\w+\b', request.lower())
|
389
|
+
key_words = [w for w in words if len(w) > 3 and w not in [
|
390
|
+
"jest", "będzie", "oraz", "które", "wszystkie", "danych"
|
391
|
+
]][:3]
|
392
|
+
|
393
|
+
if key_words:
|
394
|
+
name = "-".join(key_words)
|
395
|
+
else:
|
396
|
+
name = task_type.replace("_", "-")
|
397
|
+
|
398
|
+
return f"{name}-processor"
|
399
|
+
|
400
|
+
def save_config_to_file(self, config: Dict[str, Any], filename: str = None) -> str:
|
401
|
+
"""Zapisuje konfigurację do pliku YAML."""
|
402
|
+
|
403
|
+
if not filename:
|
404
|
+
task_name = config["metadata"]["name"]
|
405
|
+
filename = f"configs/{task_name}.yaml"
|
406
|
+
|
407
|
+
# Utwórz katalog jeśli nie istnieje
|
408
|
+
Path(filename).parent.mkdir(parents=True, exist_ok=True)
|
409
|
+
|
410
|
+
with open(filename, 'w', encoding='utf-8') as f:
|
411
|
+
yaml.dump(config, f, default_flow_style=False, allow_unicode=True, indent=2)
|
412
|
+
|
413
|
+
logger.success(f"✅ Konfiguracja zapisana do: {filename}")
|
414
|
+
return filename
|
dune/genconfig.py
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
CLI do generowania konfiguracji zadań z żądań w języku naturalnym.
|
4
|
+
"""
|
5
|
+
|
6
|
+
import sys
|
7
|
+
import argparse
|
8
|
+
from pathlib import Path
|
9
|
+
from loguru import logger
|
10
|
+
|
11
|
+
# Dodaj src do PYTHONPATH
|
12
|
+
sys.path.insert(0, str(Path(__file__).parent / "src"))
|
13
|
+
|
14
|
+
from config_generator import ConfigGenerator
|
15
|
+
from llm_analyzer import LLMAnalyzer
|
16
|
+
|
17
|
+
|
18
|
+
def main():
|
19
|
+
"""Główna funkcja CLI."""
|
20
|
+
|
21
|
+
parser = argparse.ArgumentParser(
|
22
|
+
description="Generator konfiguracji dune z żądań w języku naturalnym"
|
23
|
+
)
|
24
|
+
|
25
|
+
parser.add_argument(
|
26
|
+
"request",
|
27
|
+
nargs='?',
|
28
|
+
help="Żądanie w języku naturalnym (lub zostanie pobrane interaktywnie)"
|
29
|
+
)
|
30
|
+
|
31
|
+
parser.add_argument(
|
32
|
+
"--output", "-o",
|
33
|
+
type=str,
|
34
|
+
help="Ścieżka do pliku wyjściowego (domyślnie: configs/auto-generated.yaml)"
|
35
|
+
)
|
36
|
+
|
37
|
+
parser.add_argument(
|
38
|
+
"--interactive", "-i",
|
39
|
+
action="store_true",
|
40
|
+
help="Tryb interaktywny"
|
41
|
+
)
|
42
|
+
|
43
|
+
parser.add_argument(
|
44
|
+
"--validate", "-v",
|
45
|
+
action="store_true",
|
46
|
+
help="Waliduj wygenerowaną konfigurację"
|
47
|
+
)
|
48
|
+
|
49
|
+
parser.add_argument(
|
50
|
+
"--template", "-t",
|
51
|
+
type=str,
|
52
|
+
choices=["email_processing", "database_processing", "file_processing", "web_scraping"],
|
53
|
+
help="Użyj konkretnego szablonu"
|
54
|
+
)
|
55
|
+
|
56
|
+
args = parser.parse_args()
|
57
|
+
|
58
|
+
# Konfiguruj logowanie
|
59
|
+
logger.remove()
|
60
|
+
logger.add(sys.stdout, format="<green>{time:HH:mm:ss}</green> | <level>{message}</level>")
|
61
|
+
|
62
|
+
logger.info("🔧 Generator konfiguracji dune")
|
63
|
+
|
64
|
+
# Pobierz żądanie
|
65
|
+
if args.interactive or not args.request:
|
66
|
+
print("\n" + "=" * 60)
|
67
|
+
print("🤖 GENERATOR KONFIGURACJI dune")
|
68
|
+
print("=" * 60)
|
69
|
+
print("Opisz zadanie, które chcesz wykonać w języku naturalnym.")
|
70
|
+
print("Przykłady:")
|
71
|
+
print("• Pobierz emaile z IMAP i zapisz w folderach według dat")
|
72
|
+
print("• Przeanalizuj pliki CSV i wygeneruj raport")
|
73
|
+
print("• Pobierz dane z API i zapisz do bazy danych")
|
74
|
+
print("=" * 60)
|
75
|
+
|
76
|
+
request = input("\n📝 Twoje zadanie: ")
|
77
|
+
if not request.strip():
|
78
|
+
logger.error("❌ Nie podano żądania")
|
79
|
+
return
|
80
|
+
else:
|
81
|
+
request = args.request
|
82
|
+
|
83
|
+
try:
|
84
|
+
# Inicjalizuj generator
|
85
|
+
generator = ConfigGenerator()
|
86
|
+
|
87
|
+
logger.info("🔄 Analizowanie żądania...")
|
88
|
+
|
89
|
+
# Wygeneruj konfigurację
|
90
|
+
config = generator.generate_config_from_nlp(request)
|
91
|
+
|
92
|
+
# Określ ścieżkę wyjściową
|
93
|
+
if args.output:
|
94
|
+
output_path = args.output
|
95
|
+
else:
|
96
|
+
task_name = config["metadata"]["name"]
|
97
|
+
output_path = f"configs/{task_name}.yaml"
|
98
|
+
|
99
|
+
# Zapisz konfigurację
|
100
|
+
saved_path = generator.save_config_to_file(config, output_path)
|
101
|
+
|
102
|
+
# Pokaż podsumowanie
|
103
|
+
print("\n" + "=" * 60)
|
104
|
+
print("✅ KONFIGURACJA WYGENEROWANA POMYŚLNIE!")
|
105
|
+
print("=" * 60)
|
106
|
+
print(f"📄 Plik: {saved_path}")
|
107
|
+
print(f"🎯 Zadanie: {config['metadata']['name']}")
|
108
|
+
print(f"📦 Pakiety: {len(config['runtime']['python_packages']['required'])} wymaganych")
|
109
|
+
print(f"🔧 Usługi: {len(config['services'].get('dependencies', []))} zależności")
|
110
|
+
print(f"✅ Walidacja: {len(config['validation']['pre_execution'])} sprawdzeń")
|
111
|
+
|
112
|
+
# Pokaż kluczowe informacje
|
113
|
+
print(f"\n📋 PODSUMOWANIE:")
|
114
|
+
print(f" • Typ zadania: {config['metadata']['tags'][0] if config['metadata']['tags'] else 'generic'}")
|
115
|
+
print(f" • Wymagania: {', '.join(config['task']['requirements'])}")
|
116
|
+
|
117
|
+
required_packages = config['runtime']['python_packages']['required']
|
118
|
+
if required_packages:
|
119
|
+
print(f" • Pakiety: {', '.join(required_packages)}")
|
120
|
+
|
121
|
+
required_env = config['runtime']['environment']['required']
|
122
|
+
if required_env:
|
123
|
+
print(f" • Zmienne: {', '.join(required_env)}")
|
124
|
+
|
125
|
+
print(f"\n🚀 URUCHOMIENIE:")
|
126
|
+
print(f" python enhanced_run.py --config {saved_path}")
|
127
|
+
|
128
|
+
# Walidacja (jeśli zażądano)
|
129
|
+
if args.validate:
|
130
|
+
logger.info("🔍 Walidowanie konfiguracji...")
|
131
|
+
from task_validator import TaskValidator
|
132
|
+
|
133
|
+
validator = TaskValidator()
|
134
|
+
try:
|
135
|
+
loaded_config = validator.load_config(saved_path)
|
136
|
+
logger.success("✅ Konfiguracja jest poprawna")
|
137
|
+
except Exception as e:
|
138
|
+
logger.error(f"❌ Błąd walidacji: {e}")
|
139
|
+
|
140
|
+
except Exception as e:
|
141
|
+
logger.error(f"❌ Błąd generowania konfiguracji: {e}")
|
142
|
+
sys.exit(1)
|
143
|
+
|
144
|
+
|
145
|
+
if __name__ == "__main__":
|
146
|
+
main()
|