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,412 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Cohere provider implementation for Omnimancer.
|
|
3
|
+
|
|
4
|
+
This module provides the Cohere AI provider implementation using Cohere's API.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
from typing import Dict, List
|
|
9
|
+
|
|
10
|
+
import httpx
|
|
11
|
+
|
|
12
|
+
from ..core.models import ChatContext, ChatResponse, ModelInfo
|
|
13
|
+
from ..utils.errors import (
|
|
14
|
+
AuthenticationError,
|
|
15
|
+
ModelNotFoundError,
|
|
16
|
+
NetworkError,
|
|
17
|
+
ProviderConfigurationError,
|
|
18
|
+
ProviderError,
|
|
19
|
+
ProviderUnavailableError,
|
|
20
|
+
QuotaExceededError,
|
|
21
|
+
RateLimitError,
|
|
22
|
+
)
|
|
23
|
+
from .base import BaseProvider
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class CohereProvider(BaseProvider):
|
|
27
|
+
"""
|
|
28
|
+
Cohere AI provider implementation using Cohere's API.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
BASE_URL = "https://api.cohere.ai/v1"
|
|
32
|
+
|
|
33
|
+
def __init__(self, api_key: str, model: str = "", **kwargs):
|
|
34
|
+
"""
|
|
35
|
+
Initialize Cohere provider.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
api_key: Cohere API key
|
|
39
|
+
model: Cohere model to use (e.g., 'command-r', 'command-r-plus', 'command')
|
|
40
|
+
**kwargs: Additional configuration
|
|
41
|
+
"""
|
|
42
|
+
super().__init__(api_key, model or "command-r", **kwargs)
|
|
43
|
+
self.max_tokens = kwargs.get("max_tokens", 4096)
|
|
44
|
+
self.temperature = kwargs.get("temperature", 0.7)
|
|
45
|
+
|
|
46
|
+
async def send_message(self, message: str, context: ChatContext) -> ChatResponse:
|
|
47
|
+
"""
|
|
48
|
+
Send a message to Cohere API.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
message: User message
|
|
52
|
+
context: Conversation context
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
ChatResponse with Cohere's reply
|
|
56
|
+
"""
|
|
57
|
+
try:
|
|
58
|
+
# Prepare chat history for Cohere API
|
|
59
|
+
chat_history = self._prepare_chat_history(context)
|
|
60
|
+
|
|
61
|
+
# Make API request
|
|
62
|
+
async with httpx.AsyncClient() as client:
|
|
63
|
+
response = await client.post(
|
|
64
|
+
f"{self.BASE_URL}/chat",
|
|
65
|
+
headers={
|
|
66
|
+
"Content-Type": "application/json",
|
|
67
|
+
"Authorization": f"Bearer {self.api_key}",
|
|
68
|
+
},
|
|
69
|
+
json={
|
|
70
|
+
"model": self.model,
|
|
71
|
+
"message": message,
|
|
72
|
+
"chat_history": chat_history,
|
|
73
|
+
"max_tokens": self.max_tokens,
|
|
74
|
+
"temperature": self.temperature,
|
|
75
|
+
},
|
|
76
|
+
timeout=30.0,
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
# Handle response
|
|
80
|
+
return self._handle_response(response)
|
|
81
|
+
|
|
82
|
+
except httpx.TimeoutException:
|
|
83
|
+
raise NetworkError("Request to Cohere API timed out")
|
|
84
|
+
except httpx.RequestError as e:
|
|
85
|
+
raise NetworkError(f"Network error: {e}")
|
|
86
|
+
except (
|
|
87
|
+
AuthenticationError,
|
|
88
|
+
RateLimitError,
|
|
89
|
+
ModelNotFoundError,
|
|
90
|
+
ProviderError,
|
|
91
|
+
):
|
|
92
|
+
# Re-raise provider-specific errors without wrapping
|
|
93
|
+
raise
|
|
94
|
+
except Exception as e:
|
|
95
|
+
raise ProviderError(f"Unexpected error: {e}")
|
|
96
|
+
|
|
97
|
+
async def validate_credentials(self) -> bool:
|
|
98
|
+
"""
|
|
99
|
+
Validate Cohere API credentials by making a test request.
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
True if credentials are valid
|
|
103
|
+
"""
|
|
104
|
+
try:
|
|
105
|
+
async with httpx.AsyncClient() as client:
|
|
106
|
+
response = await client.post(
|
|
107
|
+
f"{self.BASE_URL}/chat",
|
|
108
|
+
headers={
|
|
109
|
+
"Content-Type": "application/json",
|
|
110
|
+
"Authorization": f"Bearer {self.api_key}",
|
|
111
|
+
},
|
|
112
|
+
json={
|
|
113
|
+
"model": self.model,
|
|
114
|
+
"message": "Hi",
|
|
115
|
+
"max_tokens": 10,
|
|
116
|
+
},
|
|
117
|
+
timeout=10.0,
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
return response.status_code == 200
|
|
121
|
+
|
|
122
|
+
except Exception:
|
|
123
|
+
return False
|
|
124
|
+
|
|
125
|
+
def _prepare_chat_history(self, context: ChatContext) -> List[Dict[str, str]]:
|
|
126
|
+
"""
|
|
127
|
+
Prepare chat history for Cohere API format.
|
|
128
|
+
|
|
129
|
+
Args:
|
|
130
|
+
context: Conversation context
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
List of messages formatted for Cohere API
|
|
134
|
+
"""
|
|
135
|
+
chat_history = []
|
|
136
|
+
|
|
137
|
+
# Convert context messages to Cohere format
|
|
138
|
+
# Cohere uses "USER" and "CHATBOT" roles, and excludes system messages
|
|
139
|
+
for msg in context.messages:
|
|
140
|
+
if msg.role.value == "user":
|
|
141
|
+
chat_history.append({"role": "USER", "message": msg.content})
|
|
142
|
+
elif msg.role.value == "assistant":
|
|
143
|
+
chat_history.append({"role": "CHATBOT", "message": msg.content})
|
|
144
|
+
# Skip system messages as Cohere doesn't support them in chat history
|
|
145
|
+
|
|
146
|
+
return chat_history
|
|
147
|
+
|
|
148
|
+
def _handle_response(self, response: httpx.Response) -> ChatResponse:
|
|
149
|
+
"""
|
|
150
|
+
Handle Cohere API response with comprehensive error handling.
|
|
151
|
+
|
|
152
|
+
Args:
|
|
153
|
+
response: HTTP response from Cohere API
|
|
154
|
+
|
|
155
|
+
Returns:
|
|
156
|
+
ChatResponse object
|
|
157
|
+
|
|
158
|
+
Raises:
|
|
159
|
+
Various provider errors based on response status
|
|
160
|
+
"""
|
|
161
|
+
if response.status_code == 200:
|
|
162
|
+
try:
|
|
163
|
+
data = response.json()
|
|
164
|
+
text = data.get("text", "")
|
|
165
|
+
|
|
166
|
+
if text:
|
|
167
|
+
# Extract token usage if available
|
|
168
|
+
meta = data.get("meta", {})
|
|
169
|
+
billed_units = meta.get("billed_units", {})
|
|
170
|
+
tokens_used = billed_units.get("output_tokens", 0)
|
|
171
|
+
|
|
172
|
+
return ChatResponse(
|
|
173
|
+
content=text,
|
|
174
|
+
model_used=self.model,
|
|
175
|
+
tokens_used=tokens_used,
|
|
176
|
+
timestamp=datetime.now(),
|
|
177
|
+
)
|
|
178
|
+
else:
|
|
179
|
+
raise ProviderError(
|
|
180
|
+
"Empty response from Cohere API", provider="cohere"
|
|
181
|
+
)
|
|
182
|
+
except (ValueError, KeyError) as e:
|
|
183
|
+
raise ProviderError(
|
|
184
|
+
f"Invalid JSON response from Cohere API: {e}",
|
|
185
|
+
provider="cohere",
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
elif response.status_code == 400:
|
|
189
|
+
try:
|
|
190
|
+
error_data = response.json()
|
|
191
|
+
error_msg = error_data.get("message", "Bad request")
|
|
192
|
+
|
|
193
|
+
if "model" in error_msg.lower() or "not found" in error_msg.lower():
|
|
194
|
+
available_models = [m.name for m in self.get_available_models()]
|
|
195
|
+
raise ModelNotFoundError(
|
|
196
|
+
f"Cohere model '{self.model}' not found or not accessible",
|
|
197
|
+
provider="cohere",
|
|
198
|
+
model_name=self.model,
|
|
199
|
+
available_models=available_models,
|
|
200
|
+
)
|
|
201
|
+
elif "token" in error_msg.lower() and "limit" in error_msg.lower():
|
|
202
|
+
raise ProviderError(
|
|
203
|
+
f"Token limit exceeded: {error_msg}. Try reducing message length.",
|
|
204
|
+
provider="cohere",
|
|
205
|
+
)
|
|
206
|
+
elif (
|
|
207
|
+
"invalid" in error_msg.lower() and "parameter" in error_msg.lower()
|
|
208
|
+
):
|
|
209
|
+
raise ProviderConfigurationError(
|
|
210
|
+
f"Invalid parameter in request: {error_msg}",
|
|
211
|
+
provider="cohere",
|
|
212
|
+
suggested_fix="Check model parameters and configuration",
|
|
213
|
+
)
|
|
214
|
+
else:
|
|
215
|
+
raise ProviderError(
|
|
216
|
+
f"Cohere API error: {error_msg}", provider="cohere"
|
|
217
|
+
)
|
|
218
|
+
except (ValueError, KeyError):
|
|
219
|
+
raise ProviderError("Bad request to Cohere API", provider="cohere")
|
|
220
|
+
|
|
221
|
+
elif response.status_code == 401:
|
|
222
|
+
raise AuthenticationError(
|
|
223
|
+
"Invalid Cohere API key. Check your API key configuration.",
|
|
224
|
+
provider="cohere",
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
elif response.status_code == 403:
|
|
228
|
+
try:
|
|
229
|
+
error_data = response.json()
|
|
230
|
+
error_msg = error_data.get("message", "")
|
|
231
|
+
if "billing" in error_msg.lower() or "payment" in error_msg.lower():
|
|
232
|
+
raise QuotaExceededError(
|
|
233
|
+
"Cohere API access restricted due to billing issues",
|
|
234
|
+
provider="cohere",
|
|
235
|
+
)
|
|
236
|
+
else:
|
|
237
|
+
raise AuthenticationError(
|
|
238
|
+
"Cohere API access forbidden. Check API key permissions.",
|
|
239
|
+
provider="cohere",
|
|
240
|
+
)
|
|
241
|
+
except (ValueError, KeyError):
|
|
242
|
+
raise AuthenticationError(
|
|
243
|
+
"Cohere API access forbidden. Check API key permissions.",
|
|
244
|
+
provider="cohere",
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
elif response.status_code == 429:
|
|
248
|
+
# Extract rate limit information if available
|
|
249
|
+
retry_after = response.headers.get("Retry-After")
|
|
250
|
+
if retry_after:
|
|
251
|
+
try:
|
|
252
|
+
retry_seconds = int(retry_after)
|
|
253
|
+
raise RateLimitError(
|
|
254
|
+
"Cohere API rate limit exceeded",
|
|
255
|
+
provider="cohere",
|
|
256
|
+
retry_after=retry_seconds,
|
|
257
|
+
)
|
|
258
|
+
except ValueError:
|
|
259
|
+
pass
|
|
260
|
+
|
|
261
|
+
# Check if it's a quota issue
|
|
262
|
+
try:
|
|
263
|
+
error_data = response.json()
|
|
264
|
+
error_msg = error_data.get("message", "")
|
|
265
|
+
if "quota" in error_msg.lower() or "usage" in error_msg.lower():
|
|
266
|
+
raise QuotaExceededError(
|
|
267
|
+
"Cohere API usage quota exceeded", provider="cohere"
|
|
268
|
+
)
|
|
269
|
+
except (ValueError, KeyError):
|
|
270
|
+
pass
|
|
271
|
+
|
|
272
|
+
raise RateLimitError(
|
|
273
|
+
"Cohere API rate limit exceeded. Wait before retrying.",
|
|
274
|
+
provider="cohere",
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
elif response.status_code == 500:
|
|
278
|
+
raise ProviderUnavailableError(
|
|
279
|
+
"Cohere API server error. Try again later.",
|
|
280
|
+
provider="cohere",
|
|
281
|
+
estimated_recovery="a few minutes",
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
elif response.status_code == 502 or response.status_code == 503:
|
|
285
|
+
raise ProviderUnavailableError(
|
|
286
|
+
"Cohere API temporarily unavailable. Service may be under maintenance.",
|
|
287
|
+
provider="cohere",
|
|
288
|
+
estimated_recovery="10-30 minutes",
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
else:
|
|
292
|
+
try:
|
|
293
|
+
error_data = response.json()
|
|
294
|
+
error_msg = error_data.get("message", "Unknown error")
|
|
295
|
+
except:
|
|
296
|
+
error_msg = f"HTTP {response.status_code}"
|
|
297
|
+
|
|
298
|
+
raise ProviderError(f"Cohere API error: {error_msg}", provider="cohere")
|
|
299
|
+
|
|
300
|
+
def get_model_info(self) -> ModelInfo:
|
|
301
|
+
"""
|
|
302
|
+
Get information about the current Cohere model.
|
|
303
|
+
"""
|
|
304
|
+
model_configs = {
|
|
305
|
+
"command-r": {
|
|
306
|
+
"description": "Command R - Cohere's flagship conversational model",
|
|
307
|
+
"max_tokens": 128000,
|
|
308
|
+
"cost_per_token": 0.0000005,
|
|
309
|
+
},
|
|
310
|
+
"command-r-plus": {
|
|
311
|
+
"description": "Command R+ - Enhanced version with improved capabilities",
|
|
312
|
+
"max_tokens": 128000,
|
|
313
|
+
"cost_per_token": 0.000003,
|
|
314
|
+
},
|
|
315
|
+
"command-light": {
|
|
316
|
+
"description": "Command Light - Fast and efficient model for simple tasks",
|
|
317
|
+
"max_tokens": 4096,
|
|
318
|
+
"cost_per_token": 0.0000003,
|
|
319
|
+
},
|
|
320
|
+
"command": {
|
|
321
|
+
"description": "Command - Previous generation conversational model",
|
|
322
|
+
"max_tokens": 4096,
|
|
323
|
+
"cost_per_token": 0.000001,
|
|
324
|
+
},
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
config = model_configs.get(
|
|
328
|
+
self.model,
|
|
329
|
+
{
|
|
330
|
+
"description": f"Cohere model {self.model}",
|
|
331
|
+
"max_tokens": 4096,
|
|
332
|
+
"cost_per_token": 0.000001,
|
|
333
|
+
},
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
return ModelInfo(
|
|
337
|
+
name=self.model,
|
|
338
|
+
provider="cohere",
|
|
339
|
+
description=config["description"],
|
|
340
|
+
max_tokens=config["max_tokens"],
|
|
341
|
+
cost_per_token=config["cost_per_token"],
|
|
342
|
+
available=True,
|
|
343
|
+
supports_tools=False, # Cohere doesn't support tool calling in the same way
|
|
344
|
+
supports_multimodal=False, # Cohere is primarily text-based
|
|
345
|
+
latest_version=self.model == "command-r-plus",
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
def get_available_models(self) -> List[ModelInfo]:
|
|
349
|
+
"""
|
|
350
|
+
Get list of available Cohere models.
|
|
351
|
+
"""
|
|
352
|
+
return [
|
|
353
|
+
ModelInfo(
|
|
354
|
+
name="command-r",
|
|
355
|
+
provider="cohere",
|
|
356
|
+
description="Command R - Cohere's flagship conversational model",
|
|
357
|
+
max_tokens=128000,
|
|
358
|
+
cost_per_token=0.0000005,
|
|
359
|
+
available=True,
|
|
360
|
+
supports_tools=False,
|
|
361
|
+
supports_multimodal=False,
|
|
362
|
+
),
|
|
363
|
+
ModelInfo(
|
|
364
|
+
name="command-r-plus",
|
|
365
|
+
provider="cohere",
|
|
366
|
+
description="Command R+ - Enhanced version with improved capabilities",
|
|
367
|
+
max_tokens=128000,
|
|
368
|
+
cost_per_token=0.000003,
|
|
369
|
+
available=True,
|
|
370
|
+
supports_tools=False,
|
|
371
|
+
supports_multimodal=False,
|
|
372
|
+
latest_version=True,
|
|
373
|
+
),
|
|
374
|
+
ModelInfo(
|
|
375
|
+
name="command-light",
|
|
376
|
+
provider="cohere",
|
|
377
|
+
description="Command Light - Fast and efficient model for simple tasks",
|
|
378
|
+
max_tokens=4096,
|
|
379
|
+
cost_per_token=0.0000003,
|
|
380
|
+
available=True,
|
|
381
|
+
supports_tools=False,
|
|
382
|
+
supports_multimodal=False,
|
|
383
|
+
),
|
|
384
|
+
ModelInfo(
|
|
385
|
+
name="command",
|
|
386
|
+
provider="cohere",
|
|
387
|
+
description="Command - Previous generation conversational model",
|
|
388
|
+
max_tokens=4096,
|
|
389
|
+
cost_per_token=0.000001,
|
|
390
|
+
available=True,
|
|
391
|
+
supports_tools=False,
|
|
392
|
+
supports_multimodal=False,
|
|
393
|
+
),
|
|
394
|
+
]
|
|
395
|
+
|
|
396
|
+
def supports_tools(self) -> bool:
|
|
397
|
+
"""
|
|
398
|
+
Check if Cohere provider supports tool calling.
|
|
399
|
+
|
|
400
|
+
Returns:
|
|
401
|
+
False - Cohere doesn't support tool calling in the same way as OpenAI/Claude
|
|
402
|
+
"""
|
|
403
|
+
return False
|
|
404
|
+
|
|
405
|
+
def supports_multimodal(self) -> bool:
|
|
406
|
+
"""
|
|
407
|
+
Check if Cohere provider supports multimodal inputs.
|
|
408
|
+
|
|
409
|
+
Returns:
|
|
410
|
+
False - Cohere is primarily text-based
|
|
411
|
+
"""
|
|
412
|
+
return False
|