swarm.js: drop the queue-summary banner rather than ship it on an interim jobq fetch
mara, on the already-approved PR: "dont replace one legacy thing with another. then we will have to either wait with this pr or split it into what can and cannot be done now." Splitting: the transients-only per-agent badge fix is real, correct, and fixes a live regression (the old DagView fields it read no longer exist) — nothing about it depends on job-queue data at all, so it ships as-is. The queue-summary banner is the part that doesn't belong in this shape: it was reading GET /api/jobq/graph directly and deriving counts client-side as an interim stand-in for the dedicated rollup endpoint mara separately asked for — exactly the kind of stopgap-on-a-stopgap her comment is calling out, since the endpoint that should serve it doesn't exist on main yet. Removes jobqNodesState, refreshJobqGraph(), the rebuild_queue_changed SSE subscription, and the banner's render block from swarm.js/tabs.js entirely — swarm.js now reads no job-queue state of any kind, fully satisfying "swarm.js should not need to pull in the jobq to do its job." The banner comes back once the rollup endpoint (hyperhive#2985's follow-up) exists, reading that directly instead of the full graph. Until then the per-agent transient pills still show what's actually running on each card; only the hive-wide "N running / M queued" summary line is temporarily gone. CSS classes for the banner (.queue-summary/.queue-summary-link) kept in dashboard.css rather than deleted-then-restored — commented as currently unused, expected to come back unchanged. docs/web-ui/dashboard.md updated to match (Container-row pending- badge section, the removed Build-queue-summary-banner section, and the BU1LDS-page note that used to describe SW4RM's now-removed parallel fetch).
This commit is contained in:
parent
7b05656e17
commit
40cc115a0a
4 changed files with 69 additions and 125 deletions
|
|
@ -209,10 +209,12 @@ Three sub-tabs: **R3BU1LD QU3U3** (default), **M3T4 1NPUTS**,
|
||||||
**BUILD L0GS**. Its own esbuild bundle (`builds.js`); cold-loads
|
**BUILD L0GS**. Its own esbuild bundle (`builds.js`); cold-loads
|
||||||
`/api/state` and subscribes to `/api/dashboard/stream` for
|
`/api/state` and subscribes to `/api/dashboard/stream` for
|
||||||
`rebuild_queue_changed`, `meta_inputs_changed`, `meta_update_running`.
|
`rebuild_queue_changed`, `meta_inputs_changed`, `meta_update_running`.
|
||||||
The SW4RM tab (`/dashboard.html`) independently self-fetches the same
|
The SW4RM tab (`/dashboard.html`) does **not** read this endpoint (or
|
||||||
`GET /api/jobq/graph` endpoint for its own card badges + queue-summary
|
any job-queue state) at all — mara, on review: "swarm.js should not
|
||||||
banner (`refreshJobqGraph`, `swarm.js`) — same data source, no panel
|
need to pull in the jobq to do its job." Its per-agent pending badges
|
||||||
rendering, no shared fetch between the two pages.
|
are transient-only, and its queue-summary banner is removed for now
|
||||||
|
(see Container row, below), pending a dedicated rollup endpoint it
|
||||||
|
can read directly instead of the full graph.
|
||||||
|
|
||||||
**R3BU1LD QU3U3** — pending, in-flight, and recently-settled container
|
**R3BU1LD QU3U3** — pending, in-flight, and recently-settled container
|
||||||
operations: rebuilds, meta-update cascades, and first-spawns. One
|
operations: rebuilds, meta-update cascades, and first-spawns. One
|
||||||
|
|
@ -913,14 +915,16 @@ fetch entirely.
|
||||||
their own label directly via `TransientSet`/`TransientCleared`
|
their own label directly via `TransientSet`/`TransientCleared`
|
||||||
events carrying no backing node at all.
|
events carrying no backing node at all.
|
||||||
|
|
||||||
**Queued (not-yet-started) work shows nothing on the card.** An
|
**Queued (not-yet-started) work shows nothing on the card, and
|
||||||
earlier version of this page had a job-queue-backed fallback badge
|
`swarm.js` reads no job-queue state at all.** An earlier version of
|
||||||
for the `Pending` case (`queuedOpsByAgent()` in swarm.js, reading
|
this page had a job-queue-backed fallback badge for the `Pending`
|
||||||
`jobqNodesState`); removed per mara, on review of hyperhive#3028's
|
case (`queuedOpsByAgent()`, reading a `GET /api/jobq/graph` fetch);
|
||||||
PR: *"swarm.js should not need to pull in the jobq to do its job"*,
|
removed per mara, on review of hyperhive#3028's PR: *"swarm.js
|
||||||
followed by *"remove the per agent pending stuff - only show what
|
should not need to pull in the jobq to do its job,"* followed by
|
||||||
is running."* `jobqNodesState` still exists in swarm.js, but now
|
*"remove the per agent pending stuff - only show what is running."*
|
||||||
feeds only the queue-summary banner below, not per-card badges.
|
The queue-summary banner below was, for the same reason, also pulled
|
||||||
|
rather than kept on that same client-side graph-fetch — see its own
|
||||||
|
entry below for why.
|
||||||
An **active model badge** (`model · <name>`, blue) appears when the
|
An **active model badge** (`model · <name>`, blue) appears when the
|
||||||
container is running and the harness has persisted a model name
|
container is running and the harness has persisted a model name
|
||||||
(`harness/hyperhive-model`). Read by hive-c0re's `ContainerView`
|
(`harness/hyperhive-model`). Read by hive-c0re's `ContainerView`
|
||||||
|
|
@ -961,19 +965,23 @@ per-agent actions and navigation links. Contents:
|
||||||
agent is stale. Banner pulses on each broker SSE event
|
agent is stale. Banner pulses on each broker SSE event
|
||||||
(`pulseBanner` with a 4s grace timer).
|
(`pulseBanner` with a 4s grace timer).
|
||||||
|
|
||||||
**Build-queue summary banner** — when `jobqNodesState` has any
|
**Build-queue summary banner — currently removed, coming back on a
|
||||||
`Pending` / `Running`(-or-`Finishing`) **group roots** (`parent:
|
different data source.** Previously a compact amber banner above the
|
||||||
null` — each an independent queued/running operation, not a raw
|
container list (`◐ build queue — N running · M queued — view
|
||||||
node count: a multi-step op's not-yet-started sub-steps don't inflate
|
queue →`, linking to the BU1LDS page), derived client-side from `GET
|
||||||
the number), a compact amber banner sits above the container list:
|
/api/jobq/graph` (filter to `parent: null` group roots — each an
|
||||||
`◐ build queue — N running · M queued — view queue →` (the link goes
|
independent operation, not a raw node count — bucket by `state`).
|
||||||
to the BU1LDS page's R3BU1LD QU3U3). A root's own `state` already
|
Pulled per mara, on review of hyperhive#3028's PR: *"dont replace one
|
||||||
carries its subtree's roll-up (`hive-jobq-wire`'s contract), so this
|
legacy thing with another. then we will have to either wait with
|
||||||
is a direct filter over `jobqNodesState`, not a client-side rollup
|
this pr or split it into what can and cannot be done now"* — a
|
||||||
derivation. It replaces the old per-transient spinner list; the
|
client-side derivation over the generic graph was itself judged a
|
||||||
actual running node for each agent is already shown on its card
|
stopgap not worth landing, the same way the old `DagView` read it
|
||||||
(transient + in-flight-queue badges), so the top of the tab only
|
replaced was. Comes back once a dedicated rollup endpoint (status ×
|
||||||
needs the at-a-glance summary.
|
count pairs, tracked separately) exists for `swarm.js` to read
|
||||||
|
directly instead of pulling the whole graph in for a summary. Until
|
||||||
|
then, the actual running work per agent is still visible on each
|
||||||
|
card via the transient pills; only the hive-wide at-a-glance count is
|
||||||
|
missing.
|
||||||
|
|
||||||
### Themed dialogs
|
### Themed dialogs
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -458,7 +458,11 @@ hive-agent-menu {
|
||||||
|
|
||||||
/* Build-queue summary banner on the SW4RM tab: one compact line
|
/* Build-queue summary banner on the SW4RM tab: one compact line
|
||||||
when the rebuild queue has active work, with a link to the full queue on
|
when the rebuild queue has active work, with a link to the full queue on
|
||||||
the C0R3 page. Amber to match the in-progress / "rebuilding" card tint. */
|
the C0R3 page. Amber to match the in-progress / "rebuilding" card tint.
|
||||||
|
Currently unused — swarm.js dropped the banner pending a dedicated
|
||||||
|
rollup endpoint (see swarm.js's transients-section comment) — kept
|
||||||
|
here rather than deleted-then-restored, since the markup/classes are
|
||||||
|
expected to come back unchanged once that endpoint exists. */
|
||||||
.queue-summary {
|
.queue-summary {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// SW4RM (containers) domain — extracted from tabs.js.
|
// SW4RM (containers) domain — extracted from tabs.js.
|
||||||
// Agent topology, container-row rendering, selection bar, peer-hives block,
|
// Agent topology, container-row rendering, selection bar, peer-hives block,
|
||||||
// and all live-update apply handlers for container-state, rebuild-queue, and
|
// and all live-update apply handlers for container-state and transient ops.
|
||||||
// transient ops. See docs/web-ui.md::Container row for the rendering contract.
|
// See docs/web-ui.md::Container row for the rendering contract.
|
||||||
|
|
||||||
import {
|
import {
|
||||||
$, form, fmtAgeSecs,
|
$, form, fmtAgeSecs,
|
||||||
|
|
@ -27,21 +27,6 @@ const CTX_CAUTION_TOKENS = 100_000; // fallback yellow threshold (~= 50% of 200k
|
||||||
|
|
||||||
// ─── module-level state ─────────────────────────────────────────────────────
|
// ─── module-level state ─────────────────────────────────────────────────────
|
||||||
|
|
||||||
// Flat GraphNode[] from GET /api/jobq/graph (hive-jobq-wire's generic
|
|
||||||
// shape — see hive-jobq-wire/src/lib.rs) — feeds *only* the queue-summary
|
|
||||||
// banner in renderContainers (mara, on review: "swarm.js should not need
|
|
||||||
// to pull in the jobq to do its job" — the per-agent pending-row fallback
|
|
||||||
// that used to be this state's other consumer is gone, see
|
|
||||||
// queuedOpsByAgent's removal below). Once a dedicated rollup endpoint
|
|
||||||
// exists (status-count pairs, requested separately) the banner moves
|
|
||||||
// onto that instead and this fetch goes away entirely. "Nothing is
|
|
||||||
// hidden" on this endpoint: every retained job group's nodes ride the
|
|
||||||
// wire, `Done` included, and each group's root is an ordinary node
|
|
||||||
// (`parent: null`) whose own `state` IS the group's roll-up already —
|
|
||||||
// unlike the old DagView, no client-side rollup derivation is needed,
|
|
||||||
// just an explicit filter for what's still active.
|
|
||||||
let jobqNodesState = [];
|
|
||||||
|
|
||||||
// Keyed container row cache. Maps agent name -> { el: <li>, fingerprint }.
|
// Keyed container row cache. Maps agent name -> { el: <li>, fingerprint }.
|
||||||
// Allows renderContainers to skip rebuilding rows whose displayed state
|
// Allows renderContainers to skip rebuilding rows whose displayed state
|
||||||
// hasn't changed — prevents full-wipe flicker + avoids redundant async
|
// hasn't changed — prevents full-wipe flicker + avoids redundant async
|
||||||
|
|
@ -65,42 +50,20 @@ const transientsState = new Map();
|
||||||
// tab-gated visibility).
|
// tab-gated visibility).
|
||||||
const selectionState = new Set();
|
const selectionState = new Set();
|
||||||
|
|
||||||
// ─── job queue graph ──────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
// Fetches the graph fresh and re-renders. Called on cold load (see
|
|
||||||
// tabs.js's refreshState) and whenever `rebuild_queue_changed` fires
|
|
||||||
// (applyRebuildQueueChanged below) — that event is now read purely as a
|
|
||||||
// refetch trigger, the same treatment builds.js already gives it for
|
|
||||||
// <hive-jobq-graph>.refresh(). Best-effort: a failed fetch just leaves
|
|
||||||
// the previous snapshot in place rather than wiping badges on a network
|
|
||||||
// blip (same tolerance the per-row dashboard-state fetch below has).
|
|
||||||
export async function refreshJobqGraph() {
|
|
||||||
let nodes;
|
|
||||||
try {
|
|
||||||
const r = await fetch('/api/jobq/graph');
|
|
||||||
if (!r.ok) return;
|
|
||||||
nodes = await r.json();
|
|
||||||
} catch {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
jobqNodesState = nodes;
|
|
||||||
renderContainersFromState();
|
|
||||||
}
|
|
||||||
export function applyRebuildQueueChanged() {
|
|
||||||
// No `ev.queue` payload read anymore — that event still carries its
|
|
||||||
// own DagView-shaped queue snapshot on the wire, but this page no
|
|
||||||
// longer reads it. Purely a "something changed, go refetch" signal.
|
|
||||||
refreshJobqGraph();
|
|
||||||
}
|
|
||||||
// Per-agent queued-but-not-running badges used to have their own
|
|
||||||
// fallback here (`queuedOpsByAgent()`, reading `Pending`-state nodes
|
|
||||||
// off `jobqNodesState`). Removed per mara, on review: "remove the per
|
|
||||||
// agent pending stuff - only show what is running" — a card's pending
|
|
||||||
// badges are now driven by `transientsState` alone (see below), which
|
|
||||||
// is exactly "what is running": queued-not-yet-started work shows
|
|
||||||
// nothing on the card until a node actually starts.
|
|
||||||
|
|
||||||
// ─── transients ─────────────────────────────────────────────────────────────
|
// ─── transients ─────────────────────────────────────────────────────────────
|
||||||
|
//
|
||||||
|
// This is now the ONLY job-queue-derived state on this page — mara, on
|
||||||
|
// review of the DagView migration: "swarm.js should not need to pull in
|
||||||
|
// the jobq to do its job." An earlier version of this file also fetched
|
||||||
|
// GET /api/jobq/graph directly for two things now gone: a per-agent
|
||||||
|
// queued-but-not-running badge (`queuedOpsByAgent()`, removed per "remove
|
||||||
|
// the per agent pending stuff - only show what is running" — a card's
|
||||||
|
// pending badges are transients-only now, which already means "what is
|
||||||
|
// running") and the queue-summary banner (removed per "dont replace one
|
||||||
|
// legacy thing with another" — a client-side derivation over the generic
|
||||||
|
// graph was itself judged a stopgap not worth shipping; the banner comes
|
||||||
|
// back once the dedicated rollup endpoint exists, and reads that
|
||||||
|
// directly instead of pulling the graph in here at all).
|
||||||
|
|
||||||
export function syncTransientsFromSnapshot(s) {
|
export function syncTransientsFromSnapshot(s) {
|
||||||
transientsState.clear();
|
transientsState.clear();
|
||||||
|
|
@ -620,37 +583,15 @@ export function renderContainers(s) {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Queue-summary banner: when the job queue has active work, show one
|
// No queue-summary banner for now — the previous version derived it
|
||||||
// compact at-a-glance line + a link to the full queue on the BU1LDS
|
// client-side from GET /api/jobq/graph, which mara flagged as
|
||||||
// page. Replaces the old per-transient spinner list — the actual
|
// replacing one legacy DagView-shaped hack with another rather than
|
||||||
// running step is already visible per-agent on each card (transient +
|
// landing the real fix ("dont replace one legacy thing with another
|
||||||
// in-flight-queue badges), so the top of the tab only needs the summary.
|
// ... split it into what can and cannot be done now"). Comes back once
|
||||||
//
|
// the dedicated rollup endpoint exists, reading that directly. Until
|
||||||
// Counts distinct *groups* (root nodes, `parent == null`), not raw
|
// then the queue's actual state is still visible per-agent on each
|
||||||
// nodes — a single group can have several sequential not-yet-started
|
// card via the transient pills; only the hive-wide at-a-glance summary
|
||||||
// steps, and "3 running · 2 queued" means 3/2 whole operations, not
|
// is missing.
|
||||||
// 3/2 individual steps. A root's own `state` already IS its subtree's
|
|
||||||
// roll-up (hive-jobq-wire's contract — no client-side derivation
|
|
||||||
// needed, unlike the old DagView), so this is a direct filter, not a
|
|
||||||
// parent-chain walk. `Finishing` counts as running (own work done,
|
|
||||||
// children still going, still in flight). Settled roots (Done/Failed/
|
|
||||||
// Cancelled/Skipped) ride the wire too now ("nothing is hidden" —
|
|
||||||
// unlike the old DagView snapshot, which dropped them) so both counts
|
|
||||||
// filter explicitly rather than assuming absence.
|
|
||||||
const roots = jobqNodesState.filter((n) => n.parent == null);
|
|
||||||
const running = roots.filter((n) => n.state === 'Running' || n.state === 'Finishing').length;
|
|
||||||
const queued = roots.filter((n) => n.state === 'Pending').length;
|
|
||||||
if (running || queued) {
|
|
||||||
const parts = [];
|
|
||||||
if (running) parts.push(`${running} running`);
|
|
||||||
if (queued) parts.push(`${queued} queued`);
|
|
||||||
root.append(el('div', { class: 'queue-summary' },
|
|
||||||
el('span', { class: 'glyph spinner' }, '◐'), ' ',
|
|
||||||
el('strong', {}, 'build queue'), ' — ',
|
|
||||||
parts.join(' · '), ' ',
|
|
||||||
el('a', { class: 'queue-summary-link', href: '/builds.html' }, 'view queue →'),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!containers.length && !transientsState.size) {
|
if (!containers.length && !transientsState.size) {
|
||||||
root.append(el('p', { class: 'empty' }, 'no managed containers'));
|
root.append(el('p', { class: 'empty' }, 'no managed containers'));
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,8 @@ import {
|
||||||
renderQuestions, activeQuestionCount,
|
renderQuestions, activeQuestionCount,
|
||||||
} from './call.js';
|
} from './call.js';
|
||||||
import {
|
import {
|
||||||
refreshJobqGraph, syncTransientsFromSnapshot,
|
syncTransientsFromSnapshot,
|
||||||
applyRebuildQueueChanged, applyContainerStateChanged, applyContainerRemoved,
|
applyContainerStateChanged, applyContainerRemoved,
|
||||||
applyTransientSet, applyTransientCleared,
|
applyTransientSet, applyTransientCleared,
|
||||||
renderContainers, renderContainersFromState,
|
renderContainers, renderContainersFromState,
|
||||||
renderSelectionBar, renderPeerHives,
|
renderSelectionBar, renderPeerHives,
|
||||||
|
|
@ -234,15 +234,6 @@ window.marked = marked;
|
||||||
// `transientsState` + `containersState`, not from `s.*`).
|
// `transientsState` + `containersState`, not from `s.*`).
|
||||||
syncTransientsFromSnapshot(s);
|
syncTransientsFromSnapshot(s);
|
||||||
syncContainersFromSnapshot(s);
|
syncContainersFromSnapshot(s);
|
||||||
// Job-queue graph feeds only the SW4RM queue-summary banner now
|
|
||||||
// (per-agent card badges are transient-only — see swarm.js); its
|
|
||||||
// own detailed view lives on /builds.html. Self-fetches GET
|
|
||||||
// /api/jobq/graph — not read off `s` (this page's snapshot
|
|
||||||
// carries no jobq field) — fire-and-forget: renderContainers
|
|
||||||
// below runs off whatever jobqNodesState already holds, and
|
|
||||||
// refreshJobqGraph's own re-render catches up once the fetch
|
|
||||||
// resolves.
|
|
||||||
refreshJobqGraph();
|
|
||||||
renderContainers(s);
|
renderContainers(s);
|
||||||
// Sync the derived approvals + questions stores from the
|
// Sync the derived approvals + questions stores from the
|
||||||
// snapshot, then render. Live `*_added` / `*_resolved` events
|
// snapshot, then render. Live `*_added` / `*_resolved` events
|
||||||
|
|
@ -313,10 +304,10 @@ window.marked = marked;
|
||||||
container_removed: applyContainerRemoved,
|
container_removed: applyContainerRemoved,
|
||||||
// tombstones_changed / meta_inputs_changed / meta_update_running are
|
// tombstones_changed / meta_inputs_changed / meta_update_running are
|
||||||
// handled on /core.html now (the SYST3M panels moved there).
|
// handled on /core.html now (the SYST3M panels moved there).
|
||||||
// rebuild_queue_changed stays: it refreshes the SW4RM queue-summary
|
// rebuild_queue_changed: this page no longer subscribes to it at
|
||||||
// banner (see swarm.js — the per-agent badges it fed too, before
|
// all (see swarm.js's transients-section comment) — the SW4RM tab
|
||||||
// mara's "only show what is running" ask, are transient-only now).
|
// has nothing left that reads it, unlike /builds.html which still
|
||||||
rebuild_queue_changed: applyRebuildQueueChanged,
|
// does (its own separate subscription).
|
||||||
schedules_changed: applySchedulesChanged,
|
schedules_changed: applySchedulesChanged,
|
||||||
capabilities_changed: applyCapabilitiesChanged,
|
capabilities_changed: applyCapabilitiesChanged,
|
||||||
tool_groups_changed: applyToolGroupsChanged,
|
tool_groups_changed: applyToolGroupsChanged,
|
||||||
|
|
@ -338,7 +329,7 @@ window.marked = marked;
|
||||||
const es = openStream(
|
const es = openStream(
|
||||||
'/api/dashboard/stream?kinds=sent,approval_added,approval_resolved,' +
|
'/api/dashboard/stream?kinds=sent,approval_added,approval_resolved,' +
|
||||||
'question_added,question_resolved,transient_set,transient_cleared,' +
|
'question_added,question_resolved,transient_set,transient_cleared,' +
|
||||||
'container_state_changed,container_removed,rebuild_queue_changed,' +
|
'container_state_changed,container_removed,' +
|
||||||
'schedules_changed,capabilities_changed,tool_groups_changed',
|
'schedules_changed,capabilities_changed,tool_groups_changed',
|
||||||
);
|
);
|
||||||
es.onmessage = (e) => {
|
es.onmessage = (e) => {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue