fix(ui): parse running/enabled into status; expand e2e to 13 tests

Backend /agents response shape: {id, name, version, desc, enabled: bool,
running: bool, pid, instances, config_path}. parse_agents() was reading
nonexistent fields "status", "uptime_seconds", "messages_24h" so the
table showed every agent as "unknown".

Derive status from running + enabled:
  running=true                  → "running"
  running=false, enabled=false  → "disabled"
  running=false, enabled=true   → "stopped"

E2E suite now covers (13 tests, all passing in ~9s):
- connect happy + bad-host + missing-apikey + URL-trim
- shape contract (id/name/running/enabled present + bool)
- SSE smoke: /sse/status and /sse/agents/{id}/logs must NOT return
  "streaming unsupported" (depends on backend statusWriter.Flush fix
  shipped in agents_and_robots master 4822208)
- auth boundary: /health no-auth, /agents 401 sin Bearer + 401 con key falsa
- control: POST /agents/test-bot/start returns valid JSON
- detail: GET /agents/{id} returns id + logs[]

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-22 22:34:57 +02:00
parent 47d80b4479
commit b61626b759
2 changed files with 134 additions and 4 deletions
+12 -4
View File
@@ -242,7 +242,11 @@ static std::string make_url(const AppState& s, const std::string& path) {
return base + path;
}
// Parse agents JSON array from /agents endpoint
// Parse agents JSON array from /agents endpoint.
// Backend shape (agents_and_robots/internal/api/handlers.go):
// { id, name, version, desc, enabled: bool, running: bool, pid: int,
// instances: int, config_path }
// status is derived; uptime/msg_24h not provided yet (v0.2 backend work).
static std::vector<AgentRow> parse_agents(const std::string& body) {
std::vector<AgentRow> rows;
auto j = json::parse(body, nullptr, false);
@@ -251,9 +255,13 @@ static std::vector<AgentRow> parse_agents(const std::string& body) {
AgentRow r;
r.id = a.value("id", "");
r.display_name = a.value("name", r.id);
r.status = a.value("status", "unknown");
r.uptime_s = a.value("uptime_seconds", (long long)0);
r.msg_24h = a.value("messages_24h", 0);
bool enabled = a.value("enabled", false);
bool running = a.value("running", false);
if (running) r.status = "running";
else if (!enabled) r.status = "disabled";
else r.status = "stopped";
r.uptime_s = 0;
r.msg_24h = a.value("instances", 0); // hack: show instances until backend exposes msg_24h
rows.push_back(std::move(r));
}
return rows;