v0.3.0 · Apache-2.0 · Windows · macOS · Linux
Mira qué hizo realmente tu agente.
ThreadlineLM lee los logs de auditoría que tu agente ya escribe —compatibles con OpenAI, OpenTelemetry GenAI o LiteLLM— y reconstruye la ejecución: cada llamada, cada llamada a herramientas, cada reintento. El parseo ocurre en tu máquina.
Build portable de Windows · 5,2 MB · sin cuenta ni telemetría
La ejecución se fue. El log queda.
Un agente falla y deja un archivo: requests, chunks en streaming, llamadas a herramientas, reintentos, un 429 a las 14:02:31. Grep te da líneas. No te dice a qué sesión pertenece cada una, qué llamada editó el archivo ni dónde empezó el bucle.
ThreadlineLM parsea ese archivo y reconstruye la ejecución: la conversación que vio el modelo, las herramientas que llamó, cuánto costó cada llamada. La misma evidencia, legible.
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
}
Cuatro formas de leer el mismo archivo.
La línea de tiempo es el índice. Todo lo demás está a una tecla: los mismos eventos, leídos de cuatro maneras, sin reimportar.
01 Timeline
Cada llamada, en orden
Proveedor, modelo, estado, latencia y tokens de entrada y salida. Una llamada fallida conserva su código HTTP en vez de perderse en un stack trace.
02 Chat
La conversación, reconstruida
Mensaje del usuario, llamada a herramienta, resultado, razonamiento y respuesta final — en el orden en que el modelo realmente los recibió.
03 Grafo
Las herramientas como flujo
Nodos de sistema, usuario, llamada, resultado, razonamiento y asistente. Los bucles, reintentos y callejones sin salida dejan de esconderse en el JSON.
04 Métricas
Latencia, tokens, costo
Latencia p50/p95/p99, tokens de entrada y salida, costo estimado con tabla de precios incluida y requests por modelo.
Compare es la quinta pestaña: pon una llamada que funciona al lado de una rota y compara request y respuesta, campo por campo.
Ctrl+1…5Seis formatos. Detectados por contenido, no por extensión.
Arrastrá el archivo a la ventana. El parser se elige según los primeros registros, así que .log, .jsonl y .json funcionan igual.
| Formato | Qué lee | Ejemplo | Eventos |
|---|---|---|---|
| Audit JSONL compatible con OpenAI | Llamadas a herramientas, streams SSE, razonamiento, tool_use de Anthropic, errores 429 | audit.log | 9 |
| Registros de auditoría como array JSON | Los mismos registros en un solo array | audit-array.json | 3 |
| Spans de OpenTelemetry GenAI | Un span por línea; los que no son GenAI se omiten | otel-genai-spans.jsonl | 3 |
| Envelope OTLP/JSON | resourceSpans con atributos KeyValue | otel-genai-otlp.json | 2 |
| StandardLoggingPayload de LiteLLM | Respuesta en streaming, tool use, embedding, fallo | litellm.jsonl | 5 |
| Log de proxy en texto plano | JSON de auditoría embebido entre líneas de log | proxy-raw.log | 2 |
Todos los ejemplos son sintéticos y vienen en inputExample/. Un registro por línea: el JSON multilínea con formato todavía no se detecta.
- Watch
- Ejecuciones en curso
Vuelve a leer el archivo cada 500 ms mientras el agente trabaja, para seguir la ejecución en vivo.
- Compare
- Ejecución sana contra ejecución rota
Request y respuesta de dos llamadas, lado a lado, campo por campo.
- Export
- Markdown para el ticket
Búsqueda difusa entre llamadas y exportación de la sesión para pegar en el bug report.
Nada sale de la máquina.
Sin cuenta, sin telemetría, sin nube, sin chequeos de actualización. El parseo corre en Rust, en memoria. El log nunca se sube y no se escribe nada salvo el Markdown que pidas.
La app no abre ningún socket. La línea de tiempo se arma con el cable desenchufado.
El archivo se lee, se parsea y se descarta al cerrar la ventana. Sin caché ni copia en disco.
Apache-2.0. Los parsers y los comandos IPC son unos pocos archivos Rust: léelos o compila el binario tú mismo.
Del archivo a la línea de tiempo.
El parseo y la agrupación de sesiones quedan en el backend Rust; la interfaz recibe resultados tipados por Tauri IPC.
Los primeros registros eligen el parser. Las líneas desconocidas se omiten, no rompen nada.
RustRequests, respuestas, llamadas a herramientas, razonamiento, uso y estado.
4 parsersLas llamadas se vuelven sesiones por cliente y ventana de 10 minutos.
session.rsOrden del chat, resultados de herramientas y aristas del grafo por sesión.
store.tsListas virtualizadas, búsqueda difusa y exportación a Markdown.
React · IPCPruébalo con una ejecución.
Suelta inputExample/audit.log en la ventana: 9 llamadas en la línea de tiempo, el chat reconstruido, el grafo y la latencia p50/p95.
Los builds todavía no están firmados. En Windows, SmartScreen pide Más información → Ejecutar de todos modos. En macOS, quita la cuarentena una vez: xattr -dr com.apple.quarantine /Applications/ThreadlineLM.app
Temprano: v0.3.0. Los formatos y las vistas alcanzan para depurar todos los días; un log con forma rara todavía puede confundir a un parser. Un issue con una muestra redactada es el mejor reporte.
O compilalo
Node 20+, pnpm 10+, un toolchain estable de Rust y las dependencias de sistema de Tauri.