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/lib/erd/erd.py
CHANGED
|
@@ -86,7 +86,7 @@ class MCLITypeSystem:
|
|
|
86
86
|
attr = getattr(self.mcli_obj, attr_name)
|
|
87
87
|
if hasattr(attr, "meta") and callable(attr.meta):
|
|
88
88
|
type_names.append(attr_name)
|
|
89
|
-
except:
|
|
89
|
+
except Exception:
|
|
90
90
|
pass
|
|
91
91
|
return type_names
|
|
92
92
|
|
|
@@ -102,7 +102,7 @@ class MCLITypeSystem:
|
|
|
102
102
|
attr = getattr(pkg, attr_name)
|
|
103
103
|
if hasattr(attr, "meta") and callable(attr.meta):
|
|
104
104
|
type_names.append(f"{package_name}.{attr_name}")
|
|
105
|
-
except:
|
|
105
|
+
except Exception:
|
|
106
106
|
pass
|
|
107
107
|
except Exception:
|
|
108
108
|
pass
|
|
@@ -255,7 +255,7 @@ class ERD:
|
|
|
255
255
|
label_ = getattr(vt, "name", str(vt))
|
|
256
256
|
else:
|
|
257
257
|
label_ = str(field_metadata)
|
|
258
|
-
except:
|
|
258
|
+
except Exception:
|
|
259
259
|
label_ = str(field_metadata)
|
|
260
260
|
|
|
261
261
|
entries.append((name, label_))
|
|
@@ -435,9 +435,9 @@ def do_erd(max_depth=1, type_system: Optional[TypeSystem] = None):
|
|
|
435
435
|
if hasattr(sub_attr, "meta") and callable(sub_attr.meta):
|
|
436
436
|
packages.append(attr_name)
|
|
437
437
|
break
|
|
438
|
-
except:
|
|
438
|
+
except Exception:
|
|
439
439
|
pass
|
|
440
|
-
except:
|
|
440
|
+
except Exception:
|
|
441
441
|
pass
|
|
442
442
|
|
|
443
443
|
if packages:
|
|
@@ -487,9 +487,9 @@ def do_erd(max_depth=1, type_system: Optional[TypeSystem] = None):
|
|
|
487
487
|
):
|
|
488
488
|
packages.append(attr_name)
|
|
489
489
|
break
|
|
490
|
-
except:
|
|
490
|
+
except Exception:
|
|
491
491
|
pass
|
|
492
|
-
except:
|
|
492
|
+
except Exception:
|
|
493
493
|
pass
|
|
494
494
|
|
|
495
495
|
if packages:
|
mcli/lib/files/files.py
CHANGED
mcli/lib/fs/__init__.py
CHANGED
|
@@ -1 +1,31 @@
|
|
|
1
|
-
|
|
1
|
+
"""File system utilities for MCLI."""
|
|
2
|
+
|
|
3
|
+
from .fs import (
|
|
4
|
+
copy_file,
|
|
5
|
+
delete_directory,
|
|
6
|
+
delete_file,
|
|
7
|
+
ensure_directory_exists,
|
|
8
|
+
file_exists,
|
|
9
|
+
get_absolute_path,
|
|
10
|
+
get_file_size,
|
|
11
|
+
get_user_home,
|
|
12
|
+
list_files,
|
|
13
|
+
load_global_value,
|
|
14
|
+
read_line_from_file,
|
|
15
|
+
save_global_value,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
__all__ = [
|
|
19
|
+
"copy_file",
|
|
20
|
+
"delete_directory",
|
|
21
|
+
"delete_file",
|
|
22
|
+
"ensure_directory_exists",
|
|
23
|
+
"file_exists",
|
|
24
|
+
"get_absolute_path",
|
|
25
|
+
"get_file_size",
|
|
26
|
+
"get_user_home",
|
|
27
|
+
"list_files",
|
|
28
|
+
"load_global_value",
|
|
29
|
+
"read_line_from_file",
|
|
30
|
+
"save_global_value",
|
|
31
|
+
]
|
mcli/lib/fs/fs.py
CHANGED
|
@@ -6,45 +6,44 @@ Provides basic file system operations with path normalization
|
|
|
6
6
|
import json
|
|
7
7
|
import os
|
|
8
8
|
import shutil
|
|
9
|
-
from pathlib import Path
|
|
10
9
|
|
|
11
10
|
import click
|
|
12
11
|
|
|
13
12
|
|
|
14
13
|
def get_absolute_path(pth):
|
|
15
|
-
"""Convert path to absolute path with user expansion"""
|
|
14
|
+
"""Convert path to absolute path with user expansion."""
|
|
16
15
|
pth = os.path.expanduser(pth)
|
|
17
16
|
pth = os.path.abspath(pth)
|
|
18
17
|
return pth
|
|
19
18
|
|
|
20
19
|
|
|
21
20
|
def ensure_directory_exists(dirpath):
|
|
22
|
-
"""Create directory if it doesn't exist"""
|
|
21
|
+
"""Create directory if it doesn't exist."""
|
|
23
22
|
dirpath = get_absolute_path(dirpath)
|
|
24
23
|
os.makedirs(dirpath, exist_ok=True)
|
|
25
24
|
|
|
26
25
|
|
|
27
26
|
def delete_directory(dirpath):
|
|
28
|
-
"""Delete directory if it exists"""
|
|
27
|
+
"""Delete directory if it exists."""
|
|
29
28
|
dirpath = get_absolute_path(dirpath)
|
|
30
29
|
if os.path.exists(dirpath):
|
|
31
30
|
shutil.rmtree(dirpath) # Use rmtree for non-empty directories
|
|
32
31
|
|
|
33
32
|
|
|
34
33
|
def delete_file(filepath):
|
|
35
|
-
"""Delete file if it exists"""
|
|
34
|
+
"""Delete file if it exists."""
|
|
36
35
|
filepath = get_absolute_path(filepath)
|
|
37
36
|
if os.path.exists(filepath):
|
|
38
37
|
os.remove(filepath)
|
|
39
38
|
|
|
40
39
|
|
|
41
40
|
def get_user_home():
|
|
42
|
-
"""Get user home directory"""
|
|
41
|
+
"""Get user home directory."""
|
|
43
42
|
return os.path.expanduser("~")
|
|
44
43
|
|
|
45
44
|
|
|
46
45
|
def read_line_from_file(filepath):
|
|
47
|
-
"""Read first line from file"""
|
|
46
|
+
"""Read first line from file."""
|
|
48
47
|
filepath = get_absolute_path(filepath)
|
|
49
48
|
if not os.path.exists(filepath):
|
|
50
49
|
raise Exception("File does not exist at: " + filepath)
|
|
@@ -53,7 +52,7 @@ def read_line_from_file(filepath):
|
|
|
53
52
|
|
|
54
53
|
|
|
55
54
|
def copy_file(srcpath, dstpath):
|
|
56
|
-
"""Copy a file from source to destination"""
|
|
55
|
+
"""Copy a file from source to destination."""
|
|
57
56
|
srcpath = get_absolute_path(srcpath)
|
|
58
57
|
dstpath = get_absolute_path(dstpath)
|
|
59
58
|
if os.path.exists(srcpath):
|
|
@@ -65,13 +64,13 @@ def copy_file(srcpath, dstpath):
|
|
|
65
64
|
|
|
66
65
|
|
|
67
66
|
def file_exists(path):
|
|
68
|
-
"""Check if a file exists at the given path"""
|
|
67
|
+
"""Check if a file exists at the given path."""
|
|
69
68
|
path = get_absolute_path(path)
|
|
70
69
|
return os.path.exists(path)
|
|
71
70
|
|
|
72
71
|
|
|
73
72
|
def get_file_size(path):
|
|
74
|
-
"""Get the size of a file in bytes"""
|
|
73
|
+
"""Get the size of a file in bytes."""
|
|
75
74
|
path = get_absolute_path(path)
|
|
76
75
|
if file_exists(path):
|
|
77
76
|
return os.path.getsize(path)
|
|
@@ -79,7 +78,7 @@ def get_file_size(path):
|
|
|
79
78
|
|
|
80
79
|
|
|
81
80
|
def list_files(directory, pattern="*"):
|
|
82
|
-
"""List files in a directory matching a pattern"""
|
|
81
|
+
"""List files in a directory matching a pattern."""
|
|
83
82
|
import glob
|
|
84
83
|
|
|
85
84
|
directory = get_absolute_path(directory)
|
|
@@ -94,14 +93,14 @@ CONFIG_FILE = os.path.join(click.get_app_dir("mcli"), "config.json")
|
|
|
94
93
|
|
|
95
94
|
|
|
96
95
|
def save_global_value(value):
|
|
97
|
-
"""Save a global configuration value"""
|
|
96
|
+
"""Save a global configuration value."""
|
|
98
97
|
os.makedirs(os.path.dirname(CONFIG_FILE), exist_ok=True)
|
|
99
98
|
with open(CONFIG_FILE, "w") as f:
|
|
100
99
|
json.dump({"GLOBAL_VALUE": value}, f)
|
|
101
100
|
|
|
102
101
|
|
|
103
102
|
def load_global_value():
|
|
104
|
-
"""Load a global configuration value"""
|
|
103
|
+
"""Load a global configuration value."""
|
|
105
104
|
try:
|
|
106
105
|
with open(CONFIG_FILE, "r") as f:
|
|
107
106
|
return json.load(f).get("GLOBAL_VALUE")
|
mcli/lib/lib.py
CHANGED
mcli/lib/logger/logger.py
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
import inspect
|
|
2
2
|
import logging
|
|
3
3
|
import os
|
|
4
|
-
import platform
|
|
5
|
-
import signal
|
|
6
4
|
import subprocess
|
|
7
5
|
import sys
|
|
8
6
|
import threading
|
|
9
7
|
import time
|
|
10
8
|
import traceback
|
|
11
9
|
from datetime import datetime
|
|
12
|
-
from pathlib import Path
|
|
13
10
|
from types import FrameType
|
|
14
|
-
from typing import Any, Callable, Dict, List, Optional, Set
|
|
11
|
+
from typing import Any, Callable, Dict, List, Optional, Set
|
|
15
12
|
|
|
16
13
|
import psutil
|
|
17
14
|
|
|
@@ -163,7 +160,7 @@ class McliLogger:
|
|
|
163
160
|
Register a subprocess.Popen object for monitoring.
|
|
164
161
|
Returns the process ID if successful, 0 otherwise.
|
|
165
162
|
"""
|
|
166
|
-
if proc and proc.pid:
|
|
163
|
+
if proc and proc.pid: # noqa: SIM102
|
|
167
164
|
if cls.register_process(proc.pid):
|
|
168
165
|
return proc.pid
|
|
169
166
|
return 0
|
|
@@ -271,7 +268,7 @@ class McliLogger:
|
|
|
271
268
|
module_name = module_name[:-3]
|
|
272
269
|
|
|
273
270
|
# Skip excluded modules
|
|
274
|
-
for excluded in self._excluded_modules:
|
|
271
|
+
for excluded in self._excluded_modules: # noqa: SIM111
|
|
275
272
|
if module_name.startswith(excluded):
|
|
276
273
|
return False
|
|
277
274
|
|
|
@@ -459,7 +456,7 @@ class McliLogger:
|
|
|
459
456
|
if len(arg_val) > 100:
|
|
460
457
|
arg_val = arg_val[:97] + "..."
|
|
461
458
|
args_str.append(f"{arg_name}={arg_val}")
|
|
462
|
-
except:
|
|
459
|
+
except Exception:
|
|
463
460
|
args_str.append(f"{arg_name}=<error>")
|
|
464
461
|
args_repr = ", ".join(args_str)
|
|
465
462
|
self.trace_logger.debug(
|
|
@@ -481,7 +478,7 @@ class McliLogger:
|
|
|
481
478
|
else "<source not available>"
|
|
482
479
|
)
|
|
483
480
|
self.trace_logger.debug(f"LINE {filename}:{lineno} -> {source}")
|
|
484
|
-
except:
|
|
481
|
+
except Exception:
|
|
485
482
|
self.trace_logger.debug(f"LINE {filename}:{lineno}")
|
|
486
483
|
else:
|
|
487
484
|
self.trace_logger.debug(f"LINE {filename}:{lineno}")
|
|
@@ -507,9 +504,9 @@ class McliLogger:
|
|
|
507
504
|
self.trace_logger.debug(f"Traceback:\n{tb_str}")
|
|
508
505
|
except Exception as e:
|
|
509
506
|
# Never let tracing errors crash the program
|
|
510
|
-
try:
|
|
507
|
+
try: # noqa: SIM105
|
|
511
508
|
self.trace_logger.error(f"Error in trace callback: {e}")
|
|
512
|
-
except:
|
|
509
|
+
except Exception:
|
|
513
510
|
pass
|
|
514
511
|
return None
|
|
515
512
|
|
|
@@ -2,21 +2,19 @@
|
|
|
2
2
|
Main performance optimizer that applies all available optimizations
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
import asyncio
|
|
6
|
-
import importlib.util
|
|
7
5
|
import os
|
|
8
6
|
import sys
|
|
9
7
|
from typing import Any, Dict, Optional
|
|
10
8
|
|
|
11
9
|
from mcli.lib.logger.logger import get_logger
|
|
12
|
-
from mcli.lib.performance.rust_bridge import check_rust_extensions
|
|
10
|
+
from mcli.lib.performance.rust_bridge import check_rust_extensions
|
|
13
11
|
from mcli.lib.performance.uvloop_config import get_event_loop_info, install_uvloop
|
|
14
12
|
|
|
15
13
|
logger = get_logger(__name__)
|
|
16
14
|
|
|
17
15
|
|
|
18
16
|
class PerformanceOptimizer:
|
|
19
|
-
"""Centralized performance optimizer for MCLI"""
|
|
17
|
+
"""Centralized performance optimizer for MCLI."""
|
|
20
18
|
|
|
21
19
|
def __init__(self):
|
|
22
20
|
self.optimizations_applied = {}
|
|
@@ -25,8 +23,8 @@ class PerformanceOptimizer:
|
|
|
25
23
|
self.uvloop_installed = False
|
|
26
24
|
|
|
27
25
|
def apply_all_optimizations(self) -> Dict[str, Any]:
|
|
28
|
-
"""Apply all available performance optimizations"""
|
|
29
|
-
results = {}
|
|
26
|
+
"""Apply all available performance optimizations."""
|
|
27
|
+
results = {} # noqa: SIM904
|
|
30
28
|
|
|
31
29
|
# 1. Install UVLoop for better async performance
|
|
32
30
|
results["uvloop"] = self._optimize_event_loop()
|
|
@@ -47,7 +45,7 @@ class PerformanceOptimizer:
|
|
|
47
45
|
return results
|
|
48
46
|
|
|
49
47
|
def _optimize_event_loop(self) -> Dict[str, Any]:
|
|
50
|
-
"""Optimize asyncio event loop with UVLoop"""
|
|
48
|
+
"""Optimize asyncio event loop with UVLoop."""
|
|
51
49
|
try:
|
|
52
50
|
self.uvloop_installed = install_uvloop()
|
|
53
51
|
|
|
@@ -64,7 +62,7 @@ class PerformanceOptimizer:
|
|
|
64
62
|
return {"success": False, "error": str(e)}
|
|
65
63
|
|
|
66
64
|
def _initialize_rust_extensions(self) -> Dict[str, Any]:
|
|
67
|
-
"""Initialize Rust extensions for maximum performance"""
|
|
65
|
+
"""Initialize Rust extensions for maximum performance."""
|
|
68
66
|
try:
|
|
69
67
|
self.rust_status = check_rust_extensions()
|
|
70
68
|
|
|
@@ -90,7 +88,7 @@ class PerformanceOptimizer:
|
|
|
90
88
|
import mcli_rust
|
|
91
89
|
|
|
92
90
|
# Test file watcher
|
|
93
|
-
|
|
91
|
+
mcli_rust.FileWatcher()
|
|
94
92
|
extensions_loaded["file_watcher"] = True
|
|
95
93
|
except Exception as e:
|
|
96
94
|
logger.warning(f"File watcher extension test failed: {e}")
|
|
@@ -101,7 +99,7 @@ class PerformanceOptimizer:
|
|
|
101
99
|
import mcli_rust
|
|
102
100
|
|
|
103
101
|
# Test command matcher
|
|
104
|
-
|
|
102
|
+
mcli_rust.CommandMatcher()
|
|
105
103
|
extensions_loaded["command_matcher"] = True
|
|
106
104
|
except Exception as e:
|
|
107
105
|
logger.warning(f"Command matcher extension test failed: {e}")
|
|
@@ -112,7 +110,7 @@ class PerformanceOptimizer:
|
|
|
112
110
|
import mcli_rust
|
|
113
111
|
|
|
114
112
|
# Test process manager
|
|
115
|
-
|
|
113
|
+
mcli_rust.ProcessManager()
|
|
116
114
|
extensions_loaded["process_manager"] = True
|
|
117
115
|
except Exception as e:
|
|
118
116
|
logger.warning(f"Process manager extension test failed: {e}")
|
|
@@ -135,7 +133,7 @@ class PerformanceOptimizer:
|
|
|
135
133
|
return {"success": False, "error": str(e)}
|
|
136
134
|
|
|
137
135
|
def _check_redis_availability(self) -> Dict[str, Any]:
|
|
138
|
-
"""Check Redis availability for caching"""
|
|
136
|
+
"""Check Redis availability for caching."""
|
|
139
137
|
try:
|
|
140
138
|
import redis
|
|
141
139
|
|
|
@@ -164,7 +162,7 @@ class PerformanceOptimizer:
|
|
|
164
162
|
}
|
|
165
163
|
|
|
166
164
|
def _optimize_python_settings(self) -> Dict[str, Any]:
|
|
167
|
-
"""Apply Python-specific optimizations"""
|
|
165
|
+
"""Apply Python-specific optimizations."""
|
|
168
166
|
optimizations = {}
|
|
169
167
|
|
|
170
168
|
# 1. Disable garbage collection during critical operations
|
|
@@ -174,7 +172,7 @@ class PerformanceOptimizer:
|
|
|
174
172
|
optimizations["gc_tuned"] = True
|
|
175
173
|
|
|
176
174
|
# 2. Optimize import system
|
|
177
|
-
if hasattr(sys, "dont_write_bytecode"):
|
|
175
|
+
if hasattr(sys, "dont_write_bytecode"): # noqa: SIM102
|
|
178
176
|
# In production, enable bytecode for faster imports
|
|
179
177
|
if not os.environ.get("MCLI_DEBUG"):
|
|
180
178
|
sys.dont_write_bytecode = False
|
|
@@ -190,7 +188,7 @@ class PerformanceOptimizer:
|
|
|
190
188
|
try:
|
|
191
189
|
import multiprocessing as mp
|
|
192
190
|
|
|
193
|
-
if hasattr(mp, "set_start_method"):
|
|
191
|
+
if hasattr(mp, "set_start_method"): # noqa: SIM102
|
|
194
192
|
if sys.platform != "win32":
|
|
195
193
|
mp.set_start_method("fork", force=True)
|
|
196
194
|
optimizations["multiprocessing_optimized"] = True
|
|
@@ -205,7 +203,7 @@ class PerformanceOptimizer:
|
|
|
205
203
|
}
|
|
206
204
|
|
|
207
205
|
def _apply_environment_optimizations(self) -> Dict[str, Any]:
|
|
208
|
-
"""Apply environment-specific optimizations"""
|
|
206
|
+
"""Apply environment-specific optimizations."""
|
|
209
207
|
optimizations = {}
|
|
210
208
|
|
|
211
209
|
# 1. Production vs Development optimizations
|
|
@@ -258,7 +256,7 @@ class PerformanceOptimizer:
|
|
|
258
256
|
# Enable aggressive caching
|
|
259
257
|
os.environ["MCLI_AGGRESSIVE_CACHE"] = "1"
|
|
260
258
|
optimizations["aggressive_caching"] = True
|
|
261
|
-
except:
|
|
259
|
+
except Exception:
|
|
262
260
|
pass
|
|
263
261
|
|
|
264
262
|
return {
|
|
@@ -268,7 +266,7 @@ class PerformanceOptimizer:
|
|
|
268
266
|
}
|
|
269
267
|
|
|
270
268
|
def get_optimization_summary(self) -> Dict[str, Any]:
|
|
271
|
-
"""Get a summary of all applied optimizations"""
|
|
269
|
+
"""Get a summary of all applied optimizations."""
|
|
272
270
|
if not self.optimizations_applied:
|
|
273
271
|
self.apply_all_optimizations()
|
|
274
272
|
|
|
@@ -284,7 +282,7 @@ class PerformanceOptimizer:
|
|
|
284
282
|
return summary
|
|
285
283
|
|
|
286
284
|
def _estimate_performance_gain(self) -> str:
|
|
287
|
-
"""Estimate overall performance gain"""
|
|
285
|
+
"""Estimate overall performance gain."""
|
|
288
286
|
gains = []
|
|
289
287
|
|
|
290
288
|
if self.optimizations_applied.get("uvloop", {}).get("success"):
|
|
@@ -304,7 +302,7 @@ class PerformanceOptimizer:
|
|
|
304
302
|
return "Baseline performance with Python optimizations"
|
|
305
303
|
|
|
306
304
|
def benchmark_performance(self, test_size: str = "small") -> Dict[str, Any]:
|
|
307
|
-
"""Run performance benchmarks"""
|
|
305
|
+
"""Run performance benchmarks."""
|
|
308
306
|
from mcli.lib.performance.rust_bridge import PerformanceMonitor
|
|
309
307
|
|
|
310
308
|
monitor = PerformanceMonitor()
|
|
@@ -333,19 +331,19 @@ class PerformanceOptimizer:
|
|
|
333
331
|
}
|
|
334
332
|
|
|
335
333
|
def print_performance_report(self):
|
|
336
|
-
"""Print a detailed performance report"""
|
|
334
|
+
"""Print a detailed performance report."""
|
|
337
335
|
summary = self.get_optimization_summary()
|
|
338
336
|
|
|
339
337
|
print("\n" + "=" * 60)
|
|
340
338
|
print("🚀 MCLI PERFORMANCE OPTIMIZATION REPORT")
|
|
341
339
|
print("=" * 60)
|
|
342
340
|
|
|
343
|
-
print(
|
|
341
|
+
print("\n📊 Optimization Summary:")
|
|
344
342
|
print(f" • Total optimizations attempted: {summary['total_optimizations']}")
|
|
345
343
|
print(f" • Successful optimizations: {summary['successful_optimizations']}")
|
|
346
344
|
print(f" • Estimated performance gain: {summary['estimated_performance_gain']}")
|
|
347
345
|
|
|
348
|
-
print(
|
|
346
|
+
print("\n⚡ Applied Optimizations:")
|
|
349
347
|
for name, details in summary["details"].items():
|
|
350
348
|
status = "✅" if details.get("success") else "❌"
|
|
351
349
|
print(f" {status} {name.replace('_', ' ').title()}")
|
|
@@ -354,7 +352,7 @@ class PerformanceOptimizer:
|
|
|
354
352
|
if details.get("reason"):
|
|
355
353
|
print(f" → {details['reason']}")
|
|
356
354
|
|
|
357
|
-
print(
|
|
355
|
+
print("\n🔧 Recommendations:")
|
|
358
356
|
|
|
359
357
|
# Rust extensions
|
|
360
358
|
if not self.optimizations_applied.get("rust", {}).get("success"):
|
|
@@ -379,7 +377,7 @@ _global_optimizer: Optional[PerformanceOptimizer] = None
|
|
|
379
377
|
|
|
380
378
|
|
|
381
379
|
def get_global_optimizer() -> PerformanceOptimizer:
|
|
382
|
-
"""Get the global performance optimizer instance"""
|
|
380
|
+
"""Get the global performance optimizer instance."""
|
|
383
381
|
global _global_optimizer
|
|
384
382
|
|
|
385
383
|
if _global_optimizer is None:
|
|
@@ -389,13 +387,13 @@ def get_global_optimizer() -> PerformanceOptimizer:
|
|
|
389
387
|
|
|
390
388
|
|
|
391
389
|
def apply_optimizations() -> Dict[str, Any]:
|
|
392
|
-
"""Apply all available optimizations"""
|
|
390
|
+
"""Apply all available optimizations."""
|
|
393
391
|
optimizer = get_global_optimizer()
|
|
394
392
|
return optimizer.apply_all_optimizations()
|
|
395
393
|
|
|
396
394
|
|
|
397
395
|
def print_optimization_report():
|
|
398
|
-
"""Print the optimization report"""
|
|
396
|
+
"""Print the optimization report."""
|
|
399
397
|
optimizer = get_global_optimizer()
|
|
400
398
|
optimizer.print_performance_report()
|
|
401
399
|
|
|
@@ -2,10 +2,8 @@
|
|
|
2
2
|
Bridge module for integrating Rust extensions with Python code
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
import importlib.util
|
|
6
5
|
import os
|
|
7
|
-
import
|
|
8
|
-
from typing import Any, Dict, List, Optional, Union
|
|
6
|
+
from typing import Any, Dict, List
|
|
9
7
|
|
|
10
8
|
from mcli.lib.logger.logger import get_logger
|
|
11
9
|
|
|
@@ -20,7 +18,7 @@ _RUST_PROCESS_MANAGER = None
|
|
|
20
18
|
|
|
21
19
|
|
|
22
20
|
def check_rust_extensions() -> Dict[str, bool]:
|
|
23
|
-
"""Check which Rust extensions are available"""
|
|
21
|
+
"""Check which Rust extensions are available."""
|
|
24
22
|
global _RUST_AVAILABLE, _RUST_TFIDF, _RUST_FILE_WATCHER, _RUST_COMMAND_MATCHER, _RUST_PROCESS_MANAGER
|
|
25
23
|
|
|
26
24
|
if _RUST_AVAILABLE is not None:
|
|
@@ -64,7 +62,7 @@ def check_rust_extensions() -> Dict[str, bool]:
|
|
|
64
62
|
|
|
65
63
|
|
|
66
64
|
def get_tfidf_vectorizer(use_rust: bool = True, **kwargs):
|
|
67
|
-
"""Get the best available TF-IDF vectorizer"""
|
|
65
|
+
"""Get the best available TF-IDF vectorizer."""
|
|
68
66
|
rust_status = check_rust_extensions()
|
|
69
67
|
|
|
70
68
|
if use_rust and rust_status["tfidf"]:
|
|
@@ -85,7 +83,7 @@ def get_tfidf_vectorizer(use_rust: bool = True, **kwargs):
|
|
|
85
83
|
|
|
86
84
|
|
|
87
85
|
def get_file_watcher(use_rust: bool = True):
|
|
88
|
-
"""Get the best available file watcher"""
|
|
86
|
+
"""Get the best available file watcher."""
|
|
89
87
|
rust_status = check_rust_extensions()
|
|
90
88
|
|
|
91
89
|
if use_rust and rust_status["file_watcher"]:
|
|
@@ -106,7 +104,7 @@ def get_file_watcher(use_rust: bool = True):
|
|
|
106
104
|
|
|
107
105
|
|
|
108
106
|
def get_command_matcher(use_rust: bool = True, **kwargs):
|
|
109
|
-
"""Get the best available command matcher"""
|
|
107
|
+
"""Get the best available command matcher."""
|
|
110
108
|
rust_status = check_rust_extensions()
|
|
111
109
|
|
|
112
110
|
if use_rust and rust_status["command_matcher"]:
|
|
@@ -127,7 +125,7 @@ def get_command_matcher(use_rust: bool = True, **kwargs):
|
|
|
127
125
|
|
|
128
126
|
|
|
129
127
|
def get_process_manager(use_rust: bool = True):
|
|
130
|
-
"""Get the best available process manager"""
|
|
128
|
+
"""Get the best available process manager."""
|
|
131
129
|
rust_status = check_rust_extensions()
|
|
132
130
|
|
|
133
131
|
if use_rust and rust_status["process_manager"]:
|
|
@@ -148,14 +146,14 @@ def get_process_manager(use_rust: bool = True):
|
|
|
148
146
|
|
|
149
147
|
|
|
150
148
|
class PerformanceMonitor:
|
|
151
|
-
"""Monitor performance differences between Rust and Python implementations"""
|
|
149
|
+
"""Monitor performance differences between Rust and Python implementations."""
|
|
152
150
|
|
|
153
151
|
def __init__(self):
|
|
154
152
|
self.benchmarks = {}
|
|
155
153
|
self.rust_status = check_rust_extensions()
|
|
156
154
|
|
|
157
155
|
def benchmark_tfidf(self, documents: List[str], queries: List[str]) -> Dict[str, Any]:
|
|
158
|
-
"""Benchmark TF-IDF performance"""
|
|
156
|
+
"""Benchmark TF-IDF performance."""
|
|
159
157
|
import time
|
|
160
158
|
|
|
161
159
|
results = {"rust": None, "python": None, "speedup": None}
|
|
@@ -203,7 +201,7 @@ class PerformanceMonitor:
|
|
|
203
201
|
return results
|
|
204
202
|
|
|
205
203
|
def _cosine_similarity(self, vec1, vec2):
|
|
206
|
-
"""Simple cosine similarity implementation"""
|
|
204
|
+
"""Simple cosine similarity implementation."""
|
|
207
205
|
import numpy as np
|
|
208
206
|
|
|
209
207
|
dot_product = np.dot(
|
|
@@ -219,7 +217,7 @@ class PerformanceMonitor:
|
|
|
219
217
|
return dot_product / (norm1 * norm2)
|
|
220
218
|
|
|
221
219
|
def benchmark_file_watching(self, test_dir: str, num_operations: int = 100) -> Dict[str, Any]:
|
|
222
|
-
"""Benchmark file watching performance"""
|
|
220
|
+
"""Benchmark file watching performance."""
|
|
223
221
|
import os
|
|
224
222
|
import tempfile
|
|
225
223
|
import time
|
|
@@ -243,7 +241,7 @@ class PerformanceMonitor:
|
|
|
243
241
|
|
|
244
242
|
# Give time for events to be processed
|
|
245
243
|
time.sleep(0.1)
|
|
246
|
-
|
|
244
|
+
watcher.get_events()
|
|
247
245
|
rust_time = time.perf_counter() - start_time
|
|
248
246
|
|
|
249
247
|
watcher.stop_watching()
|
|
@@ -258,7 +256,7 @@ class PerformanceMonitor:
|
|
|
258
256
|
return results
|
|
259
257
|
|
|
260
258
|
def get_system_info(self) -> Dict[str, Any]:
|
|
261
|
-
"""Get system information relevant to performance"""
|
|
259
|
+
"""Get system information relevant to performance."""
|
|
262
260
|
import platform
|
|
263
261
|
|
|
264
262
|
import psutil
|
|
@@ -276,7 +274,7 @@ class PerformanceMonitor:
|
|
|
276
274
|
|
|
277
275
|
|
|
278
276
|
class PythonFileWatcher:
|
|
279
|
-
"""Fallback Python file watcher using watchdog"""
|
|
277
|
+
"""Fallback Python file watcher using watchdog."""
|
|
280
278
|
|
|
281
279
|
def __init__(self):
|
|
282
280
|
from watchdog.events import FileSystemEventHandler
|
|
@@ -300,7 +298,7 @@ class PythonFileWatcher:
|
|
|
300
298
|
self.is_watching = False
|
|
301
299
|
|
|
302
300
|
def start_watching(self, paths: List[str], recursive: bool = True):
|
|
303
|
-
|
|
301
|
+
pass
|
|
304
302
|
|
|
305
303
|
for path in paths:
|
|
306
304
|
self.observer.schedule(self.handler, path, recursive=recursive)
|
|
@@ -321,7 +319,7 @@ class PythonFileWatcher:
|
|
|
321
319
|
|
|
322
320
|
|
|
323
321
|
class PythonCommandMatcher:
|
|
324
|
-
"""Fallback Python command matcher"""
|
|
322
|
+
"""Fallback Python command matcher."""
|
|
325
323
|
|
|
326
324
|
def __init__(self, fuzzy_threshold: float = 0.3):
|
|
327
325
|
self.fuzzy_threshold = fuzzy_threshold
|
|
@@ -331,7 +329,7 @@ class PythonCommandMatcher:
|
|
|
331
329
|
self.commands.extend(commands)
|
|
332
330
|
|
|
333
331
|
def search(self, query: str, limit: int = 10) -> List[Dict[str, Any]]:
|
|
334
|
-
|
|
332
|
+
pass
|
|
335
333
|
|
|
336
334
|
results = []
|
|
337
335
|
query_lower = query.lower()
|
|
@@ -376,14 +374,11 @@ _RUST_EXTENSIONS_STATUS = check_rust_extensions()
|
|
|
376
374
|
|
|
377
375
|
|
|
378
376
|
def print_performance_summary():
|
|
379
|
-
"""Print a stunning visual summary of available performance optimizations"""
|
|
377
|
+
"""Print a stunning visual summary of available performance optimizations."""
|
|
380
378
|
try:
|
|
381
|
-
from rich.columns import Columns
|
|
382
|
-
from rich.panel import Panel
|
|
383
379
|
from rich.rule import Rule
|
|
384
|
-
from rich.text import Text
|
|
385
380
|
|
|
386
|
-
from mcli.lib.ui.visual_effects import ColorfulOutput,
|
|
381
|
+
from mcli.lib.ui.visual_effects import ColorfulOutput, VisualTable, console
|
|
387
382
|
|
|
388
383
|
status = check_rust_extensions()
|
|
389
384
|
|
|
@@ -405,7 +400,7 @@ def print_performance_summary():
|
|
|
405
400
|
|
|
406
401
|
# Check UVLoop
|
|
407
402
|
try:
|
|
408
|
-
|
|
403
|
+
pass
|
|
409
404
|
|
|
410
405
|
optimization_data["uvloop"]["success"] = True
|
|
411
406
|
optimization_data["uvloop"]["reason"] = "High-performance event loop active"
|
|
@@ -429,7 +424,7 @@ def print_performance_summary():
|
|
|
429
424
|
|
|
430
425
|
# Check AIOSQLite
|
|
431
426
|
try:
|
|
432
|
-
|
|
427
|
+
pass
|
|
433
428
|
|
|
434
429
|
optimization_data["aiosqlite"]["success"] = True
|
|
435
430
|
optimization_data["aiosqlite"]["reason"] = "Async database operations enabled"
|
|
@@ -474,7 +469,7 @@ def print_performance_summary():
|
|
|
474
469
|
|
|
475
470
|
# Check other optimizations
|
|
476
471
|
try:
|
|
477
|
-
|
|
472
|
+
pass
|
|
478
473
|
|
|
479
474
|
print("✅ UVLoop available for async performance")
|
|
480
475
|
except ImportError:
|
|
@@ -488,7 +483,7 @@ def print_performance_summary():
|
|
|
488
483
|
print("⚠️ Redis not available - caching disabled")
|
|
489
484
|
|
|
490
485
|
try:
|
|
491
|
-
|
|
486
|
+
pass
|
|
492
487
|
|
|
493
488
|
print("✅ AIOSQLite available for async database operations")
|
|
494
489
|
except ImportError:
|