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,667 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Error classes for Omnimancer.
|
|
3
|
+
|
|
4
|
+
This module defines the exception hierarchy used throughout the application
|
|
5
|
+
to provide clear error handling and user feedback.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
# Base errors
|
|
10
|
+
"OmnimancerError",
|
|
11
|
+
"AgentError",
|
|
12
|
+
# Configuration errors
|
|
13
|
+
"ConfigurationError",
|
|
14
|
+
"ProviderConfigurationError",
|
|
15
|
+
"MCPConfigurationError",
|
|
16
|
+
# Provider errors
|
|
17
|
+
"ProviderError",
|
|
18
|
+
"AuthenticationError",
|
|
19
|
+
"RateLimitError",
|
|
20
|
+
"NetworkError",
|
|
21
|
+
"ModelNotFoundError",
|
|
22
|
+
"ProviderUnavailableError",
|
|
23
|
+
"QuotaExceededError",
|
|
24
|
+
"ToolExecutionError",
|
|
25
|
+
# Agent errors
|
|
26
|
+
"SecurityError",
|
|
27
|
+
"PermissionError",
|
|
28
|
+
"ExecutionError",
|
|
29
|
+
"TimeoutError",
|
|
30
|
+
# Application errors
|
|
31
|
+
"ValidationError",
|
|
32
|
+
"ConversationError",
|
|
33
|
+
# MCP errors
|
|
34
|
+
"MCPError",
|
|
35
|
+
"MCPServerError",
|
|
36
|
+
"MCPToolError",
|
|
37
|
+
"MCPConnectionError",
|
|
38
|
+
"MCPTimeoutError",
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class OmnimancerError(Exception):
|
|
43
|
+
"""
|
|
44
|
+
Base exception class for all Omnimancer errors.
|
|
45
|
+
|
|
46
|
+
All custom exceptions in Omnimancer should inherit from this class
|
|
47
|
+
to provide consistent error handling.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
def __init__(self, message: str, details: str = None):
|
|
51
|
+
"""
|
|
52
|
+
Initialize the error.
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
message: Human-readable error message
|
|
56
|
+
details: Additional technical details (optional)
|
|
57
|
+
"""
|
|
58
|
+
super().__init__(message)
|
|
59
|
+
self.message = message
|
|
60
|
+
self.details = details
|
|
61
|
+
|
|
62
|
+
def __str__(self) -> str:
|
|
63
|
+
"""String representation of the error."""
|
|
64
|
+
if self.details:
|
|
65
|
+
return f"{self.message}\nDetails: {self.details}"
|
|
66
|
+
return self.message
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class ConfigurationError(OmnimancerError):
|
|
70
|
+
"""
|
|
71
|
+
Raised when there are configuration-related errors.
|
|
72
|
+
|
|
73
|
+
This includes missing configuration files, invalid settings,
|
|
74
|
+
or problems with configuration file format.
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
pass
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class ProviderError(OmnimancerError):
|
|
81
|
+
"""
|
|
82
|
+
Base class for AI provider-related errors.
|
|
83
|
+
|
|
84
|
+
This is the parent class for all errors that occur when
|
|
85
|
+
communicating with AI provider APIs.
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
def __init__(self, message: str, provider: str = None, details: str = None):
|
|
89
|
+
"""
|
|
90
|
+
Initialize the provider error.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
message: Human-readable error message
|
|
94
|
+
provider: Name of the provider that caused the error
|
|
95
|
+
details: Additional technical details
|
|
96
|
+
"""
|
|
97
|
+
super().__init__(message, details)
|
|
98
|
+
self.provider = provider
|
|
99
|
+
|
|
100
|
+
def __str__(self) -> str:
|
|
101
|
+
"""String representation including provider name."""
|
|
102
|
+
base_msg = super().__str__()
|
|
103
|
+
if self.provider:
|
|
104
|
+
return f"[{self.provider}] {base_msg}"
|
|
105
|
+
return base_msg
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class AuthenticationError(ProviderError):
|
|
109
|
+
"""
|
|
110
|
+
Raised when API authentication fails.
|
|
111
|
+
|
|
112
|
+
This typically indicates invalid API keys, expired tokens,
|
|
113
|
+
or insufficient permissions.
|
|
114
|
+
"""
|
|
115
|
+
|
|
116
|
+
pass
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
class RateLimitError(ProviderError):
|
|
120
|
+
"""
|
|
121
|
+
Raised when API rate limits are exceeded.
|
|
122
|
+
|
|
123
|
+
This indicates that too many requests have been made in a
|
|
124
|
+
given time period and the client should wait before retrying.
|
|
125
|
+
"""
|
|
126
|
+
|
|
127
|
+
def __init__(
|
|
128
|
+
self,
|
|
129
|
+
message: str,
|
|
130
|
+
provider: str = None,
|
|
131
|
+
retry_after: int = None,
|
|
132
|
+
details: str = None,
|
|
133
|
+
):
|
|
134
|
+
"""
|
|
135
|
+
Initialize the rate limit error.
|
|
136
|
+
|
|
137
|
+
Args:
|
|
138
|
+
message: Human-readable error message
|
|
139
|
+
provider: Name of the provider
|
|
140
|
+
retry_after: Seconds to wait before retrying (if known)
|
|
141
|
+
details: Additional technical details
|
|
142
|
+
"""
|
|
143
|
+
super().__init__(message, provider, details)
|
|
144
|
+
self.retry_after = retry_after
|
|
145
|
+
|
|
146
|
+
def __str__(self) -> str:
|
|
147
|
+
"""String representation including retry information."""
|
|
148
|
+
base_msg = super().__str__()
|
|
149
|
+
if self.retry_after:
|
|
150
|
+
return f"{base_msg}\nRetry after: {self.retry_after} seconds"
|
|
151
|
+
return base_msg
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class NetworkError(ProviderError):
|
|
155
|
+
"""
|
|
156
|
+
Raised when network-related errors occur.
|
|
157
|
+
|
|
158
|
+
This includes connection timeouts, DNS resolution failures,
|
|
159
|
+
and other network connectivity issues.
|
|
160
|
+
"""
|
|
161
|
+
|
|
162
|
+
pass
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class ValidationError(OmnimancerError):
|
|
166
|
+
"""
|
|
167
|
+
Raised when input validation fails.
|
|
168
|
+
|
|
169
|
+
This includes invalid command parameters, malformed input,
|
|
170
|
+
or data that doesn't meet expected formats.
|
|
171
|
+
"""
|
|
172
|
+
|
|
173
|
+
pass
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
class ModelNotFoundError(ProviderError):
|
|
177
|
+
"""
|
|
178
|
+
Raised when a requested model is not available.
|
|
179
|
+
|
|
180
|
+
This occurs when trying to switch to a model that doesn't exist
|
|
181
|
+
or is not accessible with the current API key.
|
|
182
|
+
"""
|
|
183
|
+
|
|
184
|
+
def __init__(
|
|
185
|
+
self,
|
|
186
|
+
message: str,
|
|
187
|
+
provider: str = None,
|
|
188
|
+
model_name: str = None,
|
|
189
|
+
available_models: list = None,
|
|
190
|
+
details: str = None,
|
|
191
|
+
):
|
|
192
|
+
"""
|
|
193
|
+
Initialize the model not found error.
|
|
194
|
+
|
|
195
|
+
Args:
|
|
196
|
+
message: Human-readable error message
|
|
197
|
+
provider: Name of the provider
|
|
198
|
+
model_name: Name of the model that wasn't found
|
|
199
|
+
available_models: List of available models (for suggestions)
|
|
200
|
+
details: Additional technical details
|
|
201
|
+
"""
|
|
202
|
+
super().__init__(message, provider, details)
|
|
203
|
+
self.model_name = model_name
|
|
204
|
+
self.available_models = available_models or []
|
|
205
|
+
|
|
206
|
+
def get_suggestions(self) -> list:
|
|
207
|
+
"""
|
|
208
|
+
Get suggested alternative models.
|
|
209
|
+
|
|
210
|
+
Returns:
|
|
211
|
+
List of suggested model names
|
|
212
|
+
"""
|
|
213
|
+
if not self.available_models or not self.model_name:
|
|
214
|
+
return []
|
|
215
|
+
|
|
216
|
+
# Simple fuzzy matching for suggestions
|
|
217
|
+
suggestions = []
|
|
218
|
+
model_lower = self.model_name.lower()
|
|
219
|
+
|
|
220
|
+
for model in self.available_models:
|
|
221
|
+
model_lower_check = model.lower()
|
|
222
|
+
# Check for partial matches or similar names
|
|
223
|
+
if (
|
|
224
|
+
model_lower in model_lower_check
|
|
225
|
+
or model_lower_check in model_lower
|
|
226
|
+
or any(part in model_lower_check for part in model_lower.split("-"))
|
|
227
|
+
):
|
|
228
|
+
suggestions.append(model)
|
|
229
|
+
|
|
230
|
+
return suggestions[:3] # Return top 3 suggestions
|
|
231
|
+
|
|
232
|
+
def __str__(self) -> str:
|
|
233
|
+
"""String representation with suggestions."""
|
|
234
|
+
base_msg = super().__str__()
|
|
235
|
+
suggestions = self.get_suggestions()
|
|
236
|
+
|
|
237
|
+
if suggestions:
|
|
238
|
+
suggestion_text = ", ".join(suggestions)
|
|
239
|
+
return f"{base_msg}\nSuggested alternatives: {suggestion_text}"
|
|
240
|
+
elif self.available_models:
|
|
241
|
+
return (
|
|
242
|
+
f"{base_msg}\nAvailable models: {', '.join(self.available_models[:5])}"
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
return base_msg
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
class ConversationError(OmnimancerError):
|
|
249
|
+
"""
|
|
250
|
+
Raised when conversation management operations fail.
|
|
251
|
+
|
|
252
|
+
This includes errors saving/loading conversations, context
|
|
253
|
+
management issues, or conversation file corruption.
|
|
254
|
+
"""
|
|
255
|
+
|
|
256
|
+
pass
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
class MCPError(OmnimancerError):
|
|
260
|
+
"""
|
|
261
|
+
Base class for MCP (Model Context Protocol) related errors.
|
|
262
|
+
|
|
263
|
+
This is the parent class for all errors that occur when
|
|
264
|
+
working with MCP servers and tools.
|
|
265
|
+
"""
|
|
266
|
+
|
|
267
|
+
pass
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
class MCPServerError(MCPError):
|
|
271
|
+
"""
|
|
272
|
+
Raised when MCP server connection or communication fails.
|
|
273
|
+
|
|
274
|
+
This includes server startup failures, connection timeouts,
|
|
275
|
+
and communication protocol errors.
|
|
276
|
+
"""
|
|
277
|
+
|
|
278
|
+
def __init__(self, message: str, server_name: str = None, details: str = None):
|
|
279
|
+
"""
|
|
280
|
+
Initialize the MCP server error.
|
|
281
|
+
|
|
282
|
+
Args:
|
|
283
|
+
message: Human-readable error message
|
|
284
|
+
server_name: Name of the MCP server that caused the error
|
|
285
|
+
details: Additional technical details
|
|
286
|
+
"""
|
|
287
|
+
super().__init__(message, details)
|
|
288
|
+
self.server_name = server_name
|
|
289
|
+
|
|
290
|
+
def __str__(self) -> str:
|
|
291
|
+
"""String representation including server name."""
|
|
292
|
+
base_msg = super().__str__()
|
|
293
|
+
if self.server_name:
|
|
294
|
+
return f"[MCP Server: {self.server_name}] {base_msg}"
|
|
295
|
+
return f"[MCP Server] {base_msg}"
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
class MCPToolError(MCPError):
|
|
299
|
+
"""
|
|
300
|
+
Raised when MCP tool execution fails.
|
|
301
|
+
|
|
302
|
+
This includes tool not found errors, execution failures,
|
|
303
|
+
and invalid tool parameters.
|
|
304
|
+
"""
|
|
305
|
+
|
|
306
|
+
def __init__(self, message: str, tool_name: str = None, details: str = None):
|
|
307
|
+
"""
|
|
308
|
+
Initialize the MCP tool error.
|
|
309
|
+
|
|
310
|
+
Args:
|
|
311
|
+
message: Human-readable error message
|
|
312
|
+
tool_name: Name of the tool that caused the error
|
|
313
|
+
details: Additional technical details
|
|
314
|
+
"""
|
|
315
|
+
super().__init__(message, details)
|
|
316
|
+
self.tool_name = tool_name
|
|
317
|
+
|
|
318
|
+
def __str__(self) -> str:
|
|
319
|
+
"""String representation including tool name."""
|
|
320
|
+
base_msg = super().__str__()
|
|
321
|
+
if self.tool_name:
|
|
322
|
+
return f"[MCP Tool: {self.tool_name}] {base_msg}"
|
|
323
|
+
return f"[MCP Tool] {base_msg}"
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
class MCPConfigurationError(MCPError):
|
|
327
|
+
"""
|
|
328
|
+
Raised when MCP configuration is invalid.
|
|
329
|
+
|
|
330
|
+
This includes missing server configurations, invalid parameters,
|
|
331
|
+
and configuration file format errors.
|
|
332
|
+
"""
|
|
333
|
+
|
|
334
|
+
pass
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
class ProviderUnavailableError(ProviderError):
|
|
338
|
+
"""
|
|
339
|
+
Raised when a provider is temporarily unavailable.
|
|
340
|
+
|
|
341
|
+
This includes service outages, maintenance windows,
|
|
342
|
+
or temporary connectivity issues.
|
|
343
|
+
"""
|
|
344
|
+
|
|
345
|
+
def __init__(
|
|
346
|
+
self,
|
|
347
|
+
message: str,
|
|
348
|
+
provider: str = None,
|
|
349
|
+
fallback_providers: list = None,
|
|
350
|
+
estimated_recovery: str = None,
|
|
351
|
+
details: str = None,
|
|
352
|
+
):
|
|
353
|
+
"""
|
|
354
|
+
Initialize the provider unavailable error.
|
|
355
|
+
|
|
356
|
+
Args:
|
|
357
|
+
message: Human-readable error message
|
|
358
|
+
provider: Name of the provider
|
|
359
|
+
fallback_providers: List of alternative providers
|
|
360
|
+
estimated_recovery: Estimated recovery time
|
|
361
|
+
details: Additional technical details
|
|
362
|
+
"""
|
|
363
|
+
super().__init__(message, provider, details)
|
|
364
|
+
self.fallback_providers = fallback_providers or []
|
|
365
|
+
self.estimated_recovery = estimated_recovery
|
|
366
|
+
|
|
367
|
+
def __str__(self) -> str:
|
|
368
|
+
"""String representation with fallback suggestions."""
|
|
369
|
+
base_msg = super().__str__()
|
|
370
|
+
|
|
371
|
+
if self.fallback_providers:
|
|
372
|
+
fallback_text = ", ".join(
|
|
373
|
+
str(provider) for provider in self.fallback_providers
|
|
374
|
+
)
|
|
375
|
+
base_msg += f"\nTry switching to: {fallback_text}"
|
|
376
|
+
|
|
377
|
+
if self.estimated_recovery:
|
|
378
|
+
base_msg += f"\nEstimated recovery: {self.estimated_recovery}"
|
|
379
|
+
|
|
380
|
+
return base_msg
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
class ToolExecutionError(ProviderError):
|
|
384
|
+
"""
|
|
385
|
+
Raised when tool execution fails during AI conversation.
|
|
386
|
+
|
|
387
|
+
This includes MCP tool failures, invalid tool parameters,
|
|
388
|
+
or tool execution timeouts.
|
|
389
|
+
"""
|
|
390
|
+
|
|
391
|
+
def __init__(
|
|
392
|
+
self,
|
|
393
|
+
message: str,
|
|
394
|
+
provider: str = None,
|
|
395
|
+
tool_name: str = None,
|
|
396
|
+
tool_args: dict = None,
|
|
397
|
+
details: str = None,
|
|
398
|
+
):
|
|
399
|
+
"""
|
|
400
|
+
Initialize the tool execution error.
|
|
401
|
+
|
|
402
|
+
Args:
|
|
403
|
+
message: Human-readable error message
|
|
404
|
+
provider: Name of the provider
|
|
405
|
+
tool_name: Name of the tool that failed
|
|
406
|
+
tool_args: Arguments passed to the tool
|
|
407
|
+
details: Additional technical details
|
|
408
|
+
"""
|
|
409
|
+
super().__init__(message, provider, details)
|
|
410
|
+
self.tool_name = tool_name
|
|
411
|
+
self.tool_args = tool_args or {}
|
|
412
|
+
|
|
413
|
+
def __str__(self) -> str:
|
|
414
|
+
"""String representation with tool information."""
|
|
415
|
+
base_msg = super().__str__()
|
|
416
|
+
|
|
417
|
+
if self.tool_name:
|
|
418
|
+
base_msg = f"Tool '{self.tool_name}' failed: {base_msg}"
|
|
419
|
+
|
|
420
|
+
return base_msg
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
class QuotaExceededError(ProviderError):
|
|
424
|
+
"""
|
|
425
|
+
Raised when API quota or usage limits are exceeded.
|
|
426
|
+
|
|
427
|
+
This is different from rate limiting and typically indicates
|
|
428
|
+
monthly/daily usage limits have been reached.
|
|
429
|
+
"""
|
|
430
|
+
|
|
431
|
+
def __init__(
|
|
432
|
+
self,
|
|
433
|
+
message: str,
|
|
434
|
+
provider: str = None,
|
|
435
|
+
quota_type: str = None,
|
|
436
|
+
reset_date: str = None,
|
|
437
|
+
details: str = None,
|
|
438
|
+
):
|
|
439
|
+
"""
|
|
440
|
+
Initialize the quota exceeded error.
|
|
441
|
+
|
|
442
|
+
Args:
|
|
443
|
+
message: Human-readable error message
|
|
444
|
+
provider: Name of the provider
|
|
445
|
+
quota_type: Type of quota exceeded (e.g., 'monthly', 'tokens')
|
|
446
|
+
reset_date: When the quota resets
|
|
447
|
+
details: Additional technical details
|
|
448
|
+
"""
|
|
449
|
+
super().__init__(message, provider, details)
|
|
450
|
+
self.quota_type = quota_type
|
|
451
|
+
self.reset_date = reset_date
|
|
452
|
+
|
|
453
|
+
def __str__(self) -> str:
|
|
454
|
+
"""String representation with quota information."""
|
|
455
|
+
base_msg = super().__str__()
|
|
456
|
+
|
|
457
|
+
if self.quota_type:
|
|
458
|
+
base_msg += f"\nQuota type: {self.quota_type}"
|
|
459
|
+
|
|
460
|
+
if self.reset_date:
|
|
461
|
+
base_msg += f"\nQuota resets: {self.reset_date}"
|
|
462
|
+
|
|
463
|
+
return base_msg
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
class ProviderConfigurationError(ProviderError):
|
|
467
|
+
"""
|
|
468
|
+
Raised when provider configuration is invalid or incomplete.
|
|
469
|
+
|
|
470
|
+
This includes missing API keys, invalid endpoints,
|
|
471
|
+
or incompatible configuration options.
|
|
472
|
+
"""
|
|
473
|
+
|
|
474
|
+
def __init__(
|
|
475
|
+
self,
|
|
476
|
+
message: str,
|
|
477
|
+
provider: str = None,
|
|
478
|
+
config_field: str = None,
|
|
479
|
+
suggested_fix: str = None,
|
|
480
|
+
details: str = None,
|
|
481
|
+
):
|
|
482
|
+
"""
|
|
483
|
+
Initialize the provider configuration error.
|
|
484
|
+
|
|
485
|
+
Args:
|
|
486
|
+
message: Human-readable error message
|
|
487
|
+
provider: Name of the provider
|
|
488
|
+
config_field: Configuration field that's invalid
|
|
489
|
+
suggested_fix: Suggested fix for the configuration
|
|
490
|
+
details: Additional technical details
|
|
491
|
+
"""
|
|
492
|
+
super().__init__(message, provider, details)
|
|
493
|
+
self.config_field = config_field
|
|
494
|
+
self.suggested_fix = suggested_fix
|
|
495
|
+
|
|
496
|
+
def __str__(self) -> str:
|
|
497
|
+
"""String representation with configuration help."""
|
|
498
|
+
base_msg = super().__str__()
|
|
499
|
+
|
|
500
|
+
if self.config_field:
|
|
501
|
+
base_msg += f"\nConfiguration field: {self.config_field}"
|
|
502
|
+
|
|
503
|
+
if self.suggested_fix:
|
|
504
|
+
base_msg += f"\nSuggested fix: {self.suggested_fix}"
|
|
505
|
+
|
|
506
|
+
return base_msg
|
|
507
|
+
|
|
508
|
+
|
|
509
|
+
class MCPConnectionError(MCPServerError):
|
|
510
|
+
"""
|
|
511
|
+
Raised when MCP server connection fails.
|
|
512
|
+
|
|
513
|
+
This includes connection timeouts, refused connections,
|
|
514
|
+
and server startup failures.
|
|
515
|
+
"""
|
|
516
|
+
|
|
517
|
+
def __init__(
|
|
518
|
+
self,
|
|
519
|
+
message: str,
|
|
520
|
+
server_name: str = None,
|
|
521
|
+
connection_type: str = None,
|
|
522
|
+
retry_suggestion: str = None,
|
|
523
|
+
details: str = None,
|
|
524
|
+
):
|
|
525
|
+
"""
|
|
526
|
+
Initialize the MCP connection error.
|
|
527
|
+
|
|
528
|
+
Args:
|
|
529
|
+
message: Human-readable error message
|
|
530
|
+
server_name: Name of the MCP server
|
|
531
|
+
connection_type: Type of connection (e.g., 'stdio', 'tcp')
|
|
532
|
+
retry_suggestion: Suggestion for retry
|
|
533
|
+
details: Additional technical details
|
|
534
|
+
"""
|
|
535
|
+
super().__init__(message, server_name, details)
|
|
536
|
+
self.connection_type = connection_type
|
|
537
|
+
self.retry_suggestion = retry_suggestion
|
|
538
|
+
|
|
539
|
+
def __str__(self) -> str:
|
|
540
|
+
"""String representation with connection help."""
|
|
541
|
+
base_msg = super().__str__()
|
|
542
|
+
|
|
543
|
+
if self.connection_type:
|
|
544
|
+
base_msg += f"\nConnection type: {self.connection_type}"
|
|
545
|
+
|
|
546
|
+
if self.retry_suggestion:
|
|
547
|
+
base_msg += f"\nSuggestion: {self.retry_suggestion}"
|
|
548
|
+
|
|
549
|
+
return base_msg
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
class MCPTimeoutError(MCPServerError):
|
|
553
|
+
"""
|
|
554
|
+
Raised when MCP server operations timeout.
|
|
555
|
+
|
|
556
|
+
This includes tool execution timeouts, connection timeouts,
|
|
557
|
+
and response timeouts.
|
|
558
|
+
"""
|
|
559
|
+
|
|
560
|
+
def __init__(
|
|
561
|
+
self,
|
|
562
|
+
message: str,
|
|
563
|
+
server_name: str = None,
|
|
564
|
+
timeout_duration: float = None,
|
|
565
|
+
operation: str = None,
|
|
566
|
+
details: str = None,
|
|
567
|
+
):
|
|
568
|
+
"""
|
|
569
|
+
Initialize the MCP timeout error.
|
|
570
|
+
|
|
571
|
+
Args:
|
|
572
|
+
message: Human-readable error message
|
|
573
|
+
server_name: Name of the MCP server
|
|
574
|
+
timeout_duration: Duration of the timeout in seconds
|
|
575
|
+
operation: Operation that timed out
|
|
576
|
+
details: Additional technical details
|
|
577
|
+
"""
|
|
578
|
+
super().__init__(message, server_name, details)
|
|
579
|
+
self.timeout_duration = timeout_duration
|
|
580
|
+
self.operation = operation
|
|
581
|
+
|
|
582
|
+
def __str__(self) -> str:
|
|
583
|
+
"""String representation with timeout information."""
|
|
584
|
+
base_msg = super().__str__()
|
|
585
|
+
|
|
586
|
+
if self.operation:
|
|
587
|
+
base_msg += f"\nOperation: {self.operation}"
|
|
588
|
+
|
|
589
|
+
if self.timeout_duration:
|
|
590
|
+
base_msg += f"\nTimeout after: {self.timeout_duration}s"
|
|
591
|
+
|
|
592
|
+
return base_msg
|
|
593
|
+
|
|
594
|
+
|
|
595
|
+
class AgentError(OmnimancerError):
|
|
596
|
+
"""
|
|
597
|
+
Base class for agent-related errors.
|
|
598
|
+
|
|
599
|
+
This includes errors that occur during agent operations,
|
|
600
|
+
such as file system operations, command execution, or
|
|
601
|
+
web requests performed by the agent.
|
|
602
|
+
"""
|
|
603
|
+
|
|
604
|
+
pass
|
|
605
|
+
|
|
606
|
+
|
|
607
|
+
class SecurityError(AgentError):
|
|
608
|
+
"""
|
|
609
|
+
Raised when a security violation is detected.
|
|
610
|
+
|
|
611
|
+
This includes attempts to access forbidden paths,
|
|
612
|
+
execute unauthorized commands, or perform unsafe operations.
|
|
613
|
+
"""
|
|
614
|
+
|
|
615
|
+
pass
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
class PermissionError(AgentError):
|
|
619
|
+
"""
|
|
620
|
+
Raised when insufficient permissions are detected.
|
|
621
|
+
|
|
622
|
+
This includes file permission issues, command execution
|
|
623
|
+
restrictions, or other permission-related failures.
|
|
624
|
+
"""
|
|
625
|
+
|
|
626
|
+
pass
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
class ExecutionError(AgentError):
|
|
630
|
+
"""
|
|
631
|
+
Raised when command or program execution fails.
|
|
632
|
+
|
|
633
|
+
This includes process execution failures, command not found errors,
|
|
634
|
+
non-zero exit codes, and other execution-related failures.
|
|
635
|
+
"""
|
|
636
|
+
|
|
637
|
+
def __init__(self, message: str, details: str = None):
|
|
638
|
+
"""
|
|
639
|
+
Initialize the execution error.
|
|
640
|
+
|
|
641
|
+
Args:
|
|
642
|
+
message: Human-readable error message
|
|
643
|
+
details: Additional technical details (optional)
|
|
644
|
+
"""
|
|
645
|
+
super().__init__(message, details)
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+
class TimeoutError(AgentError):
|
|
649
|
+
"""
|
|
650
|
+
Raised when operations exceed their timeout duration.
|
|
651
|
+
|
|
652
|
+
This includes command execution timeouts, network timeouts,
|
|
653
|
+
and other time-based operation failures.
|
|
654
|
+
|
|
655
|
+
Note: This is distinct from Python's built-in TimeoutError
|
|
656
|
+
and follows Omnimancer's error handling patterns.
|
|
657
|
+
"""
|
|
658
|
+
|
|
659
|
+
def __init__(self, message: str, details: str = None):
|
|
660
|
+
"""
|
|
661
|
+
Initialize the timeout error.
|
|
662
|
+
|
|
663
|
+
Args:
|
|
664
|
+
message: Human-readable error message
|
|
665
|
+
details: Additional technical details (optional)
|
|
666
|
+
"""
|
|
667
|
+
super().__init__(message, details)
|