Serve /api/{version}/figures.json with normalized name/tags/location/url, load manifest in MetricsPanel, and render/search figures from manifest (name/tags/location) with fallback behavior. Add tests and generated v1/v2/v3 figure manifests under docs/figures.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Switch visualize metrics/figures to local-first with Hugging Face raw fallback, harden MetricsPanel hook usage/field handling, and refactor tests into feature-based folders with expanded API/router/data/model coverage. Add pytest config and dependency updates.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- model_registry: _detect_n_feat now checks var_selection.softmax_proj.bias FIRST
(before lstm.weight_ih_l0) so TFT detection is correct: TFT's LSTM input is
d_model (64) not n_features, so the old order returned 64 instead of 12/18,
causing Missing key errors for feature_embeddings.12..63 on every boot
- model_registry: add _NON_FEATURE_COLS constant for CSV-to-feature filtering
- model_registry: add self.feature_cols (populated by load_all -> _load_feature_cols)
- model_registry: _load_feature_cols() reads battery_features.csv from
artifacts/{version}/features/, strips non-feature columns, validates against
scaler.n_features_in_; falls back to FEATURE_COLS_SCALAR for v1/v2/missing
- model_registry: _build_x now uses self.feature_cols (18 for v3, 12 for v1/v2)
so v3 classical models (all retrained with 18 features) get correct input
- api.ts: fix /api/api/v3/simulate -> /v3/simulate (baseApi already has /api prefix,
so prepending /api caused double prefix and 405 on ever…
- model_registry: add _detect_n_feat() to read input dim from PyTorch checkpoint
so v3 deep models (18 features) load without size-mismatch errors
- model_registry: _build_pytorch_model() now accepts n_feat param (was hardcoded to 12)
- model_registry: store n_feat in model_meta after successful PyTorch load
- model_registry: _build_sequence_array/_build_sequence_tensor accept n_feat and
zero-pad the 12-feature input to match each model's expected feature count
- model_registry: predict() reads stored n_feat for deep_pytorch, derives it from
model.input_shape[-1] for deep_keras
- model_registry: model_count now returns len(self.models) (loaded only, not failed)
- api.ts: simulateBatteries() now calls /api/v3/simulate (was /api/v2/simulate which
returned 405 because the simulate router lives under /api/v3)
feat: v3 models - XGBoost R2=0.9866, GradientBoosting R2=0.9860 as default
Full source commit (clean history, no LFS):
- Models stored in HF Hub (NeerajCodz/aiBatteryLifeCycle), not in git
- Docker startup: download_models.py fetches from HF Hub before uvicorn
- simulate.py: vectorized ML prediction, batchable for all tree/ensemble models
- GraphPanel, MetricsPanel, RecommendationPanel: full dashboard rewrites
- lucide-react icons, recharts analytics, interactive controls
- BestEnsemble v2.6 (RF+XGB+LGB weighted), no v3 generation
- download_models.py: checks for 3 key component models (rf/xgb/lgb) not just sentinel