"""Repository path helpers (config, databases, ONNX artifacts under ``data/``).""" from __future__ import annotations from pathlib import Path def project_root() -> Path: """Return the chess-tutor repository root (parent of ``src/``).""" return Path(__file__).resolve().parents[2] def data_dir() -> Path: return project_root() / "data" def docs_dir() -> Path: return project_root() / "docs" def config_dir() -> Path: return data_dir() / "config" def default_playstyle_llm_grounding_path() -> Path: """Generated static context for Gemma coaching narratives.""" return docs_dir() / "playstyle_llm_grounding.md" def db_dir() -> Path: path = data_dir() / "db" path.mkdir(parents=True, exist_ok=True) return path def models_dir() -> Path: """Trained models root (per-DB subfolders under ``data/models//``).""" path = data_dir() / "models" path.mkdir(parents=True, exist_ok=True) return path def models_dir_for_db(db_path: Path | str) -> Path: """ Model artifacts for one player-moves SQLite file. Example: ``data/db/player_moves_alice_lichess.db`` → ``data/models/player_moves_alice_lichess/``. """ stem = Path(db_path).stem path = models_dir() / stem path.mkdir(parents=True, exist_ok=True) return path def onnx_dir() -> Path: """Generated / runtime ONNX models (probed LC0 graph, etc.).""" path = data_dir() / "onnx" path.mkdir(parents=True, exist_ok=True) return path def default_onnx_config_path() -> Path: return config_dir() / "onnx_config.yaml" def default_positions_db_path() -> Path: return db_dir() / "positions.db" def default_positions_duplicate_db_path() -> Path: return db_dir() / "positions_duplicate.db" def default_probed_onnx_path() -> Path: return onnx_dir() / "network_probed.onnx" def default_player_playstyle_db_path(username: str, platform: str) -> Path: """Default SQLite path for :mod:`chess_tutor.build_player_playstyle_db`.""" from chess_tutor.playstyle_db import default_player_playstyle_db_path as _fn return _fn(username, platform) def default_cohort_playstyle_db_path(platform: str) -> Path: """Shared cohort SQLite path for many players on one site.""" from chess_tutor.playstyle_db import default_cohort_playstyle_db_path as _fn return _fn(platform) def default_cohort_dir() -> Path: """ Root for cohort pipeline artifacts (selected games, move records, features). Layout: ``data/cohort/`` """ path = data_dir() / "cohort" path.mkdir(parents=True, exist_ok=True) return path def default_cohort_db_path(corpus_id: str) -> Path: """Default SQLite path for cohort L1–L5 and playstyle coaching train.""" return default_cohort_dir() / f"{corpus_id}.db" def default_web_artifacts_dir() -> Path: """Root for web UI precomputed artifacts (graphs, cohort embeddings).""" path = data_dir() / "web_artifacts" path.mkdir(parents=True, exist_ok=True) return path def default_cohort_web_artifacts_dir(corpus_id: str) -> Path: """Per-corpus_id folder for web UI precomputed artifacts.""" path = default_web_artifacts_dir() / "cohort" / corpus_id path.mkdir(parents=True, exist_ok=True) return path def default_web_pca_artifacts_path(corpus_id: str) -> Path: """Artifacts for cohort→PCA transform + precomputed PCA coordinates.""" return default_cohort_web_artifacts_dir(corpus_id) / "embedding_pca.joblib" def default_web_tsne_artifacts_path(corpus_id: str) -> Path: """Artifacts for precomputed cohort t-SNE coordinates.""" return default_cohort_web_artifacts_dir(corpus_id) / "embedding_tsne.joblib" def default_web_style_artifacts_path(corpus_id: str) -> Path: """Artifacts for cohort style z-scores and style→percentile mapping.""" return default_cohort_web_artifacts_dir(corpus_id) / "style_cohort.joblib" def default_mlflow_tracking_uri() -> str: """Local MLflow tracking store under ``data/mlruns``.""" path = data_dir() / "mlruns" path.mkdir(parents=True, exist_ok=True) return path.as_uri() def default_lichess_inference_test_users_path() -> Path: """Default Lichess username list for inference batch smoke tests.""" return data_dir() / "inference" / "lichess_test_users.txt" def default_chesscom_inference_test_users_path() -> Path: """Default Chess.com username list for inference batch smoke tests.""" return data_dir() / "inference" / "chesscom_inference_test_users.txt" def default_inference_test_users_path(site: str = "lichess") -> Path: """Site-appropriate default username list for ``--use-test-users``.""" key = site.strip().lower().replace(" ", "") if key in ("chess.com", "chesscom", "chess-com"): return default_chesscom_inference_test_users_path() return default_lichess_inference_test_users_path() def default_site_rating_comparison_xlsx_path() -> Path: """Cross-site rating comparison table (Chess.com vs Lichess pools).""" return data_dir() / "inference" / "site_and_tc_rating_comparison.xlsx" def default_chesscom_lichess_rapid_model_path() -> Path: """Fitted Chess.com rapid → Lichess rapid linear model for inference.""" return data_dir() / "inference" / "chesscom_lichess_rapid_linear.joblib" def default_lichess_aix_dir() -> Path: """ Root for Hugging Face ``thomasd1/aix-lichess-database`` monthly Parquet files. Layout: ``data/lichess-aix/low_compression/aix_lichess_YYYY-MM_low.parquet`` """ path = data_dir() / "lichess-aix" path.mkdir(parents=True, exist_ok=True) return path def default_lichess_puzzles_dir() -> Path: """ Root for Hugging Face ``Lichess/chess-puzzles`` Parquet shards. Layout: ``data/lichess-puzzles/data/train-00000-of-00003.parquet`` (etc.) """ path = data_dir() / "lichess-puzzles" path.mkdir(parents=True, exist_ok=True) return path def default_lichess_parquet_dir() -> Path: """ Root for legacy Hugging Face ``Lichess/standard-chess-games`` hive Parquet shards. Layout: ``data/lichess-parquet/data/year=YYYY/month=MM/train-*.parquet`` The cohort L1 pipeline uses :func:`default_lichess_aix_dir` instead. """ path = data_dir() / "lichess-parquet" path.mkdir(parents=True, exist_ok=True) return path