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,432 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Provider registry for comprehensive model catalog management.
|
|
3
|
+
|
|
4
|
+
This module provides a centralized registry for managing AI providers
|
|
5
|
+
and their model catalogs with enhanced information.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
from datetime import datetime
|
|
10
|
+
from typing import Any, Dict, List, Optional, Type
|
|
11
|
+
|
|
12
|
+
from ..providers.base import BaseProvider
|
|
13
|
+
from ..utils.errors import ConfigurationError
|
|
14
|
+
from .models import EnhancedModelInfo
|
|
15
|
+
|
|
16
|
+
logger = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ProviderRegistry:
|
|
20
|
+
"""Enhanced provider registry with comprehensive model catalog."""
|
|
21
|
+
|
|
22
|
+
def __init__(self):
|
|
23
|
+
"""Initialize the provider registry."""
|
|
24
|
+
self.providers: Dict[str, Type[BaseProvider]] = {}
|
|
25
|
+
self.model_catalog: Dict[str, List[EnhancedModelInfo]] = {}
|
|
26
|
+
self.last_update: Optional[datetime] = None
|
|
27
|
+
self._provider_instances: Dict[str, BaseProvider] = {}
|
|
28
|
+
|
|
29
|
+
def register_provider(self, name: str, provider_class: Type[BaseProvider]) -> None:
|
|
30
|
+
"""
|
|
31
|
+
Register a provider with the registry.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
name: Provider name (e.g., "claude", "openai")
|
|
35
|
+
provider_class: Provider class to register
|
|
36
|
+
"""
|
|
37
|
+
logger.info(f"Registering provider: {name}")
|
|
38
|
+
self.providers[name] = provider_class
|
|
39
|
+
|
|
40
|
+
# Initialize empty model catalog for this provider
|
|
41
|
+
if name not in self.model_catalog:
|
|
42
|
+
self.model_catalog[name] = []
|
|
43
|
+
|
|
44
|
+
def unregister_provider(self, name: str) -> bool:
|
|
45
|
+
"""
|
|
46
|
+
Unregister a provider from the registry.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
name: Provider name to unregister
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
True if provider was unregistered, False if not found
|
|
53
|
+
"""
|
|
54
|
+
if name in self.providers:
|
|
55
|
+
logger.info(f"Unregistering provider: {name}")
|
|
56
|
+
del self.providers[name]
|
|
57
|
+
|
|
58
|
+
# Clean up model catalog and instances
|
|
59
|
+
if name in self.model_catalog:
|
|
60
|
+
del self.model_catalog[name]
|
|
61
|
+
if name in self._provider_instances:
|
|
62
|
+
del self._provider_instances[name]
|
|
63
|
+
|
|
64
|
+
return True
|
|
65
|
+
return False
|
|
66
|
+
|
|
67
|
+
def get_registered_providers(self) -> List[str]:
|
|
68
|
+
"""
|
|
69
|
+
Get list of registered provider names.
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
List of provider names
|
|
73
|
+
"""
|
|
74
|
+
return list(self.providers.keys())
|
|
75
|
+
|
|
76
|
+
def is_provider_registered(self, name: str) -> bool:
|
|
77
|
+
"""
|
|
78
|
+
Check if a provider is registered.
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
name: Provider name
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
True if provider is registered
|
|
85
|
+
"""
|
|
86
|
+
return name in self.providers
|
|
87
|
+
|
|
88
|
+
def get_provider_class(self, name: str) -> Type[BaseProvider]:
|
|
89
|
+
"""
|
|
90
|
+
Get provider class by name.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
name: Provider name
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
Provider class
|
|
97
|
+
|
|
98
|
+
Raises:
|
|
99
|
+
ConfigurationError: If provider is not registered
|
|
100
|
+
"""
|
|
101
|
+
if name not in self.providers:
|
|
102
|
+
raise ConfigurationError(f"Provider '{name}' is not registered")
|
|
103
|
+
return self.providers[name]
|
|
104
|
+
|
|
105
|
+
def get_all_models_with_details(
|
|
106
|
+
self,
|
|
107
|
+
) -> Dict[str, List[EnhancedModelInfo]]:
|
|
108
|
+
"""
|
|
109
|
+
Get comprehensive model catalog with all details.
|
|
110
|
+
|
|
111
|
+
Returns:
|
|
112
|
+
Dictionary mapping provider names to their enhanced model lists
|
|
113
|
+
"""
|
|
114
|
+
return self.model_catalog.copy()
|
|
115
|
+
|
|
116
|
+
def get_models_for_provider(self, provider_name: str) -> List[EnhancedModelInfo]:
|
|
117
|
+
"""
|
|
118
|
+
Get models for a specific provider.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
provider_name: Name of the provider
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
List of enhanced model info for the provider
|
|
125
|
+
"""
|
|
126
|
+
return self.model_catalog.get(provider_name, [])
|
|
127
|
+
|
|
128
|
+
def update_provider_models(
|
|
129
|
+
self, provider_name: str, models: List[EnhancedModelInfo]
|
|
130
|
+
) -> None:
|
|
131
|
+
"""
|
|
132
|
+
Update model catalog for a specific provider.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
provider_name: Name of the provider
|
|
136
|
+
models: List of enhanced model info
|
|
137
|
+
"""
|
|
138
|
+
logger.info(
|
|
139
|
+
f"Updating model catalog for provider: {provider_name} ({len(models)} models)"
|
|
140
|
+
)
|
|
141
|
+
self.model_catalog[provider_name] = models
|
|
142
|
+
self.last_update = datetime.now()
|
|
143
|
+
|
|
144
|
+
def get_models_by_capability(
|
|
145
|
+
self, capability: str
|
|
146
|
+
) -> Dict[str, List[EnhancedModelInfo]]:
|
|
147
|
+
"""
|
|
148
|
+
Get models filtered by capability (tools, multimodal, etc.).
|
|
149
|
+
|
|
150
|
+
Args:
|
|
151
|
+
capability: Capability to filter by ('tools', 'multimodal', 'latest', 'free')
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
Dictionary mapping provider names to filtered models
|
|
155
|
+
"""
|
|
156
|
+
filtered_models = {}
|
|
157
|
+
|
|
158
|
+
for provider_name, models in self.model_catalog.items():
|
|
159
|
+
if capability == "tools":
|
|
160
|
+
filtered = [m for m in models if m.supports_tools]
|
|
161
|
+
elif capability == "multimodal":
|
|
162
|
+
filtered = [m for m in models if m.supports_multimodal]
|
|
163
|
+
elif capability == "latest":
|
|
164
|
+
filtered = [m for m in models if m.latest_version]
|
|
165
|
+
elif capability == "free":
|
|
166
|
+
filtered = [m for m in models if m.is_free]
|
|
167
|
+
elif capability == "available":
|
|
168
|
+
filtered = [m for m in models if m.available and not m.deprecated]
|
|
169
|
+
else:
|
|
170
|
+
filtered = models
|
|
171
|
+
|
|
172
|
+
if filtered:
|
|
173
|
+
filtered_models[provider_name] = filtered
|
|
174
|
+
|
|
175
|
+
return filtered_models
|
|
176
|
+
|
|
177
|
+
def get_models_by_pricing(
|
|
178
|
+
self, max_cost_per_million: float
|
|
179
|
+
) -> Dict[str, List[EnhancedModelInfo]]:
|
|
180
|
+
"""
|
|
181
|
+
Get models filtered by maximum cost per million tokens.
|
|
182
|
+
|
|
183
|
+
Args:
|
|
184
|
+
max_cost_per_million: Maximum average cost per million tokens
|
|
185
|
+
|
|
186
|
+
Returns:
|
|
187
|
+
Dictionary mapping provider names to models within budget
|
|
188
|
+
"""
|
|
189
|
+
filtered_models = {}
|
|
190
|
+
|
|
191
|
+
for provider_name, models in self.model_catalog.items():
|
|
192
|
+
budget_models = []
|
|
193
|
+
for model in models:
|
|
194
|
+
if model.is_free:
|
|
195
|
+
budget_models.append(model)
|
|
196
|
+
else:
|
|
197
|
+
avg_cost = (
|
|
198
|
+
model.cost_per_million_input + model.cost_per_million_output
|
|
199
|
+
) / 2
|
|
200
|
+
if avg_cost <= max_cost_per_million:
|
|
201
|
+
budget_models.append(model)
|
|
202
|
+
|
|
203
|
+
if budget_models:
|
|
204
|
+
filtered_models[provider_name] = budget_models
|
|
205
|
+
|
|
206
|
+
return filtered_models
|
|
207
|
+
|
|
208
|
+
def get_models_by_performance(
|
|
209
|
+
self, min_swe_score: float
|
|
210
|
+
) -> Dict[str, List[EnhancedModelInfo]]:
|
|
211
|
+
"""
|
|
212
|
+
Get models filtered by minimum SWE score.
|
|
213
|
+
|
|
214
|
+
Args:
|
|
215
|
+
min_swe_score: Minimum SWE score (0-100)
|
|
216
|
+
|
|
217
|
+
Returns:
|
|
218
|
+
Dictionary mapping provider names to high-performance models
|
|
219
|
+
"""
|
|
220
|
+
filtered_models = {}
|
|
221
|
+
|
|
222
|
+
for provider_name, models in self.model_catalog.items():
|
|
223
|
+
high_perf_models = [
|
|
224
|
+
m
|
|
225
|
+
for m in models
|
|
226
|
+
if m.swe_score is not None and m.swe_score >= min_swe_score
|
|
227
|
+
]
|
|
228
|
+
|
|
229
|
+
if high_perf_models:
|
|
230
|
+
filtered_models[provider_name] = high_perf_models
|
|
231
|
+
|
|
232
|
+
return filtered_models
|
|
233
|
+
|
|
234
|
+
def search_models(self, query: str) -> Dict[str, List[EnhancedModelInfo]]:
|
|
235
|
+
"""
|
|
236
|
+
Search models by name or description.
|
|
237
|
+
|
|
238
|
+
Args:
|
|
239
|
+
query: Search query string
|
|
240
|
+
|
|
241
|
+
Returns:
|
|
242
|
+
Dictionary mapping provider names to matching models
|
|
243
|
+
"""
|
|
244
|
+
query_lower = query.lower()
|
|
245
|
+
matching_models = {}
|
|
246
|
+
|
|
247
|
+
for provider_name, models in self.model_catalog.items():
|
|
248
|
+
matches = [
|
|
249
|
+
m
|
|
250
|
+
for m in models
|
|
251
|
+
if query_lower in m.name.lower() or query_lower in m.description.lower()
|
|
252
|
+
]
|
|
253
|
+
|
|
254
|
+
if matches:
|
|
255
|
+
matching_models[provider_name] = matches
|
|
256
|
+
|
|
257
|
+
return matching_models
|
|
258
|
+
|
|
259
|
+
def get_model_by_name(
|
|
260
|
+
self, provider_name: str, model_name: str
|
|
261
|
+
) -> Optional[EnhancedModelInfo]:
|
|
262
|
+
"""
|
|
263
|
+
Get a specific model by provider and name.
|
|
264
|
+
|
|
265
|
+
Args:
|
|
266
|
+
provider_name: Name of the provider
|
|
267
|
+
model_name: Name of the model
|
|
268
|
+
|
|
269
|
+
Returns:
|
|
270
|
+
Enhanced model info if found, None otherwise
|
|
271
|
+
"""
|
|
272
|
+
models = self.model_catalog.get(provider_name, [])
|
|
273
|
+
for model in models:
|
|
274
|
+
if model.name == model_name:
|
|
275
|
+
return model
|
|
276
|
+
return None
|
|
277
|
+
|
|
278
|
+
def get_latest_models(self) -> Dict[str, List[EnhancedModelInfo]]:
|
|
279
|
+
"""
|
|
280
|
+
Get the latest models from all providers.
|
|
281
|
+
|
|
282
|
+
Returns:
|
|
283
|
+
Dictionary mapping provider names to their latest models
|
|
284
|
+
"""
|
|
285
|
+
return self.get_models_by_capability("latest")
|
|
286
|
+
|
|
287
|
+
def get_free_models(self) -> Dict[str, List[EnhancedModelInfo]]:
|
|
288
|
+
"""
|
|
289
|
+
Get all free models from all providers.
|
|
290
|
+
|
|
291
|
+
Returns:
|
|
292
|
+
Dictionary mapping provider names to their free models
|
|
293
|
+
"""
|
|
294
|
+
return self.get_models_by_capability("free")
|
|
295
|
+
|
|
296
|
+
def get_tool_capable_models(self) -> Dict[str, List[EnhancedModelInfo]]:
|
|
297
|
+
"""
|
|
298
|
+
Get all models that support tool calling.
|
|
299
|
+
|
|
300
|
+
Returns:
|
|
301
|
+
Dictionary mapping provider names to their tool-capable models
|
|
302
|
+
"""
|
|
303
|
+
return self.get_models_by_capability("tools")
|
|
304
|
+
|
|
305
|
+
def get_multimodal_models(self) -> Dict[str, List[EnhancedModelInfo]]:
|
|
306
|
+
"""
|
|
307
|
+
Get all models that support multimodal inputs.
|
|
308
|
+
|
|
309
|
+
Returns:
|
|
310
|
+
Dictionary mapping provider names to their multimodal models
|
|
311
|
+
"""
|
|
312
|
+
return self.get_models_by_capability("multimodal")
|
|
313
|
+
|
|
314
|
+
def get_catalog_stats(self) -> Dict[str, Any]:
|
|
315
|
+
"""
|
|
316
|
+
Get statistics about the model catalog.
|
|
317
|
+
|
|
318
|
+
Returns:
|
|
319
|
+
Dictionary with catalog statistics
|
|
320
|
+
"""
|
|
321
|
+
total_models = sum(len(models) for models in self.model_catalog.values())
|
|
322
|
+
total_providers = len(self.providers)
|
|
323
|
+
|
|
324
|
+
# Count models by capability
|
|
325
|
+
tool_models = sum(
|
|
326
|
+
len(models) for models in self.get_tool_capable_models().values()
|
|
327
|
+
)
|
|
328
|
+
multimodal_models = sum(
|
|
329
|
+
len(models) for models in self.get_multimodal_models().values()
|
|
330
|
+
)
|
|
331
|
+
free_models = sum(len(models) for models in self.get_free_models().values())
|
|
332
|
+
latest_models = sum(len(models) for models in self.get_latest_models().values())
|
|
333
|
+
|
|
334
|
+
# Count models by performance tier
|
|
335
|
+
high_perf = sum(
|
|
336
|
+
len(models) for models in self.get_models_by_performance(60.0).values()
|
|
337
|
+
)
|
|
338
|
+
mid_perf = (
|
|
339
|
+
sum(len(models) for models in self.get_models_by_performance(40.0).values())
|
|
340
|
+
- high_perf
|
|
341
|
+
)
|
|
342
|
+
|
|
343
|
+
return {
|
|
344
|
+
"total_providers": total_providers,
|
|
345
|
+
"total_models": total_models,
|
|
346
|
+
"tool_capable_models": tool_models,
|
|
347
|
+
"multimodal_models": multimodal_models,
|
|
348
|
+
"free_models": free_models,
|
|
349
|
+
"latest_models": latest_models,
|
|
350
|
+
"high_performance_models": high_perf,
|
|
351
|
+
"mid_performance_models": mid_perf,
|
|
352
|
+
"last_update": self.last_update,
|
|
353
|
+
"providers": list(self.providers.keys()),
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
def validate_catalog(self) -> List[str]:
|
|
357
|
+
"""
|
|
358
|
+
Validate the model catalog and return any issues found.
|
|
359
|
+
|
|
360
|
+
Returns:
|
|
361
|
+
List of validation error messages
|
|
362
|
+
"""
|
|
363
|
+
errors = []
|
|
364
|
+
|
|
365
|
+
for provider_name, models in self.model_catalog.items():
|
|
366
|
+
if provider_name not in self.providers:
|
|
367
|
+
errors.append(
|
|
368
|
+
f"Models exist for unregistered provider: {provider_name}"
|
|
369
|
+
)
|
|
370
|
+
continue
|
|
371
|
+
|
|
372
|
+
for model in models:
|
|
373
|
+
# Validate model data
|
|
374
|
+
if not model.validate_pricing():
|
|
375
|
+
errors.append(f"Invalid pricing for {provider_name}:{model.name}")
|
|
376
|
+
|
|
377
|
+
if not model.validate_swe_score():
|
|
378
|
+
errors.append(f"Invalid SWE score for {provider_name}:{model.name}")
|
|
379
|
+
|
|
380
|
+
# Check for duplicate models
|
|
381
|
+
duplicates = [m for m in models if m.name == model.name]
|
|
382
|
+
if len(duplicates) > 1:
|
|
383
|
+
errors.append(
|
|
384
|
+
f"Duplicate model {model.name} in provider {provider_name}"
|
|
385
|
+
)
|
|
386
|
+
|
|
387
|
+
return errors
|
|
388
|
+
|
|
389
|
+
def clear_catalog(self) -> None:
|
|
390
|
+
"""Clear all model catalog data."""
|
|
391
|
+
logger.info("Clearing model catalog")
|
|
392
|
+
self.model_catalog.clear()
|
|
393
|
+
self.last_update = None
|
|
394
|
+
|
|
395
|
+
def get_provider_summary(self, provider_name: str) -> Dict[str, Any]:
|
|
396
|
+
"""
|
|
397
|
+
Get summary information for a specific provider.
|
|
398
|
+
|
|
399
|
+
Args:
|
|
400
|
+
provider_name: Name of the provider
|
|
401
|
+
|
|
402
|
+
Returns:
|
|
403
|
+
Dictionary with provider summary
|
|
404
|
+
"""
|
|
405
|
+
if provider_name not in self.providers:
|
|
406
|
+
return {"error": f"Provider {provider_name} not registered"}
|
|
407
|
+
|
|
408
|
+
models = self.model_catalog.get(provider_name, [])
|
|
409
|
+
|
|
410
|
+
return {
|
|
411
|
+
"name": provider_name,
|
|
412
|
+
"registered": True,
|
|
413
|
+
"total_models": len(models),
|
|
414
|
+
"available_models": len(
|
|
415
|
+
[m for m in models if m.available and not m.deprecated]
|
|
416
|
+
),
|
|
417
|
+
"tool_capable_models": len([m for m in models if m.supports_tools]),
|
|
418
|
+
"multimodal_models": len([m for m in models if m.supports_multimodal]),
|
|
419
|
+
"free_models": len([m for m in models if m.is_free]),
|
|
420
|
+
"latest_models": len([m for m in models if m.latest_version]),
|
|
421
|
+
"deprecated_models": len([m for m in models if m.deprecated]),
|
|
422
|
+
"models": [m.name for m in models if m.available and not m.deprecated],
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
def __str__(self) -> str:
|
|
426
|
+
"""String representation of the registry."""
|
|
427
|
+
stats = self.get_catalog_stats()
|
|
428
|
+
return f"ProviderRegistry({stats['total_providers']} providers, {stats['total_models']} models)"
|
|
429
|
+
|
|
430
|
+
def __repr__(self) -> str:
|
|
431
|
+
"""Detailed string representation of the registry."""
|
|
432
|
+
return f"ProviderRegistry(providers={list(self.providers.keys())}, last_update={self.last_update})"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Security framework for Omnimancer agents."""
|
|
2
|
+
|
|
3
|
+
from .approval_workflow import ApprovalWorkflow
|
|
4
|
+
from .audit_logger import AuditLogger
|
|
5
|
+
from .permission_controller import PermissionController, PermissionOperation
|
|
6
|
+
from .sandbox_manager import SandboxManager
|
|
7
|
+
from .security_manager import SecurityManager
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"SecurityManager",
|
|
11
|
+
"PermissionController",
|
|
12
|
+
"PermissionOperation",
|
|
13
|
+
"SandboxManager",
|
|
14
|
+
"ApprovalWorkflow",
|
|
15
|
+
"AuditLogger",
|
|
16
|
+
]
|