7660893538
## Motivation The socket-based internet connectivity probes (connecting to 1.1.1.1/8.8.8.8/1.0.0.1 every 10 seconds) are flaky — they produce false negatives on some networks/ISPs, causing downloads to silently fail or get stuck. Instead of dynamically detecting connectivity, this replaces it with an explicit offline mode that the user opts into. ## Changes - **Removed internet check infrastructure**: Deleted `_test_internet_connection()` (socket probes) and `_check_internet_connection()` (10s polling loop) from `DownloadCoordinator` - **Renamed `internet_connection` → `offline`** on `ShardDownloader` base class and all subclasses (`SingletonShardDownloader`, `CachedShardDownloader`, `ResumableShardDownloader`) - **Removed `on_connection_lost` callbacks** from download calls — no longer needed without dynamic connectivity detection - **Added `EXO_OFFLINE` env var support** in `constants.py` and `Args` default in `main.py` - **Added Offline Mode toggle** to macOS app Settings → General tab, which sets `EXO_OFFLINE=true` in the process environment and restarts ## Why It Works The download behavior (`skip_internet` conditionals in `download_utils.py`) is unchanged — we just changed what drives it. Instead of a flaky socket probe setting `internet_connection=True/False`, the user explicitly sets offline mode via: 1. `--offline` CLI flag 2. `EXO_OFFLINE=true` environment variable 3. macOS app Settings → General → Offline Mode toggle This is more reliable and predictable. Users on flaky networks no longer get intermittent download failures. ## Test Plan ### Manual Testing - `uv run exo --offline` starts without internet checks, rejects downloads for unavailable models - `EXO_OFFLINE=true uv run exo` behaves identically - macOS app Settings toggle persists across restarts and passes env var to the exo process ### Automated Testing - All existing tests pass (222 passed), including 8 offline-mode specific tests - `uv run basedpyright` — 0 errors - `uv run ruff check` — all checks passed - `nix fmt` — 0 files changed 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>