Spaces:
Sleeping
Sleeping
Commit History
-
Odds tab: add pitcher strikeout alt lines with Standard/Alt Lines/Both view toggle
- Fetch pitcher_strikeouts_alternate market from TheOddsAPI - Normalize alt K rows: populate threshold from line, set market_variant=alternate, is_primary_line=False - Fix latent bug: threshold now populated for all K rows, enabling Strikeout Ladder Summary to render - Ladder Summary gains Variant column (Standard/Alt/Mixed), sorted Standard-first - K section adds horizontal radio: Standard (existing O/U grids) | Alt Lines (Over-only alt grid) | Both (unified single table of all lines) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>17be445
-
Fix export PNG to use current sort state instead of default order
The response_data path was unreliable — it returned None mid-interaction, causing fallback to the old sort. Now we re-apply the session-state sort model (always in sync with AgGrid) to the original data before returning, so the exported PNG always matches what the user sees in the grid. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>e6a8789 -
Use AgGrid flex to fill container proportionally without squishing columns
fit_columns_on_grid_load shrinks all columns equally. flex distributes remaining space proportionally to each column's weight so wider columns stay wider, narrower columns stay narrower, and no scroll occurs. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>2bcaea3 -
Fill odds table to container width using fit_columns_on_grid_load
Replaces hard-locked maxWidth with proportional scaling so columns fill the full available width without horizontal scroll. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>aea26b1 -
Increase Away, Home, and Consensus columns by 20%
Away/Home: 81→97, Consensus: 59→71 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>f10ecf7 -
Increase all odds table column widths by 10%
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>b5dcdcd -
Increase Away/Home and Width%/Discrepancy columns by 15%
Away/Home: 64→74, Width%: 46→53, Discrepancy: 54→62 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>26e51bd -
Filter live games from odds page — only show upcoming games
Live (in-progress) games are only shown on the dashboard. Added a commence_time filter to remove any game that has already started. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>afc1f6e -
Fix odds table scrolling: hard-lock column widths and reduce total to 1200px
- Set maxWidth=col_w (was col_w*2) so columns cannot expand beyond their set width - More aggressively reduce Consensus/Best Odds/Width%/Discrepancy/BetMGM/Caesars to 46-54px - Drop default book column width from 76→64px (FanDuel, DraftKings, etc.) - Total table width: 1352px → 1200px, fitting Streamlit wide-layout without scroll Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>25bb14e -
Decrease odds table column widths for BetMGM, Caesars, Consensus, Best Odds, Width %, Discrepancy
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>9202166 -
Fix odds table column sizing: explicit widths + fix CSS theme selector
- Add _COL_WIDTHS dict with per-column pixel widths (Player 148px, book cols 76px, etc.) so the table fits within the viewport without horizontal scrolling - Apply width/minWidth/maxWidth on each configure_column call - Fix _GRID_THEME CSS selectors from .ag-theme-balham-dark → .ag-theme-balham (dark styling was silently not applying since the theme name changed) - Reduce rowHeight 38→36, headerHeight 42→38 for slightly tighter rows Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>8cb929f -
Fix AgGrid theme: balham-dark → balham (removed in installed st-aggrid version)
st-aggrid no longer accepts 'balham-dark' as a theme string — only the enum members STREAMLIT, ALPINE, BALHAM, MATERIAL are valid. Dark styling is already applied via custom_css=_GRID_THEME so the visual result is unchanged. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>ce29352 -
Fix ImportError: replace _normalize_name_text import in trajectory_model.py
Phase 1C removed _normalize_name_text from pitcher_adjustment.py but trajectory_model.py was still importing it directly from there, causing a startup crash on HF Spaces. Now imports normalize_pitcher_name from data.odds_name_map aliased as _normalize_name_text so internal usage lines are unchanged. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>2d30550 -
Fix logging: use basicConfig(force=True) to override Streamlit's WARNING-level root config
Streamlit sets root logger level=WARNING before app.py executes. Our previous if-not-handlers guard was skipped once Streamlit's server added its own handler, leaving all INFO messages silently dropped. force=True removes existing handlers and guarantees INFO+ output to stderr in HF Spaces logs. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>a2e183a -
Fix logging: configure root logger so all module loggers output to stdout
Previously only the 'kasper' named logger had a StreamHandler. All modules using logging.getLogger(__name__) silently discarded their messages because the root logger had no handlers. This made HF Spaces app logs appear empty. Root logger now writes to stdout with timestamp + name format. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>9a44987 -
Merge remote: resolve mlb_starters.py conflict — keep conn param + remote team canonical map
Remote added _MLB_TEAM_CANONICAL, _canonical_team, _normalize_person, _names_match, build_oddsapi_starter_fallback_map, merge_probable_starters_with_odds_fallback, fetch_mlb_current_roster_map, and lookup_batter_current_team. Combined with our conn=None parameter and pitcher_resolution_log logging additions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>abe5c7e -
Accuracy overhaul: pitcher resolution logging, baseline recalibration, vig fix, XGBoost blend
Phase 1: Unified pitcher name normalization (normalize_pitcher_name), added pitcher_resolution_log table with logging from mlb_starters, live feed, and statcast lookup. Color-coded debug page section for resolution audit. Phase 2: Baseline HR probability 0.045 → 0.036 (empirical MLB 2024 per-PA rate). Phase 3: HR edge now uses single-sided vig removal (p / 1.055) instead of circular two-way normalization. Added kelly_pct to recommendation output. Phase 4: Removed double-counted temperature/wind adjustments from context_adjustment.py — environment_model.py owns all weather signals. Phase 5: BET threshold 6%/78 → 3.5%/72; WATCH 2.5%/62 → 1.5%/58. Phase 6: XGBoost HR delta blended at 20% weight when xgb_blend_eligible. Added validate_xgb_batch() for batch-level sanity checks. Phase 7: Hit-type distribution corrected — singles 0.76→0.62, doubles 0.20→0.33 (empirical MLB 2024 non-HR hit mix). Phase 9: edge.py converted to re-exports from no_vig_props.py (single source of truth for al…21151ce -
Upgrade odds tables and strikeout ladders
4d26aa1 -
Odds tab: fix Discrepancy sort, sparse color coding, export sort alignment
- Discrepancy: assign float64 directly from numeric_df (removes object-dtype int/None column that caused lexicographic sort) - Color coding: handle single-book rows (green) and tied-odds rows (yellow) so 2+ HR tables are colored even when only one book posts a line - Server-side sort selector added per table (Discrepancy/Best Odds/Width %/EV/ Player); export PNG uses the same sorted display_df Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>aede0e8 -
Odds tab: fix Discrepancy sort + revert team_universe
- Discrepancy column now stores plain int (was "300 pts" string), so Streamlit sorts it numerically instead of lexicographically - Revert cross-market team_universe computation that was causing HuggingFace restart loop; team dropdown reverts to per-market teams Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>8ebf203 -
Odds tab: team dropdown uses cross-market universe
All four market tabs (HR/K/Hits/TB) now show the same team list, built from the full merged props feed rather than per-market subset. Teams with lines in any market appear in every tab's filter. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>3242b6f -
Odds tab: text color coding, HR overs-only all thresholds, PNG export
- _norm_to_rdylgn_css: returns color + font-weight (text) instead of background - _css_text_color: new helper to parse CSS color for PNG renderer - render_betting_tab: remove is_primary_line filter so all HR thresholds show - _render_market_section: skip HR unders; add Export PNG download button per table - _render_table_png: PIL-based dark-theme PNG with KASPER/@KasperMLB branding Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>7539471 -
Fix Odds tab ValueError: replace gmap+background_gradient with custom CSS
background_gradient(gmap=DataFrame, axis=1) raises ValueError on this pandas version because row-by-row processing passes each row as a Series, which cannot be aligned with a DataFrame gmap. Replace with a CSS-precomputation approach: - Add _norm_to_rdylgn_css(norm): converts [0,1] → RdYlGn hex CSS - Add _col_gradient_css(): column-wise gradient CSS in-place - Add _build_css_df(): computes full CSS DataFrame for all columns (book cols row-wise by implied prob, Width%/Discrepancy/EV col-wise) - Apply via Styler.apply(lambda _: css_df, axis=None) — no gmap Also fixes _render_vig_section() which had the same background_gradient pattern. Removes the broken _apply_gradient() helper entirely. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>69d2f1d -
Rework Betting tab → Odds: live market-by-market sportsbook comparison
New visualization/betting_page.py replaces the old edge-chart view with per-market tables (HR / K / Hits / Total Bases). Each row is a player prop; columns are sportsbook odds + derived analytics. Row-wise green/red gradient highlights the best book per player. All columns sortable. All 8 upgrades implemented: U1: Line movement arrows (▲▼ delta vs previous render via session state) U2: Steam move banner + per-cell 🔥 flag (≥5pt move in 15-min window) U3: Vig % expander per market section (two-sided markets only) U4: Time-to-game badge (🟢🟡⚪🔴) derived from commence_time U5: Player name search + team filter above each table U6: Threshold selector (0.5/1.5/2.5 HR, 4.5/5.5/6.5 K, etc.) U7: Missing book indicator ("—" in muted gray) U8: EV column using model probability from Props page session state Tab renamed "Betting" → "Odds" in sidebar navigation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>77c7ee3 -
Fix roster cache hammering: rate-limit empty/error retries to 5 minutes
The previous fix (don't cache empty roster results) caused the debug page to hammer the MLB Stats API — one HTTP request per pitcher candidate (~30 total) per page render, each with a 15s timeout, blocking for 7+ minutes and causing HuggingFace to kill and restart the container. Add _ROSTER_MAP_EMPTY_UNTIL timestamp: on empty result or network error, block retries for 5 minutes. This allows recovery without hammering the API, while still eventually retrying (unlike the original permanent-cache bug). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>fd52637 -
Fix pitcher resolution table: roster cache, two-candidate fallback, debug rebuild
RC1: fetch_mlb_current_roster_map() now uses gameType="R,S" so spring training roster data is returned pre-opening-day. Empty results (network error or truly empty API response) no longer permanently cache {} — the guard now returns {} without setting _ROSTER_MAP_CACHE, so the next call retries. RC2: Debug page pitcher resolution expander now always rebuilds from the live props feed (upcoming_props_debug) rather than only when session state is empty. Previously, visiting Props page first would populate merged_starters with Stats-API-only data, making `if not merged_starters` False and skipping odds API pitchers entirely. RC3: build_oddsapi_starter_fallback_map() adds elif branch for the two-candidate both-blank scenario: when exactly 2 K-props pitcher candidates exist, team inference fails for both, and neither away nor home pitcher has been set, assign alphabetically as a deterministic last-resort heuristic. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>a54e483 -
Feed odds API pitchers into debug pitcher resolution table
- In build_oddsapi_starter_fallback_map(): after _infer_pitcher_team_from_rows() returns empty, fall back to lookup_batter_current_team() (roster API cache) so offseason acquisitions/traded pitchers are correctly team-matched - In render_debug(): when session state has no props_prepared_bundle, build the pitcher resolution table directly from upcoming_props_debug merged_props_feed + DB-cached probable starters, eliminating the requirement to visit the Props page first in the same session - Add read_cached_probable_starters, build_oddsapi_starter_fallback_map, merge_probable_starters_with_odds_fallback imports to debug_page.py Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>c16be6b -
Fix debug dashboard 10-minute hang — limit unbounded DB reads
- Add LIMIT 2000 to read_recommendation_audit_view CTE query - Add read_recommendation_logs_recent() with LIMIT 2000 (replaces full table scan) - Add LIMIT 2000 to read_batter_prop_audit_view query - Replace read_table("recommendation_logs") with read_recommendation_logs_recent in _load_debug_audit_bundle() - Wrap _load_debug_audit_bundle() call site in 15s thread timeout so a slow DB never blocks the full page render Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>19017e4
-
Fix pitcher resolution: add MLB roster fallback for batter team lookup
Root cause: _resolve_batter_team() used historical statcast (2025 season) to identify a batter's team. Players who changed teams in the offseason had stale team names that no longer matched either participant in today's game, causing `batter_team_unresolved` and leaving pitchers unresolved even when both starters were known. Changes: - props_mapper.py: restructure _resolve_batter_team() so statcast early- exits no longer skip the roster fallback; suppress stale historical-team returns that don't match the current game (removed old line 349) - mlb_starters.py: add fetch_mlb_current_roster_map() (MLB Stats API /api/v1/sports/1/players?season=2026, process-lifetime cached) and lookup_batter_current_team() which is called as Level 4 fallback in _resolve_batter_team() when statcast resolution fails Players now resolve via "mlb_roster_lookup" source for offseason acquisitions, new players, and anyone not in statcast data. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>f2d8d50 -
Perf: parallelize TheOddsAPI event loop, fix schema init overhead
- provider_theoddsapi: replace serial per-event HTTP loop (worst case 457s) with ThreadPoolExecutor(max_workers=8) + 45s wall-clock cap via concurrent.futures.wait; adds _fetch_event_odds() helper - database/db: initialize_schema() now runs once per process lifetime via _schema_initialized guard + lock instead of on every get_connection() - shared_baseline: wrap 8 sequential snapshot DB reads in a daemon thread with 20s wall-clock timeout; returns degraded bundle on timeout - app.py: wrap replace_cached_upcoming_props_bundle() write in a daemon thread with 15s timeout so cache persist never blocks the render path Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>bd7830d -
Hotfix: add missing logging import and _log definition to shared_baseline.py
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>d62515b -
Recover props terminal UI redesign; fix pitcher filter and cache hang
- Restore be663f7 'Redesign Props page terminal UI' (521 insertions) lost during HF Space recovery git reset - Fix _filter_probable_starters_to_slate() to use _canonical_team() instead of _normalize_team_key() so 'sfg' matches 'san francisco giants' - Add LIMIT 5000 to cached_upcoming_props_rows query to prevent 5+ min full-table scan as table grows unbounded - Wrap read_cached_upcoming_props_bundle() in thread+10s timeout; on timeout raises RuntimeError caught by existing except block → falls through to live HTTP fetch - Re-apply timeout banner (360s auto-reload) and async _maybe_log_props Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>0b4a187 -
Fix props page hang: reduce build timeout to 5s, fix st.session_state in cache, async log
- Reduce _FALLBACK_BUILD_TIMEOUT_SECONDS from 40s to 5s: users now wait max 5s before content appears (vs 40s which appeared as a hang) - Move st.session_state write out of @st.cache_data to render_props(): prevents StreamlitAPIException on newer Streamlit; use setdefault to avoid resetting the reload timer on reruns - Wrap _maybe_log_props() in threading.Thread with join(timeout=5): prevents DB insert hang from blocking the render pipeline; logs still written synchronously within 5s or fire-and-forget if DB is slow Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>28a1d5a -
Add 40s timeout to baseline build branches to prevent props page hang
Wraps Branch 2 (patch build) and Branch 3 (full fallback build) in threading.Thread with join(timeout=40). On timeout: returns empty/partial bundle immediately, queues a persist-when-done background thread so next load hits the fast snapshot path. Props page shows an info banner and auto-reloads ~80s later once snapshots are populated. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>7b21bf1 -
Fix pitcher resolution via canonical team mapping; remove live edge strip UI
- data/mlb_starters.py: Add _MLB_TEAM_CANONICAL dict and _canonical_team() to bridge statcast abbreviations (sfg) against Odds API full names (san francisco giants). Update _infer_pitcher_team_from_rows() and lookup_pitchers_for_game() to use canonical comparison. - app.py: Remove render_recommendation_panels() and render_model_explainer() calls from render_live_games_with_edge_strips() — DB logging logic intact. - visualization/debug_page.py: Add Pitcher Resolution expander showing merged_starters per matchup with sources. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>dd66ccf -
Speed up Props baseline and market loading
cf6ef4c -
Remove Fangraphs from Props runtime
c4cd7c6 -
Remove Fangraphs starter fallback in favor of MLB and Odds API
0dfe795 -
Add safe FanGraphs starter fallback
51b1a14 -
Recover props/debug load times
549ba63 -
Stabilize props baseline and starter resolution
bb05a74 -
Hide tracked-only games from HR game explorer
7ac6efd -
Improve app speed via payload caching and reuse
54a42dd -
Optimize props load path and reuse modeled state
2885bcc
-
Fix nested expander on debug page
6f26a97 -
Fix strikeout v2 reason tag payload
71e8078 -
Promote strikeout v2 and harden telemetry models
50dc123 -
Add props confidence breakdown diagnostics
d3b6f35 -
Preserve usable HR snapshot during degraded refresh
e5071ce -
Add DraftKings-first HR supplemental coverage
7e836ba