From c79c76fa91037b5ad2bcaf4861c3fca2ff2c8fa1 Mon Sep 17 00:00:00 2001 From: Michael Neale Date: Thu, 23 Jul 2026 12:27:57 +1000 Subject: [PATCH] feat(desktop): surface who is using shared compute on the Share card Adds a read-only, host-side usage indicator to the Share compute card so you can see when someone (or your own agent) is using the compute this machine is sharing, and where it's coming from. - new read-only mesh_serving_usage Tauri command projects the serving node's own routing_metrics (request/token counts, inflight, and the local vs remote/endpoint attempt split). No new trust surface; stubbed for non-mesh-llm builds. - serving_usage_from_payload: pure, defensive extractor (missing fields -> 0, so SDK shape drift degrades to 'no usage' not an error). - deriveServingIndicator: pure label derivation. Distinguishes this machine's OWN agents (local, shown softly) from another member consuming this machine's compute (remote/endpoint -> the headline 'in use by another member' case). - useMeshServingUsage: 4s poll, only while sharing. - indicator rendered under the Share toggle status line. - tests: 3 Rust (extractor local/remote/default), 7 TS (indicator label table), e2e mock answers mesh_serving_usage + seed hook. Verified live: firing a completion at the mesh API moves exactly the fields the extractor reads (req/tokens/local_attempt), local-only traffic correctly reads as not-a-remote-consumer. Local-only exploration on the mesh-state-fix branch; not part of PR #2448. --- desktop/src-tauri/src/commands/mesh_llm.rs | 14 +++ desktop/src-tauri/src/lib.rs | 1 + desktop/src-tauri/src/mesh_llm/mod.rs | 80 ++++++++++++++ desktop/src-tauri/src/mesh_llm/mod_tests.rs | 60 +++++++++++ desktop/src-tauri/src/mesh_llm_stubs.rs | 5 + .../mesh-compute/hooks/useMeshServingUsage.ts | 43 ++++++++ .../mesh-compute/servingUsage.test.mjs | 86 +++++++++++++++ .../src/features/mesh-compute/servingUsage.ts | 101 ++++++++++++++++++ .../ui/MeshComputeSettingsCard.tsx | 25 +++++ desktop/src/shared/api/tauriMesh.ts | 21 ++++ desktop/src/testing/e2eBridge.ts | 46 ++++++++ 11 files changed, 482 insertions(+) create mode 100644 desktop/src/features/mesh-compute/hooks/useMeshServingUsage.ts create mode 100644 desktop/src/features/mesh-compute/servingUsage.test.mjs create mode 100644 desktop/src/features/mesh-compute/servingUsage.ts diff --git a/desktop/src-tauri/src/commands/mesh_llm.rs b/desktop/src-tauri/src/commands/mesh_llm.rs index 03f3ece17..732fa7be9 100644 --- a/desktop/src-tauri/src/commands/mesh_llm.rs +++ b/desktop/src-tauri/src/commands/mesh_llm.rs @@ -462,6 +462,20 @@ pub async fn mesh_node_status(state: State<'_, AppState>) -> CmdResult, +) -> CmdResult { + let runtime = state.mesh_llm_runtime.lock().await; + match runtime.as_ref() { + Some(runtime) => runtime.serving_usage().await.map_err(|e| e.to_string()), + None => Ok(mesh_llm::MeshServingUsage::default()), + } +} + #[tauri::command] pub async fn mesh_installed_models( state: State<'_, AppState>, diff --git a/desktop/src-tauri/src/lib.rs b/desktop/src-tauri/src/lib.rs index 9017356ab..af2bb3226 100644 --- a/desktop/src-tauri/src/lib.rs +++ b/desktop/src-tauri/src/lib.rs @@ -797,6 +797,7 @@ pub fn run() { mesh_start_node, mesh_stop_node, mesh_node_status, + mesh_serving_usage, mesh_installed_models, mesh_model_catalog, update_managed_agent, diff --git a/desktop/src-tauri/src/mesh_llm/mod.rs b/desktop/src-tauri/src/mesh_llm/mod.rs index 9b01d185c..acece498c 100644 --- a/desktop/src-tauri/src/mesh_llm/mod.rs +++ b/desktop/src-tauri/src/mesh_llm/mod.rs @@ -196,6 +196,80 @@ pub struct MeshNodeStatus { pub device_name: Option, } +/// Host-side "who is using the compute I'm sharing" snapshot. +/// +/// Read-only projection of the serving node's own runtime metrics (the same +/// `routing_metrics` / `inflight_requests` the SDK already exposes on the local +/// console). No new trust surface: it reads the node's own status payload. +/// +/// The local/remote/endpoint attempt split is what distinguishes *my own* +/// agent (local) from *another member consuming my compute* (remote/endpoint). +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)] +#[serde(rename_all = "camelCase")] +pub struct MeshServingUsage { + /// Requests being served right now. + pub inflight: u64, + /// Highest concurrent in-flight seen this session. + pub peak_inflight: u64, + /// Total requests routed through this node. + pub requests_served: u64, + /// Completion tokens produced. + pub tokens_served: u64, + /// Recent decode throughput. + pub tokens_per_second: f64, + /// Requests served for this machine's own agents. + pub local_attempts: u64, + /// Requests served for a remote peer (someone else consuming my compute). + pub remote_attempts: u64, + /// Requests served via an advertised endpoint (also a remote consumer). + pub endpoint_attempts: u64, + /// Other nodes currently visible as peers. + pub peers: u64, +} + +impl MeshServingUsage { + /// True when at least one request has been served for a non-local consumer. + pub fn has_remote_consumers(&self) -> bool { + self.remote_attempts > 0 || self.endpoint_attempts > 0 + } +} + +/// Pure extractor: project a raw SDK status payload into [`MeshServingUsage`]. +/// +/// Every field is read defensively (missing → 0) so an SDK shape change +/// degrades to "no usage shown" rather than an error. Kept pure so it can be +/// unit-tested against a captured payload without a live runtime. +pub fn serving_usage_from_payload(payload: &serde_json::Value) -> MeshServingUsage { + let u64_at = |v: &serde_json::Value| v.as_u64().unwrap_or(0); + let rm = payload.get("routing_metrics"); + let local = rm.and_then(|m| m.get("local_node")); + let get_u64 = |obj: Option<&serde_json::Value>, key: &str| { + obj.and_then(|o| o.get(key)).map(u64_at).unwrap_or(0) + }; + MeshServingUsage { + inflight: local + .and_then(|l| l.get("current_inflight_requests")) + .map(u64_at) + .or_else(|| payload.get("inflight_requests").map(u64_at)) + .unwrap_or(0), + peak_inflight: get_u64(local, "peak_inflight_requests"), + requests_served: get_u64(rm, "request_count"), + tokens_served: get_u64(rm, "completion_tokens_observed"), + tokens_per_second: rm + .and_then(|m| m.get("avg_tokens_per_second")) + .and_then(serde_json::Value::as_f64) + .unwrap_or(0.0), + local_attempts: get_u64(local, "local_attempt_count"), + remote_attempts: get_u64(local, "remote_attempt_count"), + endpoint_attempts: get_u64(local, "endpoint_attempt_count"), + peers: payload + .get("peers") + .and_then(serde_json::Value::as_array) + .map(|a| a.len() as u64) + .unwrap_or(0), + } +} + pub fn stopped_status() -> MeshNodeStatus { MeshNodeStatus { state: MeshNodeState::Off, @@ -428,6 +502,12 @@ impl DesktopMeshRuntime { Ok(payload) } + /// Read-only host-side usage snapshot from the node's own runtime metrics. + pub async fn serving_usage(&self) -> anyhow::Result { + let status = self.handle.status().await?; + Ok(serving_usage_from_payload(&status.payload)) + } + pub async fn dial_endpoint_addr(&self, endpoint_addr: impl Into) -> anyhow::Result<()> { let endpoint_addr = endpoint_addr.into(); let validated = validate_advertised_endpoint(&endpoint_addr)?; diff --git a/desktop/src-tauri/src/mesh_llm/mod_tests.rs b/desktop/src-tauri/src/mesh_llm/mod_tests.rs index 4c0c835ef..3f7f4cb70 100644 --- a/desktop/src-tauri/src/mesh_llm/mod_tests.rs +++ b/desktop/src-tauri/src/mesh_llm/mod_tests.rs @@ -597,3 +597,63 @@ fn owner_roster_without_membership_list_fails_closed() { assert!(super::owner_ids_from_events(&events).is_empty()); } + +#[test] +fn serving_usage_extracts_local_and_remote_attempts() { + // Captured shape from a live serving node's status payload. The local vs + // remote/endpoint split is what tells "my own agent" apart from "a peer + // consuming my compute". + let payload = json!({ + "inflight_requests": 0, + "peers": [], + "routing_metrics": { + "request_count": 5, + "completion_tokens_observed": 764, + "avg_tokens_per_second": 29.651, + "local_node": { + "current_inflight_requests": 1, + "peak_inflight_requests": 2, + "local_attempt_count": 4, + "remote_attempt_count": 0, + "endpoint_attempt_count": 0 + } + } + }); + let usage = super::serving_usage_from_payload(&payload); + assert_eq!(usage.inflight, 1); + assert_eq!(usage.peak_inflight, 2); + assert_eq!(usage.requests_served, 5); + assert_eq!(usage.tokens_served, 764); + assert_eq!(usage.local_attempts, 4); + assert_eq!(usage.remote_attempts, 0); + assert_eq!(usage.endpoint_attempts, 0); + assert!(!usage.has_remote_consumers(), "all-local traffic is not a remote consumer"); +} + +#[test] +fn serving_usage_flags_remote_consumer() { + let payload = json!({ + "peers": [{"id": "a"}, {"id": "b"}], + "routing_metrics": { + "request_count": 10, + "local_node": { + "local_attempt_count": 3, + "remote_attempt_count": 6, + "endpoint_attempt_count": 1 + } + } + }); + let usage = super::serving_usage_from_payload(&payload); + assert_eq!(usage.remote_attempts, 6); + assert_eq!(usage.endpoint_attempts, 1); + assert_eq!(usage.peers, 2); + assert!(usage.has_remote_consumers(), "remote/endpoint attempts mean someone else is using my compute"); +} + +#[test] +fn serving_usage_defaults_to_zero_on_missing_fields() { + // SDK shape drift must degrade to "no usage" not panic. + let usage = super::serving_usage_from_payload(&json!({})); + assert_eq!(usage, super::MeshServingUsage::default()); + assert!(!usage.has_remote_consumers()); +} diff --git a/desktop/src-tauri/src/mesh_llm_stubs.rs b/desktop/src-tauri/src/mesh_llm_stubs.rs index 779f7dbdd..e8c13f48e 100644 --- a/desktop/src-tauri/src/mesh_llm_stubs.rs +++ b/desktop/src-tauri/src/mesh_llm_stubs.rs @@ -26,6 +26,11 @@ pub async fn mesh_node_status(_state: State<'_, AppState>) -> CmdResult) -> CmdResult { + Err("mesh-llm feature not enabled".to_string()) +} + #[tauri::command] pub async fn mesh_installed_models( _state: State<'_, AppState>, diff --git a/desktop/src/features/mesh-compute/hooks/useMeshServingUsage.ts b/desktop/src/features/mesh-compute/hooks/useMeshServingUsage.ts new file mode 100644 index 000000000..a7e28be5d --- /dev/null +++ b/desktop/src/features/mesh-compute/hooks/useMeshServingUsage.ts @@ -0,0 +1,43 @@ +import * as React from "react"; + +import { meshServingUsage } from "@/shared/api/tauriMesh"; +import type { MeshServingUsage } from "@/shared/api/tauriMesh"; + +/** + * Polls host-side serving usage while this machine is sharing compute. + * + * Only polls when `enabled` (the card passes `isSharing`) so a machine that + * isn't serving does no work. Cadence is a plain 4s — usage is informational, + * not a lifecycle transition, so it doesn't need the adaptive stepping that + * `useMeshNodeStatus` uses. Returns `null` until the first successful fetch. + */ +export function useMeshServingUsage(enabled: boolean): MeshServingUsage | null { + const [usage, setUsage] = React.useState(null); + + React.useEffect(() => { + if (!enabled) { + setUsage(null); + return; + } + let cancelled = false; + const fetchOnce = () => { + (async () => { + try { + const value = await meshServingUsage(); + if (!cancelled) setUsage(value); + } catch { + // Usage is best-effort; a failed poll leaves the last value in place + // rather than flapping the indicator. + } + })(); + }; + fetchOnce(); + const handle = window.setInterval(fetchOnce, 4000); + return () => { + cancelled = true; + window.clearInterval(handle); + }; + }, [enabled]); + + return usage; +} diff --git a/desktop/src/features/mesh-compute/servingUsage.test.mjs b/desktop/src/features/mesh-compute/servingUsage.test.mjs new file mode 100644 index 000000000..bde42e02c --- /dev/null +++ b/desktop/src/features/mesh-compute/servingUsage.test.mjs @@ -0,0 +1,86 @@ +import assert from "node:assert/strict"; +import { test } from "node:test"; + +import { deriveServingIndicator } from "./servingUsage.ts"; + +function usage(overrides = {}) { + return { + inflight: 0, + peakInflight: 0, + requestsServed: 0, + tokensServed: 0, + tokensPerSecond: 0, + localAttempts: 0, + remoteAttempts: 0, + endpointAttempts: 0, + peers: 0, + ...overrides, + }; +} + +test("hidden when not sharing", () => { + const i = deriveServingIndicator(usage({ requestsServed: 5 }), false); + assert.equal(i.show, false); +}); + +test("hidden when usage not yet fetched", () => { + const i = deriveServingIndicator(null, true); + assert.equal(i.show, false); +}); + +test("sharing but nothing served yet -> idle, no detail", () => { + const i = deriveServingIndicator(usage(), true); + assert.equal(i.show, true); + assert.equal(i.active, false); + assert.equal(i.hasRemoteConsumers, false); + assert.match(i.label, /Idle/); +}); + +test("only local agent traffic -> not a remote consumer", () => { + const i = deriveServingIndicator( + usage({ requestsServed: 4, localAttempts: 4, tokensPerSecond: 30 }), + true, + ); + assert.equal(i.hasRemoteConsumers, false); + assert.match(i.label, /Idle/); // served earlier, none live now + assert.match(i.detail, /4 requests served/); +}); + +test("local agent live now -> serving your agent", () => { + const i = deriveServingIndicator( + usage({ inflight: 1, localAttempts: 2, tokensPerSecond: 28 }), + true, + ); + assert.equal(i.active, true); + assert.equal(i.hasRemoteConsumers, false); + assert.match(i.label, /Serving your agent/); + assert.match(i.label, /1 live/); +}); + +test("remote consumer, not live -> used by another member (headline case)", () => { + const i = deriveServingIndicator( + usage({ + requestsServed: 7, + remoteAttempts: 6, + endpointAttempts: 1, + peers: 2, + }), + true, + ); + assert.equal(i.hasRemoteConsumers, true); + assert.equal(i.active, false); + assert.match(i.label, /another member/); + assert.match(i.label, /7 requests/); // remote+endpoint = 7 + assert.match(i.detail, /2 peers/); +}); + +test("remote consumer live now -> in use now, singular peer/request grammar", () => { + const i = deriveServingIndicator( + usage({ inflight: 1, remoteAttempts: 1, peers: 1, tokensPerSecond: 31 }), + true, + ); + assert.equal(i.active, true); + assert.equal(i.hasRemoteConsumers, true); + assert.match(i.label, /In use now by another member/); + assert.match(i.detail, /1 peer\b/); // singular +}); diff --git a/desktop/src/features/mesh-compute/servingUsage.ts b/desktop/src/features/mesh-compute/servingUsage.ts new file mode 100644 index 000000000..fff7584af --- /dev/null +++ b/desktop/src/features/mesh-compute/servingUsage.ts @@ -0,0 +1,101 @@ +import type { MeshServingUsage } from "@/shared/api/tauriMesh"; + +/** + * Pure projection of host-side serving usage into a small, politely-worded + * indicator model for the Share compute card. + * + * Single source of truth for "who is using the compute I'm sharing" copy, so + * the component and its tests agree. Kept pure/total (accepts null = not yet + * fetched) and defensive (all fields optional-safe via the Rust extractor). + * + * Distinctions that matter: + * - `localAttempts` = this machine's OWN agents using the local model. Not a + * "someone else is here" signal — surfaced softly as activity, not as a peer. + * - `remoteAttempts` / `endpointAttempts` = another member consuming this + * machine's compute. THIS is the "someone connected to what I'm sharing" + * signal. + */ +export type MeshServingIndicator = { + /** Whether to show anything at all (only while actively sharing). */ + show: boolean; + /** Someone is being served right now. */ + active: boolean; + /** A non-local member is (or has been) consuming this machine's compute. */ + hasRemoteConsumers: boolean; + /** One-line status suitable for the card. */ + label: string; + /** Longer detail for a tooltip / secondary line. */ + detail: string | null; +}; + +function plural(n: number, one: string, many = `${one}s`): string { + return n === 1 ? one : many; +} + +/** + * @param usage latest snapshot from `meshServingUsage`, or null if not fetched + * @param isSharing whether this machine is currently in serve mode (card owns + * this from the toggle model). Usage is only meaningful while + * sharing. + */ +export function deriveServingIndicator( + usage: MeshServingUsage | null, + isSharing: boolean, +): MeshServingIndicator { + const hidden: MeshServingIndicator = { + show: false, + active: false, + hasRemoteConsumers: false, + label: "", + detail: null, + }; + if (!isSharing || !usage) { + return hidden; + } + + const hasRemoteConsumers = + usage.remoteAttempts > 0 || usage.endpointAttempts > 0; + const active = usage.inflight > 0; + + // Remote consumer present (or seen) — the headline case the user asked for. + if (hasRemoteConsumers) { + const remote = usage.remoteAttempts + usage.endpointAttempts; + const label = active + ? `In use now by another member · ${usage.inflight} live` + : `Used by another member · ${remote} ${plural(remote, "request")}`; + const detail = + usage.peers > 0 + ? `${usage.peers} ${plural(usage.peers, "peer")} on the mesh · ${Math.round(usage.tokensPerSecond)} tok/s` + : `${Math.round(usage.tokensPerSecond)} tok/s`; + return { show: true, active, hasRemoteConsumers: true, label, detail }; + } + + // Only local (this machine's own agents) — show softly as activity. + if (active) { + return { + show: true, + active: true, + hasRemoteConsumers: false, + label: `Serving your agent · ${usage.inflight} live`, + detail: `${Math.round(usage.tokensPerSecond)} tok/s`, + }; + } + if (usage.requestsServed > 0) { + return { + show: true, + active: false, + hasRemoteConsumers: false, + label: "Idle · no one using it right now", + detail: `${usage.requestsServed} ${plural(usage.requestsServed, "request")} served this session`, + }; + } + + // Sharing but nothing served yet. + return { + show: true, + active: false, + hasRemoteConsumers: false, + label: "Idle · no one using it yet", + detail: null, + }; +} diff --git a/desktop/src/features/mesh-compute/ui/MeshComputeSettingsCard.tsx b/desktop/src/features/mesh-compute/ui/MeshComputeSettingsCard.tsx index aef4351bd..1ca81c43b 100644 --- a/desktop/src/features/mesh-compute/ui/MeshComputeSettingsCard.tsx +++ b/desktop/src/features/mesh-compute/ui/MeshComputeSettingsCard.tsx @@ -29,7 +29,9 @@ import { useMeshDownloadProgress, } from "../hooks/useMeshDownloadProgress"; import { useMeshNodeStatus } from "../hooks/useMeshNodeStatus"; +import { useMeshServingUsage } from "../hooks/useMeshServingUsage"; import { deriveMeshShareToggle } from "../shareToggleState"; +import { deriveServingIndicator } from "../servingUsage"; const MODEL_DRAFT_STORAGE_KEY = "buzz.mesh-compute.share.model.v1"; const MAX_VRAM_DRAFT_STORAGE_KEY = "buzz.mesh-compute.share.max-vram-gb.v1"; @@ -137,6 +139,10 @@ export function MeshComputeSettingsCard() { // toggling off must never tear down that unrelated consume session. const { isSharing, isConsuming, slotOccupied } = deriveMeshShareToggle(status); + // Host-side "who is using the compute I'm sharing" — only polled while + // actively sharing (serve mode). Read-only; reads the node's own metrics. + const servingUsage = useMeshServingUsage(isSharing); + const servingIndicator = deriveServingIndicator(servingUsage, isSharing); // Any occupying runtime (serve or client, healthy or failed) locks the model // inputs and blocks a fresh start — stop it before reconfiguring. const controlsDisabled = slotOccupied || actionInFlight; @@ -222,6 +228,25 @@ export function MeshComputeSettingsCard() { pendingAction={pendingAction} status={status} /> + {servingIndicator.show ? ( +

+ {servingIndicator.label} + {servingIndicator.detail ? ( + + {" "} + · {servingIndicator.detail} + + ) : null} +

+ ) : null} { return await invokeTauri("mesh_node_status"); } +/** + * 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). + */ +export type MeshServingUsage = { + inflight: number; + peakInflight: number; + requestsServed: number; + tokensServed: number; + tokensPerSecond: number; + localAttempts: number; + remoteAttempts: number; + endpointAttempts: number; + peers: number; +}; + +export async function meshServingUsage(): Promise { + return await invokeTauri("mesh_serving_usage"); +} + export async function meshInstalledModels(): Promise { return await invokeTauri("mesh_installed_models"); } diff --git a/desktop/src/testing/e2eBridge.ts b/desktop/src/testing/e2eBridge.ts index 507b4e399..64d40191c 100644 --- a/desktop/src/testing/e2eBridge.ts +++ b/desktop/src/testing/e2eBridge.ts @@ -1029,6 +1029,18 @@ declare global { * so the Share toggle must stay off. Drives the toggle-on regression test. */ nodeMode?: "serve" | "client" | null; + /** Seed host-side serving usage to exercise the "who's using my compute" indicator. */ + servingUsage?: Partial<{ + inflight: number; + peakInflight: number; + requestsServed: number; + tokensServed: number; + tokensPerSecond: number; + localAttempts: number; + remoteAttempts: number; + endpointAttempts: number; + peers: number; + }>; }) => void; __BUZZ_E2E_SEED_ACTIVE_TURNS__?: (input: { agentPubkey: string; @@ -2742,12 +2754,37 @@ function resetMockSaveSubscriptions(config: E2eConfig | undefined) { // in a browser. They deliberately do NOT model real admission, real inference, // or real mesh routing — those are proven by the Rust layer-2 tests and the // on-hardware layer-1 example. Do not port any of this into production code. +type MockServingUsage = { + inflight: number; + peakInflight: number; + requestsServed: number; + tokensServed: number; + tokensPerSecond: number; + localAttempts: number; + remoteAttempts: number; + endpointAttempts: number; + peers: number; +}; + +const ZERO_SERVING_USAGE: MockServingUsage = { + inflight: 0, + peakInflight: 0, + requestsServed: 0, + tokensServed: 0, + tokensPerSecond: 0, + localAttempts: 0, + remoteAttempts: 0, + endpointAttempts: 0, + peers: 0, +}; + const mockMeshState: { admitted: boolean; models: Array<{ id: string; name: string | null }>; denyReason: string; nodeState: "off" | "running"; nodeMode: "serve" | "client" | null; + servingUsage: MockServingUsage; } = { admitted: true, models: [ @@ -2756,6 +2793,7 @@ const mockMeshState: { denyReason: "not a relay member", nodeState: "off", nodeMode: null, + servingUsage: { ...ZERO_SERVING_USAGE }, }; function resetMockMesh() { @@ -2766,6 +2804,7 @@ function resetMockMesh() { mockMeshState.denyReason = "not a relay member"; mockMeshState.nodeState = "off"; mockMeshState.nodeMode = null; + mockMeshState.servingUsage = { ...ZERO_SERVING_USAGE }; } let mockPersonas: RawPersona[] = []; let mockTeams: RawTeam[] = []; @@ -9076,6 +9115,11 @@ export function maybeInstallE2eTauriMocks() { mockMeshState.denyReason = mesh.denyReason; if (mesh.nodeState !== undefined) mockMeshState.nodeState = mesh.nodeState; if (mesh.nodeMode !== undefined) mockMeshState.nodeMode = mesh.nodeMode; + if (mesh.servingUsage !== undefined) + mockMeshState.servingUsage = { + ...mockMeshState.servingUsage, + ...mesh.servingUsage, + }; }; let seedTurnSeq = Date.now(); window.__BUZZ_E2E_SEED_ACTIVE_TURNS__ = ({ @@ -9195,6 +9239,8 @@ export function maybeInstallE2eTauriMocks() { return mockMeshState.models; case "mesh_node_status": return meshNodeStatus(mockMeshState.nodeState, mockMeshState.nodeMode); + case "mesh_serving_usage": + return mockMeshState.servingUsage; case "mesh_start_node": { const req = ( payload as { request?: { mode?: "serve" | "client" } } | null