Hermes Tour Assistant đŸšŽđŸš¶

August 1, 2026 · View on GitHub

Hermes Tour Assistant

Bau dir deinen persönlichen Tour-Begleiter fĂŒr Hermes Agent. Egal ob Radtour, Wanderung oder Stadtbummel — der Assistent ĂŒberwacht deine Live-Standort, warnt vor Routenabweichungen, findet Wasser- und Versorgungspunkte, checkt das Wetter und erzĂ€hlt dir an Stationen spannende Geschichten. Und das alles leise: Nur wenn wirklich was los ist, meldet er sich.

  • 🚮 Outdoor Tour Assistant — GPX-RoutenĂŒberwachung mit Echtzeit-Warnungen
  • đŸ™ïž City Walk Guide — persönlicher, quellengestĂŒtzter Stadtrundgang per Telegram
  • 💧 Live Location Nearby — findet Wasser, Essen, Reparatur, Unterkunft
  • đŸ€« Silent by default — kein Rauschen, nur Signale

Private, standortbewusste Outdoor- und StadtfĂŒhrungs-Skills fĂŒr Hermes Agent. Der Outdoor-Assistent ĂŒberwacht GPX-Touren leise und ereignisbasiert. Der City Walk Guide plant einen persönlichen, belegten Stadtrundgang und erzĂ€hlt an erreichten Stationen per Text und optionaler Telegram-Voice-Bubble.

Schweigen ist der Normalfall. Ohne ausgewĂ€hltes Ereignis antwortet der Cron-Agent ausschließlich mit [SILENT].

Stand: Version 1.4.1

Neu in 1.4.1 — Weather Hunter đŸŒ€ïž & Mobile-Optimierung đŸ“± & TTS-Sprachausgabe 🎧

  • StĂŒndliche Niederschlagsvorhersage via Open-Meteo
  • Berechnet ob du dem Regen davonfahren kannst ("Noch 15 min bis Regen — bei 28 km/h schaffst du's!")
  • Neue Event-PrioritĂ€t weather_hunter im Event-Engine-Cooldown-System
  • CLI-Kommando tourctl.py weather-forecast --hours 3
  • Mobile-optimierte Alerts fĂŒr iPhone Lock Screen:
    • Emoji-Marker als visuelle Kategorie (đŸŒ§ïžâš ïžđŸšŽđŸ˜ïžđŸœïžđŸ“âœ…)
    • Aktion + Distanz fett in Zeile 1 = Lock-Screen-Preview
    • Maximal 3 Zeilen pro Alert
    • Beispiel: đŸŒ§ïž **Regen in 12 min** – 8 km voraus
  • TTS-Sprachausgabe (lokaler qwen3-george Klon 🎧):
    • POI-Ansagen werden als Telegram-Voice-Bubble ausgeliefert
    • Wikipedia-Inhalte vom LLM auf 30–60 Sekunden gekĂŒrzt
    • Aktiviert per [[audio_as_voice]]-Tag fĂŒr native Voice-Bubble
    • LĂ€uft lokal – keine Latenz, keine Kosten, offline-fĂ€hig
  • Dynamische Cadence (Rhythmus) ⏱:
    • GeschwindigkeitsabhĂ€ngig: >20 km/h → 3 min, 5–20 km/h → 5 min, <5 km/h → 15 min
    • Ziel-AnnĂ€herung: <5 km Rest → 2 min-Takt
    • Orts-AnnĂ€herung: automatischer Wake bei <3 km zur nĂ€chsten Stadt
    • Routenabweichung: sofortiger Wake bei >150 m Abweichung
    • Mittags-Timer: 10–14 Uhr, einmaliger Einkehrtipp
    • Maximal 15 min Stille als Fallback
  • Live-Standort-Frequenz 📡:
    • Telegram sendet auf dem iPhone alle 2–10 Sekunden
    • Hermes-Adapter cached alle Edits → kein LLM-Call pro Update
    • Gate-Script entscheidet im Sekunden/Minuten-Takt, ob der Agent geweckt wird
    • ≈600 Location-Updates/Stunde → ≈12–20 LLM-Checks/Stunde

Version 1.4 ergÀnzt den fachlich getrennten city-walk-guide und zieht gemeinsame Standort-, State-, Routing-, Provider- und Ausgabeprimitive in location-session-core. Der Outdoor-State v3 und seine Migration bleiben kompatibel.

Der Outdoor-Assistent verwendet weiterhin einen einzigen produktiven Datenfluss:

  • ein selbst enthaltenes, installierbares Skill-Paket;
  • Session-State v3 mit Migration aus v1 und v2;
  • prozessĂŒbergreifende Sperre, atomare Writes und private Dateirechte;
  • segmentbasiertes GPX-Matching einschließlich AmbiguitĂ€tserkennung;
  • ein Gate ohne prĂ€zise Koordinaten im Cron-stdout;
  • priorisierte Events mit Evidenzpflicht, Confidence und Cooldown;
  • normalisierte Providerfehler, Backoff, Circuit Breaker und TTL-Cache;
  • strukturierte aktuelle Wetterdaten ĂŒber Open-Meteo;
  • strukturierte Karten-, Siedlungs-, Versorgungs- und Wassersuche ĂŒber OpenStreetMap/Nominatim/Overpass;
  • ein abgesicherter lokaler GPX-Adapter fĂŒr exportierte Komoot- oder Drittanbieter-Routen;
  • sichere Markdown-Labels und ausschließlich lokal erzeugte Navigationslinks;
  • Diagnose-, Retention- und Agent-Kommandos ĂŒber tourctl.py.

Der City Walk Guide bietet zusÀtzlich:

  • einen validierten GuideRequest fĂŒr 30–240 Minuten;
  • standardmĂ€ĂŸig einen 90-minĂŒtigen Rundgang mit lokalem Leben, Genuss, Geschichte und Architektur;
  • OSM-Kandidaten sowie deutsche Wikipedia- und Wikidata-Inhalte mit markiertem Englisch-Fallback;
  • eine OpenRouteService-Fußroute innerhalb von ±15 Prozent des Zeitbudgets;
  • privat vorab geladene, quellengestĂŒtzte Geschichten;
  • Stopauslösung bis 80 Meter und Neuplanung nach zwei Abweichungen ab 120 Meter;
  • validierte Betriebs- und Dialogkommandos ĂŒber cityctl.py.

Die Anwendung ist ein Informations- und Entwicklungswerkzeug, kein zertifiziertes Navigations- oder Warnsystem.

Architektur

flowchart LR
    T["Telegram-Location-Cache"] --> I["Input Adapter<br/>Schema, Alter, Session"]
    I --> S["State Repository v3<br/>Lock, 0700/0600, atomar"]
    S --> G["Profilspezifische Gate Policy"]
    G --> C["Cron GateDecision<br/>sanitierter Kontext"]
    C --> A["Outdoor- oder City-Skill"]
    A --> P["Gemeinsame Provider Adapter"]
    P --> N["Normalisierung + Evidenz"]
    N --> R["Route Engine"]
    N --> E["Event Engine"]
    R --> E
    E --> O["Ein Alert oder SILENT"]
    E --> S

Das LLM editiert den technischen State nicht. Route, Siedlungen, Providerdaten und Ereignisse werden ausschließlich ĂŒber die validierten Runtime-Kommandos geschrieben.

Benachrichtigungspolitik

Die Event Engine priorisiert:

  1. akute Sicherheit;
  2. deutliche Routenabweichung;
  3. Wetterwarnung;
  4. kritische VersorgungslĂŒcke;
  5. verifizierte OrtsannÀherung;
  6. Komfort-POI.

Pro Wake wird höchstens ein normales Ereignis geliefert. Bis zu drei Meldungen sind nur zulÀssig, wenn alle sicherheitskritisch sind. Externe Ereignisse ohne Evidenz oder mit Confidence unter 0.5 bleiben stumm.

Neutrale Punkte entlang einer Route heißen route_checkpoint. Sie sind keine Siedlungen und lösen keinen town_approach aus.

Repository-Struktur

hermes-tour-assistant/
├── README.md
├── INSTALLATION.md
├── SECURITY.md
├── pyproject.toml
├── .gitignore
├── skills/
│ ├── outdoor-tour-assistant/
│ ├── city-walk-guide/
│ ├── location-session-core/
│ └── live-location-nearby/
├── services/
│ └── owntracks-receiver/     # Optionaler Standort-Infrastruktur-Service
├── scripts/
│ ├── tour-assistant-update.sh # Deployment- und Update-Skript
│ └── owntracks-start.sh       # OwnTracks-Receiver-Startskript
└── tests/`

Jeder nutzerseitige Skill besitzt genau einen kanonischen Ordner. Der interne location-session-core enthÀlt die gemeinsam genutzte Implementierung; schmale Outdoor-KompatibilitÀtsmodule erhalten bestehende Installationen und Imports.

Schnellstart

git clone https://github.com/MaikD77/hermes-tour-assistant.git
cd hermes-tour-assistant
cp -R skills/outdoor-tour-assistant ~/.hermes/skills/
cp -R skills/live-location-nearby ~/.hermes/skills/
cp -R skills/location-session-core ~/.hermes/skills/
cp -R skills/city-walk-guide ~/.hermes/skills/

Beispiele — was du damit machen kannst

SkillBeispiel-PromptErgebnis
🚮 Outdoor„Ich starte meine Spessart-Tour, ĂŒberwache mich."Routen-Matching, Live-Tracking, Wetter + Warnungen
đŸ™ïž City Walk„Gib mir einen 90-minĂŒtigen Stadtrundgang durch Erfurt."QuellengestĂŒtzter Rundgang mit Geschichten pro Station
💧 Nearby„Wo gibt's hier Trinkwasser?"NĂ€chste Brunnen/Tanks/RaststĂ€tten via OSM
🛑 Sicherheit„Bin ich noch auf der Route?"Routenabweichung + Off-Route-Alarm

Die Hermes-Service-Umgebung benötigt mindestens:

export HERMES_TOUR_CHAT_ID="DEINE_TELEGRAM_CHAT_ID"
export HERMES_TOUR_ACTIVITY="cycling"  # oder walking
export HERMES_TOUR_LOCALE="de-DE"
# optional: Verzeichnis mit vorab exportierten GPX-Routen
export HERMES_TOUR_ROUTE_DIR="/privater/pfad/zu/routen"
# fĂŒr den City Walk Guide
export HERMES_CITY_GUIDE_CHAT_ID="DEINE_TELEGRAM_CHAT_ID"
export OPENROUTESERVICE_API_KEY="DEIN_ORS_SCHLUESSEL"

Das Gate muss jede Minute gestartet werden:

# Direkter Aufruf des Skill-Gates:
python3 ~/.hermes/skills/outdoor-tour-assistant/scripts/live_tour_gate.py

# Oder via Wrapper (fĂŒr Cron mit Umgebungsvariablen):
python3 ~/.hermes/scripts/live_tour_gate.py

Das Deployment erfolgt ĂŒber das Update-Skript im Repository:

bash scripts/tour-assistant-update.sh

FĂŒr die OwnTracks-Standortquelle muss der Receiver gestartet werden:

bash scripts/owntracks-start.sh

Der vollstÀndige Cronjob, Betriebsbefehle und Rollout stehen in INSTALLATION.md.

State v3

Der private State liegt standardmĂ€ĂŸig unter ~/.hermes/state/live_tour_assistant.json und enthĂ€lt:

  • session – pseudonyme Share-ID und Lebenszyklus;
  • route – Matchstatus, Provider, privater GPX-Pfad und verifizierte Orte;
  • position – interne Position und deterministischer Routenmatch;
  • schedule – Cadence, Wake-Zeitpunkte, Hysterese und Cooldowns;
  • events, weather und provider_health.

Alte v1-/v2-ZustÀnde werden beim ersten Zugriff validiert nach v3 migriert. BeschÀdigte Dateien werden privat unter live_tour_assistant.json.corrupt-* quarantÀnisiert.

Entwicklung

python3 -m pip install -e ".[test]"
ruff check skills tests
mypy skills/location-session-core/scripts skills/outdoor-tour-assistant/scripts skills/city-walk-guide/scripts
pytest --cov --cov-fail-under=85
python3 -m build

Die Tests verwenden keine echten Standort- oder Providerdaten. Realer Rollout erfolgt ĂŒber Replay, Shadow Mode und Canary Delivery.

Datenschutz

PrĂ€zise Standorte bleiben aus Gate-Ausgabe und Diagnoseberichten heraus. City Walks verwenden den separaten privaten State ~/.hermes/state/city_guide_state.json und werden nach Abschluss standardmĂ€ĂŸig nach 24 Stunden bereinigt. Ein expliziter Provideraufruf kann die aktuelle oder vorausliegende Position an den konfigurierten Anbieter ĂŒbertragen und erscheint gegebenenfalls im Hermes-Tool-Audit. Details und Grenzen stehen in SECURITY.md.


GitHub Topics (empfohlen): hermes-agent, hermes-skill, outdoor, cycling, city-walk, gpx, telegram-bot, live-location, openstreetmap, osm

Community & Austausch

PlattformWo posten?Warum?
🎼 Nous Discord#agent128k+ Mitglieder, aktivste Community
đŸ“± Redditr/hermesagentOffizielles Sub, Nous-Team aktiv
💬 GitHub DiscussionsHermes AgentSkills teilen & diskutieren
📖 Skills HubHermes DocsCommunity-Skills-Katalog
🐛 IssuesHierBug-Reports & Feature-WĂŒnsche

Quellenneutrale Standortarchitektur

Alle Standortverbraucher arbeiten mit einer unverĂ€nderlichen, validierten LocationObservation; Telegram-, OwnTracks- und Replay-Payloads bleiben in ihren Adaptern. Die deterministische Standardreihenfolge ist owntracks,telegram und kann mit HERMES_LOCATION_SOURCE_ORDER geĂ€ndert werden. Telegram bleibt eine unterstĂŒtzte Fallback- und Legacy-Quelle. Bestehende Installationen stellen das frĂŒhere Verhalten mit telegram,owntracks wieder her. ReplayLocationSource dient reproduzierbaren Tests und Offline-Demonstrationen und legt keine Historien-Datenbank an.

flowchart LR
  OT[OwnTracks Receiver API] --> OA[OwnTracks adapter]
  TG[Telegram snapshot] --> TA[Telegram adapter]
  RP[Replay observations] --> RA[Replay adapter]
  OA --> R[Deterministic source resolver]
  TA --> R
  RA --> R
  R --> O[LocationObservation]
  O --> OG[Outdoor gate/runtime]
  O --> CG[City gate/runtime]

Der Resolver fragt Quellen strikt nacheinander ab; die erste gĂŒltige und aktuelle Beobachtung gewinnt. Diagnosen enthalten nur Quellname und Zustand (not_available, stale, invalid, unreachable), niemals genaue Koordinaten.

BeobachtungsidentitÀt und Zeitmodell

observation_id ist eine reproduzierbare, koordinatenfreie SHA-256-Kennung ĂŒber kanonisch serialisierte IdentitĂ€tsfelder einer einzelnen Quellenbeobachtung. Sie ist keine Personen-, Sitzungs- oder Ortskennung. observed_at und received_at sind intern ausschließlich timezone-aware UTC-datetime-Werte. Quellspezifische Metadaten werden nach Adapter-Allowlist als sortiertes, unverĂ€nderliches Tuple gespeichert; Rohpayloads, Koordinatenkopien, Secrets und Credential-URLs sind unzulĂ€ssig. Die Architekturentscheidung und Migrationsfolgen stehen in ADR 0001.

Deterministische Movement Engine

Der gemeinsame Core leitet aus LocationObservation ausschließlich regelbasiert die Modi unknown, stationary, walking, cycling und automotive ab. BestĂ€tigte ÜbergĂ€nge erzeugen deterministische Ereignisse und kompakte aktive oder abgeschlossene Segmente. Confidence bezeichnet nur technische Klassifikationssicherheit. Hysterese (drei Beobachtungen, 20 s Mindestdauer, 45 s Cooldown), QualitĂ€tsgrenzen und getrennte EintrittsbĂ€nder verhindern Flattern und Fehlklassifikationen durch einzelne GPS-SprĂŒnge. Kurze LĂŒcken bis 180 s bleiben im Segment; ab 900 s wird es abgeschlossen.

flowchart TD
  O[LocationObservation] --> V[Observation validation]
  V --> E[Movement Engine]
  E --> S[MovementState]
  S --> ES[MovementEvents + MovementSegment]
  ES --> C[Outdoor / City / zukĂŒnftige Context Consumer]

Die Engine ist in Sprint 2 nicht an Versand- oder Gate-Entscheidungen angeschlossen. movementctl.py status|diagnose|replay|reset bietet koordinatenfreie Diagnose; Replay akzeptiert nur Dateien mit synthetic: true. Details: ADR 0002.

PrÀzisierungen aus dem Sprint-2-Review

Aktive Segmente verwenden einen konstant großen privaten Akkumulator fĂŒr Startpunkt, ungerundete Gesamtdistanz, Maximalgeschwindigkeit und zirkulĂ€re Heading-Summen. Damit bleiben Segmentmetriken nach Ringpufferrotation und State-Neuladen korrekt; der Diagnose-Output gibt den privaten Startpunkt niemals aus. Der recent-Puffer bleibt auf buffer_size begrenzt.

Die Geschwindigkeitsbereiche sind disjunkt: stationary <= 0,7 m/s, walking <= 2,6 m/s, cycling < 10,0 m/s und automotive >= 10,0 m/s. Deshalb mĂŒssen HERMES_MOVEMENT_CYCLING_MAX_MPS und HERMES_MOVEMENT_AUTOMOTIVE_MIN_MPS denselben Übergangswert besitzen. StationĂ€r wird erst nach der vollstĂ€ndigen stationary_min_seconds-Dauer innerhalb des Radius bestĂ€tigt.

FĂŒr einen quellenĂŒbergreifenden Stream muss beim Erzeugen sowohl des OwnTracks- als auch des Telegram-Adapters derselbe explizite canonical_device_id (z. B. aus HERMES_LOCATION_CANONICAL_DEVICE_ID=maik-iphone) ĂŒbergeben werden. Event- beziehungsweise Message-IDs verbleiben in source_metadata; ohne explizite Zuordnung werden GerĂ€te nicht implizit vermischt.

Private Place & Stay Engine

Sprint 3 ergĂ€nzt LocationObservation → MovementState → PlaceEngine. Ein Stay ist ein zusammenhĂ€ngender Aufenthalt, ein Place dessen wiedererkennbarer privater Raumcluster und ein Visit die trackfreie Zuordnung eines abgeschlossenen Stay. Place ist kein POI, keine Adresse, kein GebĂ€ude und keine semantische Kategorie; Tour-/City-POI-Modelle bleiben getrennt.

Ankunft ist rĂŒckwirkend der Beginn eines spĂ€ter bestĂ€tigten Stay (observed_at), confirmed_at der Evidenzzeitpunkt. Abfahrt ist erst nach zwei Minuten außerhalb des 80-m-Radius bestĂ€tigt. 50-m-Ankunftsradius, QualitĂ€tsfilter und Hysterese tolerieren kurze AusgĂ€nge und GPS-SprĂŒnge. Lange LĂŒcken bedeuten Unsicherheit, nie automatisch Abfahrt.

Bei Departure ist der erste belastbare Außenpunkt nur departure_observed_at. Erst nach erfĂŒllter Hysterese entsteht departure_confirmed_at; departed_at und die Visit-Dauer werden dann fachlich auf den ersten Außenpunkt zurĂŒckdatiert. Stay-QualitĂ€t wird aus begrenzten GOOD-/LIMITED-/POOR-ZĂ€hlern aggregiert, nicht aus Enum-Strings.

Places werden erst nach wiederholten Visits, Mindestdauer und QualitÀt bestÀtigt. Die aus dem ersten Stay abgeleitete ID bleibt bei Centroid-Verschiebung stabil. Persistierte Centroids werden auf vier Nachkommastellen minimiert; CLI, Diagnose und Events zeigen keine Koordinaten. placectl.py status|list|visits|diagnose|replay|forget|reset betrifft nur Place-State. Sprint 3 bleibt ohne Benachrichtigungen im Shadow Mode. Details: ADR 0003.

Persönliches MobilitÀtsprofil (Sprint 4)

Die ausschließlich im Shadow Mode laufende MobilityProfileEngine ergĂ€nzt Location → Movement → Place/Stay um deterministische Langzeitmuster. Sie erzeugt belegte Facts wie frequent_place, frequent_overnight_place, typische Zeitfenster und frequent_transition—niemals „home“, „work“ oder „commute“.

Jeder Fact enthĂ€lt Evidence, Confidence, Samples, Beobachtungszeitraum und den Lebenszyklus candidate → confirmed → stale → revoked. Nachtzeiten und zyklische Fenster verwenden HERMES_PROFILE_TIMEZONE einschließlich DST. Der private, koordinatenfreie State unterstĂŒtzt atomare Writes, Locking, QuarantĂ€ne, Retention/Deduplizierung, Forget, Reset und sanitisierten Export.

HERMES_PROFILE_TIMEZONE=Europe/Berlin python skills/location-session-core/scripts/profilectl.py status
HERMES_PROFILE_TIMEZONE=Europe/Berlin python skills/location-session-core/scripts/profilectl.py facts
HERMES_PROFILE_TIMEZONE=Europe/Berlin python skills/location-session-core/scripts/profilectl.py explain FACT_ID
HERMES_PROFILE_TIMEZONE=Europe/Berlin python skills/location-session-core/scripts/profilectl.py export

Rollout: Unit Tests → synthetische Replays → Offline-Rebuild → Shadow Mode → mehrwöchige Profilbildung → NutzerprĂŒfung des Exports → erst danach mögliche semantische Kontextinterpretation.

Candidate-Facts werden erst sichtbar, wenn Sample- und Confidence-Schwelle erreicht sind; Confirmed verlangt zusĂ€tzlich Confirmed-Samples und unabhĂ€ngige Tage. Retention ist eine echte Zeitspanne ab computed_at: alle Aggregate werden ausschließlich aus koordinatenfreier Evidenz innerhalb des Fensters neu gebildet. profile forget-place vergisst nur im Profil; ein Rebuild kann aus dem unverĂ€nderten Place-State neu lernen. Dauerhaftes schichtĂŒbergreifendes Vergessen erfordert zuerst place forget.

Current Context (Sprint 5)

location-session-core komponiert kanonische Location-, Movement-, Place-/Stay- und Mobility-Profile-ZustĂ€nde zu einem unverĂ€nderlichen, deterministischen CurrentContext. Der Snapshot beantwortet ausschließlich, was aktuell belastbar bekannt ist. Er enthĂ€lt Teilkontexte, Freshness, gewichtete Confidence, strukturierte Evidence, sichtbare Unsicherheiten und nicht-semantische Traits. Er ruft keine Provider auf, sendet nichts und entscheidet nicht ĂŒber Aktionen.

Das Standardmodell, context export, context explain und die optionale Last-Snapshot-Persistenz enthalten weder Koordinaten, Rohpayloads, Adressen, Tracks noch semantische Place-Namen. Details und Rollout stehen in docs/architecture/current-context.md.