Files
ModelForge-Public/frontend/src/components/RuntimeWorkspace.tsx
T

152 lines
16 KiB
TypeScript

import { useCallback, useEffect, useRef, useState } from "react";
import { api, operatorCredentialReference, operatorSessionVersion } from "../lib/api";
import type { OperatorIdentity } from "../lib/api";
import type { CompatibilityAssessment, DeploymentCandidate, ExecutionApproval, HardwareState, RuntimeEnvironment, RuntimeProbe, RuntimeProfile } from "../types";
type RuntimeState = {
environments: RuntimeEnvironment[]; profiles: RuntimeProfile[]; assessments: CompatibilityAssessment[];
approvals: ExecutionApproval[]; probes: RuntimeProbe[]; candidates: DeploymentCandidate[]; hardware: HardwareState;
};
const emptyState: RuntimeState = { environments: [], profiles: [], assessments: [], approvals: [], probes: [], candidates: [], hardware: { overview: { status: "unknown", inventory_state: "unknown", node_count: 0, accelerator_count: 0 }, nodes: [] } };
const terminal = new Set(["completed", "failed", "cancelled"]);
const label = (value: string) => value.replaceAll("_", " ").toUpperCase();
const measure = (value: unknown, divisor: number, suffix: string) => typeof value === "number" && Number.isFinite(value) ? `${(value / divisor).toFixed(2)} ${suffix}` : "unknown";
const approvalUsable = (item: ExecutionApproval) => item.scope === "lab_execution" && item.status === "approved" && !item.stale && !item.revoked_at && (!item.expires_at || Date.parse(item.expires_at) > Date.now());
export function RuntimeWorkspace({ role = "viewer" }: { role?: OperatorIdentity["role"] }) {
const [state, setState] = useState<RuntimeState>(emptyState);
const [profileId, setProfileId] = useState("");
const [nodeId, setNodeId] = useState("");
const [loading, setLoading] = useState(true);
const [working, setWorking] = useState(false);
const [error, setError] = useState<string | null>(null);
const mounted = useRef(false);
const requestId = useRef(0);
const mutation = useRef(false);
const generation = operatorSessionVersion();
const current = useCallback(() => mounted.current && generation === operatorSessionVersion() && Boolean(operatorCredentialReference()), [generation]);
const load = useCallback(async () => {
const request = ++requestId.current;
const valid = () => current() && request === requestId.current;
try {
const [environments, profiles, assessments, approvals, probes, candidates, hardware] = await Promise.all([
api.runtimeEnvironments(), api.runtimeProfiles(), api.compatibilityAssessments(), api.executionApprovals(), api.runtimeProbes(), api.deploymentCandidates(), api.hardware(),
]);
if (!valid()) return;
setState({ environments, profiles, assessments, approvals, probes, candidates, hardware });
setProfileId(id => profiles.some(item => item.id === id) ? id : "");
setNodeId(id => hardware.nodes.some(item => item.id === id) ? id : "");
setError(null);
} catch (cause) {
if (!valid()) return;
setState(emptyState); setProfileId(""); setNodeId("");
setError(cause instanceof Error ? cause.message : "Runtime evidence unavailable");
} finally { if (valid()) setLoading(false); }
}, [current]);
useEffect(() => {
mounted.current = true;
setState(emptyState); setProfileId(""); setNodeId(""); setWorking(false);
if (operatorCredentialReference()) { setLoading(true); void load(); } else setLoading(false);
return () => { mounted.current = false; requestId.current += 1; };
}, [load]);
const active = state.probes.some(item => !terminal.has(item.status));
useEffect(() => {
if (!active) return;
let stopped = false;
let timer: number;
const poll = async () => {
await load();
if (!stopped) timer = window.setTimeout(() => void poll(), 2000);
};
timer = window.setTimeout(() => void poll(), 2000);
return () => { stopped = true; window.clearTimeout(timer); };
}, [active, load]);
async function operate(action: () => Promise<unknown>, admin = false) {
if (mutation.current || !current() || role === "viewer" || (admin && role !== "admin")) return;
mutation.current = true; setWorking(true); setError(null);
requestId.current += 1;
try { await action(); if (current()) await load(); }
catch (cause) { if (current()) setError(cause instanceof Error ? cause.message : "Runtime operation failed"); }
finally { mutation.current = false; if (current()) setWorking(false); }
}
const profile = state.profiles.find(item => item.id === profileId);
const node = state.hardware.nodes.find(item => item.id === nodeId);
const environment = state.environments.find(item => item.id === profile?.runtime_environment_id);
const binding = JSON.stringify([generation, profile?.id, profile?.artifact_set_id, profile?.fingerprint, environment?.fingerprint, node?.id]);
const canOperate = role !== "viewer" && current();
if (loading) return <div className="state-card">Loading runtime evidence…</div>;
return <div className="runtime-stack">
{error ? <div className="error-banner" role="alert">{error}</div> : null}
<article className="panel runtime-boundary"><div><strong>Technical execution boundary</strong><p>Verified bytes, static compatibility and explicit LAB approval are separate gates. Successful historical probes do not establish current compatibility or production permission.</p></div></article>
{!canOperate ? <p role="status">Read-only runtime evidence. A verified operator session is required for assessment, probe and cancellation; LAB approval requires an administrator.</p> : null}
<button onClick={() => void load()} disabled={!current() || working}>Refresh runtime evidence</button>
<article className="panel runtime-controls"><h2>Runtime profile and target node</h2>
<label>Runtime profile<select value={profileId} onChange={event => setProfileId(event.target.value)}><option value="">Select an exact profile</option>{state.profiles.map(item => <option key={item.id} value={item.id}>{item.name} · v{item.version} · {item.id}</option>)}</select></label>
<label>Target node<select value={nodeId} onChange={event => setNodeId(event.target.value)}><option value="">Select an exact node</option>{state.hardware.nodes.map(item => <option key={item.id} value={item.id}>{item.display_name} · {item.liveness} · {item.id}</option>)}</select></label>
{profile ? <dl className="runtime-facts"><Fact name="Profile" value={profile.id} /><Fact name="ArtifactSet" value={profile.artifact_set_id} /><Fact name="Profile fingerprint" value={profile.fingerprint} /><Fact name="Adapter" value={`${profile.adapter}@${profile.runtime_version}`} /><Fact name="Modality" value={profile.modality} /><Fact name="Image" value={profile.image_digest} /><Fact name="Remote code" value={profile.trust_remote_code} /><Fact name="Network egress" value={profile.network_egress} /><Fact name="Environment" value={environment?.fingerprint} /></dl> : <p>Select a profile to inspect immutable runtime provenance.</p>}
</article>
<RuntimeBinding key={binding} state={state} profile={profile} nodeId={node?.id} role={role} working={working} canOperate={canOperate} operate={operate} />
</div>;
}
function Fact({ name, value }: { name: string; value: unknown }) {
return <div><dt>{name}</dt><dd>{typeof value === "boolean" ? String(value) : typeof value === "string" && value.length ? value : typeof value === "number" && Number.isFinite(value) ? value : "unknown"}</dd></div>;
}
function RuntimeBinding({ state, profile, nodeId, role, working, canOperate, operate }: {
state: RuntimeState; profile?: RuntimeProfile; nodeId?: string; role: OperatorIdentity["role"]; working: boolean; canOperate: boolean;
operate: (action: () => Promise<unknown>, admin?: boolean) => Promise<void>;
}) {
const [assessmentId, setAssessmentId] = useState("");
const [approvalId, setApprovalId] = useState("");
const [probeId, setProbeId] = useState("");
const [operator, setOperator] = useState("");
const [reason, setReason] = useState("");
const matches = (item: { artifact_set_id: string; runtime_profile_id: string; compute_node_id: string }) => Boolean(profile && nodeId && item.artifact_set_id === profile.artifact_set_id && item.runtime_profile_id === profile.id && item.compute_node_id === nodeId);
const assessments = state.assessments.filter(matches);
const approvals = state.approvals.filter(item => item.artifact_set_id === profile?.artifact_set_id);
const probes = state.probes.filter(matches);
const assessment = assessments.find(item => item.id === assessmentId);
const approval = approvals.find(item => item.id === approvalId);
const probe = probes.find(item => item.id === probeId);
const assessmentIdentity = JSON.stringify([assessment?.id, assessment?.environment_fingerprint, assessment?.stale, assessment?.status]);
useEffect(() => { setReason(""); setOperator(""); }, [assessmentIdentity]);
useEffect(() => {
if (!assessment) setAssessmentId("");
if (!approval) setApprovalId("");
if (!probe) setProbeId("");
}, [assessment, approval, probe]);
const assessmentUsable = assessment && !assessment.stale && !assessment.blockers.length && ["compatible", "requires_probe"].includes(assessment.status);
const canStart = Boolean(canOperate && !working && assessmentUsable && approval && approvalUsable(approval));
const probeAssessment = state.assessments.find(item => item.id === probe?.compatibility_assessment_id && matches(item));
// Completed probes fingerprint measured runtime facts; assessments fingerprint admission evidence.
const historyCurrent = Boolean(probe && probeAssessment && !probeAssessment.stale);
const candidates = state.candidates.filter(item => matches(item) && item.runtime_probe_id === probe?.id && item.compatibility_assessment_id === probe?.compatibility_assessment_id);
return <>
<section className="runtime-grid">
<article className="panel runtime-controls"><h2>Static compatibility matrix</h2>
{!profile || !nodeId ? <p>Select both an exact profile and node. Evidence never falls back to another combination.</p> : null}
<button disabled={!canOperate || working || !profile || !nodeId} onClick={() => profile && nodeId && void operate(() => api.assessCompatibility(profile.artifact_set_id, profile.id, nodeId))}>Run static assessment</button>
<label>Compatibility assessment<select value={assessment?.id ?? ""} onChange={event => { setAssessmentId(event.target.value); setApprovalId(""); setReason(""); setOperator(""); }}><option value="">Select an exact assessment</option>{assessments.map(item => <option key={item.id} value={item.id}>{item.id} · {item.stale ? "STALE" : label(item.status)}</option>)}</select></label>
<div className="runtime-matrix">{assessments.map(item => <button key={item.id} aria-pressed={assessment?.id === item.id} onClick={() => { setAssessmentId(item.id); setApprovalId(""); setReason(""); setOperator(""); }}>{item.id} · {item.stale ? "STALE" : label(item.status)}</button>)}</div>
{assessment ? <><dl className="runtime-facts"><Fact name="Assessment ID" value={assessment.id} /><Fact name="Integrity" value={assessment.artifact_facts.integrity_status} /><Fact name="Static compatibility" value={label(assessment.status)} /><Fact name="Evidence fingerprint" value={assessment.environment_fingerprint} /></dl>{assessment.stale ? <p role="status">Compatibility evidence is stale: {assessment.stale_reason ?? "Evidence changed"}</p> : null}{assessment.blockers.map(item => <p key={item}>Probe blocked: {label(item)}</p>)}</> : null}
</article>
<article className="panel runtime-controls"><h2>Exact ArtifactSet LAB approval</h2>
<label>Execution approval<select value={approval?.id ?? ""} onChange={event => setApprovalId(event.target.value)}><option value="">Select an exact approval</option>{approvals.map(item => <option key={item.id} value={item.id}>{item.id} · {approvalUsable(item) ? "available" : "unusable"}</option>)}</select></label>
{approval ? <dl className="runtime-facts"><Fact name="Approval ID" value={approval.id} /><Fact name="Approval scope" value={approval.scope} /><Fact name="Approval fingerprint" value={approval.evidence_fingerprint} /><Fact name="Expires" value={approval.expires_at ?? "No expiry recorded"} /><Fact name="Revoked" value={approval.revoked_at ?? "Not revoked"} /><Fact name="Approval reusable" value={approvalUsable(approval)} /></dl> : null}
{role === "admin" && canOperate && profile && nodeId ? <><p>Review exact artifact {profile.artifact_set_id}. This approval permits LAB execution only.</p><label>Approved by<input value={operator} onChange={event => setOperator(event.target.value)} /></label><label>Approval reason<textarea value={reason} onChange={event => setReason(event.target.value)} /></label><button disabled={working || operator.trim().length < 1 || reason.trim().length < 8} onClick={() => { if (operator.trim() && reason.trim().length >= 8) void operate(() => api.approveLabExecution(profile.artifact_set_id, operator.trim(), reason.trim()), true); }}>Approve exact ArtifactSet for LAB</button></> : <p>Recording LAB approval requires a verified administrator session.</p>}
<button disabled={!canStart} onClick={() => { if (canStart && assessment && approval && approvalUsable(approval)) void operate(() => api.startRuntimeProbe(assessment.id, approval.id)); }}>Start controlled probe</button>
<p>Starting uses the selected assessment and approval. Repeating that exact request returns its existing probe. A fresh assessment is needed for a new attempt after a terminal result.</p>
</article>
</section>
<article className="panel probe-detail"><h2>Probe history for selected profile and node</h2>
<label>Runtime probe<select value={probe?.id ?? ""} onChange={event => setProbeId(event.target.value)}><option value="">Select an exact probe</option>{probes.map(item => <option key={item.id} value={item.id}>{item.id} · {label(item.status)}</option>)}</select></label>
{probe ? <><h3>{label(probe.status)} · attempt {probe.attempt_count}</h3><p>{historyCurrent ? "Historical probe bound to a currently non-stale assessment. This is not production approval." : "Historical evidence: current compatibility is unknown or stale. This result is not current execution permission."}</p><dl className="runtime-facts"><Fact name="Probe ID" value={probe.id} /><Fact name="Probe node" value={probe.compute_node_id} /><Fact name="Probe assessment" value={probe.compatibility_assessment_id} /><Fact name="Probe approval" value={probe.execution_approval_id} /><Fact name="Probe environment" value={probe.environment_fingerprint} /><Fact name="Phase" value={probe.phase} /><Fact name="Load time" value={measure(probe.load_result.load_time_ms, 1, "ms")} /><Fact name="Inference latency" value={measure(probe.inference_result.latency_ms, 1, "ms")} /><Fact name="Output shape" value={JSON.stringify(probe.inference_result.shape ?? probe.inference_result.output_shape ?? "unknown")} /><Fact name="Peak VRAM" value={measure(probe.measured_resources.peak_vram_bytes, 1024 ** 3, "GiB")} /><Fact name="Reclaimed VRAM" value={measure(probe.measured_resources.reclaimed_vram_bytes, 1024 ** 3, "GiB")} /><Fact name="Worker reported reclaim" value={probe.unload_result.reclaimed} /><Fact name="Failure" value={probe.failure_code ?? "none"} /><Fact name="Started" value={probe.started_at} /><Fact name="Finished" value={probe.finished_at} /></dl>
{probe.cancel_requested && !terminal.has(probe.status) ? <p role="status">Cancellation requested; waiting for worker acknowledgement. Resource reclamation is not yet confirmed.</p> : null}
{!terminal.has(probe.status) ? <button className="danger" disabled={!canOperate || working || probe.cancel_requested} onClick={() => { if (canOperate && !working && !probe.cancel_requested) void operate(() => api.cancelRuntimeProbe(probe.id)); }}>Request cancellation of selected probe</button> : null}
{candidates.map(item => <section className="candidate-card" key={item.id}><h3>Deployment candidate {item.id}</h3><dl className="runtime-facts"><Fact name="Candidate status" value={item.status} /><Fact name="Candidate channel" value={item.channel} /><Fact name="Candidate production flag" value={item.production} /><Fact name="Candidate probe" value={item.runtime_probe_id} /></dl><p>Candidate history is bound to this exact probe; deployment and production permissions require separate evidence.</p></section>)}
</> : <p>Select a probe to inspect its own evidence or request cancellation.</p>}
</article>
</>;
}