Skip to content

feat(ui): per-schedule performance scorecards on Agent Detail (Overview + Schedules tab) (#1115)#1149

Open
dolho wants to merge 1 commit into
devfrom
feature/1115-per-schedule-scorecards
Open

feat(ui): per-schedule performance scorecards on Agent Detail (Overview + Schedules tab) (#1115)#1149
dolho wants to merge 1 commit into
devfrom
feature/1115-per-schedule-scorecards

Conversation

@dolho

@dolho dolho commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Surfaces per-schedule performance in two schedule-centric places, both from a single compact aggregate (no N per-schedule round-trips):

  1. Overview tab — a Schedules performance section comparing every schedule at a glance.
  2. Schedules tab — inline mini-stats per schedule row.

Extends #1107 (Overview) and generalises #868 (per-schedule deep analytics, which stays the drill-in target).

Backend

  • DB get_agent_schedules_summary(agent, hours) (db/schedules.py): one rollup per non-deleted schedule (zero-run schedules included with zeros). Per schedule — terminal success_rate (success / (success + failed[incl. error]); None when zero terminal), NULL-skipping avg_duration_ms, cost_total, context_avg, tool_call_total (parsed over the newest 5,000 rows agent-wide, tool_calls_sampled flag), last-run outcome. Cheap grouped SQL; iso_cutoff window (Invariant #16).
  • Router GET /api/agents/{name}/schedules/analytics-summary?window=7d|14d|30d (AuthorizedAgent). Declared before /{schedule_id} in routers/schedules.py so the literal analytics-summary isn't captured as a schedule_id — putting it in analytics.py would be shadowed since schedules_router mounts first (Invariant fix: add missing logging_config.py to backend Dockerfile #4).
  • Models ScheduleSummaryRow + AgentSchedulesSummaryResponse (Invariant Add internal health route, without which main didn't start #14).

Frontend (one fetch, two consumers — Invariant #7)

  • executions.js fetchSchedulesSummary, cached per ${name}:${window} like fetchAgentAnalytics.
  • OverviewPanel: "Schedules performance" section, honors the existing 7/14/30d selector, each row deep-links to the Schedules tab; hidden at zero schedules.
  • SchedulesPanel: inline mini-stats per row (success rate, avg duration, runs, last-run dot) — badge style, no new chart/modal.

Verification

AC

  • Single aggregate call, both surfaces reuse it; no N round-trips
  • success rate (terminal, on zero), token/cost, avg duration, total tool calls
  • Read-only / DB-sourced (renders when stopped)
  • Zero-run schedule still appears; only non-deleted
  • Backend unit test (rollup, success rate, duration avg, tool-call total, empty)
  • Overview section labeled by command + name, honors window selector, deep-links, hidden at zero
  • Schedules-tab inline stats, compact, same single source

Related to #1115

🤖 Generated with Claude Code

Surface per-schedule performance on the Overview tab and the Schedules tab,
both from a SINGLE compact aggregate (no N per-schedule round-trips) — extends
#1107 (Overview) and generalises #868 (per-schedule deep analytics).

Backend:
- db `get_agent_schedules_summary(agent, hours)` — one rollup row per
  non-deleted schedule (zero-run schedules included): terminal success_rate
  (success / (success + failed[incl. error]); None when zero terminal),
  NULL-skipping avg_duration_ms, cost_total, context_avg, tool_call_total
  (parsed over newest 5,000 rows agent-wide, tool_calls_sampled flag), and
  last-run outcome. Cheap grouped SQL; iso_cutoff window (Invariant #16).
- GET /api/agents/{name}/schedules/analytics-summary?window=7d|14d|30d
  (AuthorizedAgent). Declared BEFORE /{schedule_id} in routers/schedules.py
  so the literal segment isn't captured as a schedule_id (Invariant #4) —
  putting it in analytics.py would be shadowed (schedules_router mounts first).
- models: ScheduleSummaryRow + AgentSchedulesSummaryResponse (Invariant #14).

Frontend (single fetch, two consumers — Invariant #7):
- executions.js fetchSchedulesSummary, cached per ${name}:${window} like
  fetchAgentAnalytics.
- OverviewPanel: "Schedules performance" section, honors the existing 7/14/30d
  window selector, each row deep-links to the Schedules tab; hidden at zero.
- SchedulesPanel: inline mini-stats per row (success rate, avg duration, runs,
  last-run dot) — badge style, no new chart/modal — from the same call.

Tests: tests/unit/test_1115_schedules_summary.py (6) — terminal success rate,
NULL-skip avg, tool-call total, zero-run-still-appears, soft-delete excluded,
out-of-window excluded. Full analytics suites green (30 passed). Frontend
prod build clean; endpoint verified live across 7/14/30d windows.

Related to #1115

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@dolho dolho added the ui PR touches the frontend UI — triggers Playwright e2e tests label Jun 11, 2026
@github-actions

Copy link
Copy Markdown

⚠️ Nightly unit-suite check skipped — merge conflict against dev.

Resolve by running git merge dev locally and pushing the result. The next nightly run will re-test once the conflict is gone.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ui PR touches the frontend UI — triggers Playwright e2e tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant