Watch
0
0
Fork
You've already forked hyperhive
0

swarm-ui: retrying a broadcast shows the agents that failed, even ones the filter hides

This commit is contained in:
iris 2026-10-18 02:34:42 +02:00 • committed by mara
commit f65364759f
4 changed files with 33 additions and 3 deletions

View file

@ -307,8 +307,8 @@ seconds to answer, and the button reads **sending…** meanwhile.
The page then lists what happened to each agent. An agent that wasn't The page then lists what happened to each agent. An agent that wasn't
listening shows as not sent, with the reason, and the others still got the listening shows as not sent, with the reason, and the others still got the
message. **select the N that failed** ticks just those so you can send the same message. **select the N that failed** ticks just those, switching to **all** if the
message again. When every agent got the message the box clears; otherwise the filter hid any, so you can send the same message again. When every agent got the message the box clears; otherwise the
text stays. text stays.
### Inference settings ### Inference settings

View file

@ -25,6 +25,7 @@ import {
import { TextAreaField } from "../../ui/text-area-field/TextAreaField.js"; import { TextAreaField } from "../../ui/text-area-field/TextAreaField.js";
import { import {
failedAgents, failedAgents,
filterShowing,
isRunning, isRunning,
parseResults, parseResults,
selectedVisible, selectedVisible,
@ -130,7 +131,10 @@ export function BroadcastPage() {
} }
function retryFailed(results: BroadcastResult[]) { function retryFailed(results: BroadcastResult[]) {
setTicked(failedAgents(results)); const failed = failedAgents(results);
// Only this page's view changes; the saved choice stays as it was.
setFilterState(filterShowing(filter, all, failed));
setTicked(failed);
setSend({ status: "idle" }); setSend({ status: "idle" });
} }

View file

@ -38,6 +38,20 @@ export function selectedVisible(
return ticked.filter((name) => shown.has(name)); return ticked.filter((name) => shown.has(name));
} }
/**
* The filter to show `names` under: `filter` itself when it shows them all,
* otherwise `all`. A resend to agents that failed must show them ticked, and
* the failures are often the agents the `running` filter hides.
*/
export function filterShowing(
filter: AgentFilter,
agents: BroadcastAgent[],
names: string[],
): AgentFilter {
const shown = new Set(visibleAgents(agents, filter).map((a) => a.name));
return names.every((n) => shown.has(n)) ? filter : "all";
}
/** `ticked` with `name` flipped. */ /** `ticked` with `name` flipped. */
export function toggled(ticked: string[], name: string): string[] { export function toggled(ticked: string[], name: string): string[] {
return ticked.includes(name) return ticked.includes(name)

View file

@ -5,6 +5,7 @@ import assert from "node:assert/strict";
import { test } from "node:test"; import { test } from "node:test";
import { import {
failedAgents, failedAgents,
filterShowing,
MAX_BROADCAST, MAX_BROADCAST,
isRunning, isRunning,
parseResults, parseResults,
@ -94,3 +95,14 @@ test("an answer that is not the agreed shape is null, not an empty list", () =>
test("one broadcast may name at most 64 agents", () => { test("one broadcast may name at most 64 agents", () => {
assert.equal(MAX_BROADCAST, 64); assert.equal(MAX_BROADCAST, 64);
}); });
test("a retry shows the failed agents even when the filter hides them", () => {
const agents = [
{ name: "a", snapshot: { running: true } },
{ name: "b", snapshot: { running: false } },
];
assert.equal(filterShowing("running", agents, ["a"]), "running");
assert.equal(filterShowing("running", agents, ["a", "b"]), "all");
assert.equal(filterShowing("running", agents, ["b"]), "all");
assert.equal(filterShowing("all", agents, ["b"]), "all");
});