wrd 0.1.41__py3-none-any.whl → 1.0.2__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.
- wrd/__init__.py +0 -0
- wrd/__main__.py +518 -0
- wrd-1.0.2.dist-info/METADATA +420 -0
- wrd-1.0.2.dist-info/RECORD +8 -0
- {wrd-0.1.41.dist-info → wrd-1.0.2.dist-info}/WHEEL +2 -1
- wrd-1.0.2.dist-info/entry_points.txt +2 -0
- wrd-1.0.2.dist-info/top_level.txt +1 -0
- dune/__init__.py +0 -31
- dune/__main__.py +0 -6
- dune/config_generator.py +0 -414
- dune/genconfig.py +0 -146
- dune/interactive_dune.py +0 -272
- dune/interactive_mapper.py +0 -599
- dune/llm_analyzer.py +0 -197
- dune/processor_engine.py +0 -114
- dune/smart_env_manager.py +0 -573
- dune/task_validator.py +0 -324
- wrd-0.1.41.dist-info/METADATA +0 -501
- wrd-0.1.41.dist-info/RECORD +0 -15
- wrd-0.1.41.dist-info/entry_points.txt +0 -3
- {wrd-0.1.41.dist-info → wrd-1.0.2.dist-info/licenses}/LICENSE +0 -0
dune/llm_analyzer.py
DELETED
@@ -1,197 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Analizator LLM do interpretacji żądań w języku naturalnym.
|
3
|
-
"""
|
4
|
-
|
5
|
-
import json
|
6
|
-
import requests
|
7
|
-
from typing import Dict, Any
|
8
|
-
from loguru import logger
|
9
|
-
from processor_engine import ProcessorConfig
|
10
|
-
|
11
|
-
|
12
|
-
class LLMAnalyzer:
|
13
|
-
"""Analizator wykorzystujący LLM do interpretacji żądań."""
|
14
|
-
|
15
|
-
def __init__(self, base_url: str = "http://localhost:11434", model: str = "mistral:7b"):
|
16
|
-
self.base_url = base_url
|
17
|
-
self.model = model
|
18
|
-
self._check_ollama_connection()
|
19
|
-
|
20
|
-
def _check_ollama_connection(self):
|
21
|
-
"""Sprawdza połączenie z Ollama."""
|
22
|
-
try:
|
23
|
-
response = requests.get(f"{self.base_url}/api/tags")
|
24
|
-
if response.status_code == 200:
|
25
|
-
logger.success("Połączenie z Ollama nawiązane")
|
26
|
-
else:
|
27
|
-
logger.warning("Ollama niedostępna, używanie domyślnych szablonów")
|
28
|
-
except requests.RequestException:
|
29
|
-
logger.warning("Nie można połączyć się z Ollama, używanie domyślnych szablonów")
|
30
|
-
|
31
|
-
def analyze_request(self, request: str) -> ProcessorConfig:
|
32
|
-
"""Analizuje żądanie i zwraca konfigurację procesora."""
|
33
|
-
|
34
|
-
# Spróbuj użyć LLM
|
35
|
-
try:
|
36
|
-
return self._analyze_with_llm(request)
|
37
|
-
except Exception as e:
|
38
|
-
logger.warning(f"LLM niedostępny ({e}), używanie domyślnego szablonu")
|
39
|
-
return self._get_default_imap_processor()
|
40
|
-
|
41
|
-
def _analyze_with_llm(self, request: str) -> ProcessorConfig:
|
42
|
-
"""Analizuje żądanie za pomocą LLM."""
|
43
|
-
|
44
|
-
prompt = f"""
|
45
|
-
Przeanalizuj poniższe żądanie i zwróć konfigurację procesora danych w formacie JSON.
|
46
|
-
|
47
|
-
Żądanie: {request}
|
48
|
-
|
49
|
-
Zwróć odpowiedź w następującym formacie JSON (tylko JSON, bez dodatkowych komentarzy):
|
50
|
-
{{
|
51
|
-
"name": "nazwa_procesora",
|
52
|
-
"description": "opis działania",
|
53
|
-
"dependencies": ["lista", "wymaganych", "pakietów"],
|
54
|
-
"parameters": {{"parametr": "wartość"}},
|
55
|
-
"code_template": "kompletny kod Python do wykonania zadania"
|
56
|
-
}}
|
57
|
-
|
58
|
-
Kod powinien:
|
59
|
-
1. Wykorzystywać zmienne środowiskowe z prefiksem IMAP_ dla połączenia
|
60
|
-
2. Zapisywać rezultat w zmiennej 'result'
|
61
|
-
3. Używać logger.info() do logowania
|
62
|
-
4. Tworzyć foldery zgodnie z żądaniem
|
63
|
-
5. Obsługiwać błędy
|
64
|
-
"""
|
65
|
-
|
66
|
-
payload = {
|
67
|
-
"model": self.model,
|
68
|
-
"prompt": prompt,
|
69
|
-
"stream": False,
|
70
|
-
"options": {
|
71
|
-
"temperature": 0.1,
|
72
|
-
"top_p": 0.9
|
73
|
-
}
|
74
|
-
}
|
75
|
-
|
76
|
-
response = requests.post(
|
77
|
-
f"{self.base_url}/api/generate",
|
78
|
-
json=payload,
|
79
|
-
timeout=60
|
80
|
-
)
|
81
|
-
response.raise_for_status()
|
82
|
-
|
83
|
-
result = response.json()
|
84
|
-
response_text = result.get("response", "")
|
85
|
-
|
86
|
-
# Wyodrębnij JSON z odpowiedzi
|
87
|
-
json_start = response_text.find('{')
|
88
|
-
json_end = response_text.rfind('}') + 1
|
89
|
-
|
90
|
-
if json_start == -1 or json_end == 0:
|
91
|
-
raise ValueError("Nie znaleziono JSON w odpowiedzi LLM")
|
92
|
-
|
93
|
-
json_text = response_text[json_start:json_end]
|
94
|
-
config_data = json.loads(json_text)
|
95
|
-
|
96
|
-
return ProcessorConfig(**config_data)
|
97
|
-
|
98
|
-
def _get_default_imap_processor(self) -> ProcessorConfig:
|
99
|
-
"""Zwraca domyślny procesor IMAP jako fallback."""
|
100
|
-
|
101
|
-
code_template = '''
|
102
|
-
import imaplib
|
103
|
-
import email
|
104
|
-
import os
|
105
|
-
from datetime import datetime
|
106
|
-
from pathlib import Path
|
107
|
-
|
108
|
-
# Pobierz dane połączenia z zmiennych środowiskowych
|
109
|
-
imap_server = os.getenv("IMAP_SERVER", "localhost")
|
110
|
-
imap_port = int(os.getenv("IMAP_PORT", "143"))
|
111
|
-
username = os.getenv("IMAP_USERNAME")
|
112
|
-
password = os.getenv("IMAP_PASSWORD")
|
113
|
-
use_ssl = os.getenv("IMAP_USE_SSL", "false").lower() == "true"
|
114
|
-
|
115
|
-
if not username or not password:
|
116
|
-
raise ValueError("Brak danych logowania IMAP w zmiennych środowiskowych")
|
117
|
-
|
118
|
-
logger.info(f"Łączenie z serwerem IMAP: {imap_server}:{imap_port}")
|
119
|
-
|
120
|
-
# Nawiąż połączenie
|
121
|
-
if use_ssl:
|
122
|
-
mail = imaplib.IMAP4_SSL(imap_server, imap_port)
|
123
|
-
else:
|
124
|
-
mail = imaplib.IMAP4(imap_server, imap_port)
|
125
|
-
|
126
|
-
mail.login(username, password)
|
127
|
-
mail.select("inbox")
|
128
|
-
|
129
|
-
logger.info("Pobieranie listy wiadomości...")
|
130
|
-
|
131
|
-
# Pobierz wszystkie wiadomości
|
132
|
-
result, data = mail.search(None, "ALL")
|
133
|
-
email_ids = data[0].split()
|
134
|
-
|
135
|
-
downloaded_files = []
|
136
|
-
base_path = Path(output_dir) / "skrzynka"
|
137
|
-
|
138
|
-
logger.info(f"Znaleziono {len(email_ids)} wiadomości")
|
139
|
-
|
140
|
-
for i, email_id in enumerate(email_ids):
|
141
|
-
try:
|
142
|
-
# Pobierz wiadomość
|
143
|
-
result, msg_data = mail.fetch(email_id, "(RFC822)")
|
144
|
-
email_body = msg_data[0][1]
|
145
|
-
email_message = email.message_from_bytes(email_body)
|
146
|
-
|
147
|
-
# Pobierz datę wiadomości
|
148
|
-
date_header = email_message.get("Date")
|
149
|
-
if date_header:
|
150
|
-
try:
|
151
|
-
date_tuple = email.utils.parsedate_tz(date_header)
|
152
|
-
if date_tuple:
|
153
|
-
timestamp = email.utils.mktime_tz(date_tuple)
|
154
|
-
msg_date = datetime.fromtimestamp(timestamp)
|
155
|
-
else:
|
156
|
-
msg_date = datetime.now()
|
157
|
-
except:
|
158
|
-
msg_date = datetime.now()
|
159
|
-
else:
|
160
|
-
msg_date = datetime.now()
|
161
|
-
|
162
|
-
# Utwórz folder rok.miesiąc
|
163
|
-
year_month = f"{msg_date.year}.{msg_date.month:02d}"
|
164
|
-
folder_path = base_path / year_month
|
165
|
-
folder_path.mkdir(parents=True, exist_ok=True)
|
166
|
-
|
167
|
-
# Zapisz plik .eml
|
168
|
-
filename = folder_path / f"email_{email_id.decode()}.eml"
|
169
|
-
with open(filename, "wb") as f:
|
170
|
-
f.write(email_body)
|
171
|
-
|
172
|
-
downloaded_files.append(str(filename))
|
173
|
-
logger.info(f"Zapisano: {filename}")
|
174
|
-
|
175
|
-
except Exception as e:
|
176
|
-
logger.error(f"Błąd przetwarzania wiadomości {email_id}: {e}")
|
177
|
-
|
178
|
-
mail.close()
|
179
|
-
mail.logout()
|
180
|
-
|
181
|
-
result = {
|
182
|
-
"status": "completed",
|
183
|
-
"downloaded_files": downloaded_files,
|
184
|
-
"total_count": len(downloaded_files),
|
185
|
-
"folders_created": list(set([str(Path(f).parent) for f in downloaded_files]))
|
186
|
-
}
|
187
|
-
|
188
|
-
logger.success(f"Pobrano {len(downloaded_files)} wiadomości do {len(result['folders_created'])} folderów")
|
189
|
-
'''
|
190
|
-
|
191
|
-
return ProcessorConfig(
|
192
|
-
name="imap_email_downloader",
|
193
|
-
description="Pobiera wiadomości email z IMAP i organizuje je w foldery rok.miesiąc",
|
194
|
-
dependencies=["imaplib", "email"],
|
195
|
-
parameters={},
|
196
|
-
code_template=code_template
|
197
|
-
)
|
dune/processor_engine.py
DELETED
@@ -1,114 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Główny silnik procesora danych z dynamicznym zarządzaniem bibliotekami.
|
3
|
-
"""
|
4
|
-
|
5
|
-
import os
|
6
|
-
import sys
|
7
|
-
import subprocess
|
8
|
-
import importlib
|
9
|
-
import json
|
10
|
-
from typing import Dict, List, Any, Optional
|
11
|
-
from pathlib import Path
|
12
|
-
from loguru import logger
|
13
|
-
from pydantic import BaseModel
|
14
|
-
|
15
|
-
|
16
|
-
class ProcessorConfig(BaseModel):
|
17
|
-
"""Konfiguracja procesora danych."""
|
18
|
-
name: str
|
19
|
-
description: str
|
20
|
-
dependencies: List[str]
|
21
|
-
parameters: Dict[str, Any]
|
22
|
-
code_template: str
|
23
|
-
|
24
|
-
|
25
|
-
class DynamicPackageManager:
|
26
|
-
"""Menedżer dynamicznego instalowania pakietów."""
|
27
|
-
|
28
|
-
def __init__(self):
|
29
|
-
self.installed_packages = set()
|
30
|
-
|
31
|
-
def install_package(self, package_name: str) -> bool:
|
32
|
-
"""Instaluje pakiet jeśli nie jest zainstalowany."""
|
33
|
-
if package_name in self.installed_packages:
|
34
|
-
return True
|
35
|
-
|
36
|
-
try:
|
37
|
-
logger.info(f"Instalowanie pakietu: {package_name}")
|
38
|
-
subprocess.check_call([
|
39
|
-
sys.executable, "-m", "pip", "install", package_name
|
40
|
-
], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
41
|
-
|
42
|
-
self.installed_packages.add(package_name)
|
43
|
-
logger.success(f"Pakiet {package_name} zainstalowany pomyślnie")
|
44
|
-
return True
|
45
|
-
|
46
|
-
except subprocess.CalledProcessError as e:
|
47
|
-
logger.error(f"Błąd instalacji pakietu {package_name}: {e}")
|
48
|
-
return False
|
49
|
-
|
50
|
-
def import_module(self, module_name: str):
|
51
|
-
"""Importuje moduł po ewentualnej instalacji."""
|
52
|
-
try:
|
53
|
-
return importlib.import_module(module_name)
|
54
|
-
except ImportError:
|
55
|
-
# Spróbuj zainstalować i zaimportować ponownie
|
56
|
-
if self.install_package(module_name):
|
57
|
-
return importlib.import_module(module_name)
|
58
|
-
raise
|
59
|
-
|
60
|
-
|
61
|
-
class ProcessorEngine:
|
62
|
-
"""Główny silnik procesora danych."""
|
63
|
-
|
64
|
-
def __init__(self, llm_analyzer):
|
65
|
-
self.llm_analyzer = llm_analyzer
|
66
|
-
self.package_manager = DynamicPackageManager()
|
67
|
-
self.output_dir = Path(os.getenv("OUTPUT_DIR", "./output"))
|
68
|
-
self.output_dir.mkdir(exist_ok=True)
|
69
|
-
|
70
|
-
def process_natural_request(self, request: str) -> Dict[str, Any]:
|
71
|
-
"""Przetwarza żądanie w języku naturalnym."""
|
72
|
-
|
73
|
-
# 1. Przeanalizuj żądanie za pomocą LLM
|
74
|
-
logger.info("Analizowanie żądania za pomocą LLM...")
|
75
|
-
processor_config = self.llm_analyzer.analyze_request(request)
|
76
|
-
|
77
|
-
# 2. Zainstaluj wymagane biblioteki
|
78
|
-
logger.info("Instalowanie wymaganych bibliotek...")
|
79
|
-
for dependency in processor_config.dependencies:
|
80
|
-
self.package_manager.install_package(dependency)
|
81
|
-
|
82
|
-
# 3. Wykonaj kod procesora
|
83
|
-
logger.info("Wykonywanie procesora danych...")
|
84
|
-
return self._execute_processor(processor_config)
|
85
|
-
|
86
|
-
def _execute_processor(self, config: ProcessorConfig) -> Dict[str, Any]:
|
87
|
-
"""Wykonuje procesor danych na podstawie konfiguracji."""
|
88
|
-
|
89
|
-
# Przygotuj kontekst wykonania
|
90
|
-
execution_context = {
|
91
|
-
'os': __import__('os'),
|
92
|
-
'sys': __import__('sys'),
|
93
|
-
'Path': Path,
|
94
|
-
'logger': logger,
|
95
|
-
'output_dir': str(self.output_dir),
|
96
|
-
'package_manager': self.package_manager,
|
97
|
-
}
|
98
|
-
|
99
|
-
# Dodaj zmienne środowiskowe
|
100
|
-
for key, value in os.environ.items():
|
101
|
-
if key.startswith(('IMAP_', 'EMAIL_', 'SMTP_')):
|
102
|
-
execution_context[key.lower()] = value
|
103
|
-
|
104
|
-
# Wykonaj kod
|
105
|
-
try:
|
106
|
-
exec(config.code_template, execution_context)
|
107
|
-
|
108
|
-
# Pobierz wynik z kontekstu
|
109
|
-
result = execution_context.get('result', {'status': 'completed'})
|
110
|
-
return result
|
111
|
-
|
112
|
-
except Exception as e:
|
113
|
-
logger.error(f"Błąd wykonania procesora: {e}")
|
114
|
-
raise
|