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,470 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CLI Integration for Status-Enhanced Agent System.
|
|
3
|
+
|
|
4
|
+
This module provides integration between the CLI interface and the
|
|
5
|
+
status-enhanced agent engine, enabling status display in CLI commands.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import asyncio
|
|
9
|
+
import logging
|
|
10
|
+
from typing import Any, Callable, Dict, List, Optional
|
|
11
|
+
|
|
12
|
+
from rich.console import Console
|
|
13
|
+
from rich.live import Live
|
|
14
|
+
from rich.panel import Panel
|
|
15
|
+
|
|
16
|
+
from ..config_manager import ConfigManager
|
|
17
|
+
from .status_integrated_engine import (
|
|
18
|
+
StatusIntegratedAgentEngine,
|
|
19
|
+
create_status_integrated_engine,
|
|
20
|
+
)
|
|
21
|
+
from .status_ui_components import (
|
|
22
|
+
ComprehensiveStatusDisplay,
|
|
23
|
+
)
|
|
24
|
+
from .terminal_status_listener import TerminalStatusListener
|
|
25
|
+
|
|
26
|
+
logger = logging.getLogger(__name__)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class CLIStatusIntegration:
|
|
30
|
+
"""
|
|
31
|
+
Integration layer between CLI and status-enhanced agent system.
|
|
32
|
+
|
|
33
|
+
Provides methods for CLI commands to interact with and display
|
|
34
|
+
agent status information.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def __init__(
|
|
38
|
+
self,
|
|
39
|
+
engine: StatusIntegratedAgentEngine,
|
|
40
|
+
console: Optional[Console] = None,
|
|
41
|
+
):
|
|
42
|
+
"""
|
|
43
|
+
Initialize CLI status integration.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
engine: Status-integrated agent engine
|
|
47
|
+
console: Rich console for output
|
|
48
|
+
"""
|
|
49
|
+
self.engine = engine
|
|
50
|
+
self.console = console or Console()
|
|
51
|
+
self.status_listener: Optional[TerminalStatusListener] = None
|
|
52
|
+
self.live_display: Optional[Live] = None
|
|
53
|
+
self.ui_display = ComprehensiveStatusDisplay()
|
|
54
|
+
|
|
55
|
+
async def start_live_status_display(self) -> bool:
|
|
56
|
+
"""
|
|
57
|
+
Start live status display in the terminal.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
True if display started successfully
|
|
61
|
+
"""
|
|
62
|
+
try:
|
|
63
|
+
if not self.engine.is_status_display_enabled():
|
|
64
|
+
self.console.print("[yellow]Status display is disabled[/yellow]")
|
|
65
|
+
return False
|
|
66
|
+
|
|
67
|
+
# Ensure status monitoring is started
|
|
68
|
+
await self.engine.start_status_monitoring()
|
|
69
|
+
|
|
70
|
+
# Create terminal listener if not exists
|
|
71
|
+
if not self.status_listener:
|
|
72
|
+
self.status_listener = TerminalStatusListener(
|
|
73
|
+
"cli_status_display", console=self.console
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
# Add to status manager (which handles streaming)
|
|
77
|
+
await self.engine.status_manager.add_listener(self.status_listener)
|
|
78
|
+
|
|
79
|
+
# Start live display
|
|
80
|
+
await self.status_listener.start_live_display()
|
|
81
|
+
|
|
82
|
+
self.console.print("[green]✅ Live status display started[/green]")
|
|
83
|
+
return True
|
|
84
|
+
|
|
85
|
+
except Exception as e:
|
|
86
|
+
logger.error(f"Failed to start live status display: {e}")
|
|
87
|
+
self.console.print(f"[red]❌ Failed to start status display: {e}[/red]")
|
|
88
|
+
return False
|
|
89
|
+
|
|
90
|
+
async def stop_live_status_display(self) -> bool:
|
|
91
|
+
"""
|
|
92
|
+
Stop live status display.
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
True if display stopped successfully
|
|
96
|
+
"""
|
|
97
|
+
try:
|
|
98
|
+
if self.status_listener:
|
|
99
|
+
await self.status_listener.stop_live_display()
|
|
100
|
+
|
|
101
|
+
# Remove from status manager
|
|
102
|
+
await self.engine.status_manager.remove_listener(
|
|
103
|
+
self.status_listener.listener_id
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
self.status_listener = None
|
|
107
|
+
|
|
108
|
+
self.console.print("[yellow]⏹️ Live status display stopped[/yellow]")
|
|
109
|
+
return True
|
|
110
|
+
|
|
111
|
+
except Exception as e:
|
|
112
|
+
logger.error(f"Failed to stop live status display: {e}")
|
|
113
|
+
self.console.print(f"[red]❌ Failed to stop status display: {e}[/red]")
|
|
114
|
+
return False
|
|
115
|
+
|
|
116
|
+
async def show_status_snapshot(self, detailed: bool = False) -> None:
|
|
117
|
+
"""
|
|
118
|
+
Show a snapshot of current status.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
detailed: Whether to show detailed information
|
|
122
|
+
"""
|
|
123
|
+
try:
|
|
124
|
+
if not self.engine.is_status_display_enabled():
|
|
125
|
+
self.console.print("[yellow]Status display is disabled[/yellow]")
|
|
126
|
+
return
|
|
127
|
+
|
|
128
|
+
# Get status data
|
|
129
|
+
status_summary = await self.engine.get_status_summary()
|
|
130
|
+
|
|
131
|
+
if "error" in status_summary:
|
|
132
|
+
self.console.print(
|
|
133
|
+
f"[red]❌ Error getting status: {status_summary['error']}[/red]"
|
|
134
|
+
)
|
|
135
|
+
return
|
|
136
|
+
|
|
137
|
+
# Display basic info
|
|
138
|
+
status_summary.get("status", "unknown")
|
|
139
|
+
status_summary.get("active_operations_count", 0)
|
|
140
|
+
|
|
141
|
+
# Create status display
|
|
142
|
+
if detailed:
|
|
143
|
+
self._show_detailed_status(status_summary)
|
|
144
|
+
else:
|
|
145
|
+
self._show_basic_status(status_summary)
|
|
146
|
+
|
|
147
|
+
except Exception as e:
|
|
148
|
+
logger.error(f"Failed to show status snapshot: {e}")
|
|
149
|
+
self.console.print(f"[red]❌ Failed to get status: {e}[/red]")
|
|
150
|
+
|
|
151
|
+
def _show_basic_status(self, status_summary: Dict[str, Any]) -> None:
|
|
152
|
+
"""Show basic status information."""
|
|
153
|
+
agent_id = status_summary.get("agent_id", "unknown")
|
|
154
|
+
status = status_summary.get("status", "unknown")
|
|
155
|
+
active_ops = status_summary.get("active_operations_count", 0)
|
|
156
|
+
|
|
157
|
+
# Status color coding
|
|
158
|
+
if status == "enabled":
|
|
159
|
+
status_color = "green"
|
|
160
|
+
status_emoji = "🟢"
|
|
161
|
+
elif status == "running":
|
|
162
|
+
status_color = "blue"
|
|
163
|
+
status_emoji = "🔵"
|
|
164
|
+
elif status == "error":
|
|
165
|
+
status_color = "red"
|
|
166
|
+
status_emoji = "🔴"
|
|
167
|
+
else:
|
|
168
|
+
status_color = "yellow"
|
|
169
|
+
status_emoji = "🟡"
|
|
170
|
+
|
|
171
|
+
content = f"[bold]Agent Status[/bold]\n\n"
|
|
172
|
+
content += f"Agent ID: [cyan]{agent_id}[/cyan]\n"
|
|
173
|
+
content += f"Status: [{status_color}]{status_emoji} {status.title()}[/{status_color}]\n"
|
|
174
|
+
content += f"Active Operations: [blue]{active_ops}[/blue]\n"
|
|
175
|
+
|
|
176
|
+
if status_summary.get("status_stream_running", False):
|
|
177
|
+
content += f"Status Stream: [green]🟢 Running[/green]\n"
|
|
178
|
+
else:
|
|
179
|
+
content += f"Status Stream: [red]🔴 Stopped[/red]\n"
|
|
180
|
+
|
|
181
|
+
self.console.print(Panel(content, title="📊 Agent Status", border_style="blue"))
|
|
182
|
+
|
|
183
|
+
def _show_detailed_status(self, status_summary: Dict[str, Any]) -> None:
|
|
184
|
+
"""Show detailed status information."""
|
|
185
|
+
# Basic info
|
|
186
|
+
self._show_basic_status(status_summary)
|
|
187
|
+
|
|
188
|
+
# Active operations
|
|
189
|
+
active_operations = status_summary.get("active_operations", [])
|
|
190
|
+
if active_operations:
|
|
191
|
+
self.console.print("\n[bold]Active Operations:[/bold]")
|
|
192
|
+
|
|
193
|
+
for op in active_operations:
|
|
194
|
+
op_type = op.get("type", "unknown")
|
|
195
|
+
description = op.get("description", "No description")
|
|
196
|
+
progress = op.get("progress", 0)
|
|
197
|
+
duration = op.get("duration", 0)
|
|
198
|
+
|
|
199
|
+
# Progress bar
|
|
200
|
+
bar_width = 20
|
|
201
|
+
filled = int((progress / 100) * bar_width)
|
|
202
|
+
bar = "█" * filled + "░" * (bar_width - filled)
|
|
203
|
+
|
|
204
|
+
op_info = f" [{progress:5.1f}%] {bar} {op_type}: {description}"
|
|
205
|
+
if duration > 0:
|
|
206
|
+
op_info += f" ({duration:.1f}s)"
|
|
207
|
+
|
|
208
|
+
self.console.print(op_info)
|
|
209
|
+
|
|
210
|
+
# System stats
|
|
211
|
+
system_stats = status_summary.get("system_stats", {})
|
|
212
|
+
if system_stats:
|
|
213
|
+
self.console.print(f"\n[bold]System Statistics:[/bold]")
|
|
214
|
+
self.console.print(
|
|
215
|
+
f" Events Emitted: {system_stats.get('events_emitted', 0)}"
|
|
216
|
+
)
|
|
217
|
+
self.console.print(
|
|
218
|
+
f" Operations Started: {system_stats.get('operations_started', 0)}"
|
|
219
|
+
)
|
|
220
|
+
self.console.print(
|
|
221
|
+
f" Operations Completed: {system_stats.get('operations_completed', 0)}"
|
|
222
|
+
)
|
|
223
|
+
self.console.print(
|
|
224
|
+
f" Operations Failed: {system_stats.get('operations_failed', 0)}"
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
async def execute_with_status_display(
|
|
228
|
+
self, operation_func: Callable, *args, **kwargs
|
|
229
|
+
) -> Any:
|
|
230
|
+
"""
|
|
231
|
+
Execute a function while displaying status updates.
|
|
232
|
+
|
|
233
|
+
Args:
|
|
234
|
+
operation_func: Function to execute
|
|
235
|
+
*args, **kwargs: Arguments for the function
|
|
236
|
+
|
|
237
|
+
Returns:
|
|
238
|
+
Result of the function
|
|
239
|
+
"""
|
|
240
|
+
try:
|
|
241
|
+
# Start live display if not already running
|
|
242
|
+
display_started = False
|
|
243
|
+
if not self.status_listener:
|
|
244
|
+
display_started = await self.start_live_status_display()
|
|
245
|
+
|
|
246
|
+
# Execute the operation
|
|
247
|
+
if asyncio.iscoroutinefunction(operation_func):
|
|
248
|
+
result = await operation_func(*args, **kwargs)
|
|
249
|
+
else:
|
|
250
|
+
result = operation_func(*args, **kwargs)
|
|
251
|
+
|
|
252
|
+
# Stop display if we started it
|
|
253
|
+
if display_started:
|
|
254
|
+
await self.stop_live_status_display()
|
|
255
|
+
|
|
256
|
+
return result
|
|
257
|
+
|
|
258
|
+
except Exception:
|
|
259
|
+
# Stop display if we started it
|
|
260
|
+
if display_started and self.status_listener:
|
|
261
|
+
await self.stop_live_status_display()
|
|
262
|
+
raise
|
|
263
|
+
|
|
264
|
+
def is_live_display_running(self) -> bool:
|
|
265
|
+
"""Check if live display is currently running."""
|
|
266
|
+
return (
|
|
267
|
+
self.status_listener is not None
|
|
268
|
+
and hasattr(self.status_listener, "live_display")
|
|
269
|
+
and self.status_listener.live_display is not None
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
async def get_quick_status(self) -> str:
|
|
273
|
+
"""Get a quick one-line status summary."""
|
|
274
|
+
try:
|
|
275
|
+
if not self.engine.is_status_display_enabled():
|
|
276
|
+
return "Status display disabled"
|
|
277
|
+
|
|
278
|
+
status_summary = await self.engine.get_status_summary()
|
|
279
|
+
|
|
280
|
+
if "error" in status_summary:
|
|
281
|
+
return f"Status error: {status_summary['error']}"
|
|
282
|
+
|
|
283
|
+
agent_id = status_summary.get("agent_id", "agent")
|
|
284
|
+
status = status_summary.get("status", "unknown")
|
|
285
|
+
active_ops = status_summary.get("active_operations_count", 0)
|
|
286
|
+
|
|
287
|
+
return f"{agent_id}: {status} ({active_ops} active operations)"
|
|
288
|
+
|
|
289
|
+
except Exception as e:
|
|
290
|
+
return f"Status unavailable: {e}"
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
class CLIStatusCommand:
|
|
294
|
+
"""
|
|
295
|
+
CLI command handler for status-related operations.
|
|
296
|
+
|
|
297
|
+
Provides subcommands for managing agent status display.
|
|
298
|
+
"""
|
|
299
|
+
|
|
300
|
+
def __init__(self, integration: CLIStatusIntegration):
|
|
301
|
+
"""
|
|
302
|
+
Initialize status command handler.
|
|
303
|
+
|
|
304
|
+
Args:
|
|
305
|
+
integration: CLI status integration instance
|
|
306
|
+
"""
|
|
307
|
+
self.integration = integration
|
|
308
|
+
self.console = integration.console
|
|
309
|
+
|
|
310
|
+
async def handle_command(self, args: List[str]) -> None:
|
|
311
|
+
"""
|
|
312
|
+
Handle status command with subcommands.
|
|
313
|
+
|
|
314
|
+
Args:
|
|
315
|
+
args: Command arguments
|
|
316
|
+
"""
|
|
317
|
+
if not args:
|
|
318
|
+
args = ["show"] # Default to show
|
|
319
|
+
|
|
320
|
+
subcommand = args[0].lower()
|
|
321
|
+
|
|
322
|
+
try:
|
|
323
|
+
if subcommand == "show":
|
|
324
|
+
detailed = "--detailed" in args or "-d" in args
|
|
325
|
+
await self.integration.show_status_snapshot(detailed)
|
|
326
|
+
|
|
327
|
+
elif subcommand == "start":
|
|
328
|
+
success = await self.integration.start_live_status_display()
|
|
329
|
+
if success:
|
|
330
|
+
self.console.print(
|
|
331
|
+
"[green]Live status display started. Press Ctrl+C to stop.[/green]"
|
|
332
|
+
)
|
|
333
|
+
try:
|
|
334
|
+
# Keep running until interrupted
|
|
335
|
+
while self.integration.is_live_display_running():
|
|
336
|
+
await asyncio.sleep(1)
|
|
337
|
+
except KeyboardInterrupt:
|
|
338
|
+
await self.integration.stop_live_status_display()
|
|
339
|
+
self.console.print(
|
|
340
|
+
"\n[yellow]Live status display stopped.[/yellow]"
|
|
341
|
+
)
|
|
342
|
+
|
|
343
|
+
elif subcommand == "stop":
|
|
344
|
+
await self.integration.stop_live_status_display()
|
|
345
|
+
|
|
346
|
+
elif subcommand == "quick":
|
|
347
|
+
status = await self.integration.get_quick_status()
|
|
348
|
+
self.console.print(status)
|
|
349
|
+
|
|
350
|
+
elif subcommand in ["help", "--help", "-h"]:
|
|
351
|
+
self._show_help()
|
|
352
|
+
|
|
353
|
+
else:
|
|
354
|
+
self.console.print(
|
|
355
|
+
f"[red]Unknown status subcommand: {subcommand}[/red]"
|
|
356
|
+
)
|
|
357
|
+
self._show_help()
|
|
358
|
+
|
|
359
|
+
except Exception as e:
|
|
360
|
+
logger.error(f"Status command failed: {e}")
|
|
361
|
+
self.console.print(f"[red]❌ Status command failed: {e}[/red]")
|
|
362
|
+
|
|
363
|
+
def _show_help(self) -> None:
|
|
364
|
+
"""Show help for status commands."""
|
|
365
|
+
help_text = """[bold]Status Commands:[/bold]
|
|
366
|
+
|
|
367
|
+
[cyan]/status show[/cyan] - Show current status snapshot
|
|
368
|
+
[cyan]/status show --detailed[/cyan] - Show detailed status information
|
|
369
|
+
[cyan]/status start[/cyan] - Start live status display
|
|
370
|
+
[cyan]/status stop[/cyan] - Stop live status display
|
|
371
|
+
[cyan]/status quick[/cyan] - Get quick one-line status
|
|
372
|
+
[cyan]/status help[/cyan] - Show this help message
|
|
373
|
+
|
|
374
|
+
[bold]Examples:[/bold]
|
|
375
|
+
[cyan]/status show -d[/cyan] - Show detailed status
|
|
376
|
+
[cyan]/status start[/cyan] - Start live monitoring
|
|
377
|
+
"""
|
|
378
|
+
|
|
379
|
+
self.console.print(
|
|
380
|
+
Panel(help_text, title="📊 Status Command Help", border_style="blue")
|
|
381
|
+
)
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
# Factory function for creating CLI integration
|
|
385
|
+
async def create_cli_status_integration(
|
|
386
|
+
config_manager: ConfigManager, console: Optional[Console] = None
|
|
387
|
+
) -> CLIStatusIntegration:
|
|
388
|
+
"""
|
|
389
|
+
Create a CLI status integration with a status-enhanced engine.
|
|
390
|
+
|
|
391
|
+
Args:
|
|
392
|
+
config_manager: Configuration manager
|
|
393
|
+
console: Rich console for output
|
|
394
|
+
|
|
395
|
+
Returns:
|
|
396
|
+
Configured CLI status integration
|
|
397
|
+
"""
|
|
398
|
+
try:
|
|
399
|
+
# Create status-integrated engine
|
|
400
|
+
engine = await create_status_integrated_engine(config_manager)
|
|
401
|
+
|
|
402
|
+
# Create CLI integration
|
|
403
|
+
integration = CLIStatusIntegration(engine, console)
|
|
404
|
+
|
|
405
|
+
logger.info("CLI status integration created successfully")
|
|
406
|
+
return integration
|
|
407
|
+
|
|
408
|
+
except Exception as e:
|
|
409
|
+
logger.error(f"Failed to create CLI status integration: {e}")
|
|
410
|
+
raise
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
# Utility function to add status integration to existing engines
|
|
414
|
+
def add_status_integration_to_engine(
|
|
415
|
+
engine, console: Optional[Console] = None
|
|
416
|
+
) -> CLIStatusIntegration:
|
|
417
|
+
"""
|
|
418
|
+
Add status integration to an existing engine (if it supports it).
|
|
419
|
+
|
|
420
|
+
Args:
|
|
421
|
+
engine: Existing engine instance
|
|
422
|
+
console: Rich console for output
|
|
423
|
+
|
|
424
|
+
Returns:
|
|
425
|
+
CLI status integration instance
|
|
426
|
+
"""
|
|
427
|
+
if isinstance(engine, StatusIntegratedAgentEngine):
|
|
428
|
+
return CLIStatusIntegration(engine, console)
|
|
429
|
+
else:
|
|
430
|
+
logger.warning(
|
|
431
|
+
f"Engine {type(engine).__name__} does not support status integration"
|
|
432
|
+
)
|
|
433
|
+
# Return a dummy integration that does nothing
|
|
434
|
+
return DummyCLIStatusIntegration(console)
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
class DummyCLIStatusIntegration:
|
|
438
|
+
"""Dummy implementation for engines that don't support status integration."""
|
|
439
|
+
|
|
440
|
+
def __init__(self, console: Optional[Console] = None):
|
|
441
|
+
self.console = console or Console()
|
|
442
|
+
|
|
443
|
+
async def start_live_status_display(self) -> bool:
|
|
444
|
+
self.console.print(
|
|
445
|
+
"[yellow]Status display not available for this engine[/yellow]"
|
|
446
|
+
)
|
|
447
|
+
return False
|
|
448
|
+
|
|
449
|
+
async def stop_live_status_display(self) -> bool:
|
|
450
|
+
return True
|
|
451
|
+
|
|
452
|
+
async def show_status_snapshot(self, detailed: bool = False) -> None:
|
|
453
|
+
self.console.print(
|
|
454
|
+
"[yellow]Status information not available for this engine[/yellow]"
|
|
455
|
+
)
|
|
456
|
+
|
|
457
|
+
async def execute_with_status_display(
|
|
458
|
+
self, operation_func: Callable, *args, **kwargs
|
|
459
|
+
) -> Any:
|
|
460
|
+
# Just execute without status display
|
|
461
|
+
if asyncio.iscoroutinefunction(operation_func):
|
|
462
|
+
return await operation_func(*args, **kwargs)
|
|
463
|
+
else:
|
|
464
|
+
return operation_func(*args, **kwargs)
|
|
465
|
+
|
|
466
|
+
def is_live_display_running(self) -> bool:
|
|
467
|
+
return False
|
|
468
|
+
|
|
469
|
+
async def get_quick_status(self) -> str:
|
|
470
|
+
return "Status not available"
|