The subagent daemon stamps Swarm-Model and Swarm-Effort on each row it publishes. The list endpoint reads them off the newest row it already fetches, so a long-running subagent keeps them past the stream's 24 hour window, and the terminal page's menu and the agent panel's list show them beside the name.
82 lines
2.5 KiB
JavaScript
82 lines
2.5 KiB
JavaScript
// What counts as a running subagent, and the menu badge's wording. Run by
|
|
// `npm test`, which Node runs with its built-in test runner and type
|
|
// stripping, so the `.ts` module is imported as it is.
|
|
import assert from "node:assert/strict";
|
|
import { test } from "node:test";
|
|
import {
|
|
STALE_S,
|
|
byRecency,
|
|
isRunning,
|
|
runLabel,
|
|
runningLabel,
|
|
splitRunning,
|
|
stillListed,
|
|
} from "../src/agent/terminal/subagent-list.ts";
|
|
|
|
const NOW = 1_000_000;
|
|
const sub = (name, ago) => ({
|
|
name,
|
|
last_row_unix: ago === null ? null : NOW - ago,
|
|
model: null,
|
|
effort: null,
|
|
});
|
|
|
|
test("a subagent with a recent row is running, a quiet one is not", () => {
|
|
assert.equal(isRunning(sub("a", 5), NOW), true);
|
|
assert.equal(isRunning(sub("a", STALE_S), NOW), true);
|
|
assert.equal(isRunning(sub("a", STALE_S + 1), NOW), false);
|
|
});
|
|
|
|
test("a subagent whose time could not be read is not counted as running", () => {
|
|
assert.equal(isRunning(sub("a", null), NOW), false);
|
|
});
|
|
|
|
test("newest first, unreadable last, ties by name", () => {
|
|
const list = [sub("c", 50), sub("z", null), sub("b", 10), sub("a", 10)];
|
|
assert.deepEqual(
|
|
[...list].sort(byRecency).map((s) => s.name),
|
|
["a", "b", "c", "z"],
|
|
);
|
|
});
|
|
|
|
test("the list splits into running and quiet, each newest first", () => {
|
|
const { running, quiet } = splitRunning(
|
|
[
|
|
sub("old", STALE_S + 100),
|
|
sub("new", 1),
|
|
sub("mid", 60),
|
|
sub("none", null),
|
|
],
|
|
NOW,
|
|
);
|
|
assert.deepEqual(
|
|
running.map((s) => s.name),
|
|
["new", "mid"],
|
|
);
|
|
assert.deepEqual(
|
|
quiet.map((s) => s.name),
|
|
["old", "none"],
|
|
);
|
|
});
|
|
|
|
test("the badge counts in words", () => {
|
|
assert.equal(runningLabel(1), "1 running subagent");
|
|
assert.equal(runningLabel(4), "4 running subagents");
|
|
});
|
|
|
|
test("a pick holds only while the refreshed list still has it", () => {
|
|
const subs = [sub("a", 10), sub("b", 20)];
|
|
assert.equal(stillListed("a", subs), "a");
|
|
assert.equal(stillListed("gone", subs), null);
|
|
assert.equal(stillListed("a", []), null);
|
|
assert.equal(stillListed("a", null), null);
|
|
assert.equal(stillListed(null, subs), null);
|
|
});
|
|
|
|
test("the run label names the model and effort, whichever are known", () => {
|
|
assert.equal(runLabel({ model: "opus", effort: "high" }), "opus · high");
|
|
assert.equal(runLabel({ model: "opus", effort: null }), "opus");
|
|
assert.equal(runLabel({ model: null, effort: "medium" }), "medium");
|
|
assert.equal(runLabel({ model: null, effort: null }), "");
|
|
assert.equal(runLabel({ model: "", effort: "" }), "");
|
|
});
|