mcli-framework 7.12.2__py3-none-any.whl → 7.12.4__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.
Potentially problematic release.
This version of mcli-framework might be problematic. Click here for more details.
- mcli/app/__init__.py +0 -2
- mcli/app/commands_cmd.py +30 -26
- mcli/app/completion_helpers.py +5 -5
- mcli/app/init_cmd.py +10 -10
- mcli/app/lock_cmd.py +29 -24
- mcli/app/main.py +2 -8
- mcli/app/model/model.py +5 -10
- mcli/app/store_cmd.py +8 -8
- mcli/app/video/__init__.py +0 -2
- mcli/app/video/video.py +1 -14
- mcli/chat/chat.py +90 -108
- mcli/chat/command_rag.py +0 -4
- mcli/chat/enhanced_chat.py +32 -41
- mcli/chat/system_controller.py +37 -37
- mcli/chat/system_integration.py +4 -5
- mcli/cli.py +2 -3
- mcli/lib/api/api.py +4 -9
- mcli/lib/api/daemon_client.py +19 -20
- mcli/lib/api/daemon_client_local.py +1 -3
- mcli/lib/api/daemon_decorator.py +6 -6
- mcli/lib/api/mcli_decorators.py +4 -8
- mcli/lib/auth/__init__.py +0 -1
- mcli/lib/auth/auth.py +4 -5
- mcli/lib/auth/mcli_manager.py +7 -12
- mcli/lib/auth/token_util.py +5 -5
- mcli/lib/config/__init__.py +29 -1
- mcli/lib/config/config.py +0 -1
- mcli/lib/custom_commands.py +1 -1
- mcli/lib/discovery/command_discovery.py +15 -15
- mcli/lib/erd/erd.py +7 -7
- mcli/lib/files/files.py +1 -1
- mcli/lib/fs/__init__.py +31 -1
- mcli/lib/fs/fs.py +12 -13
- mcli/lib/lib.py +0 -1
- mcli/lib/logger/logger.py +7 -10
- mcli/lib/performance/optimizer.py +25 -27
- mcli/lib/performance/rust_bridge.py +22 -27
- mcli/lib/performance/uvloop_config.py +0 -1
- mcli/lib/pickles/__init__.py +0 -1
- mcli/lib/pickles/pickles.py +0 -2
- mcli/lib/secrets/commands.py +0 -2
- mcli/lib/secrets/manager.py +0 -1
- mcli/lib/secrets/repl.py +2 -3
- mcli/lib/secrets/store.py +1 -2
- mcli/lib/services/data_pipeline.py +34 -34
- mcli/lib/services/lsh_client.py +38 -40
- mcli/lib/shell/shell.py +2 -2
- mcli/lib/toml/__init__.py +0 -1
- mcli/lib/ui/styling.py +0 -1
- mcli/lib/ui/visual_effects.py +33 -41
- mcli/lib/watcher/watcher.py +0 -1
- mcli/ml/__init__.py +1 -1
- mcli/ml/api/__init__.py +1 -1
- mcli/ml/api/app.py +8 -9
- mcli/ml/api/middleware.py +10 -10
- mcli/ml/api/routers/__init__.py +1 -1
- mcli/ml/api/routers/admin_router.py +3 -3
- mcli/ml/api/routers/auth_router.py +17 -18
- mcli/ml/api/routers/backtest_router.py +2 -2
- mcli/ml/api/routers/data_router.py +2 -2
- mcli/ml/api/routers/model_router.py +14 -15
- mcli/ml/api/routers/monitoring_router.py +2 -2
- mcli/ml/api/routers/portfolio_router.py +2 -2
- mcli/ml/api/routers/prediction_router.py +10 -9
- mcli/ml/api/routers/trade_router.py +2 -2
- mcli/ml/api/routers/websocket_router.py +6 -7
- mcli/ml/api/schemas.py +2 -2
- mcli/ml/auth/__init__.py +1 -1
- mcli/ml/auth/auth_manager.py +22 -23
- mcli/ml/auth/models.py +17 -17
- mcli/ml/auth/permissions.py +17 -17
- mcli/ml/backtesting/__init__.py +1 -1
- mcli/ml/backtesting/backtest_engine.py +31 -35
- mcli/ml/backtesting/performance_metrics.py +12 -14
- mcli/ml/backtesting/run.py +1 -2
- mcli/ml/cache.py +35 -36
- mcli/ml/cli/__init__.py +1 -1
- mcli/ml/cli/main.py +21 -24
- mcli/ml/config/__init__.py +1 -1
- mcli/ml/config/settings.py +28 -29
- mcli/ml/configs/__init__.py +1 -1
- mcli/ml/configs/dvc_config.py +14 -15
- mcli/ml/configs/mlflow_config.py +12 -13
- mcli/ml/configs/mlops_manager.py +19 -21
- mcli/ml/dashboard/__init__.py +4 -4
- mcli/ml/dashboard/app.py +20 -30
- mcli/ml/dashboard/app_supabase.py +16 -19
- mcli/ml/dashboard/app_training.py +11 -14
- mcli/ml/dashboard/cli.py +2 -2
- mcli/ml/dashboard/common.py +2 -3
- mcli/ml/dashboard/components/__init__.py +1 -1
- mcli/ml/dashboard/components/charts.py +13 -11
- mcli/ml/dashboard/components/metrics.py +7 -7
- mcli/ml/dashboard/components/tables.py +12 -9
- mcli/ml/dashboard/overview.py +2 -2
- mcli/ml/dashboard/pages/__init__.py +1 -1
- mcli/ml/dashboard/pages/cicd.py +15 -18
- mcli/ml/dashboard/pages/debug_dependencies.py +7 -7
- mcli/ml/dashboard/pages/monte_carlo_predictions.py +11 -18
- mcli/ml/dashboard/pages/predictions_enhanced.py +24 -32
- mcli/ml/dashboard/pages/scrapers_and_logs.py +22 -24
- mcli/ml/dashboard/pages/test_portfolio.py +3 -6
- mcli/ml/dashboard/pages/trading.py +16 -18
- mcli/ml/dashboard/pages/workflows.py +20 -30
- mcli/ml/dashboard/utils.py +9 -9
- mcli/ml/dashboard/warning_suppression.py +3 -3
- mcli/ml/data_ingestion/__init__.py +1 -1
- mcli/ml/data_ingestion/api_connectors.py +41 -46
- mcli/ml/data_ingestion/data_pipeline.py +36 -46
- mcli/ml/data_ingestion/stream_processor.py +43 -46
- mcli/ml/database/__init__.py +1 -1
- mcli/ml/database/migrations/env.py +2 -2
- mcli/ml/database/models.py +22 -24
- mcli/ml/database/session.py +14 -14
- mcli/ml/experimentation/__init__.py +1 -1
- mcli/ml/experimentation/ab_testing.py +45 -46
- mcli/ml/features/__init__.py +1 -1
- mcli/ml/features/ensemble_features.py +22 -27
- mcli/ml/features/recommendation_engine.py +30 -30
- mcli/ml/features/stock_features.py +29 -32
- mcli/ml/features/test_feature_engineering.py +10 -11
- mcli/ml/logging.py +4 -4
- mcli/ml/mlops/__init__.py +1 -1
- mcli/ml/mlops/data_versioning.py +29 -30
- mcli/ml/mlops/experiment_tracker.py +24 -24
- mcli/ml/mlops/model_serving.py +31 -34
- mcli/ml/mlops/pipeline_orchestrator.py +27 -35
- mcli/ml/models/__init__.py +5 -6
- mcli/ml/models/base_models.py +23 -23
- mcli/ml/models/ensemble_models.py +31 -31
- mcli/ml/models/recommendation_models.py +18 -19
- mcli/ml/models/test_models.py +14 -16
- mcli/ml/monitoring/__init__.py +1 -1
- mcli/ml/monitoring/drift_detection.py +32 -36
- mcli/ml/monitoring/metrics.py +2 -2
- mcli/ml/optimization/__init__.py +1 -1
- mcli/ml/optimization/optimize.py +1 -2
- mcli/ml/optimization/portfolio_optimizer.py +30 -32
- mcli/ml/predictions/__init__.py +1 -1
- mcli/ml/preprocessing/__init__.py +1 -1
- mcli/ml/preprocessing/data_cleaners.py +22 -23
- mcli/ml/preprocessing/feature_extractors.py +23 -26
- mcli/ml/preprocessing/ml_pipeline.py +23 -23
- mcli/ml/preprocessing/test_preprocessing.py +7 -8
- mcli/ml/scripts/populate_sample_data.py +0 -4
- mcli/ml/serving/serve.py +1 -2
- mcli/ml/tasks.py +17 -17
- mcli/ml/tests/test_integration.py +29 -30
- mcli/ml/tests/test_training_dashboard.py +21 -21
- mcli/ml/trading/__init__.py +1 -1
- mcli/ml/trading/migrations.py +5 -5
- mcli/ml/trading/models.py +21 -23
- mcli/ml/trading/paper_trading.py +16 -13
- mcli/ml/trading/risk_management.py +17 -18
- mcli/ml/trading/trading_service.py +25 -28
- mcli/ml/training/__init__.py +1 -1
- mcli/ml/training/train.py +0 -1
- mcli/public/oi/oi.py +1 -2
- mcli/self/completion_cmd.py +6 -10
- mcli/self/logs_cmd.py +19 -24
- mcli/self/migrate_cmd.py +22 -20
- mcli/self/redis_cmd.py +10 -11
- mcli/self/self_cmd.py +10 -18
- mcli/self/store_cmd.py +10 -12
- mcli/self/visual_cmd.py +9 -14
- mcli/self/zsh_cmd.py +2 -4
- mcli/workflow/daemon/async_command_database.py +23 -24
- mcli/workflow/daemon/async_process_manager.py +27 -29
- mcli/workflow/daemon/client.py +27 -33
- mcli/workflow/daemon/daemon.py +32 -36
- mcli/workflow/daemon/enhanced_daemon.py +24 -33
- mcli/workflow/daemon/process_cli.py +11 -12
- mcli/workflow/daemon/process_manager.py +23 -26
- mcli/workflow/daemon/test_daemon.py +4 -5
- mcli/workflow/dashboard/dashboard_cmd.py +0 -1
- mcli/workflow/doc_convert.py +15 -17
- mcli/workflow/gcloud/__init__.py +0 -1
- mcli/workflow/gcloud/gcloud.py +11 -8
- mcli/workflow/git_commit/ai_service.py +14 -15
- mcli/workflow/lsh_integration.py +9 -11
- mcli/workflow/model_service/client.py +26 -31
- mcli/workflow/model_service/download_and_run_efficient_models.py +10 -14
- mcli/workflow/model_service/lightweight_embedder.py +25 -35
- mcli/workflow/model_service/lightweight_model_server.py +26 -32
- mcli/workflow/model_service/lightweight_test.py +7 -10
- mcli/workflow/model_service/model_service.py +80 -91
- mcli/workflow/model_service/ollama_efficient_runner.py +14 -18
- mcli/workflow/model_service/openai_adapter.py +23 -23
- mcli/workflow/model_service/pdf_processor.py +21 -26
- mcli/workflow/model_service/test_efficient_runner.py +12 -16
- mcli/workflow/model_service/test_example.py +11 -13
- mcli/workflow/model_service/test_integration.py +3 -5
- mcli/workflow/model_service/test_new_features.py +7 -8
- mcli/workflow/notebook/converter.py +1 -1
- mcli/workflow/notebook/notebook_cmd.py +5 -6
- mcli/workflow/notebook/schema.py +0 -1
- mcli/workflow/notebook/validator.py +7 -3
- mcli/workflow/openai/openai.py +1 -2
- mcli/workflow/registry/registry.py +4 -1
- mcli/workflow/repo/repo.py +6 -7
- mcli/workflow/scheduler/cron_parser.py +16 -19
- mcli/workflow/scheduler/job.py +10 -10
- mcli/workflow/scheduler/monitor.py +15 -15
- mcli/workflow/scheduler/persistence.py +17 -18
- mcli/workflow/scheduler/scheduler.py +37 -38
- mcli/workflow/secrets/__init__.py +1 -1
- mcli/workflow/sync/test_cmd.py +0 -1
- mcli/workflow/wakatime/__init__.py +5 -9
- mcli/workflow/wakatime/wakatime.py +1 -2
- {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/METADATA +1 -1
- mcli_framework-7.12.4.dist-info/RECORD +279 -0
- mcli_framework-7.12.2.dist-info/RECORD +0 -279
- {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/WHEEL +0 -0
- {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/entry_points.txt +0 -0
- {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/licenses/LICENSE +0 -0
- {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/top_level.txt +0 -0
mcli/chat/chat.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import re
|
|
2
|
+
from pathlib import Path
|
|
3
3
|
from typing import Dict, List, Optional
|
|
4
4
|
|
|
5
5
|
import requests
|
|
@@ -51,7 +51,7 @@ logger = get_logger(__name__)
|
|
|
51
51
|
# Fallbacks if not set in config.toml
|
|
52
52
|
LLM_PROVIDER = config.get("provider", "local")
|
|
53
53
|
MODEL_NAME = config.get("model", "prajjwal1/bert-tiny") # Default to lightweight model
|
|
54
|
-
OPENAI_API_KEY = config.get("openai_api_key"
|
|
54
|
+
OPENAI_API_KEY = config.get("openai_api_key")
|
|
55
55
|
OLLAMA_BASE_URL = config.get(
|
|
56
56
|
"ollama_base_url", "http://localhost:8080"
|
|
57
57
|
) # Default to lightweight server
|
|
@@ -79,7 +79,7 @@ I'm designed to be your digital assistant that keeps things running smoothly."""
|
|
|
79
79
|
|
|
80
80
|
|
|
81
81
|
class ChatClient:
|
|
82
|
-
"""Interactive chat client for MCLI command management"""
|
|
82
|
+
"""Interactive chat client for MCLI command management."""
|
|
83
83
|
|
|
84
84
|
def __init__(self, use_remote: bool = False, model_override: str = None):
|
|
85
85
|
self.daemon = get_daemon_client()
|
|
@@ -92,7 +92,7 @@ class ChatClient:
|
|
|
92
92
|
self._load_scheduled_jobs()
|
|
93
93
|
|
|
94
94
|
def _configure_model_settings(self):
|
|
95
|
-
"""Configure model settings based on remote/local preferences"""
|
|
95
|
+
"""Configure model settings based on remote/local preferences."""
|
|
96
96
|
global LLM_PROVIDER, MODEL_NAME, OLLAMA_BASE_URL
|
|
97
97
|
|
|
98
98
|
if not self.use_remote:
|
|
@@ -115,7 +115,7 @@ class ChatClient:
|
|
|
115
115
|
# Keep existing provider settings from config
|
|
116
116
|
|
|
117
117
|
def _ensure_lightweight_model_server(self):
|
|
118
|
-
"""Ensure the lightweight model server is running"""
|
|
118
|
+
"""Ensure the lightweight model server is running."""
|
|
119
119
|
import time
|
|
120
120
|
|
|
121
121
|
import requests
|
|
@@ -139,10 +139,10 @@ class ChatClient:
|
|
|
139
139
|
f"[yellow]Model {MODEL_NAME} not loaded, will auto-load on first use[/yellow]"
|
|
140
140
|
)
|
|
141
141
|
return # Server will auto-load model when needed
|
|
142
|
-
except:
|
|
142
|
+
except Exception:
|
|
143
143
|
# If we can't check models, assume server will handle it
|
|
144
144
|
return
|
|
145
|
-
except:
|
|
145
|
+
except Exception:
|
|
146
146
|
pass
|
|
147
147
|
|
|
148
148
|
# Try to start the server automatically
|
|
@@ -173,7 +173,7 @@ class ChatClient:
|
|
|
173
173
|
|
|
174
174
|
# Wait longer for server to start and verify it's working
|
|
175
175
|
max_retries = 10
|
|
176
|
-
for
|
|
176
|
+
for _i in range(max_retries):
|
|
177
177
|
time.sleep(1)
|
|
178
178
|
try:
|
|
179
179
|
response = requests.get(f"{OLLAMA_BASE_URL}/health", timeout=1)
|
|
@@ -182,10 +182,10 @@ class ChatClient:
|
|
|
182
182
|
f"[green]✅ Lightweight model server started with {model_name}[/green]"
|
|
183
183
|
)
|
|
184
184
|
return
|
|
185
|
-
except:
|
|
185
|
+
except Exception:
|
|
186
186
|
pass
|
|
187
187
|
|
|
188
|
-
console.print(
|
|
188
|
+
console.print("[yellow]⚠️ Server started but health check failed[/yellow]")
|
|
189
189
|
console.print("Falling back to remote models...")
|
|
190
190
|
self.use_remote = True
|
|
191
191
|
else:
|
|
@@ -199,7 +199,7 @@ class ChatClient:
|
|
|
199
199
|
self.use_remote = True
|
|
200
200
|
|
|
201
201
|
def start_interactive_session(self):
|
|
202
|
-
"""Start the chat interface"""
|
|
202
|
+
"""Start the chat interface."""
|
|
203
203
|
console.print("[bold green]MCLI Personal Assistant[/bold green] (type 'exit' to quit)")
|
|
204
204
|
|
|
205
205
|
# Show current configuration
|
|
@@ -250,7 +250,7 @@ class ChatClient:
|
|
|
250
250
|
console.print(f"[red]Error:[/red] {str(e)}")
|
|
251
251
|
|
|
252
252
|
def process_input(self, user_input: str):
|
|
253
|
-
"""Process user input and generate response"""
|
|
253
|
+
"""Process user input and generate response."""
|
|
254
254
|
self.history.append({"user": user_input})
|
|
255
255
|
|
|
256
256
|
# Check for commands list request
|
|
@@ -383,7 +383,6 @@ class ChatClient:
|
|
|
383
383
|
return "hello"
|
|
384
384
|
|
|
385
385
|
# Try to extract command name using common patterns
|
|
386
|
-
import re
|
|
387
386
|
|
|
388
387
|
patterns = [
|
|
389
388
|
r"(?:call|execute|run)\s+(?:the\s+)?([a-zA-Z0-9\-_]+)(?:\s+command)?",
|
|
@@ -413,11 +412,11 @@ class ChatClient:
|
|
|
413
412
|
# For the hello command, we need to call it appropriately
|
|
414
413
|
if command.name == "hello" and command.full_name.startswith("self."):
|
|
415
414
|
# This is the hello command from self module - call with default argument
|
|
416
|
-
|
|
417
|
-
console.print(
|
|
415
|
+
command.callback("World")
|
|
416
|
+
console.print("[green]✅ Command executed successfully[/green]")
|
|
418
417
|
else:
|
|
419
|
-
|
|
420
|
-
console.print(
|
|
418
|
+
command.callback()
|
|
419
|
+
console.print("[green]✅ Command executed successfully[/green]")
|
|
421
420
|
else:
|
|
422
421
|
console.print("[yellow]Command found but has no callback[/yellow]")
|
|
423
422
|
except Exception as e:
|
|
@@ -430,16 +429,16 @@ class ChatClient:
|
|
|
430
429
|
console.print(f"[red]Error finding command:[/red] {e}")
|
|
431
430
|
|
|
432
431
|
def handle_command_queries(self, query: str):
|
|
433
|
-
"""Handle command-related queries using existing command registry"""
|
|
432
|
+
"""Handle command-related queries using existing command registry."""
|
|
434
433
|
try:
|
|
435
434
|
# Always fetch all commands (active and inactive)
|
|
436
435
|
result = self.daemon.list_commands(all=True)
|
|
437
436
|
if isinstance(result, dict):
|
|
438
|
-
|
|
437
|
+
result.get("commands", [])
|
|
439
438
|
elif isinstance(result, list):
|
|
440
|
-
|
|
439
|
+
pass
|
|
441
440
|
else:
|
|
442
|
-
|
|
441
|
+
pass
|
|
443
442
|
except Exception as e:
|
|
444
443
|
logger.debug(
|
|
445
444
|
f"Could not fetch commands from daemon: {e}. Falling back to LLM-only mode."
|
|
@@ -466,7 +465,7 @@ class ChatClient:
|
|
|
466
465
|
self.generate_llm_response(query)
|
|
467
466
|
|
|
468
467
|
def list_commands(self, commands: List[Dict] = None):
|
|
469
|
-
"""List available commands"""
|
|
468
|
+
"""List available commands."""
|
|
470
469
|
if commands is None:
|
|
471
470
|
# Use discovery system to get all commands
|
|
472
471
|
try:
|
|
@@ -505,7 +504,7 @@ class ChatClient:
|
|
|
505
504
|
console.print("[dim]Use 'mcli commands list' to see all commands[/dim]")
|
|
506
505
|
|
|
507
506
|
def search_commands(self, query: str, commands: List[Dict] = None):
|
|
508
|
-
"""Search commands based on query"""
|
|
507
|
+
"""Search commands based on query."""
|
|
509
508
|
search_term = query.lower().replace("search", "").replace("find", "").strip()
|
|
510
509
|
|
|
511
510
|
if commands is None:
|
|
@@ -548,7 +547,7 @@ class ChatClient:
|
|
|
548
547
|
console.print(f"[dim]... and {len(results) - 10} more results[/dim]")
|
|
549
548
|
|
|
550
549
|
def handle_commands_list(self):
|
|
551
|
-
"""Handle 'commands' command to list available functions"""
|
|
550
|
+
"""Handle 'commands' command to list available functions."""
|
|
552
551
|
try:
|
|
553
552
|
# Get commands from daemon
|
|
554
553
|
if hasattr(self.daemon, "list_commands"):
|
|
@@ -560,7 +559,7 @@ class ChatClient:
|
|
|
560
559
|
|
|
561
560
|
console.print(f"[bold green]Available Commands ({len(commands)}):[/bold green]")
|
|
562
561
|
|
|
563
|
-
for
|
|
562
|
+
for _i, cmd in enumerate(commands[:20]): # Show first 20 commands
|
|
564
563
|
name = cmd.get("name", "Unknown")
|
|
565
564
|
description = cmd.get("description", cmd.get("help", "No description"))
|
|
566
565
|
|
|
@@ -597,7 +596,7 @@ class ChatClient:
|
|
|
597
596
|
console.print("• [cyan]start/stop <id>[/cyan] - Control process lifecycle")
|
|
598
597
|
|
|
599
598
|
def handle_process_list(self):
|
|
600
|
-
"""Handle 'ps' command to list running processes"""
|
|
599
|
+
"""Handle 'ps' command to list running processes."""
|
|
601
600
|
try:
|
|
602
601
|
import requests
|
|
603
602
|
|
|
@@ -627,7 +626,7 @@ class ChatClient:
|
|
|
627
626
|
console.print(f"[red]Error connecting to daemon: {e}[/red]")
|
|
628
627
|
|
|
629
628
|
def handle_process_logs(self, process_id: str):
|
|
630
|
-
"""Handle 'logs' command to show process logs"""
|
|
629
|
+
"""Handle 'logs' command to show process logs."""
|
|
631
630
|
try:
|
|
632
631
|
import requests
|
|
633
632
|
|
|
@@ -651,7 +650,7 @@ class ChatClient:
|
|
|
651
650
|
console.print(f"[red]Error connecting to daemon: {e}[/red]")
|
|
652
651
|
|
|
653
652
|
def handle_process_inspect(self, process_id: str):
|
|
654
|
-
"""Handle 'inspect' command to show detailed process info"""
|
|
653
|
+
"""Handle 'inspect' command to show detailed process info."""
|
|
655
654
|
try:
|
|
656
655
|
import requests
|
|
657
656
|
|
|
@@ -682,7 +681,7 @@ class ChatClient:
|
|
|
682
681
|
console.print(f"[red]Error connecting to daemon: {e}[/red]")
|
|
683
682
|
|
|
684
683
|
def handle_process_stop(self, process_id: str):
|
|
685
|
-
"""Handle 'stop' command to stop a process"""
|
|
684
|
+
"""Handle 'stop' command to stop a process."""
|
|
686
685
|
try:
|
|
687
686
|
import requests
|
|
688
687
|
|
|
@@ -699,7 +698,7 @@ class ChatClient:
|
|
|
699
698
|
console.print(f"[red]Error connecting to daemon: {e}[/red]")
|
|
700
699
|
|
|
701
700
|
def handle_process_start(self, process_id: str):
|
|
702
|
-
"""Handle 'start' command to start a process"""
|
|
701
|
+
"""Handle 'start' command to start a process."""
|
|
703
702
|
try:
|
|
704
703
|
import requests
|
|
705
704
|
|
|
@@ -716,7 +715,7 @@ class ChatClient:
|
|
|
716
715
|
console.print(f"[red]Error connecting to daemon: {e}[/red]")
|
|
717
716
|
|
|
718
717
|
def handle_containerized_run(self, command: str, args: List[str]):
|
|
719
|
-
"""Handle 'run' command to execute in a containerized process"""
|
|
718
|
+
"""Handle 'run' command to execute in a containerized process."""
|
|
720
719
|
try:
|
|
721
720
|
import requests
|
|
722
721
|
|
|
@@ -755,7 +754,7 @@ class ChatClient:
|
|
|
755
754
|
)
|
|
756
755
|
console.print("Use 'logs <id>' to view output or 'ps' to see status")
|
|
757
756
|
else:
|
|
758
|
-
console.print(
|
|
757
|
+
console.print("[red]Failed to start containerized command[/red]")
|
|
759
758
|
return
|
|
760
759
|
except Exception:
|
|
761
760
|
pass # Fall through to shell command execution
|
|
@@ -773,13 +772,13 @@ class ChatClient:
|
|
|
773
772
|
)
|
|
774
773
|
console.print("Use 'logs <id>' to view output or 'ps' to see status")
|
|
775
774
|
else:
|
|
776
|
-
console.print(
|
|
775
|
+
console.print("[red]Failed to start containerized process[/red]")
|
|
777
776
|
|
|
778
777
|
except Exception as e:
|
|
779
778
|
console.print(f"[red]Error connecting to daemon: {e}[/red]")
|
|
780
779
|
|
|
781
780
|
def _ensure_daemon_running(self):
|
|
782
|
-
"""Ensure the API daemon is running, start it if not"""
|
|
781
|
+
"""Ensure the API daemon is running, start it if not."""
|
|
783
782
|
try:
|
|
784
783
|
if not self.daemon.is_running():
|
|
785
784
|
console.print("[yellow]Starting MCLI daemon...[/yellow]")
|
|
@@ -813,7 +812,7 @@ class ChatClient:
|
|
|
813
812
|
console.print("[yellow]Try starting manually: mcli workflow api-daemon start[/yellow]")
|
|
814
813
|
|
|
815
814
|
def _pull_model_if_needed(self, model_name: str):
|
|
816
|
-
"""Pull the model from Ollama if it doesn't exist locally"""
|
|
815
|
+
"""Pull the model from Ollama if it doesn't exist locally."""
|
|
817
816
|
try:
|
|
818
817
|
console.print(
|
|
819
818
|
f"[yellow]Downloading model '{model_name}'. This may take a few minutes...[/yellow]"
|
|
@@ -844,7 +843,7 @@ class ChatClient:
|
|
|
844
843
|
console.print(f"[red]❌ Error downloading model '{model_name}': {e}[/red]")
|
|
845
844
|
|
|
846
845
|
def generate_llm_response(self, query: str):
|
|
847
|
-
"""Generate response using LLM integration"""
|
|
846
|
+
"""Generate response using LLM integration."""
|
|
848
847
|
try:
|
|
849
848
|
# Try to get all commands, including inactive
|
|
850
849
|
try:
|
|
@@ -858,7 +857,7 @@ class ChatClient:
|
|
|
858
857
|
except Exception:
|
|
859
858
|
commands = []
|
|
860
859
|
|
|
861
|
-
|
|
860
|
+
_command_context = ( # noqa: F841
|
|
862
861
|
"\n".join(
|
|
863
862
|
f"Command: {cmd['name']}\nDescription: {cmd.get('description', '')}\nTags: {', '.join(cmd.get('tags', []))}\nStatus: {'INACTIVE' if not cmd.get('is_active', True) else 'ACTIVE'}"
|
|
864
863
|
for cmd in commands
|
|
@@ -883,7 +882,7 @@ class ChatClient:
|
|
|
883
882
|
)
|
|
884
883
|
|
|
885
884
|
if is_creation_request:
|
|
886
|
-
prompt =
|
|
885
|
+
prompt = """{SYSTEM_PROMPT}
|
|
887
886
|
|
|
888
887
|
IMPORTANT CONTEXT:
|
|
889
888
|
- Available MCLI Commands: {command_context}
|
|
@@ -903,7 +902,7 @@ This is a command creation request. You must:
|
|
|
903
902
|
|
|
904
903
|
NEVER suggest commands that don't exist. ALWAYS create new code for missing functionality."""
|
|
905
904
|
else:
|
|
906
|
-
prompt =
|
|
905
|
+
prompt = """{SYSTEM_PROMPT}
|
|
907
906
|
|
|
908
907
|
AVAILABLE MCLI COMMANDS:
|
|
909
908
|
{command_context}
|
|
@@ -954,7 +953,6 @@ Respond naturally and helpfully, considering both MCLI commands and system contr
|
|
|
954
953
|
content = response.get("response", "")
|
|
955
954
|
|
|
956
955
|
# Clean up response like we do for OpenAI
|
|
957
|
-
import re
|
|
958
956
|
|
|
959
957
|
split_patterns = [
|
|
960
958
|
r"\n2\.",
|
|
@@ -994,7 +992,6 @@ Respond naturally and helpfully, considering both MCLI commands and system contr
|
|
|
994
992
|
},
|
|
995
993
|
)
|
|
996
994
|
content = response.get("response", "")
|
|
997
|
-
import re
|
|
998
995
|
|
|
999
996
|
split_patterns = [
|
|
1000
997
|
r"\n2\.",
|
|
@@ -1034,7 +1031,6 @@ Respond naturally and helpfully, considering both MCLI commands and system contr
|
|
|
1034
1031
|
},
|
|
1035
1032
|
)
|
|
1036
1033
|
content = response.get("response", "")
|
|
1037
|
-
import re
|
|
1038
1034
|
|
|
1039
1035
|
split_patterns = [
|
|
1040
1036
|
r"\n2\.",
|
|
@@ -1059,7 +1055,7 @@ Respond naturally and helpfully, considering both MCLI commands and system contr
|
|
|
1059
1055
|
else:
|
|
1060
1056
|
raise Exception(f"Ollama API error: {e}")
|
|
1061
1057
|
|
|
1062
|
-
except (requests.exceptions.ConnectionError, ollama.RequestError if OLLAMA_AVAILABLE else Exception): # type: ignore
|
|
1058
|
+
except (requests.exceptions.ConnectionError, ollama.RequestError if OLLAMA_AVAILABLE else Exception): # type: ignore # noqa: B030
|
|
1063
1059
|
console.print(
|
|
1064
1060
|
"[red]Could not connect to Ollama. Please ensure Ollama is running:[/red]"
|
|
1065
1061
|
)
|
|
@@ -1072,7 +1068,7 @@ Respond naturally and helpfully, considering both MCLI commands and system contr
|
|
|
1072
1068
|
"[yellow]Request timed out. The model might be processing a complex query.[/yellow]"
|
|
1073
1069
|
)
|
|
1074
1070
|
return
|
|
1075
|
-
except Exception
|
|
1071
|
+
except Exception:
|
|
1076
1072
|
raise
|
|
1077
1073
|
|
|
1078
1074
|
elif LLM_PROVIDER == "openai":
|
|
@@ -1093,7 +1089,6 @@ Respond naturally and helpfully, considering both MCLI commands and system contr
|
|
|
1093
1089
|
# Only print the first section (natural language answer) before any markdown/code block
|
|
1094
1090
|
content = response.choices[0].message.content
|
|
1095
1091
|
# Split on '```' or '2.' or 'Relevant commands' to avoid printing command/code blocks
|
|
1096
|
-
import re
|
|
1097
1092
|
|
|
1098
1093
|
# Try to split on numbered sections or code block
|
|
1099
1094
|
split_patterns = [
|
|
@@ -1110,13 +1105,13 @@ Respond naturally and helpfully, considering both MCLI commands and system contr
|
|
|
1110
1105
|
split_idx = min(split_idx, m.start())
|
|
1111
1106
|
main_answer = content[:split_idx].strip()
|
|
1112
1107
|
return console.print(main_answer)
|
|
1113
|
-
except Exception
|
|
1108
|
+
except Exception:
|
|
1114
1109
|
raise
|
|
1115
1110
|
|
|
1116
1111
|
elif LLM_PROVIDER == "anthropic":
|
|
1117
1112
|
from anthropic import Anthropic
|
|
1118
1113
|
|
|
1119
|
-
api_key = config.get("anthropic_api_key"
|
|
1114
|
+
api_key = config.get("anthropic_api_key")
|
|
1120
1115
|
client = Anthropic(api_key=api_key)
|
|
1121
1116
|
try:
|
|
1122
1117
|
response = client.messages.create(
|
|
@@ -1127,7 +1122,7 @@ Respond naturally and helpfully, considering both MCLI commands and system contr
|
|
|
1127
1122
|
messages=[{"role": "user", "content": query}],
|
|
1128
1123
|
)
|
|
1129
1124
|
return console.print(response.content)
|
|
1130
|
-
except Exception
|
|
1125
|
+
except Exception:
|
|
1131
1126
|
raise
|
|
1132
1127
|
|
|
1133
1128
|
else:
|
|
@@ -1158,9 +1153,7 @@ Respond naturally and helpfully, considering both MCLI commands and system contr
|
|
|
1158
1153
|
r"\bhelp\s+me\s+create", # "help me create"
|
|
1159
1154
|
]
|
|
1160
1155
|
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
for pattern in creation_patterns:
|
|
1156
|
+
for pattern in creation_patterns: # noqa: SIM110
|
|
1164
1157
|
if re.search(pattern, lower_input):
|
|
1165
1158
|
return True
|
|
1166
1159
|
|
|
@@ -1208,7 +1201,6 @@ Respond naturally and helpfully, considering both MCLI commands and system contr
|
|
|
1208
1201
|
|
|
1209
1202
|
def validate_and_correct_response(self, response_text: str, available_commands: list) -> str:
|
|
1210
1203
|
"""Validate AI response and correct any hallucinated commands."""
|
|
1211
|
-
import re
|
|
1212
1204
|
|
|
1213
1205
|
# Extract command names from available commands
|
|
1214
1206
|
real_commands = set()
|
|
@@ -1276,9 +1268,6 @@ Respond naturally and helpfully, considering both MCLI commands and system contr
|
|
|
1276
1268
|
|
|
1277
1269
|
def _create_complete_command(self, user_input: str):
|
|
1278
1270
|
"""Create a complete working command with full automation."""
|
|
1279
|
-
import os
|
|
1280
|
-
import re
|
|
1281
|
-
from pathlib import Path
|
|
1282
1271
|
|
|
1283
1272
|
console.print("[bold blue]🤖 Starting automated command creation...[/bold blue]")
|
|
1284
1273
|
console.print()
|
|
@@ -1336,7 +1325,7 @@ Respond naturally and helpfully, considering both MCLI commands and system contr
|
|
|
1336
1325
|
except Exception:
|
|
1337
1326
|
commands = []
|
|
1338
1327
|
|
|
1339
|
-
|
|
1328
|
+
_command_context = ( # noqa: F841
|
|
1340
1329
|
"\n".join(
|
|
1341
1330
|
f"Command: {cmd['name']}\nDescription: {cmd.get('description', '')}"
|
|
1342
1331
|
for cmd in commands
|
|
@@ -1345,7 +1334,7 @@ Respond naturally and helpfully, considering both MCLI commands and system contr
|
|
|
1345
1334
|
else "(No command context available)"
|
|
1346
1335
|
)
|
|
1347
1336
|
|
|
1348
|
-
prompt =
|
|
1337
|
+
prompt = """You are creating a complete MCLI command. Generate ONLY the Python code with this exact structure:
|
|
1349
1338
|
|
|
1350
1339
|
COMMAND_NAME: [single word command name]
|
|
1351
1340
|
FILENAME: [snake_case_filename.py]
|
|
@@ -1389,7 +1378,6 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
1389
1378
|
|
|
1390
1379
|
def _parse_command_response(self, response: str) -> dict:
|
|
1391
1380
|
"""Parse AI response to extract command information."""
|
|
1392
|
-
import re
|
|
1393
1381
|
|
|
1394
1382
|
# Extract command name
|
|
1395
1383
|
name_match = re.search(r"COMMAND_NAME:\s*([a-zA-Z_][a-zA-Z0-9_-]*)", response)
|
|
@@ -1422,7 +1410,6 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
1422
1410
|
|
|
1423
1411
|
def _create_command_file(self, command_info: dict) -> str:
|
|
1424
1412
|
"""Create the command file in the appropriate directory."""
|
|
1425
|
-
from pathlib import Path
|
|
1426
1413
|
|
|
1427
1414
|
# Choose directory based on command type
|
|
1428
1415
|
base_dir = Path(__file__).parent.parent.parent # mcli src directory
|
|
@@ -1457,7 +1444,7 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
1457
1444
|
return False
|
|
1458
1445
|
|
|
1459
1446
|
def is_system_control_request(self, user_input: str) -> bool:
|
|
1460
|
-
"""Check if user input is requesting system control functionality"""
|
|
1447
|
+
"""Check if user input is requesting system control functionality."""
|
|
1461
1448
|
lower_input = user_input.lower()
|
|
1462
1449
|
|
|
1463
1450
|
# System control keywords
|
|
@@ -1547,9 +1534,7 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
1547
1534
|
r"\bclear\s+(cache|system)", # "clear cache" or "clear system"
|
|
1548
1535
|
]
|
|
1549
1536
|
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
for pattern in system_patterns:
|
|
1537
|
+
for pattern in system_patterns: # noqa: SIM110
|
|
1553
1538
|
if re.search(pattern, lower_input):
|
|
1554
1539
|
return True
|
|
1555
1540
|
|
|
@@ -1557,7 +1542,7 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
1557
1542
|
return any(keyword in lower_input for keyword in system_keywords)
|
|
1558
1543
|
|
|
1559
1544
|
def handle_system_control(self, user_input: str):
|
|
1560
|
-
"""Handle system control requests with intelligent reasoning and suggestions"""
|
|
1545
|
+
"""Handle system control requests with intelligent reasoning and suggestions."""
|
|
1561
1546
|
try:
|
|
1562
1547
|
console.print("[dim]🤖 Processing system control request...[/dim]")
|
|
1563
1548
|
|
|
@@ -1609,7 +1594,7 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
1609
1594
|
console.print(" • 'Close TextEdit'")
|
|
1610
1595
|
|
|
1611
1596
|
def _provide_intelligent_suggestions(self, user_input: str, result: dict):
|
|
1612
|
-
"""Provide intelligent suggestions based on system control results"""
|
|
1597
|
+
"""Provide intelligent suggestions based on system control results."""
|
|
1613
1598
|
try:
|
|
1614
1599
|
lower_input = user_input.lower()
|
|
1615
1600
|
data = result.get("data", {})
|
|
@@ -1630,12 +1615,12 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
1630
1615
|
elif "time" in lower_input:
|
|
1631
1616
|
self._suggest_time_actions(data)
|
|
1632
1617
|
|
|
1633
|
-
except Exception
|
|
1618
|
+
except Exception:
|
|
1634
1619
|
# Don't let suggestion errors break the main flow
|
|
1635
1620
|
pass
|
|
1636
1621
|
|
|
1637
1622
|
def _suggest_disk_cleanup(self, disk_data: dict):
|
|
1638
|
-
"""Suggest disk cleanup actions based on usage"""
|
|
1623
|
+
"""Suggest disk cleanup actions based on usage."""
|
|
1639
1624
|
if not disk_data:
|
|
1640
1625
|
return
|
|
1641
1626
|
|
|
@@ -1671,7 +1656,7 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
1671
1656
|
console.print(f" {suggestion}")
|
|
1672
1657
|
|
|
1673
1658
|
def _suggest_memory_optimization(self, memory_data: dict):
|
|
1674
|
-
"""Suggest memory optimization actions"""
|
|
1659
|
+
"""Suggest memory optimization actions."""
|
|
1675
1660
|
if not memory_data:
|
|
1676
1661
|
return
|
|
1677
1662
|
|
|
@@ -1696,7 +1681,7 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
1696
1681
|
console.print(f" {suggestion}")
|
|
1697
1682
|
|
|
1698
1683
|
def _suggest_system_actions(self, system_data: dict):
|
|
1699
|
-
"""Suggest system-related actions"""
|
|
1684
|
+
"""Suggest system-related actions."""
|
|
1700
1685
|
if not system_data:
|
|
1701
1686
|
return
|
|
1702
1687
|
|
|
@@ -1734,7 +1719,7 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
1734
1719
|
console.print(f" {suggestion}")
|
|
1735
1720
|
|
|
1736
1721
|
def _suggest_time_actions(self, time_data: dict):
|
|
1737
|
-
"""Suggest time-related actions"""
|
|
1722
|
+
"""Suggest time-related actions."""
|
|
1738
1723
|
if not time_data:
|
|
1739
1724
|
return
|
|
1740
1725
|
|
|
@@ -1756,7 +1741,7 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
1756
1741
|
elif 17 < hour < 22: # Evening
|
|
1757
1742
|
suggestions.append("🌆 Good evening! Wrapping up for the day?")
|
|
1758
1743
|
|
|
1759
|
-
except:
|
|
1744
|
+
except Exception:
|
|
1760
1745
|
pass
|
|
1761
1746
|
|
|
1762
1747
|
suggestions.append("I can also help you schedule tasks with the workflow system!")
|
|
@@ -1767,7 +1752,7 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
1767
1752
|
console.print(f" {suggestion}")
|
|
1768
1753
|
|
|
1769
1754
|
def _is_system_help_request(self, query: str) -> bool:
|
|
1770
|
-
"""Detect if this is a request for system help or cleanup"""
|
|
1755
|
+
"""Detect if this is a request for system help or cleanup."""
|
|
1771
1756
|
lower_query = query.lower()
|
|
1772
1757
|
|
|
1773
1758
|
help_patterns = [
|
|
@@ -1788,16 +1773,14 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
1788
1773
|
r"help me.*clean",
|
|
1789
1774
|
]
|
|
1790
1775
|
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
for pattern in help_patterns:
|
|
1776
|
+
for pattern in help_patterns: # noqa: SIM110
|
|
1794
1777
|
if re.search(pattern, lower_query):
|
|
1795
1778
|
return True
|
|
1796
1779
|
|
|
1797
1780
|
return False
|
|
1798
1781
|
|
|
1799
1782
|
def _handle_system_help_request(self, query: str):
|
|
1800
|
-
"""Handle requests for system help and cleanup"""
|
|
1783
|
+
"""Handle requests for system help and cleanup."""
|
|
1801
1784
|
lower_query = query.lower()
|
|
1802
1785
|
|
|
1803
1786
|
console.print("[dim]🤖 I can definitely help you with system cleanup![/dim]")
|
|
@@ -1846,7 +1829,7 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
1846
1829
|
)
|
|
1847
1830
|
|
|
1848
1831
|
def _load_scheduled_jobs(self):
|
|
1849
|
-
"""Load and start monitoring existing scheduled jobs"""
|
|
1832
|
+
"""Load and start monitoring existing scheduled jobs."""
|
|
1850
1833
|
try:
|
|
1851
1834
|
# Lazy import to avoid circular dependencies
|
|
1852
1835
|
from mcli.workflow.scheduler.job import JobStatus
|
|
@@ -1863,12 +1846,12 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
1863
1846
|
if active_count > 0:
|
|
1864
1847
|
console.print(f"[dim]📅 {active_count} scheduled jobs loaded[/dim]")
|
|
1865
1848
|
|
|
1866
|
-
except Exception
|
|
1849
|
+
except Exception:
|
|
1867
1850
|
# Silently handle import/loading errors at startup
|
|
1868
1851
|
pass
|
|
1869
1852
|
|
|
1870
1853
|
def _is_job_management_request(self, query: str) -> bool:
|
|
1871
|
-
"""Detect if this is a job/schedule management request"""
|
|
1854
|
+
"""Detect if this is a job/schedule management request."""
|
|
1872
1855
|
lower_query = query.lower()
|
|
1873
1856
|
|
|
1874
1857
|
job_patterns = [
|
|
@@ -1901,16 +1884,14 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
1901
1884
|
r".*completion.*",
|
|
1902
1885
|
]
|
|
1903
1886
|
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
for pattern in job_patterns:
|
|
1887
|
+
for pattern in job_patterns: # noqa: SIM110
|
|
1907
1888
|
if re.search(pattern, lower_query):
|
|
1908
1889
|
return True
|
|
1909
1890
|
|
|
1910
1891
|
return False
|
|
1911
1892
|
|
|
1912
1893
|
def _handle_job_management(self, query: str):
|
|
1913
|
-
"""Handle job scheduling and management requests"""
|
|
1894
|
+
"""Handle job scheduling and management requests."""
|
|
1914
1895
|
lower_query = query.lower()
|
|
1915
1896
|
|
|
1916
1897
|
console.print("[dim]🤖 Processing job management request...[/dim]")
|
|
@@ -1982,12 +1963,13 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
1982
1963
|
console.print(f"[red]❌ Error handling job request: {e}[/red]")
|
|
1983
1964
|
|
|
1984
1965
|
def _show_agent_status(self):
|
|
1985
|
-
"""Show comprehensive agent status including jobs, system state, and context"""
|
|
1966
|
+
"""Show comprehensive agent status including jobs, system state, and context."""
|
|
1986
1967
|
console.print("\n[bold cyan]🤖 Personal Assistant Status Report[/bold cyan]")
|
|
1987
1968
|
|
|
1988
1969
|
# Jobs and schedules
|
|
1989
1970
|
try:
|
|
1990
|
-
from mcli.workflow.scheduler.job import JobStatus
|
|
1971
|
+
from mcli.workflow.scheduler.job import JobStatus
|
|
1972
|
+
from mcli.workflow.scheduler.job import ScheduledJob as Job
|
|
1991
1973
|
from mcli.workflow.scheduler.persistence import JobStorage
|
|
1992
1974
|
|
|
1993
1975
|
job_storage = JobStorage()
|
|
@@ -2024,13 +2006,13 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
2024
2006
|
elif status == JobStatus.FAILED.value:
|
|
2025
2007
|
failed_jobs.append(job_dict)
|
|
2026
2008
|
|
|
2027
|
-
except Exception
|
|
2009
|
+
except Exception:
|
|
2028
2010
|
jobs = []
|
|
2029
2011
|
active_jobs = []
|
|
2030
2012
|
completed_jobs = []
|
|
2031
2013
|
failed_jobs = []
|
|
2032
2014
|
|
|
2033
|
-
console.print(
|
|
2015
|
+
console.print("\n[green]📅 Scheduled Jobs:[/green]")
|
|
2034
2016
|
if active_jobs:
|
|
2035
2017
|
for job_data in active_jobs[:5]: # Show first 5
|
|
2036
2018
|
try:
|
|
@@ -2053,7 +2035,7 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
2053
2035
|
|
|
2054
2036
|
# Recent activity
|
|
2055
2037
|
if completed_jobs or failed_jobs:
|
|
2056
|
-
console.print(
|
|
2038
|
+
console.print("\n[blue]📊 Recent Activity:[/blue]")
|
|
2057
2039
|
if completed_jobs:
|
|
2058
2040
|
console.print(f" ✅ {len(completed_jobs)} completed jobs")
|
|
2059
2041
|
if failed_jobs:
|
|
@@ -2067,7 +2049,7 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
2067
2049
|
memory_result = system_controller.get_memory_usage()
|
|
2068
2050
|
disk_result = system_controller.get_disk_usage()
|
|
2069
2051
|
|
|
2070
|
-
console.print(
|
|
2052
|
+
console.print("\n[yellow]💻 System Context:[/yellow]")
|
|
2071
2053
|
|
|
2072
2054
|
if memory_result.get("success"):
|
|
2073
2055
|
mem_data = memory_result["data"]["virtual_memory"]
|
|
@@ -2086,10 +2068,10 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
2086
2068
|
)
|
|
2087
2069
|
|
|
2088
2070
|
except Exception:
|
|
2089
|
-
console.print(
|
|
2071
|
+
console.print("\n[yellow]💻 System Context: Unable to get current status[/yellow]")
|
|
2090
2072
|
|
|
2091
2073
|
# Agent capabilities reminder
|
|
2092
|
-
console.print(
|
|
2074
|
+
console.print("\n[magenta]🛠️ I can help you with:[/magenta]")
|
|
2093
2075
|
console.print(" • System monitoring and cleanup")
|
|
2094
2076
|
console.print(" • Application control and automation")
|
|
2095
2077
|
console.print(" • Scheduled tasks and reminders")
|
|
@@ -2101,7 +2083,7 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
2101
2083
|
)
|
|
2102
2084
|
|
|
2103
2085
|
def _handle_job_scheduling(self, query: str):
|
|
2104
|
-
"""Handle requests to schedule new jobs"""
|
|
2086
|
+
"""Handle requests to schedule new jobs."""
|
|
2105
2087
|
console.print("[green]📅 Let me help you schedule that task![/green]")
|
|
2106
2088
|
|
|
2107
2089
|
# For now, provide guidance on scheduling
|
|
@@ -2124,9 +2106,10 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
2124
2106
|
)
|
|
2125
2107
|
|
|
2126
2108
|
def _handle_job_cancellation(self, query: str):
|
|
2127
|
-
"""Handle requests to cancel jobs"""
|
|
2109
|
+
"""Handle requests to cancel jobs."""
|
|
2128
2110
|
try:
|
|
2129
2111
|
from mcli.workflow.scheduler.job import JobStatus
|
|
2112
|
+
from mcli.workflow.scheduler.job import ScheduledJob as Job
|
|
2130
2113
|
from mcli.workflow.scheduler.persistence import JobStorage
|
|
2131
2114
|
|
|
2132
2115
|
job_storage = JobStorage()
|
|
@@ -2156,7 +2139,7 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
2156
2139
|
console.print("\n[dim]To cancel a specific job, use: 'cancel job [name]'[/dim]")
|
|
2157
2140
|
|
|
2158
2141
|
def _show_startup_status(self):
|
|
2159
|
-
"""Show proactive status update when assistant starts"""
|
|
2142
|
+
"""Show proactive status update when assistant starts."""
|
|
2160
2143
|
try:
|
|
2161
2144
|
# Quick system check
|
|
2162
2145
|
from mcli.chat.system_controller import system_controller
|
|
@@ -2215,11 +2198,11 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
2215
2198
|
else:
|
|
2216
2199
|
console.print("\n[green]🤖 All systems running smoothly![/green]")
|
|
2217
2200
|
|
|
2218
|
-
except Exception
|
|
2219
|
-
console.print(
|
|
2201
|
+
except Exception:
|
|
2202
|
+
console.print("\n[green]🤖 All systems running smoothly![/green]")
|
|
2220
2203
|
|
|
2221
2204
|
def _handle_cron_test(self, query: str):
|
|
2222
|
-
"""Handle cron test execution requests"""
|
|
2205
|
+
"""Handle cron test execution requests."""
|
|
2223
2206
|
console.print("[green]🕒 Running MCLI Cron Validation Test...[/green]")
|
|
2224
2207
|
|
|
2225
2208
|
try:
|
|
@@ -2247,7 +2230,7 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
2247
2230
|
# Show successful output
|
|
2248
2231
|
console.print(result.stdout)
|
|
2249
2232
|
else:
|
|
2250
|
-
console.print(
|
|
2233
|
+
console.print("[red]❌ Cron test failed:[/red]")
|
|
2251
2234
|
console.print(result.stderr if result.stderr else result.stdout)
|
|
2252
2235
|
|
|
2253
2236
|
except subprocess.TimeoutExpired:
|
|
@@ -2258,7 +2241,7 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
2258
2241
|
console.print(" mcli cron-test --quick --verbose")
|
|
2259
2242
|
|
|
2260
2243
|
def _show_failed_jobs(self):
|
|
2261
|
-
"""Show detailed information about failed jobs"""
|
|
2244
|
+
"""Show detailed information about failed jobs."""
|
|
2262
2245
|
console.print("[red]❌ Analyzing Failed Jobs...[/red]")
|
|
2263
2246
|
|
|
2264
2247
|
try:
|
|
@@ -2304,7 +2287,7 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
2304
2287
|
console.print(f"\n[dim]... and {len(failed_jobs) - 10} more failed jobs[/dim]")
|
|
2305
2288
|
|
|
2306
2289
|
# Show helpful actions
|
|
2307
|
-
console.print(
|
|
2290
|
+
console.print("\n[cyan]💡 Recommended Actions:[/cyan]")
|
|
2308
2291
|
console.print("• Check job commands and file paths")
|
|
2309
2292
|
console.print("• Verify system permissions")
|
|
2310
2293
|
console.print("• Review error messages above")
|
|
@@ -2314,11 +2297,10 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
2314
2297
|
console.print(f"[red]❌ Failed to analyze jobs: {e}[/red]")
|
|
2315
2298
|
|
|
2316
2299
|
def _show_job_completion_details(self):
|
|
2317
|
-
"""Show comprehensive job completion analysis"""
|
|
2300
|
+
"""Show comprehensive job completion analysis."""
|
|
2318
2301
|
console.print("[blue]📊 Job Completion Analysis...[/blue]")
|
|
2319
2302
|
|
|
2320
2303
|
try:
|
|
2321
|
-
from datetime import datetime, timedelta
|
|
2322
2304
|
|
|
2323
2305
|
from mcli.workflow.scheduler.job import JobStatus
|
|
2324
2306
|
from mcli.workflow.scheduler.persistence import JobStorage
|
|
@@ -2348,7 +2330,7 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
2348
2330
|
pending_jobs.append(job)
|
|
2349
2331
|
|
|
2350
2332
|
# Status summary
|
|
2351
|
-
console.print(
|
|
2333
|
+
console.print("\n[green]📈 Job Status Summary:[/green]")
|
|
2352
2334
|
console.print(f" ✅ Completed: {len(completed_jobs)}")
|
|
2353
2335
|
console.print(f" 🔄 Running: {len(running_jobs)}")
|
|
2354
2336
|
console.print(f" ❌ Failed: {len(failed_jobs)}")
|
|
@@ -2361,7 +2343,7 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
2361
2343
|
|
|
2362
2344
|
if total_runs > 0:
|
|
2363
2345
|
success_rate = total_successes / total_runs * 100
|
|
2364
|
-
console.print(
|
|
2346
|
+
console.print("\n[cyan]⚡ Performance Metrics:[/cyan]")
|
|
2365
2347
|
console.print(f" Total Executions: {total_runs}")
|
|
2366
2348
|
console.print(f" Success Rate: {success_rate:.1f}%")
|
|
2367
2349
|
console.print(f" Successful: {total_successes}")
|
|
@@ -2375,7 +2357,7 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
2375
2357
|
)[:5]
|
|
2376
2358
|
|
|
2377
2359
|
if recent_completed:
|
|
2378
|
-
console.print(
|
|
2360
|
+
console.print("\n[green]🎯 Recent Completions:[/green]")
|
|
2379
2361
|
for job in recent_completed:
|
|
2380
2362
|
runtime = (
|
|
2381
2363
|
f" ({job.runtime_seconds:.2f}s)"
|
|
@@ -2391,12 +2373,12 @@ Generate a working command that implements the requested functionality. Use prop
|
|
|
2391
2373
|
job_types[job_type] = job_types.get(job_type, 0) + 1
|
|
2392
2374
|
|
|
2393
2375
|
if job_types:
|
|
2394
|
-
console.print(
|
|
2376
|
+
console.print("\n[blue]📋 Job Types:[/blue]")
|
|
2395
2377
|
for job_type, count in sorted(job_types.items()):
|
|
2396
2378
|
console.print(f" {job_type}: {count} jobs")
|
|
2397
2379
|
|
|
2398
2380
|
# Helpful commands
|
|
2399
|
-
console.print(
|
|
2381
|
+
console.print("\n[yellow]🔧 Available Commands:[/yellow]")
|
|
2400
2382
|
console.print("• 'show failed jobs' - Analyze job failures")
|
|
2401
2383
|
console.print("• 'run cron test' - Validate cron system")
|
|
2402
2384
|
console.print("• 'cancel job <name>' - Remove specific job")
|