omnimancer-cli 0.1.0__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.
- omnimancer/__init__.py +42 -0
- omnimancer/__main__.py +9 -0
- omnimancer/cli/__init__.py +8 -0
- omnimancer/cli/agent_manager.py +826 -0
- omnimancer/cli/agent_wizard.py +944 -0
- omnimancer/cli/approval_formatter.py +734 -0
- omnimancer/cli/approval_integration.py +734 -0
- omnimancer/cli/approval_prompt.py +1286 -0
- omnimancer/cli/batch_approval_display.py +617 -0
- omnimancer/cli/batch_approval_filters.py +729 -0
- omnimancer/cli/batch_operation_monitor.py +775 -0
- omnimancer/cli/commands/performance_cmd.py +624 -0
- omnimancer/cli/commands.py +757 -0
- omnimancer/cli/completion_handler.py +281 -0
- omnimancer/cli/config_setup_wizard.py +783 -0
- omnimancer/cli/dynamic_commands.py +371 -0
- omnimancer/cli/handlers/__init__.py +18 -0
- omnimancer/cli/handlers/agent_handler.py +865 -0
- omnimancer/cli/handlers/agent_persona_handler.py +1048 -0
- omnimancer/cli/handlers/custom_agent_handler.py +352 -0
- omnimancer/cli/handlers/permissions_handler.py +1609 -0
- omnimancer/cli/interface.py +6695 -0
- omnimancer/cli/performance_dashboard.py +612 -0
- omnimancer/core/__init__.py +34 -0
- omnimancer/core/agent/__init__.py +256 -0
- omnimancer/core/agent/agent_config.py +715 -0
- omnimancer/core/agent/agent_switcher.py +668 -0
- omnimancer/core/agent/approval_context.py +460 -0
- omnimancer/core/agent/approval_dialog.py +902 -0
- omnimancer/core/agent/approval_interface.py +628 -0
- omnimancer/core/agent/approval_manager.py +760 -0
- omnimancer/core/agent/cli_integration.py +470 -0
- omnimancer/core/agent/config.py +845 -0
- omnimancer/core/agent/custom_agent_integration.py +654 -0
- omnimancer/core/agent/diff_renderer.py +706 -0
- omnimancer/core/agent/file_content_display.py +503 -0
- omnimancer/core/agent/file_modification_workflow.py +658 -0
- omnimancer/core/agent/file_system_manager.py +1790 -0
- omnimancer/core/agent/input_handler.py +614 -0
- omnimancer/core/agent/metrics_collector.py +771 -0
- omnimancer/core/agent/optimization_engine.py +729 -0
- omnimancer/core/agent/performance_monitor.py +717 -0
- omnimancer/core/agent/persona.py +870 -0
- omnimancer/core/agent/persona_validator.py +672 -0
- omnimancer/core/agent/program_executor.py +748 -0
- omnimancer/core/agent/proposed_changes_integration.py +663 -0
- omnimancer/core/agent/read_before_write_errors.py +492 -0
- omnimancer/core/agent/read_before_write_ui.py +647 -0
- omnimancer/core/agent/rich_renderer.py +763 -0
- omnimancer/core/agent/status_config.py +238 -0
- omnimancer/core/agent/status_core.py +446 -0
- omnimancer/core/agent/status_integrated_engine.py +540 -0
- omnimancer/core/agent/status_manager.py +878 -0
- omnimancer/core/agent/status_ui_components.py +535 -0
- omnimancer/core/agent/template_applicator.py +548 -0
- omnimancer/core/agent/terminal_status_listener.py +394 -0
- omnimancer/core/agent/token_tracker.py +679 -0
- omnimancer/core/agent/types.py +60 -0
- omnimancer/core/agent/web_client.py +745 -0
- omnimancer/core/agent/workflow_orchestrator.py +826 -0
- omnimancer/core/agent_engine.py +1625 -0
- omnimancer/core/agent_mode_manager.py +706 -0
- omnimancer/core/agent_progress_ui.py +545 -0
- omnimancer/core/chat_manager.py +141 -0
- omnimancer/core/config_manager.py +2199 -0
- omnimancer/core/config_migration.py +772 -0
- omnimancer/core/config_provider.py +1974 -0
- omnimancer/core/config_security_validator.py +393 -0
- omnimancer/core/config_validator.py +768 -0
- omnimancer/core/conversation_manager.py +352 -0
- omnimancer/core/engine.py +787 -0
- omnimancer/core/enhanced_input.py +523 -0
- omnimancer/core/env_loader.py +83 -0
- omnimancer/core/fallback_manager.py +568 -0
- omnimancer/core/health_monitor.py +462 -0
- omnimancer/core/history_manager.py +462 -0
- omnimancer/core/mcp_integration_layer.py +878 -0
- omnimancer/core/models.py +1889 -0
- omnimancer/core/provider_capabilities.py +403 -0
- omnimancer/core/provider_initializer.py +450 -0
- omnimancer/core/provider_registry.py +432 -0
- omnimancer/core/security/__init__.py +16 -0
- omnimancer/core/security/approval_workflow.py +406 -0
- omnimancer/core/security/audit_logger.py +511 -0
- omnimancer/core/security/permission_controller.py +511 -0
- omnimancer/core/security/sandbox_manager.py +379 -0
- omnimancer/core/security/security_manager.py +530 -0
- omnimancer/core/setup_wizard.py +345 -0
- omnimancer/core/setup_wizard_core.py +449 -0
- omnimancer/core/setup_wizard_guide_generator.py +376 -0
- omnimancer/core/setup_wizard_provider_setup.py +454 -0
- omnimancer/core/setup_wizard_ui.py +317 -0
- omnimancer/core/setup_wizard_validation.py +371 -0
- omnimancer/core/signal_handler.py +174 -0
- omnimancer/mcp/__init__.py +11 -0
- omnimancer/mcp/client.py +725 -0
- omnimancer/mcp/manager.py +649 -0
- omnimancer/providers/__init__.py +24 -0
- omnimancer/providers/azure.py +608 -0
- omnimancer/providers/base.py +262 -0
- omnimancer/providers/bedrock.py +711 -0
- omnimancer/providers/claude.py +426 -0
- omnimancer/providers/claude_code.py +406 -0
- omnimancer/providers/cohere.py +412 -0
- omnimancer/providers/factory.py +988 -0
- omnimancer/providers/gemini.py +708 -0
- omnimancer/providers/mistral.py +554 -0
- omnimancer/providers/ollama.py +510 -0
- omnimancer/providers/openai.py +362 -0
- omnimancer/providers/openrouter.py +709 -0
- omnimancer/providers/perplexity.py +476 -0
- omnimancer/providers/vertex.py +617 -0
- omnimancer/providers/xai.py +484 -0
- omnimancer/ui/__init__.py +6 -0
- omnimancer/ui/cancellation_handler.py +235 -0
- omnimancer/ui/progress_indicator.py +318 -0
- omnimancer/utils/__init__.py +22 -0
- omnimancer/utils/error_handler.py +589 -0
- omnimancer/utils/errors.py +667 -0
- omnimancer/utils/retry.py +238 -0
- omnimancer_cli-0.1.0.dist-info/METADATA +413 -0
- omnimancer_cli-0.1.0.dist-info/RECORD +126 -0
- omnimancer_cli-0.1.0.dist-info/WHEEL +5 -0
- omnimancer_cli-0.1.0.dist-info/entry_points.txt +4 -0
- omnimancer_cli-0.1.0.dist-info/licenses/LICENSE +21 -0
- omnimancer_cli-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Provider initialization optimization module.
|
|
3
|
+
|
|
4
|
+
This module provides optimized initialization for providers with
|
|
5
|
+
lazy loading and caching mechanisms to improve performance.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import importlib
|
|
9
|
+
import inspect
|
|
10
|
+
import logging
|
|
11
|
+
import threading
|
|
12
|
+
import time
|
|
13
|
+
from typing import Dict, List, Type
|
|
14
|
+
|
|
15
|
+
from ..providers.base import BaseProvider
|
|
16
|
+
from .models import EnhancedModelInfo, ProviderConfig
|
|
17
|
+
|
|
18
|
+
logger = logging.getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ProviderInitializer:
|
|
22
|
+
"""
|
|
23
|
+
Optimized provider initialization with lazy loading and caching.
|
|
24
|
+
|
|
25
|
+
This class handles lazy loading of provider classes and caching
|
|
26
|
+
of provider instances and model information to improve performance.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
# Class-level caches
|
|
30
|
+
_provider_classes: Dict[str, Type[BaseProvider]] = {}
|
|
31
|
+
_provider_instances: Dict[str, BaseProvider] = {}
|
|
32
|
+
_model_cache: Dict[str, List[EnhancedModelInfo]] = {}
|
|
33
|
+
_cache_timestamps: Dict[str, float] = {}
|
|
34
|
+
_cache_ttl: float = 3600.0 # 1 hour cache TTL by default
|
|
35
|
+
|
|
36
|
+
# Locks for thread safety
|
|
37
|
+
_class_lock = threading.RLock()
|
|
38
|
+
_instance_lock = threading.RLock()
|
|
39
|
+
_model_lock = threading.RLock()
|
|
40
|
+
|
|
41
|
+
# Configuration
|
|
42
|
+
_lazy_loading_enabled: bool = True
|
|
43
|
+
_cache_enabled: bool = True
|
|
44
|
+
|
|
45
|
+
@classmethod
|
|
46
|
+
def get_provider_class(cls, provider_name: str) -> Type[BaseProvider]:
|
|
47
|
+
"""
|
|
48
|
+
Get provider class with lazy loading.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
provider_name: Name of the provider
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
Provider class
|
|
55
|
+
|
|
56
|
+
Raises:
|
|
57
|
+
ImportError: If provider module cannot be imported
|
|
58
|
+
ValueError: If provider class cannot be found
|
|
59
|
+
"""
|
|
60
|
+
with cls._class_lock:
|
|
61
|
+
# Check if class is already loaded
|
|
62
|
+
if provider_name in cls._provider_classes:
|
|
63
|
+
return cls._provider_classes[provider_name]
|
|
64
|
+
|
|
65
|
+
# Lazy load provider class
|
|
66
|
+
try:
|
|
67
|
+
# Map provider name to module path
|
|
68
|
+
module_path = cls._get_module_path(provider_name)
|
|
69
|
+
|
|
70
|
+
# Import module
|
|
71
|
+
module = importlib.import_module(module_path)
|
|
72
|
+
|
|
73
|
+
# Find provider class in module
|
|
74
|
+
provider_class = None
|
|
75
|
+
for name, obj in inspect.getmembers(module):
|
|
76
|
+
if (
|
|
77
|
+
inspect.isclass(obj)
|
|
78
|
+
and issubclass(obj, BaseProvider)
|
|
79
|
+
and obj != BaseProvider
|
|
80
|
+
and name.lower().endswith("provider")
|
|
81
|
+
):
|
|
82
|
+
provider_class = obj
|
|
83
|
+
break
|
|
84
|
+
|
|
85
|
+
if not provider_class:
|
|
86
|
+
raise ValueError(f"Could not find provider class in {module_path}")
|
|
87
|
+
|
|
88
|
+
# Cache provider class
|
|
89
|
+
cls._provider_classes[provider_name] = provider_class
|
|
90
|
+
logger.debug(f"Lazy loaded provider class for {provider_name}")
|
|
91
|
+
|
|
92
|
+
return provider_class
|
|
93
|
+
|
|
94
|
+
except ImportError as e:
|
|
95
|
+
logger.error(
|
|
96
|
+
f"Failed to import provider module for {provider_name}: {e}"
|
|
97
|
+
)
|
|
98
|
+
raise
|
|
99
|
+
except Exception as e:
|
|
100
|
+
logger.error(f"Error loading provider class for {provider_name}: {e}")
|
|
101
|
+
raise ValueError(
|
|
102
|
+
f"Failed to load provider class for {provider_name}: {e}"
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
@classmethod
|
|
106
|
+
def _get_module_path(cls, provider_name: str) -> str:
|
|
107
|
+
"""
|
|
108
|
+
Map provider name to module path.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
provider_name: Name of the provider
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
Module path
|
|
115
|
+
"""
|
|
116
|
+
# Special case for claude-code provider
|
|
117
|
+
if provider_name == "claude-code":
|
|
118
|
+
return "omnimancer.providers.claude_code"
|
|
119
|
+
|
|
120
|
+
# Standard mapping
|
|
121
|
+
return f"omnimancer.providers.{provider_name}"
|
|
122
|
+
|
|
123
|
+
@classmethod
|
|
124
|
+
def get_provider_instance(
|
|
125
|
+
cls,
|
|
126
|
+
provider_name: str,
|
|
127
|
+
config: ProviderConfig,
|
|
128
|
+
config_manager: "ConfigManager" = None,
|
|
129
|
+
) -> BaseProvider:
|
|
130
|
+
"""
|
|
131
|
+
Get or create cached provider instance.
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
provider_name: Name of the provider
|
|
135
|
+
config: Provider configuration
|
|
136
|
+
config_manager: Optional config manager for API key decryption
|
|
137
|
+
|
|
138
|
+
Returns:
|
|
139
|
+
Provider instance
|
|
140
|
+
"""
|
|
141
|
+
if not cls._cache_enabled:
|
|
142
|
+
# If caching is disabled, create new instance every time
|
|
143
|
+
return cls._create_provider_instance(provider_name, config, config_manager)
|
|
144
|
+
|
|
145
|
+
# Generate cache key based on provider name and config
|
|
146
|
+
cache_key = cls._generate_cache_key(provider_name, config)
|
|
147
|
+
|
|
148
|
+
with cls._instance_lock:
|
|
149
|
+
# Check if instance is already cached and valid
|
|
150
|
+
if cache_key in cls._provider_instances and cls._is_cache_valid(cache_key):
|
|
151
|
+
logger.debug(f"Using cached provider instance for {provider_name}")
|
|
152
|
+
return cls._provider_instances[cache_key]
|
|
153
|
+
|
|
154
|
+
# Create new instance
|
|
155
|
+
instance = cls._create_provider_instance(
|
|
156
|
+
provider_name, config, config_manager
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
# Cache instance
|
|
160
|
+
cls._provider_instances[cache_key] = instance
|
|
161
|
+
cls._cache_timestamps[cache_key] = time.time()
|
|
162
|
+
|
|
163
|
+
return instance
|
|
164
|
+
|
|
165
|
+
@classmethod
|
|
166
|
+
def _create_provider_instance(
|
|
167
|
+
cls,
|
|
168
|
+
provider_name: str,
|
|
169
|
+
config: ProviderConfig,
|
|
170
|
+
config_manager: "ConfigManager" = None,
|
|
171
|
+
) -> BaseProvider:
|
|
172
|
+
"""
|
|
173
|
+
Create a new provider instance.
|
|
174
|
+
|
|
175
|
+
Args:
|
|
176
|
+
provider_name: Name of the provider
|
|
177
|
+
config: Provider configuration
|
|
178
|
+
config_manager: Optional config manager for API key decryption
|
|
179
|
+
|
|
180
|
+
Returns:
|
|
181
|
+
Provider instance
|
|
182
|
+
"""
|
|
183
|
+
# Get provider class
|
|
184
|
+
provider_class = cls.get_provider_class(provider_name)
|
|
185
|
+
|
|
186
|
+
# Get decrypted API key
|
|
187
|
+
api_key = config.api_key
|
|
188
|
+
if config_manager and api_key:
|
|
189
|
+
try:
|
|
190
|
+
# Use config manager to get properly decrypted API key
|
|
191
|
+
decrypted_key = config_manager.get_api_key(provider_name)
|
|
192
|
+
if decrypted_key:
|
|
193
|
+
api_key = decrypted_key
|
|
194
|
+
except Exception as e:
|
|
195
|
+
logger.warning(f"Failed to decrypt API key for {provider_name}: {e}")
|
|
196
|
+
# Fall back to using the key as-is
|
|
197
|
+
pass
|
|
198
|
+
|
|
199
|
+
# If still no valid API key, try environment variables
|
|
200
|
+
if not api_key or api_key.startswith("your-") or api_key.startswith("sk-your"):
|
|
201
|
+
from .env_loader import load_api_key_from_env
|
|
202
|
+
|
|
203
|
+
env_key = load_api_key_from_env(provider_name)
|
|
204
|
+
if env_key:
|
|
205
|
+
api_key = env_key
|
|
206
|
+
logger.info(f"Using API key from environment for {provider_name}")
|
|
207
|
+
|
|
208
|
+
# Create instance
|
|
209
|
+
# Filter out None values to allow provider defaults to work
|
|
210
|
+
kwargs = {
|
|
211
|
+
k: v
|
|
212
|
+
for k, v in config.model_dump(exclude={"api_key", "model"}).items()
|
|
213
|
+
if v is not None
|
|
214
|
+
}
|
|
215
|
+
instance = provider_class(api_key=api_key, model=config.model, **kwargs)
|
|
216
|
+
|
|
217
|
+
return instance
|
|
218
|
+
|
|
219
|
+
@classmethod
|
|
220
|
+
def _generate_cache_key(cls, provider_name: str, config: ProviderConfig) -> str:
|
|
221
|
+
"""
|
|
222
|
+
Generate cache key for provider instance.
|
|
223
|
+
|
|
224
|
+
Args:
|
|
225
|
+
provider_name: Name of the provider
|
|
226
|
+
config: Provider configuration
|
|
227
|
+
|
|
228
|
+
Returns:
|
|
229
|
+
Cache key
|
|
230
|
+
"""
|
|
231
|
+
# Include key configuration parameters in cache key
|
|
232
|
+
key_params = {
|
|
233
|
+
"model": config.model,
|
|
234
|
+
"base_url": getattr(config, "base_url", None),
|
|
235
|
+
"organization": getattr(config, "organization", None),
|
|
236
|
+
"project_id": getattr(config, "project_id", None),
|
|
237
|
+
"azure_endpoint": getattr(config, "azure_endpoint", None),
|
|
238
|
+
"azure_deployment": getattr(config, "azure_deployment", None),
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
# Filter out None values
|
|
242
|
+
key_params = {k: v for k, v in key_params.items() if v is not None}
|
|
243
|
+
|
|
244
|
+
# Generate key
|
|
245
|
+
key_str = f"{provider_name}:{config.model}:{hash(str(key_params))}"
|
|
246
|
+
return key_str
|
|
247
|
+
|
|
248
|
+
@classmethod
|
|
249
|
+
def _is_cache_valid(cls, cache_key: str) -> bool:
|
|
250
|
+
"""
|
|
251
|
+
Check if cached data is still valid.
|
|
252
|
+
|
|
253
|
+
Args:
|
|
254
|
+
cache_key: Cache key
|
|
255
|
+
|
|
256
|
+
Returns:
|
|
257
|
+
True if cache is valid
|
|
258
|
+
"""
|
|
259
|
+
if cache_key not in cls._cache_timestamps:
|
|
260
|
+
return False
|
|
261
|
+
|
|
262
|
+
return (time.time() - cls._cache_timestamps[cache_key]) < cls._cache_ttl
|
|
263
|
+
|
|
264
|
+
@classmethod
|
|
265
|
+
def get_model_info(
|
|
266
|
+
cls, provider_name: str, enhanced: bool = True
|
|
267
|
+
) -> List[EnhancedModelInfo]:
|
|
268
|
+
"""
|
|
269
|
+
Get cached model information for a provider.
|
|
270
|
+
|
|
271
|
+
Args:
|
|
272
|
+
provider_name: Name of the provider
|
|
273
|
+
enhanced: Whether to return enhanced model info
|
|
274
|
+
|
|
275
|
+
Returns:
|
|
276
|
+
List of model info objects
|
|
277
|
+
"""
|
|
278
|
+
if not cls._cache_enabled:
|
|
279
|
+
# If caching is disabled, fetch models every time
|
|
280
|
+
return cls._fetch_model_info(provider_name, enhanced)
|
|
281
|
+
|
|
282
|
+
with cls._model_lock:
|
|
283
|
+
cache_key = f"{provider_name}:{'enhanced' if enhanced else 'basic'}"
|
|
284
|
+
|
|
285
|
+
# Check if models are already cached and valid
|
|
286
|
+
if cache_key in cls._model_cache and cls._is_cache_valid(cache_key):
|
|
287
|
+
logger.debug(f"Using cached model info for {provider_name}")
|
|
288
|
+
return cls._model_cache[cache_key]
|
|
289
|
+
|
|
290
|
+
# Fetch models
|
|
291
|
+
models = cls._fetch_model_info(provider_name, enhanced)
|
|
292
|
+
|
|
293
|
+
# Cache models
|
|
294
|
+
cls._model_cache[cache_key] = models
|
|
295
|
+
cls._cache_timestamps[cache_key] = time.time()
|
|
296
|
+
|
|
297
|
+
return models
|
|
298
|
+
|
|
299
|
+
@classmethod
|
|
300
|
+
def _fetch_model_info(
|
|
301
|
+
cls, provider_name: str, enhanced: bool
|
|
302
|
+
) -> List[EnhancedModelInfo]:
|
|
303
|
+
"""
|
|
304
|
+
Fetch model information from provider.
|
|
305
|
+
|
|
306
|
+
Args:
|
|
307
|
+
provider_name: Name of the provider
|
|
308
|
+
enhanced: Whether to return enhanced model info
|
|
309
|
+
|
|
310
|
+
Returns:
|
|
311
|
+
List of model info objects
|
|
312
|
+
"""
|
|
313
|
+
try:
|
|
314
|
+
# Get provider class
|
|
315
|
+
provider_class = cls.get_provider_class(provider_name)
|
|
316
|
+
|
|
317
|
+
# Create temporary instance with dummy credentials
|
|
318
|
+
temp_provider = provider_class(api_key="dummy", model="dummy")
|
|
319
|
+
|
|
320
|
+
# Get models
|
|
321
|
+
models = temp_provider.get_available_models()
|
|
322
|
+
|
|
323
|
+
# Convert to EnhancedModelInfo if needed
|
|
324
|
+
from .models import ModelInfo
|
|
325
|
+
|
|
326
|
+
if enhanced and models and isinstance(models[0], ModelInfo):
|
|
327
|
+
models = [EnhancedModelInfo.from_model_info(model) for model in models]
|
|
328
|
+
|
|
329
|
+
return models
|
|
330
|
+
|
|
331
|
+
except Exception as e:
|
|
332
|
+
logger.error(f"Error fetching model info for {provider_name}: {e}")
|
|
333
|
+
return []
|
|
334
|
+
|
|
335
|
+
@classmethod
|
|
336
|
+
def clear_caches(cls) -> None:
|
|
337
|
+
"""Clear all caches."""
|
|
338
|
+
with cls._class_lock:
|
|
339
|
+
cls._provider_classes.clear()
|
|
340
|
+
|
|
341
|
+
with cls._instance_lock:
|
|
342
|
+
cls._provider_instances.clear()
|
|
343
|
+
|
|
344
|
+
with cls._model_lock:
|
|
345
|
+
cls._model_cache.clear()
|
|
346
|
+
|
|
347
|
+
cls._cache_timestamps.clear()
|
|
348
|
+
logger.info("Cleared all provider caches")
|
|
349
|
+
|
|
350
|
+
@classmethod
|
|
351
|
+
def set_cache_ttl(cls, ttl_seconds: float) -> None:
|
|
352
|
+
"""
|
|
353
|
+
Set cache TTL (time to live).
|
|
354
|
+
|
|
355
|
+
Args:
|
|
356
|
+
ttl_seconds: TTL in seconds
|
|
357
|
+
"""
|
|
358
|
+
cls._cache_ttl = ttl_seconds
|
|
359
|
+
logger.info(f"Set provider cache TTL to {ttl_seconds} seconds")
|
|
360
|
+
|
|
361
|
+
@classmethod
|
|
362
|
+
def enable_lazy_loading(cls, enabled: bool = True) -> None:
|
|
363
|
+
"""
|
|
364
|
+
Enable or disable lazy loading.
|
|
365
|
+
|
|
366
|
+
Args:
|
|
367
|
+
enabled: Whether to enable lazy loading
|
|
368
|
+
"""
|
|
369
|
+
cls._lazy_loading_enabled = enabled
|
|
370
|
+
logger.info(f"{'Enabled' if enabled else 'Disabled'} provider lazy loading")
|
|
371
|
+
|
|
372
|
+
@classmethod
|
|
373
|
+
def enable_caching(cls, enabled: bool = True) -> None:
|
|
374
|
+
"""
|
|
375
|
+
Enable or disable caching.
|
|
376
|
+
|
|
377
|
+
Args:
|
|
378
|
+
enabled: Whether to enable caching
|
|
379
|
+
"""
|
|
380
|
+
cls._cache_enabled = enabled
|
|
381
|
+
if not enabled:
|
|
382
|
+
cls.clear_caches()
|
|
383
|
+
logger.info(f"{'Enabled' if enabled else 'Disabled'} provider caching")
|
|
384
|
+
|
|
385
|
+
@classmethod
|
|
386
|
+
def preload_provider_classes(cls, provider_names: List[str]) -> None:
|
|
387
|
+
"""
|
|
388
|
+
Preload provider classes.
|
|
389
|
+
|
|
390
|
+
Args:
|
|
391
|
+
provider_names: List of provider names to preload
|
|
392
|
+
"""
|
|
393
|
+
for provider_name in provider_names:
|
|
394
|
+
try:
|
|
395
|
+
cls.get_provider_class(provider_name)
|
|
396
|
+
logger.debug(f"Preloaded provider class for {provider_name}")
|
|
397
|
+
except Exception as e:
|
|
398
|
+
logger.warning(
|
|
399
|
+
f"Failed to preload provider class for {provider_name}: {e}"
|
|
400
|
+
)
|
|
401
|
+
|
|
402
|
+
@classmethod
|
|
403
|
+
async def initialize_providers(
|
|
404
|
+
cls,
|
|
405
|
+
provider_configs: Dict[str, ProviderConfig],
|
|
406
|
+
config_manager: "ConfigManager" = None,
|
|
407
|
+
) -> Dict[str, BaseProvider]:
|
|
408
|
+
"""
|
|
409
|
+
Initialize all providers from configuration.
|
|
410
|
+
|
|
411
|
+
Args:
|
|
412
|
+
provider_configs: Dictionary of provider configurations
|
|
413
|
+
config_manager: Optional config manager for API key decryption
|
|
414
|
+
|
|
415
|
+
Returns:
|
|
416
|
+
Dictionary of initialized provider instances
|
|
417
|
+
"""
|
|
418
|
+
from ..providers.factory import ProviderFactory
|
|
419
|
+
|
|
420
|
+
providers = {}
|
|
421
|
+
|
|
422
|
+
for provider_name, config in provider_configs.items():
|
|
423
|
+
try:
|
|
424
|
+
# Use ProviderFactory instead of direct class loading
|
|
425
|
+
provider = ProviderFactory.create_provider(
|
|
426
|
+
provider_name, config, config_manager
|
|
427
|
+
)
|
|
428
|
+
providers[provider_name] = provider
|
|
429
|
+
logger.info(f"Initialized provider: {provider_name}")
|
|
430
|
+
except Exception as e:
|
|
431
|
+
logger.error(f"Failed to initialize provider {provider_name}: {e}")
|
|
432
|
+
# Continue with other providers instead of failing completely
|
|
433
|
+
continue
|
|
434
|
+
|
|
435
|
+
return providers
|
|
436
|
+
|
|
437
|
+
@classmethod
|
|
438
|
+
def preload_model_info(cls, provider_names: List[str]) -> None:
|
|
439
|
+
"""
|
|
440
|
+
Preload model information.
|
|
441
|
+
|
|
442
|
+
Args:
|
|
443
|
+
provider_names: List of provider names to preload
|
|
444
|
+
"""
|
|
445
|
+
for provider_name in provider_names:
|
|
446
|
+
try:
|
|
447
|
+
cls.get_model_info(provider_name)
|
|
448
|
+
logger.debug(f"Preloaded model info for {provider_name}")
|
|
449
|
+
except Exception as e:
|
|
450
|
+
logger.warning(f"Failed to preload model info for {provider_name}: {e}")
|