Skip to content

[Feature]: Multi-profile dashboard support - surface cron jobs across all profiles in one view #20622

@arshad2k

Description

@arshad2k

Problem or Use Case

The Hermes dashboard is profile-scoped at process startup: each hermes dashboard instance reads only the HERMES_HOME it was launched under. When users run multiple profiles (each with its own gateway, MCP servers, Discord routing, model defaults, and crons), there is no single dashboard view that surfaces activity across the fleet.

In particular, GET /api/cron/jobs (web_server.py) calls list_jobs(include_disabled=True) with no profile parameter, so the cron list page shows only the active profile's cron/jobs.json. Cron jobs configured under non-default profiles are invisible from the default-profile dashboard, even though their jobs.json files exist on disk and are readable.

The current workaround is to launch one dashboard per profile on different ports and open a browser tab per profile. This works but adds friction:

  • Multiple processes, ports, and tabs to remember
  • No aggregate "anything broken across the fleet?" view
  • No single place to spot stale/failing jobs across profiles
  • Profile-scoped log/session navigation has the same limitation

Related: #10674 (broader multi-profile dashboard switching design), #20423 (cross-team dashboard visibility).

Proposed Solution

Two reasonable options, in order of effort:

Option A - profile-aware cron API (smallest diff)
Accept an optional ?profile=<name> query parameter on GET /api/cron/jobs (and the related cron mutation endpoints). When omitted, behave as today (active profile). When present, read jobs from the requested profile's HERMES_HOME/cron/jobs.json. The /api/profiles endpoint already exists, so the frontend can populate a profile picker without new backend listing logic.

Option B - aggregate endpoint
Add GET /api/cron/jobs?profile=all that returns {profile_name: [jobs...]} so the dashboard can render a fleet-wide cron list in one call. This is the actually-useful UX for users who want to spot failures across the fleet at a glance.

The frontend change is a profile dropdown in the cron page header (single-profile mode) plus an "All Profiles" option (aggregate mode). The same pattern would naturally extend to sessions, logs, and gateway status pages.

Alternatives Considered

  1. Spawn N dashboards on different ports - works today but is fragile (need to track which port maps to which profile, every browser restart loses tab state, N processes consume memory).
  2. Consolidate all crons into the default profile - breaks profile isolation. Each profile typically has its own MCP server set, Discord channel, model defaults, and auth context. Crons depend on profile-scoped state and cannot move without losing context.
  3. Symlink profile jobs.json files into default's cron dir - Hermes does not merge cron files; it would just overwrite. Even if it did merge, job IDs collide and triggering a job would run it under the wrong profile context.

Option A above is the minimal change that unblocks the user-facing pain. The backend infrastructure is already profile-aware (_profile_to_dict, list_profiles, HERMES_HOME resolution); it just isn't plumbed through to the cron endpoints.

Feature Type

Configuration option / CLI improvement (web layer plumbing).

Scope

Small to medium. Backend: a few endpoints take an optional profile parameter and re-scope HERMES_HOME for the request lifetime. Frontend: a profile dropdown component on the cron page (and reusable for other pages later).

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low — cosmetic, nice to havecomp/cronCron scheduler and job managementsweeper:implemented-on-mainSweeper: behavior already present on current maintype/featureNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions