Files
fn_registry/dev/issues/0118-agent-runs-timeline-cpp.md
T
egutierrez b9716a7cd6 chore: snapshot WIP previo + flow 0008 + 7 sub-issues (0112-0119)
Snapshot de WIP acumulado de sesiones previas antes de merge wave 1
del flow 0008 (kanban_cpp + agent_runner_api + DoD schema).

Incluye:
- dev/flows/0008-kanban-cpp-and-agent-workflows.md
- dev/issues/0112-0119*.md (7 sub-issues)
- WIP previo en cmd/fn/doctor.go, registry/*, modules/, cpp/, etc.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 18:17:08 +02:00

101 lines
3.6 KiB
Markdown

---
id: "0118"
title: "Funcion cpp agent_runs_timeline: panel SSE de runs cross-app"
status: pendiente
type: feature
domain:
- cpp-stack
- agents
- registry-quality
scope: registry
priority: alta
depends:
- "0110"
- "0113"
blocks: []
related:
- "0008"
- "0112"
- "0116"
- "0117"
created: 2026-05-18
updated: 2026-05-18
tags: [agents, timeline, sse, cpp, imgui, viz, registry-gap]
flow: "0008"
---
# 0118 — Funcion `agent_runs_timeline_cpp_viz`
## Problema
Panel de timeline de runs es identico en kanban_cpp (0112) y skill_tree v2 (0116). Sin funcion compartida = duplicacion.
## Decision
Funcion C++ en `cpp/functions/viz/agent_runs_timeline.{cpp,h,md}`. API:
```cpp
namespace fn_viz {
struct AgentRun {
std::string id;
std::string app; // "kanban_cpp" | "skill_tree" | ...
std::string issue_id;
std::string card_id;
std::string branch;
std::string status; // "pending" | "running" | "done" | "validated" | "merged" | "aborted" | "failed"
int64_t started_at;
int64_t finished_at;
int dod_total;
int dod_done;
int dod_validated;
};
struct TimelineFilter {
std::vector<std::string> apps; // vacio = todos
std::vector<std::string> statuses; // vacio = todos
int64_t since_ts; // 0 = sin filtro
};
struct TimelineState {
std::string sse_url; // ej "http://localhost:8486/api/runs/sse"
std::vector<AgentRun> runs;
TimelineFilter filter;
std::function<void(const std::string&)> on_select; // callback(run_id)
};
void render_agent_runs_timeline(TimelineState& state);
void poll_sse_runs(TimelineState& state); // llamar 1x/frame, no bloquea
}
```
Renderiza tabla con `data_table_cpp_viz`:
- Cols: status (icon), app (chip color), issue/card, branch, dod_done/total, dod_validated/total, duration, started_at.
- Sort por started_at desc por defecto.
- Click row -> `on_select(run_id)`.
- Filtros arriba: combo apps multi-select + combo statuses + date picker `since`.
- SSE en background thread: append runs nuevos, update statuses en vivo.
## Criterios de aceptacion
- [ ] `cpp/functions/viz/agent_runs_timeline.{cpp,h,md}` registrado.
- [ ] `params_schema` y `output` completos.
- [ ] Tag `agents` aplicado.
- [ ] `.md` cumple contrato self-doc (`## Ejemplo`, `## Cuando usarla`, `## Gotchas`).
- [ ] SSE client en background thread con reconnect + `Last-Event-ID` resume.
- [ ] Demo en `cpp/apps/primitives_gallery/demos_viz.cpp` con TimelineState mock (5 runs varied status).
- [ ] `kanban_cpp::panel_agent_runs` usa la funcion.
- [ ] `skill_tree` `panel_timeline` usa la funcion.
- [ ] `fn doctor capabilities` muestra grupo `agents` con esta funcion.
- [ ] `uses_functions` declara: `http_request_cpp_core`, `data_table_cpp_viz`, `icons_tabler_cpp_core`, `tokens_cpp_core`.
## Gotchas
- SSE reconnect: si `agent_runner_api` cae, reintenta cada 5s con backoff. Estado `disconnected` visible.
- Thread-safety: SSE thread escribe `state.runs`; UI thread lee. Mutex o cola SPSC.
- Memory: si runs > 1000 historicos, paginar (LRU 200 visibles). Antiguos se descargan on-demand via `GET /api/runs?since=...`.
- App `chip color`: mapear app_name -> accent del trio (kanban_cpp `#a855f7`, skill_tree color actual). Cache.
- Click row durante streaming SSE: no resetear seleccion al refrescar lista; preservar por `run_id`.
## Out of scope
- Editor inline de DoD desde timeline (eso es panel DoD 0117).
- Export CSV/JSON.
- Notificaciones desktop al cambiar status.