feat(mesh): mesh capacity framing, honest usage signal, clickable card

Card now leads with pool capacity ("115 GB · 1 device") rather than this
machine's participation, and drops the model name — it belongs in the detail
view, not a 256px card.

Fixes an inverted usage signal: routing_metrics is incremented only by this
node's own OpenAI ingress, so remote/endpoint attempts mean this machine is
CONSUMING, not being consumed. The old activeConsumers check read them as
"someone is using your compute" — exactly backwards. mesh-llm exposes no
inbound counter, so participation copy now uses inflight ("working now") and
request_count ("N requests this session") and never claims work was served
for other members. A test pins that wording.

Headline text block is now a button for the forthcoming mesh detail view.

Signed-off-by: Michael Neale <michael.neale@gmail.com>
This commit is contained in:
Michael Neale
2026-08-04 19:38:07 +10:00
parent 9df2a5a69a
commit dda20b5d62
4 changed files with 164 additions and 34 deletions
@@ -15,6 +15,7 @@ import assert from "node:assert/strict";
import {
describeMeshCapacity,
describeParticipation,
describeReadyModels,
deriveMeshCardModel,
formatCapacityGb,
@@ -68,7 +69,8 @@ function derive(overrides = {}) {
toggle: OFF_TOGGLE,
pendingAction: null,
canShare: true,
activeConsumers: false,
busyNow: false,
requestsRouted: 0,
...overrides,
});
}
@@ -78,13 +80,13 @@ test("capacity headline counts devices and sums reported memory", () => {
describeMeshCapacity(
snapshot({ sharingDeviceCount: 3, sharedCapacityGb: 42.3 }),
),
"3 devices sharing · 42 GB",
"42 GB · 3 devices",
);
assert.equal(
describeMeshCapacity(
snapshot({ sharingDeviceCount: 1, sharedCapacityGb: 18 }),
),
"1 device sharing · 18 GB",
"18 GB · 1 device",
);
});
@@ -92,7 +94,7 @@ test("unknown capacity degrades to a device count, never 0 GB", () => {
const text = describeMeshCapacity(
snapshot({ sharingDeviceCount: 3, sharedCapacityGb: null }),
);
assert.equal(text, "3 devices sharing");
assert.equal(text, "Mesh capacity · 3 devices");
assert.ok(!text.includes("0 GB"), "must not claim zero capacity");
});
@@ -101,9 +103,9 @@ test("an empty mesh reads as an honest empty state", () => {
describeMeshCapacity(
snapshot({ sharingDeviceCount: 0, sharedCapacityGb: null }),
),
"No compute shared yet",
"No mesh capacity yet",
);
assert.equal(describeMeshCapacity(null), "No compute shared yet");
assert.equal(describeMeshCapacity(null), "No mesh capacity yet");
});
test("capacity formatting keeps small figures meaningful", () => {
@@ -145,7 +147,7 @@ test("consuming never renders as sharing", () => {
assert.equal(model.switchDisabled, false);
});
test("sharing states name the model and the community capacity", () => {
test("sharing leads with mesh capacity and omits the model name", () => {
const model = derive({
toggle: SHARING_TOGGLE,
status: {
@@ -158,16 +160,20 @@ test("sharing states name the model and the community capacity", () => {
consoleUrl: null,
},
snapshot: snapshot({
sharingDeviceCount: 1,
sharedCapacityGb: 115,
devices: [device({ isSelf: true })],
includesSelf: true,
}),
});
assert.equal(model.tone, "sharing");
assert.equal(model.switchOn, true);
assert.match(model.detail, /Gemma 4 26B A4B/);
assert.equal(model.headline, "115 GB · 1 device");
// The model belongs in the detail view, not on a 256px card.
assert.ok(!/Gemma/i.test(model.detail ?? ""), "card must not name the model");
});
test("active consumers are called out in the headline", () => {
test("inflight work reads as working, never as 'someone is using you'", () => {
const model = derive({
toggle: SHARING_TOGGLE,
status: {
@@ -179,9 +185,54 @@ test("active consumers are called out in the headline", () => {
apiBaseUrl: null,
consoleUrl: null,
},
activeConsumers: true,
busyNow: true,
});
assert.match(model.headline, /in use now/);
assert.match(model.detail, /working now/);
});
test("routed requests are a subtle used-ness signal, not a served claim", () => {
const model = derive({
toggle: SHARING_TOGGLE,
status: {
state: "running",
mode: "serve",
health: { status: "ok", reason: null },
modelId: "m",
modelName: null,
apiBaseUrl: null,
consoleUrl: null,
},
requestsRouted: 7,
});
assert.match(model.detail, /7 requests this session/);
});
test("participation copy never claims work was served for other members", () => {
// mesh-llm exposes no inbound counter, so no wording here may imply that
// another member consumed this machine's compute.
const claims = [
describeParticipation({ busyNow: false, requestsRouted: 0 }),
describeParticipation({ busyNow: true, requestsRouted: 3 }),
describeParticipation({ busyNow: false, requestsRouted: 3 }),
];
assert.deepEqual(claims, [
"Sharing · ready",
"Sharing · working now",
"Sharing · 3 requests this session",
]);
for (const claim of claims) {
assert.ok(
!/served|for (others|members|someone)|consumed/i.test(claim),
`must not claim served-for-others: ${claim}`,
);
}
});
test("one routed request is singular", () => {
assert.equal(
describeParticipation({ busyNow: false, requestsRouted: 1 }),
"Sharing · 1 request this session",
);
});
test("a serve node with no advertised model is warming up, not serving", () => {
@@ -227,7 +278,7 @@ test("the idle invitation leads with what the community already has", () => {
snapshot: snapshot({ sharingDeviceCount: 2, sharedCapacityGb: 54 }),
});
assert.equal(model.tone, "idle");
assert.equal(model.headline, "2 devices sharing · 54 GB");
assert.equal(model.headline, "54 GB · 2 devices");
});
test("the switch is disabled until a model can be resolved", () => {
@@ -65,7 +65,11 @@ function plural(n: number, one: string, many = `${one}s`): string {
}
/**
* The community headline: how much compute is actually available right now.
* The community headline: how much compute is actually reachable right now.
*
* Named "Mesh capacity" rather than "sharing" because the figure describes the
* pool, not this machine's participation — the switch already says whether you
* are in it.
*
* Counts only devices advertising a routable model — the same standard routing
* uses — so the number never promises capacity that cannot be reached. Never
@@ -73,12 +77,14 @@ function plural(n: number, one: string, many = `${one}s`): string {
*/
export function describeMeshCapacity(snapshot: MeshSnapshot | null): string {
if (!snapshot || snapshot.sharingDeviceCount === 0) {
return "No compute shared yet";
return "No mesh capacity yet";
}
const { sharingDeviceCount: count, sharedCapacityGb: gb } = snapshot;
const devices = `${count} ${plural(count, "device")} sharing`;
const devices = `${count} ${plural(count, "device")}`;
// Unknown capacity degrades to the device count rather than printing 0 GB.
return gb === null ? devices : `${devices} · ${formatCapacityGb(gb)}`;
return gb === null
? `Mesh capacity · ${devices}`
: `${formatCapacityGb(gb)} · ${devices}`;
}
/** Short label for what is ready to run, or null when nothing is. */
@@ -95,6 +101,30 @@ export function describeReadyModels(
return `${models.length} models ready`;
}
/**
* The sharing detail line: proof this machine is participating, and that the
* mesh has actually been used.
*
* Scrupulously avoids claiming someone else consumed this machine's compute —
* mesh-llm exposes no inbound counter, so "requests routed" is the strongest
* true statement available. Worded as "requests" without "served for others".
*/
export function describeParticipation({
busyNow,
requestsRouted,
}: {
busyNow: boolean;
requestsRouted: number;
}): string {
if (busyNow) {
return "Sharing · working now";
}
if (requestsRouted > 0) {
return `Sharing · ${requestsRouted} ${plural(requestsRouted, "request")} this session`;
}
return "Sharing · ready";
}
/**
* Trim a model reference down to something that fits a 256px sidebar.
* `unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q4_K_M` → `Gemma 4 26B A4B`.
@@ -125,7 +155,8 @@ export function deriveMeshCardModel({
toggle,
pendingAction,
canShare,
activeConsumers,
busyNow,
requestsRouted,
}: {
snapshot: MeshSnapshot | null;
status: MeshNodeStatus | null;
@@ -133,8 +164,21 @@ export function deriveMeshCardModel({
pendingAction: "start" | "stop" | null;
/** False when no model can be resolved yet (catalog still loading). */
canShare: boolean;
/** Another member is actively using this machine's compute right now. */
activeConsumers: boolean;
/**
* This node has inference in flight (`inflight > 0`).
*
* Honest but coarse: mesh-llm's inflight counter does not say whether the
* work is for a local agent or a remote member, so this only ever claims
* "working", never "someone is using your compute".
*/
busyNow: boolean;
/**
* Requests this node's ingress has routed this session (`request_count`).
*
* Outbound routing, NOT work served for others — mesh-llm exposes no inbound
* counter. Used only as a subtle "this has been used" signal.
*/
requestsRouted: number;
}): MeshCardModel {
const devices = snapshot?.devices ?? [];
const participantCount = devices.length;
@@ -219,14 +263,13 @@ export function deriveMeshCardModel({
showSoloHint: false,
};
}
const model = status?.modelName ?? status?.modelId;
// Model name is deliberately absent: it belongs in the detail view, not on
// a 256px card whose job is "am I in the mesh, and is it alive".
return {
...base,
tone: "sharing",
headline: activeConsumers
? "Sharing · in use now"
: "Sharing this computer",
detail: model ? `${shortModelLabel(model)} · ${capacity}` : capacity,
headline: capacity,
detail: describeParticipation({ busyNow, requestsRouted }),
showSoloHint: isSolo,
};
}
@@ -62,9 +62,12 @@ const TONE_RING_CLASS: Record<MeshCardTone, string> = {
export function SidebarMeshComputeCard({
className,
onOpenComputeSettings,
onOpenDetail,
}: {
className?: string;
onOpenComputeSettings?: () => void;
/** Open the full mesh view (topology, capacity, per-device detail). */
onOpenDetail?: () => void;
}) {
const shouldReduceMotion = useReducedMotion();
const { status, refresh: refreshStatus } = useMeshNodeStatus();
@@ -82,9 +85,15 @@ export function SidebarMeshComputeCard({
});
const toggle = deriveMeshShareToggle(status);
const usage = useMeshServingUsage(toggle.isSharing);
const activeConsumers =
(usage?.remoteAttempts ?? 0) > 0 || (usage?.endpointAttempts ?? 0) > 0;
// Poll whenever a runtime slot is occupied, not just when sharing: a
// consuming node also has inflight work worth showing.
const usage = useMeshServingUsage(toggle.isSharing || toggle.isConsuming);
// `inflight` is the only honest "working" signal: mesh-llm's routing metrics
// are all OUTBOUND (incremented by this node's own ingress), so a remote/
// endpoint attempt means this machine is CONSUMING, not being consumed.
// Reading them as "someone is using my compute" is exactly backwards.
const busyNow = (usage?.inflight ?? 0) > 0;
const requestsRouted = usage?.requestsServed ?? 0;
// One-shot catalog fetch: the card needs the hardware-appropriate
// recommendation so the switch can start sharing without a model picker.
@@ -116,7 +125,8 @@ export function SidebarMeshComputeCard({
toggle,
pendingAction,
canShare: Boolean(recommended),
activeConsumers,
busyNow,
requestsRouted,
});
async function handleToggle(next: boolean) {
@@ -146,7 +156,7 @@ export function SidebarMeshComputeCard({
}
// A transport failure is worth showing; an empty mesh is not an error and is
// already expressed by the headline ("No compute shared yet").
// already expressed by the headline ("No mesh capacity yet").
const errorText = actionError ?? snapshotError;
return (
@@ -178,7 +188,17 @@ export function SidebarMeshComputeCard({
{TONE_ICON[model.tone]}
</span>
<div className="min-w-0 flex-1">
{/*
Clickable region is the text block, not the whole card: wrapping the
Switch in a button would nest interactive elements.
*/}
<button
className="min-w-0 flex-1 rounded-md text-left focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-default"
data-testid="mesh-card-open-detail"
disabled={!onOpenDetail}
onClick={onOpenDetail}
type="button"
>
<p
className="truncate text-sm font-semibold leading-tight"
data-testid="mesh-card-headline"
@@ -193,7 +213,7 @@ export function SidebarMeshComputeCard({
{model.detail}
</p>
) : null}
</div>
</button>
<Switch
aria-label={model.switchLabel}
+19 -3
View File
@@ -53,9 +53,25 @@ export async function meshNodeStatus(): Promise<MeshNodeStatus> {
}
/**
* Host-side usage of the compute this machine is sharing. The
* local/remote/endpoint attempt split distinguishes this machine's own agents
* (local) from another member consuming this machine's compute (remote/endpoint).
* This machine's own routing activity — **outbound**, not work done for others.
*
* Every counter here comes from mesh-llm's `routing_metrics`, which is
* incremented only by the local OpenAI ingress (`network/openai/transport.rs`)
* when *this* node dispatches a request. The inbound peer-serving path
* (`mesh/stage_transport.rs`) never touches it — it only observes inflight.
*
* So the attempt split means where MY requests went, not who asked me:
* - `localAttempts` — I ran it on my own GPU
* - `remoteAttempts` — I sent it to a peer (i.e. I am CONSUMING)
* - `endpointAttempts` — I sent it to an endpoint
*
* `tokensServed` is likewise `completion_tokens_observed`: tokens I received,
* not tokens I produced for someone else.
*
* mesh-llm exposes no inbound "requests I served for others" counter today, so
* never label any field here as proof that this machine's compute was used by
* another member. `inflight` is the one honest "busy right now" signal, and it
* does not distinguish who the work is for.
*/
export type MeshServingUsage = {
inflight: number;