isa-model 0.3.5__py3-none-any.whl → 0.3.7__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.
- isa_model/__init__.py +30 -1
- isa_model/client.py +937 -0
- isa_model/core/config/__init__.py +16 -0
- isa_model/core/config/config_manager.py +514 -0
- isa_model/core/config.py +426 -0
- isa_model/core/models/model_billing_tracker.py +476 -0
- isa_model/core/models/model_manager.py +399 -0
- isa_model/core/{storage/supabase_storage.py → models/model_repo.py} +72 -73
- isa_model/core/pricing_manager.py +426 -0
- isa_model/core/services/__init__.py +19 -0
- isa_model/core/services/intelligent_model_selector.py +547 -0
- isa_model/core/types.py +291 -0
- isa_model/deployment/__init__.py +2 -0
- isa_model/deployment/cloud/modal/isa_vision_doc_service.py +157 -3
- isa_model/deployment/cloud/modal/isa_vision_table_service.py +532 -0
- isa_model/deployment/cloud/modal/isa_vision_ui_service.py +104 -3
- isa_model/deployment/cloud/modal/register_models.py +321 -0
- isa_model/deployment/runtime/deployed_service.py +338 -0
- isa_model/deployment/services/__init__.py +9 -0
- isa_model/deployment/services/auto_deploy_vision_service.py +538 -0
- isa_model/deployment/services/model_service.py +332 -0
- isa_model/deployment/services/service_monitor.py +356 -0
- isa_model/deployment/services/service_registry.py +527 -0
- isa_model/deployment/services/simple_auto_deploy_vision_service.py +275 -0
- isa_model/eval/__init__.py +80 -44
- isa_model/eval/config/__init__.py +10 -0
- isa_model/eval/config/evaluation_config.py +108 -0
- isa_model/eval/evaluators/__init__.py +18 -0
- isa_model/eval/evaluators/base_evaluator.py +503 -0
- isa_model/eval/evaluators/llm_evaluator.py +472 -0
- isa_model/eval/factory.py +417 -709
- isa_model/eval/infrastructure/__init__.py +24 -0
- isa_model/eval/infrastructure/experiment_tracker.py +466 -0
- isa_model/eval/metrics.py +191 -21
- isa_model/inference/ai_factory.py +257 -601
- isa_model/inference/services/audio/base_stt_service.py +65 -1
- isa_model/inference/services/audio/base_tts_service.py +75 -1
- isa_model/inference/services/audio/openai_stt_service.py +189 -151
- isa_model/inference/services/audio/openai_tts_service.py +12 -10
- isa_model/inference/services/audio/replicate_tts_service.py +61 -56
- isa_model/inference/services/base_service.py +55 -17
- isa_model/inference/services/embedding/base_embed_service.py +65 -1
- isa_model/inference/services/embedding/ollama_embed_service.py +103 -43
- isa_model/inference/services/embedding/openai_embed_service.py +8 -10
- isa_model/inference/services/helpers/stacked_config.py +148 -0
- isa_model/inference/services/img/__init__.py +18 -0
- isa_model/inference/services/{vision → img}/base_image_gen_service.py +80 -1
- isa_model/inference/services/{stacked → img}/flux_professional_service.py +25 -1
- isa_model/inference/services/{stacked → img/helpers}/base_stacked_service.py +40 -35
- isa_model/inference/services/{vision → img}/replicate_image_gen_service.py +44 -31
- isa_model/inference/services/llm/__init__.py +3 -3
- isa_model/inference/services/llm/base_llm_service.py +492 -40
- isa_model/inference/services/llm/helpers/llm_prompts.py +258 -0
- isa_model/inference/services/llm/helpers/llm_utils.py +280 -0
- isa_model/inference/services/llm/ollama_llm_service.py +51 -17
- isa_model/inference/services/llm/openai_llm_service.py +70 -19
- isa_model/inference/services/llm/yyds_llm_service.py +24 -23
- isa_model/inference/services/vision/__init__.py +38 -4
- isa_model/inference/services/vision/base_vision_service.py +218 -117
- isa_model/inference/services/vision/{isA_vision_service.py → disabled/isA_vision_service.py} +98 -0
- isa_model/inference/services/{stacked → vision}/doc_analysis_service.py +1 -1
- isa_model/inference/services/vision/helpers/base_stacked_service.py +274 -0
- isa_model/inference/services/vision/helpers/image_utils.py +272 -3
- isa_model/inference/services/vision/helpers/vision_prompts.py +297 -0
- isa_model/inference/services/vision/openai_vision_service.py +104 -307
- isa_model/inference/services/vision/replicate_vision_service.py +140 -325
- isa_model/inference/services/{stacked → vision}/ui_analysis_service.py +2 -498
- isa_model/scripts/register_models.py +370 -0
- isa_model/scripts/register_models_with_embeddings.py +510 -0
- isa_model/serving/api/fastapi_server.py +6 -1
- isa_model/serving/api/routes/unified.py +274 -0
- {isa_model-0.3.5.dist-info → isa_model-0.3.7.dist-info}/METADATA +4 -1
- {isa_model-0.3.5.dist-info → isa_model-0.3.7.dist-info}/RECORD +78 -53
- isa_model/config/__init__.py +0 -9
- isa_model/config/config_manager.py +0 -213
- isa_model/core/model_manager.py +0 -213
- isa_model/core/model_registry.py +0 -375
- isa_model/core/vision_models_init.py +0 -116
- isa_model/inference/billing_tracker.py +0 -406
- isa_model/inference/services/llm/triton_llm_service.py +0 -481
- isa_model/inference/services/stacked/__init__.py +0 -26
- isa_model/inference/services/stacked/config.py +0 -426
- isa_model/inference/services/vision/ollama_vision_service.py +0 -194
- /isa_model/core/{model_storage.py → models/model_storage.py} +0 -0
- /isa_model/inference/services/{vision → embedding}/helpers/text_splitter.py +0 -0
- /isa_model/inference/services/llm/{llm_adapter.py → helpers/llm_adapter.py} +0 -0
- {isa_model-0.3.5.dist-info → isa_model-0.3.7.dist-info}/WHEEL +0 -0
- {isa_model-0.3.5.dist-info → isa_model-0.3.7.dist-info}/top_level.txt +0 -0
isa_model/core/config.py
ADDED
@@ -0,0 +1,426 @@
|
|
1
|
+
"""
|
2
|
+
Centralized Configuration Management for ISA Model SDK
|
3
|
+
|
4
|
+
This module provides unified configuration management across all modules:
|
5
|
+
- Environment variable loading
|
6
|
+
- Provider API key management
|
7
|
+
- Global settings and defaults
|
8
|
+
- Configuration validation
|
9
|
+
"""
|
10
|
+
|
11
|
+
import os
|
12
|
+
import logging
|
13
|
+
from typing import Dict, Any, Optional, List
|
14
|
+
from pathlib import Path
|
15
|
+
from dataclasses import dataclass, field
|
16
|
+
import yaml
|
17
|
+
import json
|
18
|
+
from dotenv import load_dotenv
|
19
|
+
|
20
|
+
from .types import Provider, DeploymentPlatform
|
21
|
+
|
22
|
+
logger = logging.getLogger(__name__)
|
23
|
+
|
24
|
+
|
25
|
+
@dataclass
|
26
|
+
class ProviderConfig:
|
27
|
+
"""Configuration for a single provider"""
|
28
|
+
name: str
|
29
|
+
api_key: Optional[str] = None
|
30
|
+
api_base_url: Optional[str] = None
|
31
|
+
organization: Optional[str] = None
|
32
|
+
rate_limit_rpm: Optional[int] = None
|
33
|
+
rate_limit_tpm: Optional[int] = None
|
34
|
+
enabled: bool = True
|
35
|
+
metadata: Dict[str, Any] = field(default_factory=dict)
|
36
|
+
|
37
|
+
|
38
|
+
@dataclass
|
39
|
+
class DeploymentConfig:
|
40
|
+
"""Configuration for deployment platforms"""
|
41
|
+
platform: DeploymentPlatform
|
42
|
+
endpoint: Optional[str] = None
|
43
|
+
api_key: Optional[str] = None
|
44
|
+
default_gpu: str = "T4"
|
45
|
+
default_memory_mb: int = 16384
|
46
|
+
auto_scaling: bool = True
|
47
|
+
scale_to_zero: bool = True
|
48
|
+
metadata: Dict[str, Any] = field(default_factory=dict)
|
49
|
+
|
50
|
+
|
51
|
+
@dataclass
|
52
|
+
class GlobalConfig:
|
53
|
+
"""Global configuration settings"""
|
54
|
+
# Storage settings
|
55
|
+
default_storage_backend: str = "local"
|
56
|
+
storage_path: str = "./isa_model_data"
|
57
|
+
cache_dir: str = "./isa_model_cache"
|
58
|
+
|
59
|
+
# Database settings
|
60
|
+
use_supabase: bool = False
|
61
|
+
supabase_url: Optional[str] = None
|
62
|
+
supabase_key: Optional[str] = None
|
63
|
+
sqlite_path: str = "./isa_model.db"
|
64
|
+
|
65
|
+
# Billing settings
|
66
|
+
track_costs: bool = True
|
67
|
+
cost_alerts_enabled: bool = True
|
68
|
+
monthly_budget_usd: Optional[float] = None
|
69
|
+
|
70
|
+
# Health monitoring
|
71
|
+
health_check_interval: int = 300 # 5 minutes
|
72
|
+
health_check_timeout: int = 30 # 30 seconds
|
73
|
+
|
74
|
+
# Logging
|
75
|
+
log_level: str = "INFO"
|
76
|
+
log_file: Optional[str] = None
|
77
|
+
|
78
|
+
# Model caching
|
79
|
+
enable_model_cache: bool = True
|
80
|
+
cache_size_gb: int = 50
|
81
|
+
cache_cleanup_interval: int = 3600 # 1 hour
|
82
|
+
|
83
|
+
|
84
|
+
class ConfigManager:
|
85
|
+
"""
|
86
|
+
Centralized configuration manager for the entire ISA Model SDK.
|
87
|
+
|
88
|
+
Features:
|
89
|
+
- Loads configuration from .env files, YAML files, and environment variables
|
90
|
+
- Manages provider API keys and settings
|
91
|
+
- Handles deployment platform configurations
|
92
|
+
- Provides unified access to all settings
|
93
|
+
|
94
|
+
Example:
|
95
|
+
```python
|
96
|
+
from isa_model.core.config import ConfigManager
|
97
|
+
|
98
|
+
config = ConfigManager()
|
99
|
+
|
100
|
+
# Get provider configuration
|
101
|
+
openai_config = config.get_provider_config(Provider.OPENAI)
|
102
|
+
|
103
|
+
# Get deployment configuration
|
104
|
+
modal_config = config.get_deployment_config(DeploymentPlatform.MODAL)
|
105
|
+
|
106
|
+
# Check if provider is enabled
|
107
|
+
if config.is_provider_enabled(Provider.OPENAI):
|
108
|
+
print("OpenAI is configured and enabled")
|
109
|
+
```
|
110
|
+
"""
|
111
|
+
|
112
|
+
_instance = None
|
113
|
+
_initialized = False
|
114
|
+
|
115
|
+
def __new__(cls):
|
116
|
+
if cls._instance is None:
|
117
|
+
cls._instance = super().__new__(cls)
|
118
|
+
return cls._instance
|
119
|
+
|
120
|
+
def __init__(self):
|
121
|
+
"""Initialize configuration manager"""
|
122
|
+
if not self._initialized:
|
123
|
+
self.global_config = GlobalConfig()
|
124
|
+
self.provider_configs: Dict[str, ProviderConfig] = {}
|
125
|
+
self.deployment_configs: Dict[str, DeploymentConfig] = {}
|
126
|
+
|
127
|
+
self._load_configuration()
|
128
|
+
ConfigManager._initialized = True
|
129
|
+
|
130
|
+
def _load_configuration(self):
|
131
|
+
"""Load configuration from various sources"""
|
132
|
+
# 1. Load environment variables
|
133
|
+
self._load_env_files()
|
134
|
+
|
135
|
+
# 2. Load from YAML config file if exists
|
136
|
+
self._load_yaml_config()
|
137
|
+
|
138
|
+
# 3. Load provider configurations
|
139
|
+
self._load_provider_configs()
|
140
|
+
|
141
|
+
# 4. Load deployment configurations
|
142
|
+
self._load_deployment_configs()
|
143
|
+
|
144
|
+
# 5. Validate configuration
|
145
|
+
self._validate_configuration()
|
146
|
+
|
147
|
+
logger.info("Configuration loaded successfully")
|
148
|
+
|
149
|
+
def _load_env_files(self):
|
150
|
+
"""Load environment variables from .env files"""
|
151
|
+
# Load from project root
|
152
|
+
project_root = self._find_project_root()
|
153
|
+
env_files = [
|
154
|
+
project_root / ".env",
|
155
|
+
project_root / ".env.local",
|
156
|
+
Path.cwd() / ".env",
|
157
|
+
]
|
158
|
+
|
159
|
+
for env_file in env_files:
|
160
|
+
if env_file.exists():
|
161
|
+
load_dotenv(env_file)
|
162
|
+
logger.debug(f"Loaded environment from {env_file}")
|
163
|
+
|
164
|
+
def _find_project_root(self) -> Path:
|
165
|
+
"""Find the project root directory"""
|
166
|
+
current = Path(__file__).parent
|
167
|
+
while current != current.parent:
|
168
|
+
if (current / "pyproject.toml").exists() or (current / "setup.py").exists():
|
169
|
+
return current
|
170
|
+
current = current.parent
|
171
|
+
return Path.cwd()
|
172
|
+
|
173
|
+
def _load_yaml_config(self):
|
174
|
+
"""Load configuration from YAML file"""
|
175
|
+
config_files = [
|
176
|
+
Path.cwd() / "isa_model_config.yaml",
|
177
|
+
Path.cwd() / "config.yaml",
|
178
|
+
self._find_project_root() / "isa_model_config.yaml",
|
179
|
+
]
|
180
|
+
|
181
|
+
for config_file in config_files:
|
182
|
+
if config_file.exists():
|
183
|
+
try:
|
184
|
+
with open(config_file, 'r') as f:
|
185
|
+
yaml_config = yaml.safe_load(f)
|
186
|
+
|
187
|
+
self._apply_yaml_config(yaml_config)
|
188
|
+
logger.info(f"Loaded YAML configuration from {config_file}")
|
189
|
+
break
|
190
|
+
except Exception as e:
|
191
|
+
logger.warning(f"Failed to load YAML config from {config_file}: {e}")
|
192
|
+
|
193
|
+
def _apply_yaml_config(self, yaml_config: Dict[str, Any]):
|
194
|
+
"""Apply YAML configuration to global settings"""
|
195
|
+
if "global" in yaml_config:
|
196
|
+
global_settings = yaml_config["global"]
|
197
|
+
for key, value in global_settings.items():
|
198
|
+
if hasattr(self.global_config, key):
|
199
|
+
setattr(self.global_config, key, value)
|
200
|
+
|
201
|
+
def _load_provider_configs(self):
|
202
|
+
"""Load provider configurations from environment"""
|
203
|
+
|
204
|
+
# Define provider environment variable patterns
|
205
|
+
provider_env_mapping = {
|
206
|
+
Provider.OPENAI: {
|
207
|
+
"api_key": ["OPENAI_API_KEY"],
|
208
|
+
"organization": ["OPENAI_ORG_ID", "OPENAI_ORGANIZATION"],
|
209
|
+
"api_base_url": ["OPENAI_API_BASE", "OPENAI_BASE_URL"],
|
210
|
+
},
|
211
|
+
Provider.REPLICATE: {
|
212
|
+
"api_key": ["REPLICATE_API_TOKEN", "REPLICATE_API_KEY"],
|
213
|
+
},
|
214
|
+
Provider.ANTHROPIC: {
|
215
|
+
"api_key": ["ANTHROPIC_API_KEY"],
|
216
|
+
},
|
217
|
+
Provider.GOOGLE: {
|
218
|
+
"api_key": ["GOOGLE_API_KEY", "GEMINI_API_KEY"],
|
219
|
+
},
|
220
|
+
Provider.YYDS: {
|
221
|
+
"api_key": ["YYDS_API_KEY"],
|
222
|
+
"api_base_url": ["YYDS_API_BASE", "YYDS_BASE_URL"],
|
223
|
+
},
|
224
|
+
}
|
225
|
+
|
226
|
+
for provider, env_vars in provider_env_mapping.items():
|
227
|
+
config = ProviderConfig(name=provider.value)
|
228
|
+
|
229
|
+
# Load API key
|
230
|
+
for env_var in env_vars.get("api_key", []):
|
231
|
+
if os.getenv(env_var):
|
232
|
+
config.api_key = os.getenv(env_var)
|
233
|
+
break
|
234
|
+
|
235
|
+
# Load other settings
|
236
|
+
for setting, env_var_list in env_vars.items():
|
237
|
+
if setting == "api_key":
|
238
|
+
continue
|
239
|
+
for env_var in env_var_list:
|
240
|
+
if os.getenv(env_var):
|
241
|
+
setattr(config, setting, os.getenv(env_var))
|
242
|
+
break
|
243
|
+
|
244
|
+
# Check if provider is enabled
|
245
|
+
config.enabled = bool(config.api_key)
|
246
|
+
|
247
|
+
self.provider_configs[provider.value] = config
|
248
|
+
|
249
|
+
def _load_deployment_configs(self):
|
250
|
+
"""Load deployment platform configurations"""
|
251
|
+
|
252
|
+
deployment_env_mapping = {
|
253
|
+
DeploymentPlatform.MODAL: {
|
254
|
+
"api_key": ["MODAL_TOKEN"],
|
255
|
+
"endpoint": ["MODAL_ENDPOINT"],
|
256
|
+
},
|
257
|
+
DeploymentPlatform.RUNPOD: {
|
258
|
+
"api_key": ["RUNPOD_API_KEY"],
|
259
|
+
"endpoint": ["RUNPOD_ENDPOINT"],
|
260
|
+
},
|
261
|
+
DeploymentPlatform.KUBERNETES: {
|
262
|
+
"endpoint": ["K8S_ENDPOINT", "KUBERNETES_ENDPOINT"],
|
263
|
+
"api_key": ["K8S_TOKEN", "KUBERNETES_TOKEN"],
|
264
|
+
},
|
265
|
+
}
|
266
|
+
|
267
|
+
for platform, env_vars in deployment_env_mapping.items():
|
268
|
+
config = DeploymentConfig(platform=platform)
|
269
|
+
|
270
|
+
# Load settings from environment
|
271
|
+
for setting, env_var_list in env_vars.items():
|
272
|
+
for env_var in env_var_list:
|
273
|
+
if os.getenv(env_var):
|
274
|
+
setattr(config, setting, os.getenv(env_var))
|
275
|
+
break
|
276
|
+
|
277
|
+
self.deployment_configs[platform.value] = config
|
278
|
+
|
279
|
+
def _validate_configuration(self):
|
280
|
+
"""Validate loaded configuration"""
|
281
|
+
warnings = []
|
282
|
+
|
283
|
+
# Check if any providers are configured
|
284
|
+
enabled_providers = [p for p in self.provider_configs.values() if p.enabled]
|
285
|
+
if not enabled_providers:
|
286
|
+
warnings.append("No providers are configured with API keys")
|
287
|
+
|
288
|
+
# Check storage path accessibility
|
289
|
+
storage_path = Path(self.global_config.storage_path)
|
290
|
+
try:
|
291
|
+
storage_path.mkdir(parents=True, exist_ok=True)
|
292
|
+
except Exception as e:
|
293
|
+
warnings.append(f"Storage path not accessible: {e}")
|
294
|
+
|
295
|
+
# Check database configuration
|
296
|
+
if self.global_config.use_supabase:
|
297
|
+
if not self.global_config.supabase_url or not self.global_config.supabase_key:
|
298
|
+
warnings.append("Supabase is enabled but URL/key not configured")
|
299
|
+
|
300
|
+
for warning in warnings:
|
301
|
+
logger.warning(f"Configuration warning: {warning}")
|
302
|
+
|
303
|
+
# Public API methods
|
304
|
+
|
305
|
+
def get_provider_config(self, provider: Provider) -> Optional[ProviderConfig]:
|
306
|
+
"""Get configuration for a specific provider"""
|
307
|
+
return self.provider_configs.get(provider.value)
|
308
|
+
|
309
|
+
def get_deployment_config(self, platform: DeploymentPlatform) -> Optional[DeploymentConfig]:
|
310
|
+
"""Get configuration for a specific deployment platform"""
|
311
|
+
return self.deployment_configs.get(platform.value)
|
312
|
+
|
313
|
+
def is_provider_enabled(self, provider: Provider) -> bool:
|
314
|
+
"""Check if a provider is enabled and configured"""
|
315
|
+
config = self.get_provider_config(provider)
|
316
|
+
return config is not None and config.enabled and config.api_key is not None
|
317
|
+
|
318
|
+
def get_enabled_providers(self) -> List[Provider]:
|
319
|
+
"""Get list of all enabled providers"""
|
320
|
+
enabled = []
|
321
|
+
for provider_str, config in self.provider_configs.items():
|
322
|
+
if config.enabled:
|
323
|
+
try:
|
324
|
+
enabled.append(Provider(provider_str))
|
325
|
+
except ValueError:
|
326
|
+
continue
|
327
|
+
return enabled
|
328
|
+
|
329
|
+
def get_provider_api_key(self, provider: Provider) -> Optional[str]:
|
330
|
+
"""Get API key for a specific provider"""
|
331
|
+
config = self.get_provider_config(provider)
|
332
|
+
return config.api_key if config else None
|
333
|
+
|
334
|
+
def get_global_config(self) -> GlobalConfig:
|
335
|
+
"""Get global configuration"""
|
336
|
+
return self.global_config
|
337
|
+
|
338
|
+
def update_provider_config(self, provider: Provider, **kwargs):
|
339
|
+
"""Update provider configuration"""
|
340
|
+
if provider.value not in self.provider_configs:
|
341
|
+
self.provider_configs[provider.value] = ProviderConfig(name=provider.value)
|
342
|
+
|
343
|
+
config = self.provider_configs[provider.value]
|
344
|
+
for key, value in kwargs.items():
|
345
|
+
if hasattr(config, key):
|
346
|
+
setattr(config, key, value)
|
347
|
+
|
348
|
+
def save_config(self, config_file: Optional[Path] = None):
|
349
|
+
"""Save current configuration to YAML file"""
|
350
|
+
if config_file is None:
|
351
|
+
config_file = Path.cwd() / "isa_model_config.yaml"
|
352
|
+
|
353
|
+
config_data = {
|
354
|
+
"global": {
|
355
|
+
"default_storage_backend": self.global_config.default_storage_backend,
|
356
|
+
"storage_path": self.global_config.storage_path,
|
357
|
+
"cache_dir": self.global_config.cache_dir,
|
358
|
+
"use_supabase": self.global_config.use_supabase,
|
359
|
+
"track_costs": self.global_config.track_costs,
|
360
|
+
"health_check_interval": self.global_config.health_check_interval,
|
361
|
+
"log_level": self.global_config.log_level,
|
362
|
+
},
|
363
|
+
"providers": {},
|
364
|
+
"deployments": {}
|
365
|
+
}
|
366
|
+
|
367
|
+
# Add provider configs (without API keys for security)
|
368
|
+
for provider_name, config in self.provider_configs.items():
|
369
|
+
config_data["providers"][provider_name] = {
|
370
|
+
"enabled": config.enabled,
|
371
|
+
"rate_limit_rpm": config.rate_limit_rpm,
|
372
|
+
"rate_limit_tpm": config.rate_limit_tpm,
|
373
|
+
"metadata": config.metadata,
|
374
|
+
}
|
375
|
+
|
376
|
+
# Add deployment configs (without API keys)
|
377
|
+
for platform_name, config in self.deployment_configs.items():
|
378
|
+
config_data["deployments"][platform_name] = {
|
379
|
+
"default_gpu": config.default_gpu,
|
380
|
+
"default_memory_mb": config.default_memory_mb,
|
381
|
+
"auto_scaling": config.auto_scaling,
|
382
|
+
"scale_to_zero": config.scale_to_zero,
|
383
|
+
"metadata": config.metadata,
|
384
|
+
}
|
385
|
+
|
386
|
+
try:
|
387
|
+
with open(config_file, 'w') as f:
|
388
|
+
yaml.dump(config_data, f, default_flow_style=False)
|
389
|
+
logger.info(f"Configuration saved to {config_file}")
|
390
|
+
except Exception as e:
|
391
|
+
logger.error(f"Failed to save configuration: {e}")
|
392
|
+
|
393
|
+
def get_summary(self) -> Dict[str, Any]:
|
394
|
+
"""Get configuration summary"""
|
395
|
+
enabled_providers = [p.name for p in self.provider_configs.values() if p.enabled]
|
396
|
+
configured_deployments = [p.platform.value for p in self.deployment_configs.values() if p.api_key]
|
397
|
+
|
398
|
+
return {
|
399
|
+
"enabled_providers": enabled_providers,
|
400
|
+
"configured_deployments": configured_deployments,
|
401
|
+
"storage_backend": self.global_config.default_storage_backend,
|
402
|
+
"database": "supabase" if self.global_config.use_supabase else "sqlite",
|
403
|
+
"cost_tracking": self.global_config.track_costs,
|
404
|
+
"model_caching": self.global_config.enable_model_cache,
|
405
|
+
}
|
406
|
+
|
407
|
+
|
408
|
+
# Global configuration instance
|
409
|
+
config_manager = ConfigManager()
|
410
|
+
|
411
|
+
# Convenience functions
|
412
|
+
def get_provider_config(provider: Provider) -> Optional[ProviderConfig]:
|
413
|
+
"""Get provider configuration"""
|
414
|
+
return config_manager.get_provider_config(provider)
|
415
|
+
|
416
|
+
def get_deployment_config(platform: DeploymentPlatform) -> Optional[DeploymentConfig]:
|
417
|
+
"""Get deployment platform configuration"""
|
418
|
+
return config_manager.get_deployment_config(platform)
|
419
|
+
|
420
|
+
def is_provider_enabled(provider: Provider) -> bool:
|
421
|
+
"""Check if provider is enabled"""
|
422
|
+
return config_manager.is_provider_enabled(provider)
|
423
|
+
|
424
|
+
def get_api_key(provider: Provider) -> Optional[str]:
|
425
|
+
"""Get API key for provider"""
|
426
|
+
return config_manager.get_provider_api_key(provider)
|