Aller au contenu

Datasette — Explorateur des sessions Hermes

Résumé

Interface web read-only pour explorer la base SQLite ~/.hermes/state.db qui contient toutes les conversations Hermes, tous canaux confondus (CLI, Telegram, workspace). Permet de rechercher, filtrer, trier et exporter les sessions et messages.

Accès : http://178.105.46.57:4001 Login : hermes / mot de passe Caddy (même que dashboard et ttyd)


Base de données — ~/.hermes/state.db

Toutes les interactions avec Hermes sont stockées dans cette base SQLite sur le VPS host (pas dans Docker).

Table sessions

Colonne Type Description
id TEXT Identifiant unique (ex: 20260514_100111_0181e0, api-xxxx)
source TEXT Origine : cli, telegram, api_server
title TEXT Titre auto-généré de la conversation
model TEXT Modèle utilisé
started_at REAL Timestamp Unix de début
ended_at REAL Timestamp Unix de fin
message_count INTEGER Nombre de messages
input_tokens INTEGER Tokens en entrée
output_tokens INTEGER Tokens en sortie
estimated_cost_usd REAL Coût estimé en USD
user_id TEXT ID utilisateur (Telegram user_id pour les sessions Telegram)

Sources de sessions : - clihermes chat en SSH ou via ttyd - telegram → conversations Telegram - api_server → workspace navigateur (http://178.105.46.57:3001)

Table messages

Colonne Type Description
id INTEGER Clé primaire auto-incrémentée
session_id TEXT Référence vers sessions.id
role TEXT user, assistant, tool
content TEXT Contenu du message
tool_name TEXT Nom de l'outil appelé (si role=tool)
tool_calls TEXT JSON des appels d'outils
timestamp REAL Timestamp Unix
token_count INTEGER Nombre de tokens du message
reasoning TEXT Raisonnement interne du modèle (si disponible)

Installation

Prérequis

  • Python 3.12+ sur le VPS host
  • pipx installé (apt-get install -y pipx)

Étapes

# 1. Installer datasette
pipx install datasette

# 2. Tester manuellement
~/.local/bin/datasette serve ~/.hermes/state.db \
  --port 8765 --host 127.0.0.1 \
  --immutable ~/.hermes/state.db
# → HTTP 200 sur http://127.0.0.1:8765/

Service systemd (~/.config/systemd/user/hermes-datasette.service)

[Unit]
Description=Datasette — Hermes sessions explorer
After=network.target

[Service]
WorkingDirectory=/home/kanmaber
ExecStart=/home/kanmaber/.local/bin/datasette serve /home/kanmaber/.hermes/state.db --port 8765 --host 127.0.0.1 --immutable /home/kanmaber/.hermes/state.db
Restart=always
RestartSec=5

[Install]
WantedBy=default.target
systemctl --user daemon-reload
systemctl --user enable hermes-datasette
systemctl --user start hermes-datasette

Exposition via Caddy (~/hermes/Caddyfile)

:4001 {
    basic_auth {
        hermes $2a$14$dUPLU1KCV/M42Lj1dRp97eUcx3uZM494j5xNIvR18bCNdWEW4zhX2
    }
    reverse_proxy localhost:8765
}
docker restart caddy

Règle UFW

ufw allow 4001/tcp comment 'Datasette — hermes sessions explorer'

Utilisation dans l'interface web

  • / → liste des bases de données ouvertes
  • /state → liste des tables de state.db
  • /state/sessions → toutes les sessions
  • /state/messages → tous les messages

Recherche full-text

La table messages_fts est indexée pour la recherche full-text. Dans l'interface, utiliser la barre de recherche sur la table messages.

Via URL : /state/messages?_search=telegram

Filtres et tri

Cliquer sur un en-tête de colonne pour trier. Filtres via URL :

# Sessions Telegram uniquement
/state/sessions?source=telegram

# Sessions CLI triées par date
/state/sessions?source=cli&_sort_desc=started_at

# Messages d'une session spécifique
/state/messages?session_id=20260514_064949_1265b6

# Messages utilisateur uniquement
/state/messages?role=user

Export

Ajouter .csv ou .json à n'importe quelle URL :

/state/sessions.csv
/state/sessions.json
/state/messages.json?session_id=20260514_064949_1265b6

Requêtes SQL custom

Datasette expose un endpoint SQL :

/state?sql=SELECT s.title, s.source, COUNT(m.id) as nb_messages
FROM sessions s
JOIN messages m ON m.session_id = s.id
GROUP BY s.id
ORDER BY nb_messages DESC


Requêtes SQL utiles

Toutes les sessions avec nombre de messages et coût :

SELECT id, title, source, message_count,
       datetime(started_at, 'unixepoch') as date,
       estimated_cost_usd
FROM sessions
ORDER BY started_at DESC

Conversations Telegram uniquement :

SELECT id, title, user_id, message_count,
       datetime(started_at, 'unixepoch') as date
FROM sessions
WHERE source = 'telegram'
ORDER BY started_at DESC

Recherche dans les messages :

SELECT s.title, s.source, m.role, m.content, 
       datetime(m.timestamp, 'unixepoch') as date
FROM messages m
JOIN sessions s ON s.id = m.session_id
WHERE m.content LIKE '%mot_clé%'
ORDER BY m.timestamp DESC

Statistiques par canal :

SELECT source,
       COUNT(*) as nb_sessions,
       SUM(message_count) as nb_messages,
       ROUND(SUM(estimated_cost_usd), 4) as cout_total_usd
FROM sessions
GROUP BY source


Requêtes depuis le VPS (CLI)

python3 << 'EOF'
import sqlite3
conn = sqlite3.connect('/home/kanmaber/.hermes/state.db')
cur = conn.cursor()

# Lire les messages d'une session
cur.execute('''
    SELECT role, content FROM messages 
    WHERE session_id = "ID_SESSION" 
    ORDER BY timestamp
''')
for role, content in cur.fetchall():
    print(f'[{role}] {content[:300]}')
conn.close()
EOF

Architecture

~/.hermes/state.db (SQLite sur le host)
    ↓
hermes-datasette.service (systemd user, port 8765 — localhost uniquement)
    ↓
Caddy (reverse proxy, basic auth, port 4001 exposé)
    ↓
Navigateur (http://178.105.46.57:4001)

Liens connexes