-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.py
More file actions
182 lines (137 loc) · 5.94 KB
/
Copy pathconfig.py
File metadata and controls
182 lines (137 loc) · 5.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
"""
ITERUN: Configuration
Environment-based configuration for all components.
Loads from .env file if present.
"""
import os
from pathlib import Path
from typing import Optional
from dataclasses import dataclass, field
try:
from getv import EnvStore
_HAS_GETV = True
except ImportError:
_HAS_GETV = False
def _load_getv_profiles() -> None:
if not _HAS_GETV:
return
try:
from getv import AppDefaults
from getv.integrations.pydantic_env import load_profile_into_env
defaults = AppDefaults("iterun")
for category in ("llm", "devices"):
profile = defaults.get(category)
if profile:
load_profile_into_env(category, profile)
except Exception:
pass
def _apply_env_pairs(pairs: list[tuple[str, str]]) -> None:
for key, value in pairs:
if key not in os.environ:
os.environ[key] = value
def _load_envstore(env_path: Path) -> None:
store = EnvStore(env_path, auto_create=False)
_apply_env_pairs(list(store.items()))
def _parse_dotenv_lines(env_path: Path) -> list[tuple[str, str]]:
pairs: list[tuple[str, str]] = []
with open(env_path) as f:
for line in f:
line = line.strip()
if not line or line.startswith("#") or "=" not in line:
continue
key, value = line.split("=", 1)
pairs.append((key.strip(), value.strip().strip('"').strip("'")))
return pairs
def load_dotenv(env_path: Path = None):
"""Load environment variables from .env file.
Delegates to getv.EnvStore when available.
Also loads getv app defaults (``getv use iterun llm PROFILE``).
"""
_load_getv_profiles()
if env_path is None:
env_path = Path(__file__).parent / ".env"
if not env_path.exists():
return
if _HAS_GETV:
_load_envstore(env_path)
return
_apply_env_pairs(_parse_dotenv_lines(env_path))
# Load .env on module import
load_dotenv()
# Canonical DSL package filename written to workspace/generated/
PACKAGE_FILENAME = "iterun.yaml"
def get_env(key: str, default: str = None) -> Optional[str]:
"""Get environment variable."""
return os.getenv(key, default)
def get_env_bool(key: str, default: bool = False) -> bool:
"""Get boolean environment variable."""
value = os.getenv(key, str(default)).lower()
return value in ("true", "1", "yes", "on")
def get_env_int(key: str, default: int = 0) -> int:
"""Get integer environment variable."""
try:
return int(os.getenv(key, str(default)))
except ValueError:
return default
def get_env_float(key: str, default: float = 0.0) -> float:
"""Get float environment variable."""
try:
return float(os.getenv(key, str(default)))
except ValueError:
return default
@dataclass
class AppConfig:
"""Main application configuration."""
# General
debug: bool = field(default_factory=lambda: get_env_bool("DEBUG", False))
log_level: str = field(default_factory=lambda: get_env("LOG_LEVEL", "INFO"))
# Web server
host: str = field(default_factory=lambda: get_env("HOST", "0.0.0.0"))
port: int = field(default_factory=lambda: get_env_int("PORT", 8080))
# AI Gateway
ai_enabled: bool = field(default_factory=lambda: get_env_bool("AI_ENABLED", True))
default_model: str = field(default_factory=lambda: get_env("DEFAULT_MODEL", "llama3.2"))
llm_model: Optional[str] = field(default_factory=lambda: get_env("LLM_MODEL"))
max_model_params: float = field(default_factory=lambda: get_env_float("MAX_MODEL_PARAMS", 12.0))
# Ollama
ollama_base_url: str = field(default_factory=lambda: get_env("OLLAMA_BASE_URL", "http://localhost:11434"))
ollama_timeout: int = field(default_factory=lambda: get_env_int("OLLAMA_TIMEOUT", 120))
# Optional API keys
openai_api_key: Optional[str] = field(default_factory=lambda: get_env("OPENAI_API_KEY"))
anthropic_api_key: Optional[str] = field(default_factory=lambda: get_env("ANTHROPIC_API_KEY"))
openrouter_api_key: Optional[str] = field(default_factory=lambda: get_env("OPENROUTER_API_KEY"))
# Execution runtime: docker (default) | pactown (markpact sandboxes)
runtime: str = field(default_factory=lambda: get_env("ITERUN_RUNTIME", "docker"))
# Execution
docker_enabled: bool = field(default_factory=lambda: get_env_bool("DOCKER_ENABLED", True))
workspace_dir: str = field(default_factory=lambda: get_env("WORKSPACE_DIR", "/tmp/iterun"))
auto_execute: bool = field(default_factory=lambda: get_env_bool("AUTO_EXECUTE", True))
skip_iterun_confirmation: bool = field(default_factory=lambda: get_env_bool("SKIP_ITERUN_CONFIRMATION", True))
# Docker container settings
container_port: int = field(default_factory=lambda: get_env_int("CONTAINER_PORT", 8000))
container_prefix: str = field(default_factory=lambda: get_env("CONTAINER_PREFIX", "intent"))
# Validation & Auto-fix
validate_after_execute: bool = field(default_factory=lambda: get_env_bool("VALIDATE_AFTER_EXECUTE", True))
auto_fix_enabled: bool = field(default_factory=lambda: get_env_bool("AUTO_FIX_ENABLED", True))
max_fix_iterations: int = field(default_factory=lambda: get_env_int("MAX_FIX_ITERATIONS", 3))
startup_wait: int = field(default_factory=lambda: get_env_int("STARTUP_WAIT", 2))
validation_timeout: int = field(default_factory=lambda: get_env_int("VALIDATION_TIMEOUT", 10))
# Global config instance
_config: Optional[AppConfig] = None
def get_config() -> AppConfig:
"""Get or create application config."""
global _config
if _config is None:
_config = AppConfig()
return _config
def reload_config() -> AppConfig:
"""Force reload configuration."""
global _config
load_dotenv()
_config = AppConfig()
return _config
def configure(**kwargs) -> AppConfig:
"""Configure application with custom settings."""
global _config
_config = AppConfig(**kwargs)
return _config