mentis 0.1.0__tar.gz

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.
Files changed (73) hide show
  1. mentis-0.1.0/.github/workflows/ci.yml +39 -0
  2. mentis-0.1.0/.github/workflows/lint.yml +35 -0
  3. mentis-0.1.0/.github/workflows/release.yml +35 -0
  4. mentis-0.1.0/.gitignore +149 -0
  5. mentis-0.1.0/LICENSE +21 -0
  6. mentis-0.1.0/PKG-INFO +79 -0
  7. mentis-0.1.0/README.md +1 -0
  8. mentis-0.1.0/mentis/__init__.py +4 -0
  9. mentis-0.1.0/mentis/cli/__init__.py +8 -0
  10. mentis-0.1.0/mentis/cli/main.py +177 -0
  11. mentis-0.1.0/mentis/comparison/__init__.py +21 -0
  12. mentis-0.1.0/mentis/comparison/leaderboard.py +155 -0
  13. mentis-0.1.0/mentis/comparison/metrics.py +183 -0
  14. mentis-0.1.0/mentis/comparison/model_zoo.py +179 -0
  15. mentis-0.1.0/mentis/comparison/trainer.py +201 -0
  16. mentis-0.1.0/mentis/config.py +132 -0
  17. mentis-0.1.0/mentis/constants.py +39 -0
  18. mentis-0.1.0/mentis/deployment/__init__.py +9 -0
  19. mentis-0.1.0/mentis/deployment/checker.py +204 -0
  20. mentis-0.1.0/mentis/exceptions.py +38 -0
  21. mentis-0.1.0/mentis/explainability/__init__.py +28 -0
  22. mentis-0.1.0/mentis/explainability/curves.py +242 -0
  23. mentis-0.1.0/mentis/explainability/permutation.py +87 -0
  24. mentis-0.1.0/mentis/explainability/shap_explainer.py +141 -0
  25. mentis-0.1.0/mentis/guardian.py +495 -0
  26. mentis-0.1.0/mentis/monitoring/__init__.py +11 -0
  27. mentis-0.1.0/mentis/monitoring/dashboard.py +172 -0
  28. mentis-0.1.0/mentis/monitoring/drift.py +130 -0
  29. mentis-0.1.0/mentis/reporting/__init__.py +10 -0
  30. mentis-0.1.0/mentis/reporting/html_report.py +81 -0
  31. mentis-0.1.0/mentis/reporting/pdf_report.py +68 -0
  32. mentis-0.1.0/mentis/reporting/report_builder.py +176 -0
  33. mentis-0.1.0/mentis/scanner/__init__.py +18 -0
  34. mentis-0.1.0/mentis/scanner/base.py +52 -0
  35. mentis-0.1.0/mentis/scanner/checks.py +450 -0
  36. mentis-0.1.0/mentis/scanner/dataset_scanner.py +201 -0
  37. mentis-0.1.0/mentis/scanner/result.py +121 -0
  38. mentis-0.1.0/mentis/templates/report.html.j2 +383 -0
  39. mentis-0.1.0/mentis/templates/styles.css +56 -0
  40. mentis-0.1.0/mentis/utils/__init__.py +39 -0
  41. mentis-0.1.0/mentis/utils/helpers.py +198 -0
  42. mentis-0.1.0/mentis/utils/logger.py +80 -0
  43. mentis-0.1.0/mentis/utils/validators.py +103 -0
  44. mentis-0.1.0/mentis/validation/__init__.py +16 -0
  45. mentis-0.1.0/mentis/validation/auditor.py +138 -0
  46. mentis-0.1.0/mentis/validation/fairness.py +177 -0
  47. mentis-0.1.0/mentis/visualization/__init__.py +8 -0
  48. mentis-0.1.0/mentis/visualization/charts.py +376 -0
  49. mentis-0.1.0/pyproject.toml +84 -0
  50. mentis-0.1.0/requirements.txt +99 -0
  51. mentis-0.1.0/tests/__init__.py +1 -0
  52. mentis-0.1.0/tests/conftest.py +209 -0
  53. mentis-0.1.0/tests/test_comparison/__init__.py +1 -0
  54. mentis-0.1.0/tests/test_comparison/test_metrics.py +133 -0
  55. mentis-0.1.0/tests/test_comparison/test_model_zoo.py +76 -0
  56. mentis-0.1.0/tests/test_comparison/test_trainer.py +124 -0
  57. mentis-0.1.0/tests/test_deployment/__init__.py +1 -0
  58. mentis-0.1.0/tests/test_deployment/test_checker.py +70 -0
  59. mentis-0.1.0/tests/test_explainability/__init__.py +1 -0
  60. mentis-0.1.0/tests/test_explainability/test_curves.py +148 -0
  61. mentis-0.1.0/tests/test_explainability/test_permutation.py +45 -0
  62. mentis-0.1.0/tests/test_explainability/test_shap_explainer.py +66 -0
  63. mentis-0.1.0/tests/test_monitoring/__init__.py +1 -0
  64. mentis-0.1.0/tests/test_monitoring/test_dashboard.py +72 -0
  65. mentis-0.1.0/tests/test_monitoring/test_drift.py +50 -0
  66. mentis-0.1.0/tests/test_reporting/__init__.py +1 -0
  67. mentis-0.1.0/tests/test_reporting/test_report_builder.py +144 -0
  68. mentis-0.1.0/tests/test_scanner/__init__.py +1 -0
  69. mentis-0.1.0/tests/test_scanner/test_checks.py +302 -0
  70. mentis-0.1.0/tests/test_scanner/test_dataset_scanner.py +165 -0
  71. mentis-0.1.0/tests/test_validation/__init__.py +1 -0
  72. mentis-0.1.0/tests/test_validation/test_auditor.py +82 -0
  73. mentis-0.1.0/tests/test_validation/test_fairness.py +73 -0
@@ -0,0 +1,39 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main, master]
6
+ pull_request:
7
+ branches: [main, master]
8
+
9
+ jobs:
10
+ test:
11
+ name: Test Python ${{ matrix.python-version }}
12
+ runs-on: ubuntu-latest
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ python-version: ["3.12", "3.13"]
17
+
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+
21
+ - name: Set up Python ${{ matrix.python-version }}
22
+ uses: actions/setup-python@v5
23
+ with:
24
+ python-version: ${{ matrix.python-version }}
25
+ cache: "pip"
26
+
27
+ - name: Install dependencies
28
+ run: |
29
+ python -m pip install --upgrade pip
30
+ pip install -e ".[dev,all]"
31
+
32
+ - name: Run tests with coverage
33
+ run: pytest --cov=mentis --cov-report=xml --cov-report=term-missing
34
+
35
+ - name: Upload coverage artifact
36
+ uses: actions/upload-artifact@v4
37
+ with:
38
+ name: coverage-report-${{ matrix.python-version }}
39
+ path: coverage.xml
@@ -0,0 +1,35 @@
1
+ name: Lint
2
+
3
+ on:
4
+ push:
5
+ branches: [main, master]
6
+ pull_request:
7
+ branches: [main, master]
8
+
9
+ jobs:
10
+ lint:
11
+ name: Lint & Type Check
12
+ runs-on: ubuntu-latest
13
+
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+
17
+ - name: Set up Python
18
+ uses: actions/setup-python@v5
19
+ with:
20
+ python-version: "3.12"
21
+ cache: "pip"
22
+
23
+ - name: Install dependencies
24
+ run: |
25
+ python -m pip install --upgrade pip
26
+ pip install -e ".[dev]"
27
+
28
+ - name: Run black (check formatting)
29
+ run: black --check mentis/ tests/
30
+
31
+ - name: Run ruff
32
+ run: ruff check mentis/ tests/
33
+
34
+ - name: Run mypy
35
+ run: mypy mentis/
@@ -0,0 +1,35 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*.*.*"
7
+
8
+ jobs:
9
+ build-and-publish:
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+
15
+ - name: Set up Python
16
+ uses: actions/setup-python@v5
17
+ with:
18
+ python-version: "3.12"
19
+
20
+ - name: Install build tools
21
+ run: |
22
+ python -m pip install --upgrade pip
23
+ pip install build twine
24
+
25
+ - name: Build package
26
+ run: python -m build
27
+
28
+ - name: Publish to PyPI
29
+ env:
30
+ TWINE_USERNAME: __token__
31
+ TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
32
+ run: twine upload dist/*
33
+
34
+
35
+
@@ -0,0 +1,149 @@
1
+ # =========================
2
+ # Python
3
+ # =========================
4
+
5
+ __pycache__/
6
+ *.py[cod]
7
+ *$py.class
8
+
9
+ # Python virtual environments
10
+ venv/
11
+ .venv/
12
+ env/
13
+ ENV/
14
+
15
+ # Distribution / Packaging
16
+ build/
17
+ dist/
18
+ *.egg-info/
19
+ .eggs/
20
+ wheels/
21
+
22
+ # PyPI build files
23
+ *.whl
24
+
25
+
26
+ # =========================
27
+ # Jupyter Notebook
28
+ # =========================
29
+
30
+ .ipynb_checkpoints/
31
+
32
+
33
+ # =========================
34
+ # Testing
35
+ # =========================
36
+
37
+ .pytest_cache/
38
+ .coverage
39
+ htmlcov/
40
+ .tox/
41
+ .nox/
42
+
43
+
44
+ # =========================
45
+ # Type Checking
46
+ # =========================
47
+
48
+ .mypy_cache/
49
+ .dmypy.json
50
+ .pyre/
51
+
52
+
53
+ # =========================
54
+ # Linters / Formatters
55
+ # =========================
56
+
57
+ .ruff_cache/
58
+ .black_cache/
59
+
60
+
61
+ # =========================
62
+ # ML Artifacts
63
+ # =========================
64
+
65
+ # Trained models
66
+ models/
67
+ *.pkl
68
+ *.pickle
69
+ *.joblib
70
+ *.h5
71
+ *.pt
72
+ *.pth
73
+
74
+ # Experiment tracking
75
+ mlruns/
76
+ wandb/
77
+ runs/
78
+
79
+
80
+ # =========================
81
+ # Data
82
+ # =========================
83
+
84
+ # Raw datasets
85
+ data/raw/
86
+
87
+ # Processed datasets
88
+ data/processed/
89
+
90
+ # Large files
91
+ *.csv
92
+ *.parquet
93
+ *.jsonl
94
+
95
+
96
+ # =========================
97
+ # Reports
98
+ # =========================
99
+
100
+ reports/
101
+ *.html
102
+ *.pdf
103
+
104
+
105
+ # =========================
106
+ # Documentation
107
+ # =========================
108
+
109
+ docs/site/
110
+
111
+
112
+ # =========================
113
+ # IDE
114
+ # =========================
115
+
116
+ .vscode/
117
+ .idea/
118
+
119
+ # MacOS
120
+ .DS_Store
121
+
122
+ # Windows
123
+ Thumbs.db
124
+
125
+
126
+ # =========================
127
+ # Environment Variables
128
+ # =========================
129
+
130
+ .env
131
+ .env.*
132
+ !.env.example
133
+
134
+
135
+ # =========================
136
+ # Logs
137
+ # =========================
138
+
139
+ *.log
140
+
141
+
142
+ # =========================
143
+ # OS temporary files
144
+ # =========================
145
+
146
+ *.tmp
147
+ *.swp
148
+
149
+
mentis-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mentis Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO QUALITY AND MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
mentis-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,79 @@
1
+ Metadata-Version: 2.4
2
+ Name: mentis
3
+ Version: 0.1.0
4
+ Summary: An AI engineer's toolkit: dataset scanning, model comparison, explainability, auditing, deployment checks, monitoring, and professional reporting behind a single API.
5
+ Project-URL: Homepage, https://github.com/your-org/mentis
6
+ Project-URL: Repository, https://github.com/your-org/mentis
7
+ Project-URL: Issues, https://github.com/your-org/mentis/issues
8
+ Author: Mentis Contributors
9
+ License: MIT License
10
+
11
+ Copyright (c) 2026 Mentis Contributors
12
+
13
+ Permission is hereby granted, free of charge, to any person obtaining a copy
14
+ of this software and associated documentation files (the "Software"), to deal
15
+ in the Software without restriction, including without limitation the rights
16
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
+ copies of the Software, and to permit persons to whom the Software is
18
+ furnished to do so, subject to the following conditions:
19
+
20
+ The above copyright notice and this permission notice shall be included in all
21
+ copies or substantial portions of the Software.
22
+
23
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
+ IMPLIED, INCLUDING BUT NOT LIMITED TO QUALITY AND MERCHANTABILITY,
25
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
+ SOFTWARE.
30
+ License-File: LICENSE
31
+ Keywords: data-quality,explainability,machine-learning,mlops,model-comparison
32
+ Classifier: Development Status :: 3 - Alpha
33
+ Classifier: Intended Audience :: Developers
34
+ Classifier: Intended Audience :: Science/Research
35
+ Classifier: License :: OSI Approved :: MIT License
36
+ Classifier: Programming Language :: Python :: 3.12
37
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
38
+ Requires-Python: >=3.12
39
+ Requires-Dist: jinja2>=3.1
40
+ Requires-Dist: matplotlib>=3.8
41
+ Requires-Dist: numpy>=1.26
42
+ Requires-Dist: pandas>=2.0
43
+ Requires-Dist: plotly>=5.18
44
+ Requires-Dist: pydantic>=2.5
45
+ Requires-Dist: pyyaml>=6.0
46
+ Requires-Dist: rich>=13.7
47
+ Requires-Dist: scikit-learn>=1.4
48
+ Requires-Dist: scipy>=1.11
49
+ Requires-Dist: typer>=0.9
50
+ Provides-Extra: all
51
+ Requires-Dist: catboost>=1.2; extra == 'all'
52
+ Requires-Dist: evidently>=0.4; extra == 'all'
53
+ Requires-Dist: fairlearn>=0.10; extra == 'all'
54
+ Requires-Dist: lightgbm>=4.3; extra == 'all'
55
+ Requires-Dist: shap>=0.44; extra == 'all'
56
+ Requires-Dist: weasyprint>=61.0; extra == 'all'
57
+ Requires-Dist: xgboost>=2.0; extra == 'all'
58
+ Provides-Extra: boosting
59
+ Requires-Dist: catboost>=1.2; extra == 'boosting'
60
+ Requires-Dist: lightgbm>=4.3; extra == 'boosting'
61
+ Requires-Dist: xgboost>=2.0; extra == 'boosting'
62
+ Provides-Extra: dev
63
+ Requires-Dist: black>=24.0; extra == 'dev'
64
+ Requires-Dist: mkdocs>=1.5; extra == 'dev'
65
+ Requires-Dist: mypy>=1.9; extra == 'dev'
66
+ Requires-Dist: pytest-cov>=4.1; extra == 'dev'
67
+ Requires-Dist: pytest>=8.0; extra == 'dev'
68
+ Requires-Dist: ruff>=0.4; extra == 'dev'
69
+ Provides-Extra: explainability
70
+ Requires-Dist: shap>=0.44; extra == 'explainability'
71
+ Provides-Extra: fairness
72
+ Requires-Dist: fairlearn>=0.10; extra == 'fairness'
73
+ Provides-Extra: monitoring
74
+ Requires-Dist: evidently>=0.4; extra == 'monitoring'
75
+ Provides-Extra: pdf
76
+ Requires-Dist: weasyprint>=61.0; extra == 'pdf'
77
+ Description-Content-Type: text/markdown
78
+
79
+ # Mentis
mentis-0.1.0/README.md ADDED
@@ -0,0 +1 @@
1
+ # Mentis
@@ -0,0 +1,4 @@
1
+ from mentis.config import MentisConfig
2
+ from mentis.guardian import Guardian
3
+
4
+ __all__ = ["Guardian", "MentisConfig"]
@@ -0,0 +1,8 @@
1
+ """
2
+ CLI subpackage: Typer-based command-line interface for Mentis.
3
+ """
4
+
5
+ from mentis.cli.main import app
6
+
7
+ __all__ = ["app"]
8
+
@@ -0,0 +1,177 @@
1
+ """
2
+ Command-line interface for Mentis, built with Typer.
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ from pathlib import Path
8
+
9
+ import pandas as pd
10
+ import typer
11
+ from rich.console import Console
12
+ from rich.table import Table
13
+
14
+ from mentis import Guardian, MentisConfig
15
+ from mentis.exceptions import MentisError
16
+
17
+ app = typer.Typer(name="mentis", help="Mentis: an AI engineer's toolkit.")
18
+ console = Console()
19
+
20
+
21
+ def _load_guardian(config: str | None) -> Guardian:
22
+ return Guardian.from_yaml(config) if config else Guardian()
23
+
24
+
25
+ def _load_dataframe(data_path: str) -> pd.DataFrame:
26
+ path = Path(data_path)
27
+ if not path.exists():
28
+ console.print(f"[red]File not found: {data_path}[/red]")
29
+ raise typer.Exit(code=1)
30
+ if path.suffix == ".parquet":
31
+ return pd.read_parquet(path)
32
+ return pd.read_csv(path)
33
+
34
+
35
+ @app.command()
36
+ def scan(
37
+ data: str = typer.Argument(..., help="Path to CSV/Parquet dataset."),
38
+ target: str | None = typer.Option(None, help="Target column name."),
39
+ config: str | None = typer.Option(None, help="Path to a Mentis YAML config."),
40
+ ) -> None:
41
+ """Run the Dataset Scanner on a CSV/Parquet file."""
42
+ guardian = _load_guardian(config)
43
+ df = _load_dataframe(data)
44
+
45
+ with console.status("Scanning dataset..."):
46
+ try:
47
+ result = guardian.scan(df, target=target)
48
+ except MentisError as exc:
49
+ console.print(f"[red]Scan failed: {exc}[/red]")
50
+ raise typer.Exit(code=1)
51
+
52
+ console.print(result)
53
+ for finding in result.warnings():
54
+ console.print(f"[yellow]⚠ {finding.message}[/yellow] -> {finding.suggestion}")
55
+
56
+
57
+ @app.command()
58
+ def compare(
59
+ config: str = typer.Argument(..., help="Path to a Mentis YAML config."),
60
+ data: str = typer.Option(..., help="Path to CSV/Parquet dataset."),
61
+ ) -> None:
62
+ """Train and compare models using settings from a YAML config."""
63
+ guardian = Guardian.from_yaml(config)
64
+ df = _load_dataframe(data)
65
+
66
+ target = guardian.config.project.target
67
+ if not target:
68
+ console.print("[red]Config must specify project.target for comparison.[/red]")
69
+ raise typer.Exit(code=1)
70
+
71
+ from sklearn.model_selection import train_test_split
72
+
73
+ X = df.drop(columns=[target])
74
+ y = df[target]
75
+ X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
76
+
77
+ with console.status("Training and comparing models..."):
78
+ try:
79
+ leaderboard = guardian.compare_models(X_train, X_test, y_train, y_test)
80
+ except MentisError as exc:
81
+ console.print(f"[red]Comparison failed: {exc}[/red]")
82
+ raise typer.Exit(code=1)
83
+
84
+ table = Table(title="Model Leaderboard")
85
+ table.add_column("Model")
86
+ table.add_column(leaderboard.primary_metric)
87
+ for r in leaderboard.results:
88
+ score = r.metrics.get(leaderboard.primary_metric, "N/A")
89
+ table.add_row(r.model_name, f"{score:.4f}" if isinstance(score, float) else str(score))
90
+ console.print(table)
91
+
92
+
93
+ @app.command()
94
+ def audit(
95
+ project_path: str = typer.Argument(".", help="Path to the project to audit.")
96
+ ) -> None:
97
+ """Audit an ML project's structure and production readiness."""
98
+ guardian = Guardian()
99
+ with console.status("Auditing project..."):
100
+ result = guardian.audit_pipeline(project_path)
101
+
102
+ console.print(f"[bold]Production Readiness Score: {result.score}/100[/bold]")
103
+ for finding in result.failed():
104
+ console.print(f"[yellow]✗ {finding.name}[/yellow] ({finding.severity}) -> {finding.suggestion}")
105
+
106
+
107
+ @app.command(name="deploy-check")
108
+ def deploy_check(
109
+ project_path: str = typer.Argument(".", help="Path to the project to check.")
110
+ ) -> None:
111
+ """Check a project's deployment readiness."""
112
+ guardian = Guardian()
113
+ with console.status("Checking deployment readiness..."):
114
+ result = guardian.deploy_check(project_path)
115
+
116
+ console.print(f"[bold]Deployment Score: {result.score}/100[/bold]")
117
+ if result.detected_framework:
118
+ console.print(f"Framework detected: {result.detected_framework}")
119
+ for finding in result.failed():
120
+ console.print(f"[yellow]✗ {finding.name}[/yellow] ({finding.severity}) -> {finding.suggestion}")
121
+
122
+
123
+ @app.command()
124
+ def report(
125
+ data: str | None = typer.Option(None, help="Path to CSV/Parquet dataset (optional, enables scan)."),
126
+ target: str | None = typer.Option(None, help="Target column name."),
127
+ project_path: str = typer.Option(".", help="Project path for audit + deploy checks."),
128
+ output_dir: str = typer.Option("mentis_reports", help="Output directory for the report."),
129
+ fmt: str = typer.Option("html", help="Report format: html, markdown, or pdf."),
130
+ config: str | None = typer.Option(None, help="Path to a Mentis YAML config."),
131
+ ) -> None:
132
+ """
133
+ Generate a Mentis report: optionally scans a dataset, then always
134
+ runs pipeline audit and deployment checks, and writes the report.
135
+ """
136
+ guardian = _load_guardian(config)
137
+
138
+ if data:
139
+ df = _load_dataframe(data)
140
+ with console.status("Scanning dataset..."):
141
+ try:
142
+ guardian.scan(df, target=target)
143
+ except MentisError as exc:
144
+ console.print(f"[yellow]⚠ Scan skipped: {exc}[/yellow]")
145
+
146
+ with console.status("Auditing project structure..."):
147
+ try:
148
+ guardian.audit_pipeline(project_path)
149
+ except Exception as exc:
150
+ console.print(f"[yellow]⚠ Audit skipped: {exc}[/yellow]")
151
+
152
+ with console.status("Checking deployment readiness..."):
153
+ try:
154
+ guardian.deploy_check(project_path)
155
+ except Exception as exc:
156
+ console.print(f"[yellow]⚠ Deploy check skipped: {exc}[/yellow]")
157
+
158
+ with console.status(f"Generating {fmt.upper()} report..."):
159
+ try:
160
+ path = guardian.generate_report(output_path=output_dir, fmt=fmt)
161
+ except MentisError as exc:
162
+ console.print(f"[red]Report generation failed: {exc}[/red]")
163
+ raise typer.Exit(code=1)
164
+
165
+ console.print(f"[green]✓ Report written to:[/green] {path}")
166
+
167
+
168
+ def main() -> None:
169
+ app()
170
+
171
+
172
+ if __name__ == "__main__":
173
+ main()
174
+
175
+
176
+
177
+
@@ -0,0 +1,21 @@
1
+ """
2
+ Comparison subpackage: automated multi-model training, evaluation,
3
+ and leaderboard ranking for Mentis.
4
+ """
5
+
6
+ from mentis.comparison.leaderboard import Leaderboard, ModelResult, build_leaderboard
7
+ from mentis.comparison.metrics import compute_metrics, primary_metric_for_task
8
+ from mentis.comparison.model_zoo import get_model_zoo
9
+ from mentis.comparison.trainer import ModelTrainer
10
+
11
+ __all__ = [
12
+ "ModelTrainer",
13
+ "Leaderboard",
14
+ "ModelResult",
15
+ "build_leaderboard",
16
+ "get_model_zoo",
17
+ "compute_metrics",
18
+ "primary_metric_for_task",
19
+ ]
20
+
21
+