From 065ae76a18de85d967ba94af799494115d0fbabd Mon Sep 17 00:00:00 2001 From: Alessandro Joabar Date: Tue, 18 Aug 2026 14:33:31 -0400 Subject: [PATCH] Simplify community compute visibility Signed-off-by: Alessandro Joabar --- .../ui/CommunityComputeComponents.test.mjs | 51 +- .../ui/CommunityComputeHealthScorecard.tsx | 154 ----- .../ui/CommunityComputeKpiRow.tsx | 2 +- .../ui/CommunityComputeTerritoryMap.tsx | 524 +----------------- .../ui/CommunityComputeTutorialPanel.tsx | 146 ----- .../ui/MeshComputeCommunityView.tsx | 92 +-- .../ui/MeshComputeImpactReceipt.tsx | 91 --- .../mesh-compute/ui/MeshComputePage.tsx | 61 +- .../ui/MeshComputeTokenLeaderboard.tsx | 103 ---- desktop/tailwind.config.js | 8 - .../e2e/mesh-compute-screenshots.spec.ts | 79 ++- desktop/tests/e2e/mesh-compute.spec.ts | 71 +-- 12 files changed, 125 insertions(+), 1257 deletions(-) delete mode 100644 desktop/src/features/mesh-compute/ui/CommunityComputeHealthScorecard.tsx delete mode 100644 desktop/src/features/mesh-compute/ui/CommunityComputeTutorialPanel.tsx delete mode 100644 desktop/src/features/mesh-compute/ui/MeshComputeImpactReceipt.tsx delete mode 100644 desktop/src/features/mesh-compute/ui/MeshComputeTokenLeaderboard.tsx diff --git a/desktop/src/features/mesh-compute/ui/CommunityComputeComponents.test.mjs b/desktop/src/features/mesh-compute/ui/CommunityComputeComponents.test.mjs index d20ed6ebee..99569262d8 100644 --- a/desktop/src/features/mesh-compute/ui/CommunityComputeComponents.test.mjs +++ b/desktop/src/features/mesh-compute/ui/CommunityComputeComponents.test.mjs @@ -8,7 +8,6 @@ import { SMALL_COMPANY_COMMUNITY_COMPUTE_FIXTURE, } from "../communityComputeFixtures.ts"; import { deriveCommunityComputeMapModel } from "../communityComputeMapModel.ts"; -import { CommunityComputeHealthScorecard } from "./CommunityComputeHealthScorecard.tsx"; import { CommunityComputeKpiRow } from "./CommunityComputeKpiRow.tsx"; import { CommunityComputeTerritoryMap } from "./CommunityComputeTerritoryMap.tsx"; @@ -17,7 +16,7 @@ const smallModel = deriveCommunityComputeMapModel( ); describe("community compute visual components", () => { - it("renders contract-backed KPI values", () => { + it("renders contract-backed headline values", () => { const html = renderToStaticMarkup( React.createElement(CommunityComputeKpiRow, { kpis: smallModel.kpis }), ); @@ -28,18 +27,7 @@ describe("community compute visual components", () => { assert.match(html, />2,744 GB { - const html = renderToStaticMarkup( - React.createElement(CommunityComputeHealthScorecard, { - health: smallModel.health, - }), - ); - assert.match(html, /data-status="healthy"/); - assert.match(html, /No reported issues/); - assert.match(html, /data-testid="community-compute-health-healthy"/); - }); - - it("renders one accessible territory and list item per ready model", () => { + it("renders a simple accessible territory map without dashboard modules", () => { const html = renderToStaticMarkup( React.createElement(CommunityComputeTerritoryMap, { model: smallModel }), ); @@ -52,37 +40,14 @@ describe("community compute visual components", () => { ].length, smallModel.deployments.length, ); - assert.equal( - [ - ...html.matchAll( - /data-testid="community-compute-deployment-deployment-/g, - ), - ].length, - smallModel.deployments.length, - ); assert.match(html, /tabindex="0"/); - assert.match(html, /Search models or devices/); - assert.match(html, /Model footprint/); - assert.doesNotMatch(html, /Utilization|Region|Split across machines/); + assert.doesNotMatch( + html, + /Search models or devices|community-compute-deployment-list|community-compute-contributor-avatar|animate-mesh-inference|Map legend|Gold|selected/, + ); }); - it("keeps the production map static and supports explicit tutorial motion", () => { - const html = renderToStaticMarkup( - React.createElement(CommunityComputeTerritoryMap, { model: smallModel }), - ); - assert.doesNotMatch(html, /animate-mesh-inference/); - - const tutorialHtml = renderToStaticMarkup( - React.createElement(CommunityComputeTerritoryMap, { - model: smallModel, - inferenceDeploymentIds: [smallModel.deployments[0].id], - }), - ); - assert.match(tutorialHtml, /animate-mesh-inference/); - assert.doesNotMatch(html, /community-compute-split-boundary/); - }); - - it("renders a static empty state without a deployment list", () => { + it("renders a static empty state without extra controls", () => { const emptyModel = deriveCommunityComputeMapModel( EMPTY_COMMUNITY_COMPUTE_FIXTURE.snapshot, ); @@ -90,6 +55,6 @@ describe("community compute visual components", () => { React.createElement(CommunityComputeTerritoryMap, { model: emptyModel }), ); assert.match(html, /data-testid="community-compute-map-empty"/); - assert.doesNotMatch(html, /community-compute-deployment-list/); + assert.doesNotMatch(html, /community-compute-deployment-list|Search/); }); }); diff --git a/desktop/src/features/mesh-compute/ui/CommunityComputeHealthScorecard.tsx b/desktop/src/features/mesh-compute/ui/CommunityComputeHealthScorecard.tsx deleted file mode 100644 index cbf39dc9a4..0000000000 --- a/desktop/src/features/mesh-compute/ui/CommunityComputeHealthScorecard.tsx +++ /dev/null @@ -1,154 +0,0 @@ -import { - AlertTriangle, - CheckCircle2, - CircleHelp, - MinusCircle, - XCircle, -} from "lucide-react"; - -import { cn } from "@/shared/lib/cn"; -import type { - CommunityComputeDeploymentHealth, - CommunityComputeHealthSummary, -} from "../communityComputeMapModel"; - -export type CommunityComputeHealthScorecardProps = { - health: CommunityComputeHealthSummary; - className?: string; -}; - -const HEALTH_ROWS: readonly { - status: CommunityComputeDeploymentHealth; - label: string; -}[] = [ - { status: "healthy", label: "Healthy" }, - { status: "warming", label: "Warming" }, - { status: "idle", label: "Idle" }, - { status: "degraded", label: "Degraded" }, - { status: "offline", label: "Offline" }, - { status: "unknown", label: "Unknown" }, -]; - -/** Health summary with icon, copy, and count labels that do not rely on color. */ -export function CommunityComputeHealthScorecard({ - health, - className, -}: CommunityComputeHealthScorecardProps) { - const Icon = statusIcon(health.status); - const total = Object.values(health.counts).reduce( - (sum, count) => sum + count, - 0, - ); - - return ( -
-
- -
-

- {health.label} -

-

- {health.reason ?? healthDescription(health.status, total)} -

-
- - {total} total - -
- -
- {HEALTH_ROWS.map(({ status, label }) => ( -
0 && healthClass(status), - )} - data-testid={`community-compute-health-${status}`} - key={status} - > -
{label}
-
- {health.counts[status]} -
-
- ))} -
-
- ); -} - -function statusIcon(status: CommunityComputeHealthSummary["status"]) { - switch (status) { - case "healthy": - return CheckCircle2; - case "attention": - return AlertTriangle; - case "critical": - return XCircle; - case "empty": - return MinusCircle; - case "unknown": - return CircleHelp; - } -} - -function healthClass(status: CommunityComputeDeploymentHealth): string { - switch (status) { - case "healthy": - return "border-solid bg-foreground/[0.04]"; - case "warming": - return "border-dashed bg-foreground/[0.03]"; - case "idle": - return "border-dotted"; - case "degraded": - return "border-dashed border-foreground/50"; - case "offline": - return "border-foreground/50 bg-muted/50 line-through decoration-muted-foreground/50"; - case "unknown": - return "border-dotted bg-muted/20"; - } -} - -function healthDescription( - status: CommunityComputeHealthSummary["status"], - total: number, -): string { - switch (status) { - case "healthy": - return "No reporting device needs attention; some may still be warming or idle."; - case "attention": - return "Some deployments may have reduced availability."; - case "critical": - return "Shared compute is currently unavailable."; - case "empty": - return "No deployments have joined this community yet."; - case "unknown": - return total === 0 - ? "Waiting for deployment health reports." - : "Deployment health could not be determined."; - } -} diff --git a/desktop/src/features/mesh-compute/ui/CommunityComputeKpiRow.tsx b/desktop/src/features/mesh-compute/ui/CommunityComputeKpiRow.tsx index 7e77943f6e..dac942562e 100644 --- a/desktop/src/features/mesh-compute/ui/CommunityComputeKpiRow.tsx +++ b/desktop/src/features/mesh-compute/ui/CommunityComputeKpiRow.tsx @@ -20,7 +20,7 @@ export function CommunityComputeKpiRow({ { label: "Contributed VRAM", value: formatCapacity(kpis.sharedCapacityGb), - detail: `${formatCount(kpis.deploymentCount)} deployments`, + detail: `${formatCount(kpis.deploymentCount)} models available`, }, { label: "VRAM allocated", diff --git a/desktop/src/features/mesh-compute/ui/CommunityComputeTerritoryMap.tsx b/desktop/src/features/mesh-compute/ui/CommunityComputeTerritoryMap.tsx index 75f34fc277..91dd44d2ab 100644 --- a/desktop/src/features/mesh-compute/ui/CommunityComputeTerritoryMap.tsx +++ b/desktop/src/features/mesh-compute/ui/CommunityComputeTerritoryMap.tsx @@ -1,8 +1,6 @@ import * as React from "react"; import { cn } from "@/shared/lib/cn"; -import { getAvatarSnapshotUrl } from "@/shared/lib/animatedAvatar"; -import { rewriteRelayUrl } from "@/shared/lib/mediaUrl"; import { hexTerritoryBoundaryEdges, layoutCommunityComputeHexTerritories, @@ -10,18 +8,12 @@ import { } from "../communityComputeHexLayout"; import type { CommunityComputeDeployment, - CommunityComputeDeploymentHealth, CommunityComputeMapModel, } from "../communityComputeMapModel"; export type CommunityComputeTerritoryMapProps = { model: CommunityComputeMapModel; - selectedDeploymentId?: string | null; - onSelectedDeploymentChange?: (deploymentId: string) => void; className?: string; - /** Tutorial-only simulated activity; live snapshots cannot attribute requests. */ - inferenceDeploymentIds?: readonly string[]; - contributorProfiles?: ContributorProfiles; }; type Point = { x: number; y: number }; @@ -45,15 +37,8 @@ const SQRT_THREE = Math.sqrt(3); */ export function CommunityComputeTerritoryMap({ model, - selectedDeploymentId, - onSelectedDeploymentChange, className, - inferenceDeploymentIds = [], - contributorProfiles = {}, }: CommunityComputeTerritoryMapProps) { - const [internalSelection, setInternalSelection] = React.useState< - string | null - >(null); const deploymentById = React.useMemo( () => new Map( @@ -75,29 +60,14 @@ export function CommunityComputeTerritoryMap({ React.useEffect(() => { previousLayoutRef.current = layout; }, [layout]); - const fallbackId = model.deployments[0]?.id ?? null; - const requestedId = selectedDeploymentId ?? internalSelection; - const activeId = - requestedId !== null && deploymentById.has(requestedId) - ? requestedId - : fallbackId; - const activeDeployment = activeId - ? (deploymentById.get(activeId) ?? null) - : null; const viewBox = computeViewBox(layout.cells); - const inferenceIds = React.useMemo( - () => new Set(inferenceDeploymentIds), - [inferenceDeploymentIds], - ); const [hoveredId, setHoveredId] = React.useState(null); const lowerTimerRef = React.useRef | null>( null, ); - const [deploymentSearch, setDeploymentSearch] = React.useState(""); const hoveredDeployment = hoveredId ? (deploymentById.get(hoveredId) ?? null) : null; - const isHeroDeployment = model.deployments.length === 1; const isDenseMap = model.deployments.length >= 50; React.useEffect( @@ -109,26 +79,18 @@ export function CommunityComputeTerritoryMap({ function raiseTerritory(deploymentId: string, territoryElement: SVGGElement) { if (lowerTimerRef.current) clearTimeout(lowerTimerRef.current); - // SVG paints in DOM order. Move the existing node rather than sorting the - // React children: sorting reconstructs animated SVG content and restarts - // its breathing phase whenever hover changes. + // SVG paints in DOM order. Move the existing node instead of rebuilding + // children so hover stays smooth as territories scale. territoryElement.parentNode?.appendChild(territoryElement); setHoveredId(deploymentId); } function lowerTerritory() { if (lowerTimerRef.current) clearTimeout(lowerTimerRef.current); - // Delay only the contributor overlay; the CSS scale settles independently. + // Let the detail card linger briefly while the territory settles. lowerTimerRef.current = setTimeout(() => setHoveredId(null), 280); } - function selectDeployment(deploymentId: string) { - if (selectedDeploymentId === undefined) { - setInternalSelection(deploymentId); - } - onSelectedDeploymentChange?.(deploymentId); - } - if (model.status === "loading") { return (

- Mapping community deployments… + Mapping community compute…

); @@ -161,7 +123,8 @@ export function CommunityComputeTerritoryMap({

No compute territories yet

- Deployments appear here when members share compute with the community. + Shared compute appears here when members make it available to the + community.

); @@ -177,9 +140,8 @@ export function CommunityComputeTerritoryMap({ data-testid="community-compute-territory-map" >
- { const deployment = deploymentById.get(territory.deploymentId); if (!deployment) return null; - const selected = deployment.id === activeId; - const inferenceActive = inferenceIds.has(deployment.id); return ( - // SVG groups have no semantic button equivalent; keyboard selection remains in the adjacent deployment list. - // biome-ignore lint/a11y/useSemanticElements: SVG has no native button element. + // SVG groups have no semantic element for hover/focus detail disclosure. + // biome-ignore lint/a11y/noStaticElementInteractions: keyboard focus mirrors hover without making the territory an action. selectDeployment(deployment.id)} - onKeyDown={(event) => { - if (event.key === "Enter" || event.key === " ") { - event.preventDefault(); - selectDeployment(deployment.id); - } - }} onBlur={lowerTerritory} onFocus={(event) => raiseTerritory(deployment.id, event.currentTarget) @@ -219,7 +169,6 @@ export function CommunityComputeTerritoryMap({ raiseTerritory(deployment.id, event.currentTarget) } onMouseLeave={lowerTerritory} - role="button" style={territoryHoverStyle( territory.cells, viewBox, @@ -228,31 +177,11 @@ export function CommunityComputeTerritoryMap({ tabIndex={0} > {territoryAccessibleLabel(deployment)} - + ); })} - {isHeroDeployment && activeDeployment ? ( - - ) : null} {hoveredDeployment ? (
-

- {inferenceIds.has(hoveredDeployment.id) - ? "Simulated inference" - : hoveredDeployment.health}{" "} - · {hoveredDeployment.cellCount}{" "} - {hoveredDeployment.cellCount === 1 ? "cell" : "cells"} +

+ Available to the community

) : null}
- -
- - {activeDeployment ? ( - - ) : null} -
); } -function MapLegend({ dense }: { dense: boolean }) { - return ( -
- - - Area = model memory - - - - Gold breath = serving - - - - {dense ? "Hover = contributor" : "Avatar = contributor"} - - - - Gold border = selected - -
- ); -} - -function HeroDeploymentOverlay({ - deployment, - inferenceActive, -}: { - deployment: CommunityComputeDeployment; - inferenceActive: boolean; -}) { - return ( -
-
- - - {inferenceActive ? "Serving now" : deployment.health} - -
-

- {shortModelName(deployment.modelId)} -

-

- {deployment.deviceLabel} - {deployment.isSelf ? " · This machine" : ""} -

-
- - - -
-
- ); -} - -function HeroMetric({ label, value }: { label: string; value: string }) { - return ( -
-
- {label} -
-
- {value} -
-
- ); -} - function TerritoryShape({ - avatarUrl, cells, - contributorLabel, - inferenceActive, - selected, - showContributor, - territoryCenter, }: { - avatarUrl: string | null; cells: readonly CommunityComputeHexCell[]; - contributorLabel: string; - inferenceActive: boolean; - selected: boolean; - showContributor: boolean; - territoryCenter: { q: number; r: number }; }) { const boundary = hexTerritoryBoundaryEdges(cells); - const fillClass = "fill-foreground"; - const territoryAnimationStyle = inferenceActive - ? ({ - "--mesh-breath-duration": `${5.8 + (stableVisualHash(cells[0]?.deploymentId ?? "") % 7) * 0.24}s`, - animationDelay: `${-((stableVisualHash(`${cells[0]?.deploymentId}:phase`) % 37) / 10)}s`, - } as React.CSSProperties) - : undefined; - const center = axialToPoint(territoryCenter.q, territoryCenter.r); - const avatarRadius = 0.42; - const avatarClipId = `contributor-${testId(cells[0]?.deploymentId ?? "unknown")}`; return ( - - - - - {cells.map((cell) => { const center = axialToPoint(cell.q, cell.r); return ( ); })} - {showContributor ? ( - - ) : null} - {showContributor && avatarUrl ? ( - - ) : showContributor ? ( - - {contributorInitials(contributorLabel)} - - ) : null} ); } @@ -521,169 +269,6 @@ function edgesToPath( .join(" "); } -function DeploymentList({ - deployments, - activeId, - onSearchChange, - onSelect, - search, -}: { - deployments: readonly CommunityComputeDeployment[]; - activeId: string | null; - onSearchChange: (value: string) => void; - onSelect: (id: string) => void; - search: string; -}) { - const query = search.trim().toLowerCase(); - const visibleDeployments = query - ? deployments.filter((deployment) => - [deployment.modelId, deployment.deviceLabel] - .filter(Boolean) - .some((value) => value?.toLowerCase().includes(query)), - ) - : deployments; - return ( -
-
-

Deployments

- - {visibleDeployments.length} of {deployments.length} - -
- onSearchChange(event.target.value)} - placeholder="Search models or devices" - type="search" - value={search} - /> -
    - {visibleDeployments.map((deployment) => { - const selected = deployment.id === activeId; - return ( -
  • - -
  • - ); - })} -
-
- ); -} - -function DeploymentDetails({ - deployment, -}: { - deployment: CommunityComputeDeployment; -}) { - return ( -
-
- -
-

- {shortModelName(deployment.modelId)} -

-

- {deployment.deviceLabel} - {deployment.isSelf ? " · This machine" : ""} -

-

- {deployment.health} · {deployment.cellCount}{" "} - {deployment.cellCount === 1 ? "cell" : "cells"} -

-
-
- {deployment.healthReason ? ( -

- {deployment.healthReason} -

- ) : null} -
- - - - -
-
- ); -} - -function Detail({ label, value }: { label: string; value: string }) { - return ( -
-
{label}
-
- {value} -
-
- ); -} - -function HealthGlyph({ health }: { health: CommunityComputeDeploymentHealth }) { - const cue = healthCue(health); - return ( - - ); -} - function EmptyHexes() { const centers = [ { x: 2, y: 1.75 }, @@ -734,85 +319,16 @@ function computeViewBox( }; } -function healthCue(health: CommunityComputeDeploymentHealth): { - dashArray?: string; - glyph: string; - strokeWidth: number; -} { - switch (health) { - case "healthy": - return { glyph: "✓", strokeWidth: 0.075 }; - case "warming": - return { glyph: "↻", dashArray: "0.2 0.12", strokeWidth: 0.085 }; - case "idle": - return { glyph: "–", dashArray: "0.04 0.14", strokeWidth: 0.08 }; - case "degraded": - return { glyph: "!", dashArray: "0.3 0.12", strokeWidth: 0.11 }; - case "offline": - return { glyph: "×", dashArray: "0.08 0.1", strokeWidth: 0.075 }; - case "unknown": - return { glyph: "?", dashArray: "0.03 0.12", strokeWidth: 0.075 }; - } -} - -function stableVisualHash(value: string): number { - let hash = 2166136261; - for (const character of value) { - hash ^= character.codePointAt(0) ?? 0; - hash = Math.imul(hash, 16777619); - } - return hash >>> 0; -} - function shortModelName(modelId: string): string { const tail = modelId.split("/").at(-1) ?? modelId; return tail.length > 34 ? `${tail.slice(0, 31)}…` : tail; } -type ContributorProfiles = Record< - string, - { avatarUrl: string | null; displayName: string | null } ->; - -function contributorProfile( - pubkey: string | null | undefined, - profiles: ContributorProfiles, -) { - return pubkey ? profiles[pubkey.trim().toLowerCase()] : undefined; -} - -function contributorAvatarUrl( - pubkey: string | null | undefined, - profiles: ContributorProfiles, -): string | null { - const avatarUrl = contributorProfile(pubkey, profiles)?.avatarUrl ?? null; - const snapshotUrl = getAvatarSnapshotUrl(avatarUrl); - return snapshotUrl ? rewriteRelayUrl(snapshotUrl) : null; -} - -function contributorLabel( - deployment: CommunityComputeDeployment, - profiles: ContributorProfiles, -): string { - return ( - contributorProfile(deployment.source.memberPubkey, profiles)?.displayName ?? - (deployment.isSelf ? "You" : deployment.deviceLabel) - ); -} - -function contributorInitials(label: string): string { - const words = label.trim().split(/\s+/).filter(Boolean); - return words - .slice(0, 2) - .map((word) => word[0]?.toUpperCase() ?? "") - .join(""); -} - function territoryAccessibleLabel( deployment: CommunityComputeDeployment, ): string { const capacity = formatCapacity(deployment.capacityGb); - return `${deployment.modelId} on ${deployment.deviceLabel}, ${deployment.health}, ${capacity}, ${deployment.cellCount} ${deployment.cellCount === 1 ? "cell" : "cells"}`; + return `${deployment.modelId} on ${deployment.deviceLabel}, ${capacity}`; } function formatCapacity(value: number | null): string { @@ -821,12 +337,6 @@ function formatCapacity(value: number | null): string { : `${Math.round(value)} GB shared`; } -function formatReportedAt(value: number | null | undefined): string { - if (value === null || value === undefined) return "Not reported"; - const milliseconds = value < 10_000_000_000 ? value * 1000 : value; - return new Date(milliseconds).toLocaleString(); -} - function testId(value: string): string { return encodeURIComponent(value).replaceAll("%", "-"); } diff --git a/desktop/src/features/mesh-compute/ui/CommunityComputeTutorialPanel.tsx b/desktop/src/features/mesh-compute/ui/CommunityComputeTutorialPanel.tsx deleted file mode 100644 index 7a97ccdacf..0000000000 --- a/desktop/src/features/mesh-compute/ui/CommunityComputeTutorialPanel.tsx +++ /dev/null @@ -1,146 +0,0 @@ -import { ArrowLeft, ArrowRight, FlaskConical, X } from "lucide-react"; - -import { Button } from "@/shared/ui/button"; -import { cn } from "@/shared/lib/cn"; -import type { CommunityComputeTutorialFixtureId } from "../communityComputeFixtures"; - -const STEPS = [ - { - title: "Every territory is a model deployment", - body: "Each connected group is one ready model on one contributed device. If one device serves multiple models, each model gets its own territory; another device serving the same model appears separately.", - }, - { - title: "Area represents memory", - body: "Models snap to four coarse footprints: 1, 2, 4, or 7 cells. The footprint comes from reported model size, or shared device capacity when model size is unavailable.", - }, - { - title: "Motion illustrates inference in flight", - body: "For this tutorial, breathing territories simulate models handling requests. The live community snapshot cannot yet identify the deployment serving a request, so the live map remains static.", - }, - { - title: "The headline measures the pool", - body: "Members sharing counts contributors, contributed VRAM is the memory they offered, and VRAM allocated is the reported model footprint—not GPU processing utilization.", - }, - { - title: "Health summarizes reported state", - body: "The scorecard counts ready, warming, and idle deployments from current status reports. It does not infer utilization, offline devices, replica resilience, or capacity headroom.", - }, -] as const; - -export function CommunityComputeTutorialPanel({ - fixtureId, - onExit, - onFixtureChange, - onStepChange, - step, -}: { - fixtureId: CommunityComputeTutorialFixtureId; - onExit: () => void; - onFixtureChange: (fixture: CommunityComputeTutorialFixtureId) => void; - onStepChange: (step: number) => void; - step: number; -}) { - const current = STEPS[step] ?? STEPS[0]; - const showDeveloperControls = - import.meta.env.DEV || import.meta.env.MODE === "e2e"; - - return ( -
-
-
-

- Tutorial · {step + 1} of {STEPS.length} -

-

- {current.title} -

-

- {current.body} -

-
- -
- -
- - -
- {STEPS.map((item, index) => ( -
-
- - {showDeveloperControls ? ( -
- - - - - Development-only · deterministic frontend data - -
- ) : null} -
- ); -} diff --git a/desktop/src/features/mesh-compute/ui/MeshComputeCommunityView.tsx b/desktop/src/features/mesh-compute/ui/MeshComputeCommunityView.tsx index 2c329409bd..67692c6797 100644 --- a/desktop/src/features/mesh-compute/ui/MeshComputeCommunityView.tsx +++ b/desktop/src/features/mesh-compute/ui/MeshComputeCommunityView.tsx @@ -1,14 +1,11 @@ -import { Info, RefreshCw } from "lucide-react"; -import * as React from "react"; +import { RefreshCw } from "lucide-react"; -import { useUsersBatchQuery } from "@/features/profile/hooks"; import { Button } from "@/shared/ui/button"; import type { MeshSnapshot } from "@/shared/api/tauriMesh"; import { deriveCommunityComputeMapModel, type CommunityComputeSnapshotInput, } from "../communityComputeMapModel"; -import { CommunityComputeHealthScorecard } from "./CommunityComputeHealthScorecard"; import { CommunityComputeKpiRow } from "./CommunityComputeKpiRow"; import { CommunityComputeTerritoryMap } from "./CommunityComputeTerritoryMap"; @@ -16,53 +13,19 @@ export function MeshComputeCommunityView({ communityName, error, onRefresh, - simulated, snapshot, - tutorialInference = false, }: { communityName: string; error: string | null; onRefresh: () => void; - simulated: boolean; snapshot: MeshSnapshot | CommunityComputeSnapshotInput | null; - tutorialInference?: boolean; }) { const model = deriveCommunityComputeMapModel(snapshot); - const inferenceDeploymentIds = tutorialInference - ? model.deployments - .filter( - (deployment, index) => - deployment.cellCount > 1 || index % 3 === 0 || index % 7 === 2, - ) - .map((deployment) => deployment.id) - : []; const observedAt = (snapshot as MeshSnapshot | null)?.observedAt; - const contributorPubkeys = React.useMemo( - () => - model.deployments - .map((deployment) => deployment.source.memberPubkey?.trim() ?? "") - .filter(Boolean), - [model.deployments], - ); - const contributorProfiles = - useUsersBatchQuery(contributorPubkeys).data?.profiles ?? {}; return (
- {simulated ? ( -
- - - Simulated mesh for learning and development. Live community data is - unchanged. - -
- ) : null} - - {error && !simulated ? ( + {error ? (
Couldn’t load {communityName} compute: {error} @@ -81,51 +44,32 @@ export function MeshComputeCommunityView({

{model.deployments.length === 1 ? "Your community’s first compute node" - : "Model mesh"} + : "Community mesh"}

{model.deployments.length === 1 ? "This machine is the foundation of the mesh. More contributors add capacity, model choice, and resilience." - : "Each territory is one ready model on one device. Area reflects its reported model-memory tier."} + : "See the compute currently available to your community. Larger territories offer more model memory."}

- {!simulated ? ( - - ) : null} +
- +

- {simulated - ? "Deterministic tutorial snapshot" - : observedAt - ? `Recently reported · updated ${formatAge(observedAt)}` - : "Recently reported by community members · presence may take up to two minutes to expire"} + {observedAt + ? `Recently reported · updated ${formatAge(observedAt)}` + : "Recently reported by community members · presence may take up to two minutes to expire"}

- -
-
-

Mesh health

-

- Current ready, warming, and idle states from community status - reports. -

-
- -
); } diff --git a/desktop/src/features/mesh-compute/ui/MeshComputeImpactReceipt.tsx b/desktop/src/features/mesh-compute/ui/MeshComputeImpactReceipt.tsx deleted file mode 100644 index fa5e7c6a8d..0000000000 --- a/desktop/src/features/mesh-compute/ui/MeshComputeImpactReceipt.tsx +++ /dev/null @@ -1,91 +0,0 @@ -import { Activity, Cpu, Network, Sparkles } from "lucide-react"; - -import { cn } from "@/shared/lib/cn"; -import type { useMeshComputeState } from "../hooks/useMeshComputeState"; - -export function MeshComputeImpactReceipt({ - mesh, -}: { - mesh: ReturnType; -}) { - const { memory, toggle, usage } = mesh; - const isSharing = toggle.isSharing; - const tokensProcessed = usage?.tokensServed ?? 0; - const peers = usage?.peers ?? 0; - const capacity = memory.totalGb == null ? "—" : formatGb(memory.totalGb); - - const items = [ - { - icon: Cpu, - label: "Capacity offered", - value: isSharing ? capacity : "Not sharing", - }, - { - icon: Sparkles, - label: "Tokens served", - value: isSharing ? formatCount(tokensProcessed) : "—", - }, - { - icon: Network, - label: "Mesh peers", - value: isSharing ? formatCount(peers) : "—", - }, - ]; - - return ( -
-
- - - -
-

Your contribution

-

- {isSharing - ? usage?.inflight - ? `Helping run ${usage.inflight} request${usage.inflight === 1 ? "" : "s"} right now.` - : "Available when your community needs more compute." - : "Turn on automatic contribution to start building your impact."} -

-
- {isSharing ? ( - - Live - - ) : null} -
-
- {items.map(({ icon: Icon, label, value }) => ( -
-
- {label} -
-
- {value} -
-
- ))} -
-

- Session totals from this machine. Request attribution to other members - is coming soon. -

-
- ); -} - -function formatCount(value: number): string { - return new Intl.NumberFormat(undefined, { maximumFractionDigits: 0 }).format( - value, - ); -} - -function formatGb(value: number): string { - return `${new Intl.NumberFormat(undefined, { maximumFractionDigits: 1 }).format(value)} GB`; -} diff --git a/desktop/src/features/mesh-compute/ui/MeshComputePage.tsx b/desktop/src/features/mesh-compute/ui/MeshComputePage.tsx index 3a4d5d165b..12de3356ce 100644 --- a/desktop/src/features/mesh-compute/ui/MeshComputePage.tsx +++ b/desktop/src/features/mesh-compute/ui/MeshComputePage.tsx @@ -1,67 +1,28 @@ import * as React from "react"; -import { BookOpen } from "lucide-react"; import { useCommunities } from "@/features/communities/useCommunities"; import { SettingsSectionHeader } from "@/features/settings/ui/SettingsSectionHeader"; -import { Button } from "@/shared/ui/button"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/shared/ui/tabs"; -import { - COMMUNITY_COMPUTE_TUTORIAL_FIXTURES, - type CommunityComputeTutorialFixtureId, -} from "../communityComputeFixtures"; import { useMeshComputeState } from "../hooks/useMeshComputeState"; -import { CommunityComputeTutorialPanel } from "./CommunityComputeTutorialPanel"; import { MeshComputeCommunityView } from "./MeshComputeCommunityView"; -import { MeshComputeImpactReceipt } from "./MeshComputeImpactReceipt"; import { MeshComputeSettingsCard } from "./MeshComputeSettingsCard"; import { MeshComputeShareBanner } from "./MeshComputeShareBanner"; -import { MeshComputeTokenLeaderboard } from "./MeshComputeTokenLeaderboard"; export function MeshComputePage() { const { activeCommunity } = useCommunities(); const mesh = useMeshComputeState(); const [tab, setTab] = React.useState("community"); - const [tutorialOpen, setTutorialOpen] = React.useState(false); - const [tutorialStep, setTutorialStep] = React.useState(0); - const [fixtureId, setFixtureId] = - React.useState("small-company"); const communityName = activeCommunity?.name ?? "this community"; - const tutorialFixture = COMMUNITY_COMPUTE_TUTORIAL_FIXTURES[fixtureId]; - - function toggleTutorial() { - if (tutorialOpen) { - setTutorialOpen(false); - return; - } - setTab("community"); - setTutorialOpen(true); - setTutorialStep(0); - setFixtureId("small-company"); - } return (
- Tutorial - - } description={`Contribute this machine’s spare capacity to unlock more models and keep ${communityName}’s agents available when demand grows.`} title="Compute" />
- {tutorialOpen ? null : ( - - )} + @@ -74,27 +35,11 @@ export function MeshComputePage() { - {tutorialOpen ? ( - setTutorialOpen(false)} - onFixtureChange={setFixtureId} - onStepChange={setTutorialStep} - step={tutorialStep} - /> - ) : ( - - )} - diff --git a/desktop/src/features/mesh-compute/ui/MeshComputeTokenLeaderboard.tsx b/desktop/src/features/mesh-compute/ui/MeshComputeTokenLeaderboard.tsx deleted file mode 100644 index 9b6a999fb8..0000000000 --- a/desktop/src/features/mesh-compute/ui/MeshComputeTokenLeaderboard.tsx +++ /dev/null @@ -1,103 +0,0 @@ -import { Medal, Trophy } from "lucide-react"; - -import { cn } from "@/shared/lib/cn"; -import type { useMeshComputeState } from "../hooks/useMeshComputeState"; - -const PREVIEW_LEADERS = [ - { name: "Maya", tokens: 2_840_912 }, - { name: "Jon", tokens: 1_967_401 }, - { name: "Priya", tokens: 1_204_885 }, -] as const; - -export function MeshComputeTokenLeaderboard({ - mesh, - simulated = false, -}: { - mesh: ReturnType; - simulated?: boolean; -}) { - const yourTokens = simulated ? 1_638_240 : (mesh.usage?.tokensServed ?? 0); - const communityLeaders = simulated ? PREVIEW_LEADERS : []; - const rows = [...communityLeaders, { name: "You", tokens: yourTokens }] - .sort((a, b) => b.tokens - a.tokens) - .map((entry, index) => ({ ...entry, rank: index + 1 })); - const yourRank = - rows.find((entry) => entry.name === "You")?.rank ?? rows.length; - - return ( -
-
- - - -
-

- Community token contributors -

-

- {simulated - ? "Tokenmaxxing, inverted: celebrate the tokens you serve—not the tokens you consume." - : "Your locally reported total. Community rankings will appear when aggregate reporting is available."} -

-
- {simulated ? ( -
-

- Your rank -

-

- #{yourRank} -

-
- ) : null} -
- -
    - {rows.map((entry) => ( -
  1. - - {entry.rank <= 3 ? : null}# - {entry.rank} - - - {entry.name} - {entry.name === "You" ? ( - - YOU - - ) : null} - - - {formatTokens(entry.tokens)} - - tokens - - -
  2. - ))} -
- -

- {simulated - ? "Tutorial preview · example contribution totals" - : "Community rankings preview · aggregate contribution reporting is coming soon."} -

-
- ); -} - -function formatTokens(value: number): string { - return new Intl.NumberFormat(undefined, { - notation: value >= 10_000 ? "compact" : "standard", - maximumFractionDigits: 1, - }).format(value); -} diff --git a/desktop/tailwind.config.js b/desktop/tailwind.config.js index a1500f316b..491cd87063 100644 --- a/desktop/tailwind.config.js +++ b/desktop/tailwind.config.js @@ -53,18 +53,10 @@ export default { "0%, 100%": { opacity: "1" }, "50%": { opacity: "0.25" }, }, - "mesh-breath": { - "0%, 100%": { fill: "hsl(var(--foreground))" }, - "50%": { - fill: "color-mix(in oklab, hsl(var(--foreground)) 18%, #ffd84d)", - }, - }, }, animation: { // Work in flight right now. "mesh-activity": "mesh-dim 1s cubic-bezier(0.4, 0, 0.6, 1) infinite", - "mesh-inference": - "mesh-breath var(--mesh-breath-duration, 4.8s) ease-in-out infinite", // A start or stop in flight. Slower: nothing is wrong, and nothing needs // a decision. "mesh-progress": "mesh-dim 1.8s cubic-bezier(0.4, 0, 0.6, 1) infinite", diff --git a/desktop/tests/e2e/mesh-compute-screenshots.spec.ts b/desktop/tests/e2e/mesh-compute-screenshots.spec.ts index 939feddc6d..1cb8d75a88 100644 --- a/desktop/tests/e2e/mesh-compute-screenshots.spec.ts +++ b/desktop/tests/e2e/mesh-compute-screenshots.spec.ts @@ -4,33 +4,80 @@ import { installMockBridge } from "../helpers/bridge"; import { openSettings } from "../helpers/settings"; import { waitForAnimations } from "../helpers/animations"; -test("captures the Community Compute tutorial", async ({ page }) => { +type E2eWindow = Window & { + __BUZZ_E2E_SET_MESH__?: (mesh: { + snapshotMemberCount?: number; + snapshotDevices?: Array<{ + deviceId: string; + label: string; + capacityGb: number; + models: string[]; + state: "serving"; + isSelf: boolean; + memberPubkey?: string; + modelSizeGb?: number; + }>; + }) => void; +}; + +test("captures the focused Community Compute topology", async ({ page }) => { await installMockBridge(page); await page.goto("/"); + await page.waitForFunction( + () => typeof (window as E2eWindow).__BUZZ_E2E_SET_MESH__ === "function", + ); + await page.evaluate(() => { + (window as E2eWindow).__BUZZ_E2E_SET_MESH__?.({ + snapshotMemberCount: 18, + snapshotDevices: [ + { + deviceId: "design-studio", + label: "Design Studio", + capacityGb: 64, + models: ["qwen-32b"], + state: "serving", + isSelf: true, + memberPubkey: "design-member", + modelSizeGb: 28, + }, + { + deviceId: "engineering-workstation", + label: "Engineering Workstation", + capacityGb: 128, + models: ["gemma-27b"], + state: "serving", + isSelf: false, + memberPubkey: "engineering-member", + modelSizeGb: 64, + }, + { + deviceId: "research-host", + label: "Research Host", + capacityGb: 512, + models: ["community/research-140b"], + state: "serving", + isSelf: false, + memberPubkey: "research-member", + modelSizeGb: 350, + }, + ], + }); + }); await openSettings(page, "compute"); - await page.getByTestId("community-compute-tutorial-button").click(); await expect( page.getByTestId("community-compute-territory-map"), ).toBeVisible(); - await expect(page.getByTestId("compute-share-banner")).toHaveCount(0); await waitForAnimations(page); await page.getByTestId("settings-panel-compute").screenshot({ - path: "test-results/mesh-compute/community-tutorial.png", - }); - await page.getByTestId("community-compute-territory-map").screenshot({ - path: "test-results/mesh-compute/community-map.png", + path: "test-results/mesh-compute/community-compute.png", }); - await page.getByLabel("Preview scenario").selectOption("large-dense-500"); + await page.locator('[data-deployment-id*="research-host"]').hover(); await expect( - page.getByTestId("community-compute-kpi-members-sharing"), - ).toContainText("458"); - await expect(page.locator("[data-cell-count]")).toHaveCount(458); - await expect( - page.locator('[data-inference-active="true"]').first(), - ).toBeVisible(); + page.getByTestId("community-compute-hover-details"), + ).toContainText("Research Host"); await waitForAnimations(page); - await page.getByTestId("settings-panel-compute").screenshot({ - path: "test-results/mesh-compute/community-dense.png", + await page.getByTestId("community-compute-territory-map").screenshot({ + path: "test-results/mesh-compute/community-map-hover.png", }); }); diff --git a/desktop/tests/e2e/mesh-compute.spec.ts b/desktop/tests/e2e/mesh-compute.spec.ts index 218ec5d29f..9d3d4ce15e 100644 --- a/desktop/tests/e2e/mesh-compute.spec.ts +++ b/desktop/tests/e2e/mesh-compute.spec.ts @@ -166,13 +166,12 @@ test("Shared Compute is only available from Settings", async ({ page }) => { await page.goto("/"); await expect(page.getByTestId("sidebar-mesh-compute-row")).toHaveCount(0); - await page.getByTestId("open-settings").click(); - await page.getByTestId("settings-nav-compute").click(); + await openSettings(page, "compute"); await expect(page.getByTestId("settings-mesh-compute-page")).toBeVisible(); }); -test("Community Compute shows live KPIs and the tutorial simulation", async ({ +test("Community Compute keeps the live community topology focused", async ({ page, }) => { await installMockBridge(page); @@ -222,66 +221,26 @@ test("Community Compute shows live KPIs and the tutorial simulation", async ({ await expect( page.getByTestId("community-compute-territory-map"), ).toBeVisible(); - await expect( - page.getByTestId("community-compute-deployment-list"), - ).toContainText("Alpha Studio"); - await page.getByLabel("Search deployments").fill("Beta"); - await expect( - page.getByTestId("community-compute-deployment-list"), - ).toContainText("Beta Workstation"); - await expect( - page.getByTestId("community-compute-deployment-list"), - ).not.toContainText("Alpha Studio"); - await page.getByLabel("Search deployments").fill(""); - const tutorialButton = page.getByTestId("community-compute-tutorial-button"); - await tutorialButton.click(); - await expect(tutorialButton).toHaveAttribute("aria-pressed", "true"); await expect( - page.getByTestId("community-compute-simulated-banner"), - ).toBeVisible(); + page.getByTestId("community-compute-tutorial-button"), + ).toHaveCount(0); + await expect(page.getByTestId("compute-token-leaderboard")).toHaveCount(0); await expect( - page.getByTestId("community-compute-tutorial-panel"), - ).toContainText("Every territory is a model deployment"); - await expect(page.getByTestId("compute-share-banner")).toHaveCount(0); - const tutorialTile = page - .locator('[data-inference-active="true"]') - .first() - .getByTestId("community-compute-tile") - .first(); - await expect(tutorialTile).toBeVisible(); - await expect - .poll(() => - tutorialTile.evaluate( - (element) => getComputedStyle(element).animationName, - ), - ) - .toBe("mesh-breath"); - await page.getByLabel("Preview scenario").selectOption("single-device"); + page.getByTestId("community-compute-deployment-list"), + ).toHaveCount(0); + await expect(page.getByText("Mesh health", { exact: true })).toHaveCount(0); await expect( - page.getByTestId("community-compute-kpi-members-sharing"), - ).toContainText("1"); - await page.getByRole("button", { name: "Next" }).click(); - await expect( - page.getByTestId("community-compute-tutorial-panel"), - ).toContainText("Area represents memory"); - await page.getByRole("button", { name: "Next" }).click(); - await expect( - page.getByTestId("community-compute-tutorial-panel"), - ).toContainText("Motion illustrates inference in flight"); + page.getByTestId("community-compute-contributor-avatar"), + ).toHaveCount(0); + await expect(page.locator('[data-inference-active="true"]')).toHaveCount(0); + const territory = page.locator("[data-cell-count]").first(); - await territory.click(); - await expect(territory).toHaveAttribute("data-selected", "true"); await territory.hover(); await expect( page.getByTestId("community-compute-hover-details"), - ).toContainText("Simulated inference"); - await tutorialButton.click(); - await expect(tutorialButton).toHaveAttribute("aria-pressed", "false"); + ).toContainText("Alpha Studio"); await expect( - page.getByTestId("community-compute-simulated-banner"), - ).toHaveCount(0); - await expect( - page.getByTestId("community-compute-kpi-members-sharing"), - ).toContainText("2"); + page.getByTestId("community-compute-hover-details"), + ).toContainText("Available to the community"); });