No description
Find a file
2026-11-04 10:13:16 +01:00
src chore(deps): ureq 2.12 -> 3.5, the version the code was written against is two majors behind 2026-11-03 09:57:22 +01:00
tests fix(paths): fail loud when HOME is unset, and make parity tests bite 2026-10-31 09:07:30 +01:00
.gitignore chore: initial commit 2026-10-30 12:45:06 +01:00
Cargo.lock chore(deps): ureq 3.5.1 (connection reuse and cookie header fixes) 2026-11-04 10:13:16 +01:00
Cargo.toml chore(deps): ureq 2.12 -> 3.5, the version the code was written against is two majors behind 2026-11-03 09:57:22 +01:00
README.md chore: initial commit 2026-10-30 12:45:06 +01:00

ollama-cloud (Rust)

Rust-Port von ~/.hermes/scripts/ollama_cloud_usage.py und ~/.hermes/scripts/ollama_cloud_watchdog.py. Liest die Usage-Seite von ollama.com, parst Session- und Weekly-Verbrauch, führt eine Snapshot-Historie und prognostiziert, ob das Limit vor dem Reset erreicht wird.

Zwei Binaries, eine Lib:

Binary ersetzt
ollama-cloud-usage ollama_cloud_usage.py
ollama-cloud-watchdog ollama_cloud_watchdog.py

Warum

Beide Skripte laufen bei jedem Agenten-Lauf und der Watchdog zusätzlich im 10-Minuten-Takt. Sie teilen HTTP-Fetch, HTML-Parser, Historie und Prognose — deshalb ein Crate mit gemeinsamer Lib statt zwei getrennter Projekte.

Bauen und installieren

cargo build --release
install -m 755 target/release/ollama-cloud-usage ~/bin/ollama-cloud-usage
install -m 755 target/release/ollama-cloud-watchdog ~/bin/ollama-cloud-watchdog

Benutzen

ollama-cloud-usage              # menschlich lesbar (Default)
ollama-cloud-usage --json       # Usage-Payload
ollama-cloud-usage --check      # Exit 0 OK / 1 Warnung (>=80%) / 2 kritisch (>=95%)

ollama-cloud-watchdog           # watch (Default): Snapshot + Meldung nur bei Problemen
ollama-cloud-watchdog --snapshot
ollama-cloud-watchdog --predict # Prognose-Meldung
ollama-cloud-watchdog --message # wie --predict
ollama-cloud-watchdog --json    # vollständige Prognose
ollama-cloud-watchdog --check   # Exit 0/1/2
ollama-cloud-watchdog --history # letzte 20 Snapshots
ollama-cloud-watchdog --clear   # Historie + Statusdatei löschen

Dateien: ~/.hermes/ollama_cookie.txt, ~/.hermes/ollama_usage_history.json, ~/.hermes/ollama_cloud_status.json. HOME wird respektiert.

Für Tests/Proxies lässt sich die Quelle über OLLAMA_SETTINGS_URL überschreiben (Default https://ollama.com/settings) — eine additive Ergänzung, die das Original nicht hat.

Abweichungen zum Python-Original

  1. Login-Seite ist ein Fehler, nicht 0 %. Antwortet ollama.com nach abgelaufenem Cookie mit einem Redirect auf die Login-Seite (HTTP 200, aber ohne Usage-Marker), meldet das Original Session=None% und --check gibt OK zurück — der Monitor ist dann blind. Hier enden beide Binaries mit Exit 2 und … cookie likely expired. Bewusst und getestet.
  2. JSON ist UTF-8 statt \uXXXX. Python nutzt ensure_ascii=True; Umlaute und Emojis in der Prognose-Meldung stehen hier direkt. Semantisch identisch, besser lesbar in cat/jq.
  3. --help / --version existieren zusätzlich.
  4. Ein Snapshot mit session_pct: null wird als 0 behandelt; das Original stürzt an dieser Stelle mit TypeError ab.

Tests

cargo test

10 Tests. Die Paritätstests importieren das jeweilige Python-Modul mit gepatchter SETTINGS_URL und setzen HOME auf ein Temp-Verzeichnis, sodass beide Implementierungen dieselben Mock-Antworten und dieselben Dateien sehen. Die Historie-Fixture wird einmal aus now() gebaut und an beide Seiten gegeben — seeded man jede Seite mit ihrem eigenen now(), kreuzt das alle paar Dutzend Läufe eine Minutengrenze und die Ausgaben unterscheiden sich um eine Sekunde (aufgetreten am 2026-10-30, behoben):

  • usage_json_matches_python — Byte-Vergleich
  • usage_human_matches_python — Byte-Vergleich (nur die Timestamp-Zeile maskiert)
  • usage_check_matches_python — Ausgabe und Exit-Code
  • watchdog_check_matches_python — mit zwei Snapshots in der Historie (Burn-Rate)
  • watchdog_predict_matches_python — komplette Meldung Byte für Byte
  • watchdog_json_matches_python_semantically — Felder gleich, Float-Toleranz 1e-6
  • watchdog_history_and_clear_match — Ausgabe, Exit-Code und Dateiinhalt
  • missing_cookie_exits_two
  • unknown_watchdog_mode_exits_one
  • login_page_is_an_error_not_zero_percent — die bewusste Abweichung

Messung (2026-10-29)

--history, also ohne Netzwerk, 5 Läufe:

Rust    < 10 ms
Python   30 ms

Mit Netzwerk dominiert der HTTP-Request (15 s Timeout, real ~200–400 ms), dort ist der Startvorteil nebensächlich — der Port lohnt wegen der Aufruffrequenz, nicht wegen CPU.