v0.3.0 · Apache-2.0 · Windows · macOS · Linux
Voyez ce que votre agent a réellement fait.
ThreadlineLM lit les journaux d’audit que votre agent écrit déjà — compatibles OpenAI, OpenTelemetry GenAI ou LiteLLM — et reconstruit l’exécution : chaque appel, chaque appel d’outil, chaque nouvelle tentative. L’analyse se fait sur votre machine.
Build portable Windows · 5,2 Mo · sans compte ni télémétrie
L’exécution est passée. Le journal reste.
Un agent échoue et laisse un fichier : requêtes, chunks en streaming, appels d’outils, nouvelles tentatives, un 429 à 14:02:31. Grep vous donne des lignes. Il ne dit pas à quelle session elles appartiennent, quel appel a modifié le fichier ni où la boucle a commencé.
ThreadlineLM analyse ce fichier et reconstruit l’exécution : la conversation vue par le modèle, les outils appelés, le coût de chaque appel. La même preuve, lisible.
01
{
02
"id": "evt_0009",
03
"ts": "2026-05-17T15:30:09.000Z",
04
"client": "eval-runner",
05
"model": "gemini/gemini-2.0-flash",
06
"status": 429,
07
"duration_ms": 95,
08
"upstream": { "status": 429 },
09
"req_body": {
10
"messages": [
11
{
12
"role": "user",
13
"content": "Translate to Spanish: good night."
14
}
15
]
16
},
17
"resp_body": {
18
"error": {
19
"code": 429,
20
"status": "RESOURCE_EXHAUSTED"
21
}
22
}
23
}
Quatre lectures du même fichier.
La chronologie est l’index. Le reste tient à une touche : les mêmes événements, lus de quatre façons, sans réimport.
01 Chronologie
Chaque appel, dans l’ordre
Fournisseur, modèle, statut, latence et tokens entrée/sortie. Une requête en échec garde son code HTTP au lieu de disparaître dans une stack trace.
02 Chat
La conversation, reconstruite
Message utilisateur, appel d’outil, résultat, raisonnement et réponse finale — dans l’ordre où le modèle les a réellement reçus.
03 Graphe
Les outils comme flux
Nœuds système, utilisateur, appel, résultat, réflexion et assistant. Boucles, reprises et impasses cessent de se cacher dans le JSON.
04 Métriques
Latence, tokens, coût
Latence p50/p95/p99, tokens entrée/sortie, coût estimé avec table de prix intégrée et requêtes par modèle.
Compare est le cinquième onglet : placez un appel qui marche à côté d’un appel cassé et comparez requête et réponse, champ par champ.
Ctrl+1…5Six formats. Détectés au contenu, pas à l’extension.
Déposez le fichier sur la fenêtre. Le parseur est choisi d’après les premiers enregistrements : .log, .jsonl et .json fonctionnent tous.
| Format | Ce qu’il lit | Exemple | Événements |
|---|---|---|---|
| Audit JSONL compatible OpenAI | Appels d’outils, flux SSE, raisonnement, tool_use d’Anthropic, erreurs 429 | audit.log | 9 |
| Enregistrements d’audit en tableau JSON | Les mêmes enregistrements dans un seul tableau | audit-array.json | 3 |
| Spans OpenTelemetry GenAI | Un span par ligne ; les spans non GenAI sont ignorés | otel-genai-spans.jsonl | 3 |
| Enveloppe OTLP/JSON | resourceSpans avec attributs KeyValue | otel-genai-otlp.json | 2 |
| StandardLoggingPayload LiteLLM | Réponse en streaming, tool use, embedding, échec | litellm.jsonl | 5 |
| Journal de proxy en texte brut | JSON d’audit intégré aux lignes de journal | proxy-raw.log | 2 |
Tous les exemples sont synthétiques et fournis dans inputExample/. Un enregistrement par ligne : le JSON multiligne formaté n’est pas encore détecté.
- Watch
- Exécutions en cours
Relit le fichier toutes les 500 ms pendant que l’agent travaille, pour suivre une exécution en direct.
- Compare
- Exécution saine contre exécution cassée
Requête et réponse de deux appels, côte à côte, champ par champ.
- Export
- Du Markdown pour le ticket
Recherche floue entre les appels, puis export de la session à coller dans le rapport de bug.
Rien ne quitte la machine.
Sans compte, sans télémétrie, sans cloud, sans vérification de mise à jour. L’analyse tourne en Rust, en mémoire. Le journal n’est jamais envoyé et rien n’est écrit, sauf le Markdown demandé.
L’application n’ouvre aucune socket. La chronologie se construit avec le câble débranché.
Le fichier est lu, analysé puis oublié à la fermeture. Ni cache, ni copie sur disque.
Apache-2.0. Les parseurs et les commandes IPC tiennent en quelques fichiers Rust : lisez-les, ou compilez le binaire vous-même.
Du fichier à la chronologie.
L’analyse et le regroupement des sessions restent dans le backend Rust ; l’interface reçoit des résultats typés via Tauri IPC.
Les premiers enregistrements choisissent le parseur. Les lignes inconnues sont ignorées, pas fatales.
RustRequêtes, réponses, appels d’outils, raisonnement, usage et statut.
4 parseursLes appels deviennent des sessions par client et fenêtre de 10 minutes.
session.rsOrdre du chat, résultats d’outils et arêtes du graphe par session.
store.tsListes virtualisées, recherche floue, export Markdown.
React · IPCEssayez sur une exécution.
Déposez inputExample/audit.log sur la fenêtre : 9 appels dans la chronologie, le chat reconstruit, le graphe et la latence p50/p95.
Les builds ne sont pas encore signés. Sous Windows, SmartScreen demande Plus d’informations → Exécuter quand même. Sous macOS, retirez la quarantaine une fois : xattr -dr com.apple.quarantine /Applications/ThreadlineLM.app
Début : v0.3.0. Formats et vues suffisent au débogage quotidien ; une forme de journal inhabituelle peut encore dérouter un parseur. Une issue avec un échantillon expurgé est le meilleur rapport.
Ou compilez-le
Node 20+, pnpm 10+, une toolchain Rust stable et les dépendances système de Tauri.