Skip to content

Commit 2a170ad

Browse files
draft
1 parent 3f02ffa commit 2a170ad

File tree

5 files changed

+168
-81
lines changed

5 files changed

+168
-81
lines changed

projektor.yaml

Lines changed: 39 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,51 @@
1+
integration:
2+
auto_fix: true
3+
create_github_issues: false
4+
default_labels:
5+
- projektor
6+
- auto-reported
7+
enabled: true
8+
github_repo: null
9+
global_handler: true
10+
ignore_errors:
11+
- KeyboardInterrupt
12+
- SystemExit
13+
ignore_patterns:
14+
- '*.pyc'
15+
- __pycache__
16+
- .git
17+
- .venv
18+
- venv
19+
- '*.egg-info'
20+
- .projektor
21+
- htmlcov
22+
- .coverage
23+
- '*.log'
24+
notify_on_error: true
25+
notify_on_fix: true
26+
priority: high
27+
report_file: .projektor/errors.log
28+
report_to_console: true
29+
report_to_file: true
30+
state_file: .projektor/state.json
31+
tickets_dir: .projektor/tickets
32+
watch_paths:
33+
- src
34+
- tests
35+
workflows: {}
136
orchestration:
2-
auto_commit: true
37+
auto_commit: false
338
max_iterations: 10
439
run_tests: true
5-
640
project:
741
authors: []
8-
created_at: '2026-01-26T15:35:06.695980'
9-
description: 'Natural Language to Command Line Interface'
42+
created_at: '2026-01-26T16:17:37.364595'
43+
description: ''
1044
language: python
1145
name: nlp2cmd
1246
repository: null
13-
updated_at: '2026-01-26T15:35:06.695984'
47+
updated_at: '2026-01-26T16:17:37.364599'
1448
version: 0.1.0
15-
1649
targets:
1750
max_complexity: 15
1851
min_coverage: 85
19-
20-
# Integracja - automatyczne przechwytywanie błędów
21-
integration:
22-
enabled: true
23-
global_handler: true
24-
auto_fix: false
25-
priority: high
26-
default_labels:
27-
- nlp2cmd
28-
- projektor
29-
30-
# Workflows - podobne do CI/CD, uruchamiane na zdarzeniach
31-
workflows:
32-
error-reporter:
33-
trigger: on_error
34-
enabled: true
35-
auto_fix: false
36-
priority: high
37-
labels:
38-
- runtime-error
39-
- auto-reported
40-
41-
test-failure-tracker:
42-
trigger: on_test_fail
43-
enabled: true
44-
auto_fix: true
45-
priority: critical
46-
labels:
47-
- test-failure
48-
- needs-fix

projektor_integration.py

Lines changed: 113 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@
55
i tworzenie ticketów w projektorze.
66
77
Użycie:
8-
# W głównym pliku nlp2cmd (np. __main__.py lub cli.py):
8+
# Automatyczna instalacja (zalecane) - w __init__.py lub main.py:
9+
try:
10+
from projektor import install
11+
install()
12+
except ImportError:
13+
pass # projektor nie jest zainstalowany
14+
15+
# Lub przez ten moduł:
916
from projektor_integration import setup_projektor
1017
setup_projektor()
11-
12-
# Lub importuj z projektor bezpośrednio:
13-
from projektor.integration import install_global_handler
14-
install_global_handler(auto_fix=False)
1518
"""
1619

1720
import sys
@@ -23,75 +26,142 @@
2326
sys.path.insert(0, str(PROJEKTOR_PATH))
2427

2528

26-
def setup_projektor(auto_fix: bool = False) -> None:
29+
def setup_projektor(auto_fix: bool = False) -> bool:
2730
"""
2831
Konfiguruje integrację projektora z nlp2cmd.
2932
3033
Args:
3134
auto_fix: Czy automatycznie próbować naprawiać błędy
35+
36+
Returns:
37+
True jeśli instalacja się powiodła
3238
"""
3339
try:
34-
from projektor.integration import install_global_handler
35-
from projektor.integration.config_loader import load_integration_config
36-
37-
# Załaduj konfigurację z projektor.yaml lub pyproject.toml
38-
config = load_integration_config(Path(__file__).parent)
39-
40-
if not config.enabled:
41-
print("[projektor] Integration disabled in config")
42-
return
43-
44-
# Użyj ustawień z konfiguracji
45-
install_global_handler(auto_fix=config.auto_fix or auto_fix)
46-
47-
print("[projektor] Error tracking enabled for nlp2cmd")
48-
if config.auto_fix or auto_fix:
49-
print("[projektor] Auto-fix is ON")
50-
40+
from projektor import install
41+
return install(auto_fix=auto_fix)
5142
except ImportError as e:
5243
print(f"[projektor] Not available: {e}")
5344
print("[projektor] Install with: pip install projektor")
45+
return False
46+
5447

48+
# ==================== Dekoratory ====================
5549

56-
def catch_nlp2cmd_errors(func):
50+
def track_errors(func=None, **kwargs):
5751
"""
58-
Dekorator do przechwytywania błędów w nlp2cmd.
52+
Dekorator do śledzenia błędów w funkcjach.
5953
6054
Użycie:
61-
@catch_nlp2cmd_errors
55+
@track_errors
6256
def parse_command(text):
6357
...
58+
59+
@track_errors(context={"component": "parser"})
60+
def process(data):
61+
...
6462
"""
6563
try:
66-
from projektor.integration import catch_errors
67-
from projektor.core.ticket import Priority
64+
from projektor import track_errors as _track_errors
65+
return _track_errors(func, **kwargs)
66+
except ImportError:
67+
# Fallback - zwróć oryginalną funkcję
68+
if func is None:
69+
return lambda f: f
70+
return func
71+
72+
73+
def track_async_errors(func=None, **kwargs):
74+
"""
75+
Dekorator do śledzenia błędów w funkcjach async.
76+
77+
Użycie:
78+
@track_async_errors
79+
async def fetch_data(url):
80+
...
6881
69-
return catch_errors(
70-
func,
71-
auto_fix=False,
72-
priority=Priority.HIGH,
73-
labels=["nlp2cmd", "runtime-error"],
74-
)
82+
@track_async_errors(context={"component": "thermodynamic"})
83+
async def generate(text):
84+
...
85+
"""
86+
try:
87+
from projektor import track_async_errors as _track_async_errors
88+
return _track_async_errors(func, **kwargs)
7589
except ImportError:
7690
# Fallback - zwróć oryginalną funkcję
91+
if func is None:
92+
return lambda f: f
7793
return func
7894

7995

80-
# ==================== Przykłady użycia ====================
96+
# ==================== Context Manager ====================
97+
98+
class ErrorTracker:
99+
"""
100+
Context manager do śledzenia błędów.
101+
102+
Użycie:
103+
with ErrorTracker(context={"input": text[:50]}) as tracker:
104+
result = process(text)
105+
106+
if tracker.had_error:
107+
print(f"Error: {tracker.error}")
108+
"""
109+
110+
def __init__(self, **kwargs):
111+
self.kwargs = kwargs
112+
self.had_error = False
113+
self.error = None
114+
self.ticket = None
115+
self._real_tracker = None
116+
117+
def __enter__(self):
118+
try:
119+
from projektor import ErrorTracker as _ErrorTracker
120+
self._real_tracker = _ErrorTracker(**self.kwargs)
121+
return self._real_tracker.__enter__()
122+
except ImportError:
123+
return self
124+
125+
def __exit__(self, exc_type, exc_val, exc_tb):
126+
if self._real_tracker:
127+
return self._real_tracker.__exit__(exc_type, exc_val, exc_tb)
128+
if exc_val:
129+
self.had_error = True
130+
self.error = exc_val
131+
return False
132+
133+
134+
# ==================== Test ====================
81135

82136
if __name__ == "__main__":
137+
print("=== Testing Projektor Integration for nlp2cmd ===\n")
138+
83139
# Włącz integrację
84-
setup_projektor(auto_fix=False)
140+
if setup_projektor(auto_fix=False):
141+
print("[OK] Projektor installed\n")
142+
else:
143+
print("[SKIP] Projektor not available\n")
85144

86-
# Przykład funkcji z dekoratorem
87-
@catch_nlp2cmd_errors
145+
# Przykład 1: Dekorator
146+
print("1. Testing @track_errors decorator...")
147+
148+
@track_errors
88149
def example_function():
89-
# Ta funkcja automatycznie utworzy ticket przy błędzie
90-
raise ValueError("Example error for testing projektor integration")
150+
raise ValueError("Example error for testing")
91151

92-
print("Testing projektor integration...")
93152
try:
94153
example_function()
95154
except ValueError as e:
96-
print(f"Error caught: {e}")
97-
print("Check .projektor/tickets/ for the created bug ticket")
155+
print(f" Error caught: {e}")
156+
157+
# Przykład 2: Context manager
158+
print("\n2. Testing ErrorTracker context manager...")
159+
160+
with ErrorTracker(context={"test": "example"}) as tracker:
161+
# To nie rzuci błędu
162+
x = 1 + 1
163+
164+
print(f" Had error: {tracker.had_error}")
165+
166+
print("\n=== Done ===")
167+
print("Check .projektor/tickets/ for created bug tickets")

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "nlp2cmd"
7-
version = "1.0.40"
7+
version = "1.0.41"
88
description = "Natural Language to Domain-Specific Commands with Thermodynamic Optimization - Transform natural language into SQL, Shell, Docker, Kubernetes and solve optimization problems using Langevin dynamics"
99
readme = "README.md"
1010
license = "Apache-2.0"

src/nlp2cmd/cli/main.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
from pathlib import Path
1717
from typing import Any, Optional
1818

19+
from nlp2cmd.execution import ExecutionRunner
20+
1921
try:
2022
import click
2123
except Exception: # pragma: no cover
@@ -831,7 +833,6 @@ def _handle_run_query(
831833
AppSpecAdapter,
832834
BrowserAdapter,
833835
)
834-
from nlp2cmd.execution import ExecutionRunner
835836
from nlp2cmd.web_schema.form_data_loader import FormDataLoader
836837

837838
print(f"```bash")

tests/e2e/conftest.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,19 @@ def pytest_configure(config):
4343
)
4444

4545

46+
def pytest_collection_modifyitems(config, items):
47+
for item in items:
48+
# This conftest is imported as a plugin and the hook runs for the whole
49+
# test session. Only mark tests that actually live under tests/e2e.
50+
try:
51+
path = str(item.fspath)
52+
except Exception:
53+
path = item.nodeid
54+
55+
if "/tests/e2e/" in path or path.startswith("tests/e2e/"):
56+
item.add_marker(pytest.mark.e2e)
57+
58+
4659
@pytest.fixture(scope="session")
4760
def e2e_config():
4861
"""E2E test configuration."""

0 commit comments

Comments
 (0)