This commit is contained in:
team3
2026-07-08 18:55:36 +02:00
parent 224ba1ed4f
commit 9a6ab0937b
15 changed files with 172 additions and 55 deletions

View File

@@ -882,18 +882,27 @@ async def kanban_fail_card(topic: str, board: str, card_id: str, error: str,
return dead
async def events_run_summary(topic: str, run_id: str) -> dict:
"""Agent/token aggregate of ONE run — the numbers block of lauf-summary.json."""
async def events_run_summary(topic: str, run_id: str, board: str | None = None) -> dict:
"""Agent/token aggregate of ONE run — the numbers block of lauf-summary.json.
board="inventory"|"artefacts" scopes to that level (via meta.board); None = whole run.
Returns start/ende (MIN/MAX ts of the scoped events) so the caller can show a per-board span."""
db = await get_db()
where = "topic = ? AND run_id = ? AND kind = 'agent'"
params = [topic, run_id]
if board:
where += " AND json_extract(meta,'$.board') = ?"
params.append(board)
cursor = await db.execute(
"""SELECT status, COUNT(*), SUM(dur_ms),
SUM(json_extract(meta,'$.tokens.input')), SUM(json_extract(meta,'$.tokens.output')),
SUM(json_extract(meta,'$.tokens.cache_read')), SUM(json_extract(meta,'$.tokens.cache_write'))
FROM events WHERE topic = ? AND run_id = ? AND kind = 'agent' GROUP BY status""",
(topic, run_id))
f"""SELECT status, COUNT(*), SUM(dur_ms),
SUM(json_extract(meta,'$.tokens.input')), SUM(json_extract(meta,'$.tokens.output')),
SUM(json_extract(meta,'$.tokens.cache_read')), SUM(json_extract(meta,'$.tokens.cache_write')),
MIN(ts), MAX(ts)
FROM events WHERE {where} GROUP BY status""",
params)
agents = {"gesamt": 0, "ok": 0, "timeout": 0, "cancelled": 0, "sonstige": 0, "verlorene_min": 0}
tokens = {"input": 0, "output": 0, "cache_read": 0, "cache_write": 0}
for status, n, dur, ti, to, cr, cw in await cursor.fetchall():
start = ende = None
for status, n, dur, ti, to, cr, cw, mn, mx in await cursor.fetchall():
agents["gesamt"] += n
if status in ("ok", "timeout", "cancelled"):
agents[status] += n
@@ -905,7 +914,11 @@ async def events_run_summary(topic: str, run_id: str) -> dict:
tokens["output"] += to or 0
tokens["cache_read"] += cr or 0
tokens["cache_write"] += cw or 0
return {"agents": agents, "tokens": tokens}
if mn and (start is None or mn < start):
start = mn
if mx and (ende is None or mx > ende):
ende = mx
return {"agents": agents, "tokens": tokens, "start": start, "ende": ende}
async def list_runs(topic: str, limit: int = 10) -> list[dict]:
@@ -919,13 +932,16 @@ async def list_runs(topic: str, limit: int = 10) -> list[dict]:
out = []
for run_id, start, ende in rows:
summary = await events_run_summary(topic, run_id)
# Per-Board-Aufschlüsselung (Zeit/Tokens getrennt für Inventar vs. Artefakte)
boards = {b: await events_run_summary(topic, run_id, board=b)
for b in ("inventory", "artefacts")}
cur = await db.execute(
"SELECT key, status, meta, ts FROM events WHERE topic = ? AND run_id = ? AND kind = 'fail' "
"ORDER BY ts DESC LIMIT 10", (topic, run_id))
fails = [{"key": k, "status": s, "error": json.loads(m or "{}").get("error", ""), "ts": ts}
for k, s, m, ts in await cur.fetchall()]
out.append({"run_id": run_id, "aktiv": _current_run.get(topic) == run_id,
"start": start, "ende": ende, **summary, "fails": fails})
"start": start, "ende": ende, **summary, "boards": boards, "fails": fails})
return out