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,238 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Retry logic utilities for Omnimancer.
|
|
3
|
+
|
|
4
|
+
This module provides retry mechanisms with exponential backoff
|
|
5
|
+
for handling transient errors in API calls and other operations.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import asyncio
|
|
9
|
+
import logging
|
|
10
|
+
import random
|
|
11
|
+
from typing import Any, Callable, Optional
|
|
12
|
+
|
|
13
|
+
from .errors import NetworkError, RateLimitError
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class RetryHandler:
|
|
19
|
+
"""
|
|
20
|
+
Handles retry logic with exponential backoff.
|
|
21
|
+
|
|
22
|
+
This class provides configurable retry behavior for operations
|
|
23
|
+
that may fail due to transient errors like network issues or
|
|
24
|
+
rate limiting.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def __init__(
|
|
28
|
+
self,
|
|
29
|
+
max_retries: int = 3,
|
|
30
|
+
base_delay: float = 1.0,
|
|
31
|
+
max_delay: float = 60.0,
|
|
32
|
+
exponential_base: float = 2.0,
|
|
33
|
+
jitter: bool = True,
|
|
34
|
+
):
|
|
35
|
+
"""
|
|
36
|
+
Initialize the retry handler.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
max_retries: Maximum number of retry attempts
|
|
40
|
+
base_delay: Initial delay between retries in seconds
|
|
41
|
+
max_delay: Maximum delay between retries in seconds
|
|
42
|
+
exponential_base: Base for exponential backoff calculation
|
|
43
|
+
jitter: Whether to add random jitter to delays
|
|
44
|
+
"""
|
|
45
|
+
self.max_retries = max_retries
|
|
46
|
+
self.base_delay = base_delay
|
|
47
|
+
self.max_delay = max_delay
|
|
48
|
+
self.exponential_base = exponential_base
|
|
49
|
+
self.jitter = jitter
|
|
50
|
+
|
|
51
|
+
def should_retry(self, error: Exception, attempt: int) -> bool:
|
|
52
|
+
"""
|
|
53
|
+
Determine if an operation should be retried.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
error: The exception that occurred
|
|
57
|
+
attempt: Current attempt number (0-indexed)
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
True if the operation should be retried, False otherwise
|
|
61
|
+
"""
|
|
62
|
+
if attempt >= self.max_retries:
|
|
63
|
+
return False
|
|
64
|
+
|
|
65
|
+
# Always retry network errors
|
|
66
|
+
if isinstance(error, NetworkError):
|
|
67
|
+
return True
|
|
68
|
+
|
|
69
|
+
# Retry rate limit errors
|
|
70
|
+
if isinstance(error, RateLimitError):
|
|
71
|
+
return True
|
|
72
|
+
|
|
73
|
+
# Don't retry other types of errors by default
|
|
74
|
+
return False
|
|
75
|
+
|
|
76
|
+
def calculate_delay(
|
|
77
|
+
self, attempt: int, rate_limit_retry_after: Optional[int] = None
|
|
78
|
+
) -> float:
|
|
79
|
+
"""
|
|
80
|
+
Calculate the delay before the next retry attempt.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
attempt: Current attempt number (0-indexed)
|
|
84
|
+
rate_limit_retry_after: Specific delay for rate limit errors
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
Delay in seconds
|
|
88
|
+
"""
|
|
89
|
+
if rate_limit_retry_after is not None:
|
|
90
|
+
# Use the specific delay provided by the API
|
|
91
|
+
delay = float(rate_limit_retry_after)
|
|
92
|
+
else:
|
|
93
|
+
# Calculate exponential backoff delay
|
|
94
|
+
delay = self.base_delay * (self.exponential_base**attempt)
|
|
95
|
+
|
|
96
|
+
# Cap the delay at max_delay
|
|
97
|
+
delay = min(delay, self.max_delay)
|
|
98
|
+
|
|
99
|
+
# Add jitter to avoid thundering herd
|
|
100
|
+
if self.jitter:
|
|
101
|
+
jitter_amount = delay * 0.1 # 10% jitter
|
|
102
|
+
delay += random.uniform(-jitter_amount, jitter_amount)
|
|
103
|
+
|
|
104
|
+
return max(0, delay)
|
|
105
|
+
|
|
106
|
+
async def execute_with_retry(
|
|
107
|
+
self, func: Callable[..., Any], *args, **kwargs
|
|
108
|
+
) -> Any:
|
|
109
|
+
"""
|
|
110
|
+
Execute a function with retry logic.
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
func: The function to execute
|
|
114
|
+
*args: Positional arguments for the function
|
|
115
|
+
**kwargs: Keyword arguments for the function
|
|
116
|
+
|
|
117
|
+
Returns:
|
|
118
|
+
The result of the function call
|
|
119
|
+
|
|
120
|
+
Raises:
|
|
121
|
+
The last exception if all retries are exhausted
|
|
122
|
+
"""
|
|
123
|
+
last_exception = None
|
|
124
|
+
|
|
125
|
+
for attempt in range(self.max_retries + 1):
|
|
126
|
+
try:
|
|
127
|
+
# Execute the function
|
|
128
|
+
if asyncio.iscoroutinefunction(func):
|
|
129
|
+
result = await func(*args, **kwargs)
|
|
130
|
+
else:
|
|
131
|
+
result = func(*args, **kwargs)
|
|
132
|
+
|
|
133
|
+
# Success - log if this was a retry
|
|
134
|
+
if attempt > 0:
|
|
135
|
+
logger.info(f"Operation succeeded after {attempt} retries")
|
|
136
|
+
|
|
137
|
+
return result
|
|
138
|
+
|
|
139
|
+
except Exception as e:
|
|
140
|
+
last_exception = e
|
|
141
|
+
|
|
142
|
+
# Check if we should retry
|
|
143
|
+
if not self.should_retry(e, attempt):
|
|
144
|
+
logger.debug(f"Not retrying after attempt {attempt}: {e}")
|
|
145
|
+
break
|
|
146
|
+
|
|
147
|
+
# Calculate delay
|
|
148
|
+
retry_after = None
|
|
149
|
+
if isinstance(e, RateLimitError):
|
|
150
|
+
retry_after = e.retry_after
|
|
151
|
+
|
|
152
|
+
delay = self.calculate_delay(attempt, retry_after)
|
|
153
|
+
|
|
154
|
+
logger.warning(
|
|
155
|
+
f"Attempt {attempt + 1} failed: {e}. "
|
|
156
|
+
f"Retrying in {delay:.2f} seconds..."
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
# Wait before retrying
|
|
160
|
+
await asyncio.sleep(delay)
|
|
161
|
+
|
|
162
|
+
# All retries exhausted
|
|
163
|
+
logger.error(
|
|
164
|
+
f"All {self.max_retries} retries exhausted. Last error: {last_exception}"
|
|
165
|
+
)
|
|
166
|
+
raise last_exception
|
|
167
|
+
|
|
168
|
+
def execute_sync_with_retry(self, func: Callable[..., Any], *args, **kwargs) -> Any:
|
|
169
|
+
"""
|
|
170
|
+
Execute a synchronous function with retry logic.
|
|
171
|
+
|
|
172
|
+
Args:
|
|
173
|
+
func: The synchronous function to execute
|
|
174
|
+
*args: Positional arguments for the function
|
|
175
|
+
**kwargs: Keyword arguments for the function
|
|
176
|
+
|
|
177
|
+
Returns:
|
|
178
|
+
The result of the function call
|
|
179
|
+
|
|
180
|
+
Raises:
|
|
181
|
+
The last exception if all retries are exhausted
|
|
182
|
+
"""
|
|
183
|
+
import time
|
|
184
|
+
|
|
185
|
+
last_exception = None
|
|
186
|
+
|
|
187
|
+
for attempt in range(self.max_retries + 1):
|
|
188
|
+
try:
|
|
189
|
+
result = func(*args, **kwargs)
|
|
190
|
+
|
|
191
|
+
# Success - log if this was a retry
|
|
192
|
+
if attempt > 0:
|
|
193
|
+
logger.info(f"Operation succeeded after {attempt} retries")
|
|
194
|
+
|
|
195
|
+
return result
|
|
196
|
+
|
|
197
|
+
except Exception as e:
|
|
198
|
+
last_exception = e
|
|
199
|
+
|
|
200
|
+
# Check if we should retry
|
|
201
|
+
if not self.should_retry(e, attempt):
|
|
202
|
+
logger.debug(f"Not retrying after attempt {attempt}: {e}")
|
|
203
|
+
break
|
|
204
|
+
|
|
205
|
+
# Calculate delay
|
|
206
|
+
retry_after = None
|
|
207
|
+
if isinstance(e, RateLimitError):
|
|
208
|
+
retry_after = e.retry_after
|
|
209
|
+
|
|
210
|
+
delay = self.calculate_delay(attempt, retry_after)
|
|
211
|
+
|
|
212
|
+
logger.warning(
|
|
213
|
+
f"Attempt {attempt + 1} failed: {e}. "
|
|
214
|
+
f"Retrying in {delay:.2f} seconds..."
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
# Wait before retrying
|
|
218
|
+
time.sleep(delay)
|
|
219
|
+
|
|
220
|
+
# All retries exhausted
|
|
221
|
+
logger.error(
|
|
222
|
+
f"All {self.max_retries} retries exhausted. Last error: {last_exception}"
|
|
223
|
+
)
|
|
224
|
+
raise last_exception
|
|
225
|
+
|
|
226
|
+
def retry(self, func: Callable[..., Any], *args, **kwargs) -> Any:
|
|
227
|
+
"""
|
|
228
|
+
Convenience method for synchronous retry execution.
|
|
229
|
+
|
|
230
|
+
Args:
|
|
231
|
+
func: The function to execute with retry
|
|
232
|
+
*args: Positional arguments for the function
|
|
233
|
+
**kwargs: Keyword arguments for the function
|
|
234
|
+
|
|
235
|
+
Returns:
|
|
236
|
+
The result of the function call
|
|
237
|
+
"""
|
|
238
|
+
return self.execute_sync_with_retry(func, *args, **kwargs)
|
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: omnimancer-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A unified command-line interface for multiple AI language models
|
|
5
|
+
Author-email: Kellan Strong <kellan@jite.ai>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://gitlab.com/jite-ai/omnimancer
|
|
8
|
+
Project-URL: Repository, https://gitlab.com/jite-ai/omnimancer
|
|
9
|
+
Project-URL: Issues, https://gitlab.com/jite-ai/omnimancer/issues
|
|
10
|
+
Keywords: ai,cli,chat,openai,claude,language-model
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
+
Classifier: Topic :: Communications :: Chat
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: click>=8.0.0
|
|
25
|
+
Requires-Dist: rich>=13.0.0
|
|
26
|
+
Requires-Dist: httpx>=0.24.0
|
|
27
|
+
Requires-Dist: pydantic>=2.0.0
|
|
28
|
+
Requires-Dist: cryptography>=41.0.0
|
|
29
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
30
|
+
Requires-Dist: certifi>=2023.0.0
|
|
31
|
+
Requires-Dist: aiofiles>=23.0.0
|
|
32
|
+
Requires-Dist: aiohttp>=3.8.0
|
|
33
|
+
Requires-Dist: psutil>=5.9.0
|
|
34
|
+
Requires-Dist: beautifulsoup4>=4.12.0
|
|
35
|
+
Requires-Dist: html2text>=2020.1.16
|
|
36
|
+
Requires-Dist: jsonschema>=4.17.0
|
|
37
|
+
Requires-Dist: readability-lxml>=0.8.1
|
|
38
|
+
Requires-Dist: PyYAML>=6.0.0
|
|
39
|
+
Requires-Dist: toml>=0.10.2
|
|
40
|
+
Provides-Extra: dev
|
|
41
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
42
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
43
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
44
|
+
Requires-Dist: pytest-mock>=3.10.0; extra == "dev"
|
|
45
|
+
Requires-Dist: black>=23.0.0; extra == "dev"
|
|
46
|
+
Requires-Dist: isort>=5.12.0; extra == "dev"
|
|
47
|
+
Requires-Dist: flake8>=6.0.0; extra == "dev"
|
|
48
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
49
|
+
Dynamic: license-file
|
|
50
|
+
|
|
51
|
+
# Omnimancer CLI
|
|
52
|
+
|
|
53
|
+
A unified command-line interface for multiple AI providers - chat with Claude, OpenAI, Gemini, and 10+ other AI models through a single, intuitive tool.
|
|
54
|
+
|
|
55
|
+
## Quick Start
|
|
56
|
+
|
|
57
|
+
### Installation
|
|
58
|
+
|
|
59
|
+
**Using pipx (recommended):**
|
|
60
|
+
```bash
|
|
61
|
+
pipx install omnimancer-cli
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Using pip:**
|
|
65
|
+
```bash
|
|
66
|
+
pip install omnimancer-cli
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Available Commands
|
|
70
|
+
|
|
71
|
+
After installation, use any of these commands:
|
|
72
|
+
- **`omnimancer`** - Full command name
|
|
73
|
+
- **`omn`** - Quick alias ⚡
|
|
74
|
+
- **`omniman`** - Alternative alias
|
|
75
|
+
|
|
76
|
+
### First Run
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
omn # or omnimancer, or omniman
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
On first run, you'll be guided through setup:
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
🚀 Omnimancer Setup Wizard
|
|
86
|
+
|
|
87
|
+
Select a provider to configure:
|
|
88
|
+
1. Claude (Anthropic)
|
|
89
|
+
2. OpenAI
|
|
90
|
+
3. Google Gemini
|
|
91
|
+
4. Perplexity AI
|
|
92
|
+
5. Ollama (Local)
|
|
93
|
+
...
|
|
94
|
+
|
|
95
|
+
Choose [1]: 1
|
|
96
|
+
|
|
97
|
+
Enter your Claude API key: sk-ant-...
|
|
98
|
+
✅ Configuration complete!
|
|
99
|
+
|
|
100
|
+
>>> Hello! How can you help me today?
|
|
101
|
+
🤖 Claude: I'm Claude, an AI assistant created by Anthropic...
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Basic Usage
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Start Omnimancer
|
|
108
|
+
omn
|
|
109
|
+
|
|
110
|
+
# Start chatting
|
|
111
|
+
>>> What's the weather like?
|
|
112
|
+
|
|
113
|
+
# Switch models mid-conversation
|
|
114
|
+
>>> /switch openai gpt-4o
|
|
115
|
+
>>> Now using GPT-4. How are you different?
|
|
116
|
+
|
|
117
|
+
# Check available providers and models
|
|
118
|
+
>>> /providers
|
|
119
|
+
>>> /models
|
|
120
|
+
|
|
121
|
+
# Save conversations
|
|
122
|
+
>>> /save my-chat
|
|
123
|
+
|
|
124
|
+
# Load previous conversations
|
|
125
|
+
>>> /load my-chat
|
|
126
|
+
|
|
127
|
+
# Get help
|
|
128
|
+
>>> /help
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Agent Mode & File Operations
|
|
132
|
+
|
|
133
|
+
Omnimancer includes advanced agent capabilities that allow AI models to perform file operations with your explicit approval:
|
|
134
|
+
|
|
135
|
+
### 🤖 **Autonomous Agent Features**
|
|
136
|
+
- **File Creation**: Create new files with AI-generated content
|
|
137
|
+
- **File Modification**: Edit existing files with intelligent changes
|
|
138
|
+
- **Code Refactoring**: Restructure and improve existing code
|
|
139
|
+
- **Documentation Generation**: Create comprehensive documentation
|
|
140
|
+
- **Project Setup**: Initialize new projects with proper structure
|
|
141
|
+
|
|
142
|
+
### 🔒 **Secure Approval System**
|
|
143
|
+
Every file operation requires your explicit approval with:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
🔍 File Operation Approval Required
|
|
147
|
+
📄 Creating: data_analyzer.py
|
|
148
|
+
📊 Risk Level: Low | 🟢
|
|
149
|
+
📏 Size: 1,247 bytes (45 lines)
|
|
150
|
+
|
|
151
|
+
[Y] Approve [N] Deny [D] View Details [Q] Quit
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### 🎨 **Rich Visual Interface**
|
|
155
|
+
- **Syntax Highlighting**: Code displayed with proper formatting
|
|
156
|
+
- **Diff Views**: See exactly what changes before approval
|
|
157
|
+
- **Risk Assessment**: Operations rated Low/Medium/High/Critical
|
|
158
|
+
- **Batch Operations**: Handle multiple files efficiently
|
|
159
|
+
|
|
160
|
+
### ⚡ **Quick Examples**
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
# Ask AI to create files
|
|
164
|
+
>>> Create a Python script to analyze CSV data
|
|
165
|
+
🔍 Shows preview → [Y] to approve → ✅ File created
|
|
166
|
+
|
|
167
|
+
# Request code modifications
|
|
168
|
+
>>> Add error handling to this function
|
|
169
|
+
🔍 Shows diff view → [Y] to approve → ✅ File updated
|
|
170
|
+
|
|
171
|
+
# Batch project setup
|
|
172
|
+
>>> Set up a Flask web application
|
|
173
|
+
🔍 Shows 8 files → [A] approve all → ✅ Project ready
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
[**📖 Full Documentation**](docs/agent-approval-system.md) | [**🛡️ Security Guide**](docs/security.md)
|
|
177
|
+
|
|
178
|
+
## Supported Providers
|
|
179
|
+
|
|
180
|
+
| Provider | API Key Required | Best For |
|
|
181
|
+
|----------|------------------|----------|
|
|
182
|
+
| **Claude** | [Anthropic Console](https://console.anthropic.com/) | Complex reasoning, analysis |
|
|
183
|
+
| **Claude Code** | Anthropic API key | IDE integration, coding |
|
|
184
|
+
| **OpenAI** | [OpenAI Platform](https://platform.openai.com/) | General purpose, coding |
|
|
185
|
+
| **Gemini** | [Google AI Studio](https://aistudio.google.com/) | Large context, research |
|
|
186
|
+
| **Perplexity** | [Perplexity](https://www.perplexity.ai/) | Real-time web search |
|
|
187
|
+
| **xAI (Grok)** | [xAI Console](https://console.x.ai/) | Creative tasks, real-time info |
|
|
188
|
+
| **Mistral** | [Mistral Platform](https://mistral.ai/) | Code generation, efficiency |
|
|
189
|
+
| **AWS Bedrock** | [AWS Console](https://console.aws.amazon.com/bedrock/) | AWS integration |
|
|
190
|
+
| **Ollama** | No API key (local) | Privacy, offline use |
|
|
191
|
+
| **Azure OpenAI** | Azure setup required | Enterprise |
|
|
192
|
+
| **Vertex AI** | Google Cloud setup | Enterprise |
|
|
193
|
+
| **OpenRouter** | [OpenRouter](https://openrouter.ai/) | 100+ models access |
|
|
194
|
+
| **Cohere** | [Cohere Platform](https://cohere.com/) | Multilingual, embeddings |
|
|
195
|
+
|
|
196
|
+
## Commands
|
|
197
|
+
|
|
198
|
+
### Core Commands
|
|
199
|
+
| Command | Description |
|
|
200
|
+
|---------|-------------|
|
|
201
|
+
| `/help` | Show all commands |
|
|
202
|
+
| `/setup` | Run interactive setup wizard |
|
|
203
|
+
| `/quit` | Exit Omnimancer |
|
|
204
|
+
| `/clear` | Clear screen |
|
|
205
|
+
|
|
206
|
+
### Model & Provider Management
|
|
207
|
+
| Command | Description |
|
|
208
|
+
|---------|-------------|
|
|
209
|
+
| `/models` | List available models |
|
|
210
|
+
| `/providers` | Show configured providers |
|
|
211
|
+
| `/switch [provider] [model]` | Change provider/model |
|
|
212
|
+
| `/validate [provider]` | Validate provider configurations |
|
|
213
|
+
| `/health [provider]` | Check provider health status |
|
|
214
|
+
| `/repair [provider]` | Repair provider issues |
|
|
215
|
+
| `/diagnose [provider]` | Run diagnostic tests |
|
|
216
|
+
|
|
217
|
+
### Conversation Management
|
|
218
|
+
| Command | Description |
|
|
219
|
+
|---------|-------------|
|
|
220
|
+
| `/save [name]` | Save current conversation |
|
|
221
|
+
| `/load [name]` | Load saved conversation |
|
|
222
|
+
| `/list` | List saved conversations |
|
|
223
|
+
| `/history` | Conversation history management |
|
|
224
|
+
|
|
225
|
+
### Agent & File Operations
|
|
226
|
+
| Command | Description |
|
|
227
|
+
|---------|-------------|
|
|
228
|
+
| `/agent` | Enable/disable agent mode |
|
|
229
|
+
| `/agents` | Manage agent configurations |
|
|
230
|
+
| `/approvals` | View/manage file operation approvals |
|
|
231
|
+
| `/permissions` | Configure security permissions |
|
|
232
|
+
|
|
233
|
+
### Tool Integration
|
|
234
|
+
| Command | Description |
|
|
235
|
+
|---------|-------------|
|
|
236
|
+
| `/tools` | Show available tools |
|
|
237
|
+
| `/mcp` | MCP server management |
|
|
238
|
+
|
|
239
|
+
### Model Management
|
|
240
|
+
| Command | Description |
|
|
241
|
+
|---------|-------------|
|
|
242
|
+
| `/add-model` | Add custom model |
|
|
243
|
+
| `/remove-model` | Remove custom model |
|
|
244
|
+
| `/list-custom-models` | List custom models |
|
|
245
|
+
|
|
246
|
+
### System
|
|
247
|
+
| Command | Description |
|
|
248
|
+
|---------|-------------|
|
|
249
|
+
| `/status` | Show system status |
|
|
250
|
+
|
|
251
|
+
## Configuration
|
|
252
|
+
|
|
253
|
+
Omnimancer stores encrypted configuration in `~/.omnimancer/config.json`.
|
|
254
|
+
|
|
255
|
+
### Manual Configuration
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
# Add a provider
|
|
259
|
+
omnimancer --config
|
|
260
|
+
|
|
261
|
+
# Or edit configuration interactively
|
|
262
|
+
>>> /config
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Environment Variables
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
export ANTHROPIC_API_KEY="your-key"
|
|
269
|
+
export OPENAI_API_KEY="your-key"
|
|
270
|
+
export GOOGLE_API_KEY="your-key"
|
|
271
|
+
# ... then run omnimancer
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## Local AI with Ollama
|
|
275
|
+
|
|
276
|
+
For privacy and offline use:
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
# Install Ollama
|
|
280
|
+
curl -fsSL https://ollama.ai/install.sh | sh
|
|
281
|
+
|
|
282
|
+
# Start Ollama server
|
|
283
|
+
ollama serve
|
|
284
|
+
|
|
285
|
+
# Download a model
|
|
286
|
+
ollama pull llama3.1
|
|
287
|
+
|
|
288
|
+
# Configure Omnimancer
|
|
289
|
+
omn
|
|
290
|
+
>>> /switch ollama llama3.1
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## Tool Integration (MCP)
|
|
294
|
+
|
|
295
|
+
Enable AI tool calling for file operations, web search, and more:
|
|
296
|
+
|
|
297
|
+
```bash
|
|
298
|
+
# Install UV for MCP servers
|
|
299
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
300
|
+
|
|
301
|
+
# Check tool status
|
|
302
|
+
>>> /tools
|
|
303
|
+
>>> /mcp status
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
Popular MCP tools:
|
|
307
|
+
- **Filesystem**: File operations
|
|
308
|
+
- **Web Search**: Real-time search
|
|
309
|
+
- **Git**: Repository management
|
|
310
|
+
|
|
311
|
+
## Examples
|
|
312
|
+
|
|
313
|
+
### Basic Chat
|
|
314
|
+
```
|
|
315
|
+
>>> Explain quantum computing in simple terms
|
|
316
|
+
🤖 Claude: Quantum computing is like having a super-powered calculator...
|
|
317
|
+
|
|
318
|
+
>>> /switch openai gpt-4o
|
|
319
|
+
>>> How would you explain it differently?
|
|
320
|
+
🤖 GPT-4: I'd compare quantum computing to exploring a maze...
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Code Generation
|
|
324
|
+
```
|
|
325
|
+
>>> Write a Python function to calculate fibonacci numbers
|
|
326
|
+
🤖 Claude: Here's an efficient implementation using memoization:
|
|
327
|
+
|
|
328
|
+
```python
|
|
329
|
+
def fibonacci(n, memo={}):
|
|
330
|
+
if n in memo:
|
|
331
|
+
return memo[n]
|
|
332
|
+
if n <= 1:
|
|
333
|
+
return n
|
|
334
|
+
memo[n] = fibonacci(n-1, memo) + fibonacci(n-2, memo)
|
|
335
|
+
return memo[n]
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Model Comparison
|
|
339
|
+
```
|
|
340
|
+
>>> /switch claude claude-3-5-sonnet
|
|
341
|
+
>>> What's 15 * 24?
|
|
342
|
+
🤖 Claude: 15 × 24 = 360
|
|
343
|
+
|
|
344
|
+
>>> /switch openai gpt-4o
|
|
345
|
+
>>> What's 15 * 24?
|
|
346
|
+
🤖 GPT-4: 15 × 24 = 360
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
## Advanced Features
|
|
350
|
+
|
|
351
|
+
- **Conversation Management**: Save/load chat history
|
|
352
|
+
- **Model Switching**: Compare responses between providers
|
|
353
|
+
- **Tool Calling**: AI can execute code, search web, manage files
|
|
354
|
+
- **Health Monitoring**: Provider status and diagnostics
|
|
355
|
+
- **Configuration Templates**: Pre-configured setups for different use cases
|
|
356
|
+
|
|
357
|
+
## Development
|
|
358
|
+
|
|
359
|
+
```bash
|
|
360
|
+
git clone https://gitlab.com/jite-ai/omnimancer
|
|
361
|
+
cd omnimancer
|
|
362
|
+
pip install -e ".[dev]"
|
|
363
|
+
pytest
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
## Troubleshooting
|
|
367
|
+
|
|
368
|
+
### Common Issues
|
|
369
|
+
|
|
370
|
+
**"No providers configured"**
|
|
371
|
+
```bash
|
|
372
|
+
omn # Run setup wizard
|
|
373
|
+
>>> /setup
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
**"Invalid API key"**
|
|
377
|
+
- Check key format (Claude: `sk-ant-`, OpenAI: `sk-`, etc.)
|
|
378
|
+
- Verify key at provider's website
|
|
379
|
+
- Use `/validate` command to test configuration
|
|
380
|
+
|
|
381
|
+
**"Ollama connection failed"**
|
|
382
|
+
```bash
|
|
383
|
+
ollama serve # Start Ollama server
|
|
384
|
+
ollama pull llama3.1 # Download a model
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
**Check system health:**
|
|
388
|
+
```bash
|
|
389
|
+
omn
|
|
390
|
+
>>> /health # Check all providers
|
|
391
|
+
>>> /diagnose # Run diagnostics
|
|
392
|
+
>>> /validate # Validate configurations
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
**Debug mode:**
|
|
396
|
+
```bash
|
|
397
|
+
export OMNIMANCER_DEBUG=1
|
|
398
|
+
omn
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
## License
|
|
402
|
+
|
|
403
|
+
MIT License - see [LICENSE](LICENSE) file.
|
|
404
|
+
|
|
405
|
+
## Links
|
|
406
|
+
|
|
407
|
+
- [GitHub Repository]https://gitlab.com/jite-ai/omnimancer)
|
|
408
|
+
- [Issues](https://gitlab.com/jite-ai/omnimancer/issues)
|
|
409
|
+
- [Documentation](https://gitlab.com/jite-ai/omnimancer/docs)
|
|
410
|
+
|
|
411
|
+
---
|
|
412
|
+
|
|
413
|
+
**Omnimancer CLI** - One tool, multiple AI providers, endless possibilities.
|