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

321 lines
32 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { FormEvent, useCallback, useEffect, useState } from "react";
import type { ReactNode } from "react";
import { Activity, CircleGauge, Clock3, KeyRound, Play, RefreshCw, ShieldCheck } from "lucide-react";
import { api, ApiError, operatorCredentialReference } from "../lib/api";
import { SafetyDialog } from "./SafetyDialog";
import { TabList, TabPanel } from "./TabList";
import type { TabDescriptor } from "./TabList";
import type {
CapabilityDeployment, CapabilityEstate, DeploymentCandidate, GatewayInvokeResponse,
GatewayRequest, OCRInvokeResponse, PlacementPlan, ProductionApproval, SchedulerBudget, SchedulerPolicy, ServiceClient,
ServiceClientCreated, SpeechTranscriptionResponse, VisionEmbeddingResponse,
} from "../types";
type View = "overview" | "scheduler" | "requests" | "clients" | "promotion" | "playground";
const capabilityViews: TabDescriptor<View>[] = [
{ key: "overview", label: "overview" }, { key: "scheduler", label: "scheduler" },
{ key: "requests", label: "requests" }, { key: "clients", label: "clients" },
{ key: "promotion", label: "promotion" }, { key: "playground", label: "playground" },
];
export function CapabilityWorkspace({ onError }: { onError: (message: string | null) => void }) {
const sessionReference = operatorCredentialReference();
const sessionActive = Boolean(sessionReference);
const [view, setView] = useState<View>("overview");
const [deployments, setDeployments] = useState<CapabilityDeployment[]>([]);
const [estate, setEstate] = useState<CapabilityEstate[]>([]);
const [budgets, setBudgets] = useState<SchedulerBudget[]>([]);
const [candidates, setCandidates] = useState<DeploymentCandidate[]>([]);
const [requests, setRequests] = useState<GatewayRequest[]>([]);
const [clients, setClients] = useState<ServiceClient[]>([]);
const [approvals, setApprovals] = useState<ProductionApproval[]>([]);
const [plans, setPlans] = useState<PlacementPlan[]>([]);
const [policy, setPolicy] = useState<SchedulerPolicy | null>(null);
const [adminToken, setAdminToken] = useState(sessionReference);
const [adminUnlocked, setAdminUnlocked] = useState(sessionActive);
const [loading, setLoading] = useState(true);
const loadPublic = useCallback(async () => {
const [nextDeployments, nextBudgets, nextCandidates, nextEstate] = await Promise.all([
api.capabilityDeployments(), api.scheduler(), api.deploymentCandidates(), api.capabilityEstate(),
]);
setDeployments(nextDeployments);
setBudgets(nextBudgets);
setCandidates(nextCandidates);
setEstate(nextEstate);
}, []);
const loadAdmin = useCallback(async (token: string) => {
if (!token && !sessionActive) return;
const [nextRequests, nextClients, nextApprovals, nextPlans, nextPolicy] = await Promise.all([
api.gatewayRequests(token), api.serviceClients(token), api.productionApprovals(token),
api.placementHistory(token), api.schedulerPolicy(token),
]);
setRequests(nextRequests);
setClients(nextClients);
setApprovals(nextApprovals);
setPlans(nextPlans);
setPolicy(nextPolicy);
}, [sessionActive]);
useEffect(() => {
Promise.all([loadPublic(), sessionActive ? loadAdmin(sessionReference) : Promise.resolve()])
.catch((cause: unknown) => onError(errorMessage(cause)))
.finally(() => setLoading(false));
}, [loadAdmin, loadPublic, onError, sessionActive, sessionReference]);
useEffect(() => {
const interval = window.setInterval(() => {
loadPublic().catch((cause: unknown) => onError(errorMessage(cause)));
if (adminUnlocked) loadAdmin(adminToken).catch((cause: unknown) => onError(errorMessage(cause)));
}, 5000);
return () => window.clearInterval(interval);
}, [adminToken, adminUnlocked, loadAdmin, loadPublic, onError]);
const deployment = deployments.find((item) =>
item.capability === "rag.embedding" && item.contract_version === 1 && item.production && item.status === "stable",
) ?? deployments.find((item) => item.capability === "rag.embedding" && item.contract_version === 1);
const refresh = async () => {
onError(null);
try { await Promise.all([loadPublic(), loadAdmin(adminToken)]); }
catch (cause: unknown) { onError(errorMessage(cause)); }
};
const authenticateAdmin = async (event: FormEvent) => {
event.preventDefault(); onError(null);
try { await loadAdmin(adminToken); setAdminUnlocked(true); }
catch (cause: unknown) { onError(errorMessage(cause)); }
};
if (loading) return <div className="state-card"><span className="state-spinner" />Loading capability serving state…</div>;
return <div className="capability-stack">
<section className="capability-hero panel">
<div><span className="eyebrow">MULTI-CAPABILITY ESTATE</span><h2>{estate.length} governed contracts</h2><p>Capability-first routing across RAG, document, vision and audio · no client-visible model names</p></div>
<div className="capability-health"><span className={`status-chip ${deployment && ["healthy", "ready_on_demand"].includes(deployment.health_status) ? "active" : "degraded"}`}>{deployment?.health_status ?? "unavailable"}</span><strong>{deployment?.status ?? "not promoted"}</strong></div>
</section>
<div className="capability-toolbar">
<TabList idPrefix="capability" label="Capability operations" className="capability-tabs" tabs={capabilityViews} active={view} onSelect={setView} />
<button className="icon-action" aria-label="Refresh capability state" onClick={refresh}><RefreshCw size={15} /></button>
</div>
<TabPanel idPrefix="capability" active={view} className="capability-tabpanel">
{view === "overview" ? <CapabilityOverview deployment={deployment} requests={requests} estate={estate} /> : null}
{view === "scheduler" ? <><SchedulerView budgets={budgets} deployments={deployments} plans={plans} policy={policy} token={adminToken} unlocked={adminUnlocked} onChanged={refresh} onError={onError} /><AdminBoundary unlocked={adminUnlocked} token={adminToken} onToken={setAdminToken} onSubmit={authenticateAdmin}><></></AdminBoundary></> : null}
{view === "requests" ? <AdminBoundary unlocked={adminUnlocked} token={adminToken} onToken={setAdminToken} onSubmit={authenticateAdmin}><RequestHistory requests={requests} /></AdminBoundary> : null}
{view === "clients" ? <AdminBoundary unlocked={adminUnlocked} token={adminToken} onToken={setAdminToken} onSubmit={authenticateAdmin}><Clients clients={clients} token={adminToken} onChanged={() => loadAdmin(adminToken)} onError={onError} /></AdminBoundary> : null}
{view === "promotion" ? <AdminBoundary unlocked={adminUnlocked} token={adminToken} onToken={setAdminToken} onSubmit={authenticateAdmin}><Promotion deployment={deployment} candidates={candidates} approvals={approvals} token={adminToken} onChanged={refresh} onError={onError} /></AdminBoundary> : null}
{view === "playground" ? <Playground /> : null}
</TabPanel>
</div>;
}
function CapabilityOverview({ deployment, requests, estate }: { deployment?: CapabilityDeployment; requests: GatewayRequest[]; estate: CapabilityEstate[] }) {
if (!estate.length) return <div className="state-card">No capability contracts are registered.</div>;
const successful = requests.filter((item) => item.status === "completed");
const warmHits = successful.filter((item) => item.cold === false).length;
return <>
<section className="project-grid">{estate.map((item) => <article className="panel project-card" key={`${item.capability}@${item.version}`}><span className="eyebrow">{item.category} · {item.resource_class}</span><h2>{item.capability}@{item.version}</h2><p>{item.purpose}</p><div className="binding-list"><div><span>State</span><strong>{item.operational_state}</strong></div><div><span>Evaluation</span><strong>{item.evaluation_state}</strong></div><div><span>Privacy</span><strong>{item.privacy_class}</strong></div><div><span>Consumers</span><strong>{item.consumers.join(", ") || "none declared"}</strong></div></div></article>)}</section>
{!deployment ? <div className="state-card">No stable deployment exists. New modality capabilities remain LAB-only.</div> : <>
<section className="metrics-grid capability-metrics">
<CapabilityMetric label="Channel" value={deployment.channel} hint={deployment.production ? "Production approved" : "Not production"} />
<CapabilityMetric label="Residency" value={deployment.residency.state} hint={`${deployment.residency.load_count} measured loads`} />
<CapabilityMetric label="GPU envelope" value={formatBytes(deployment.resource_envelope.required_vram_bytes)} hint="Measured, not estimated" />
<CapabilityMetric label="Queue" value={String(Math.max(0, requests.filter((item) => item.status === "queued").length))} hint={`Bounded at ${deployment.max_queue_depth}`} />
<CapabilityMetric label="Requests" value={String(requests.length)} hint="Bounded visible history" />
<CapabilityMetric label="Warm hit rate" value={successful.length ? `${Math.round((warmHits / successful.length) * 100)}%` : "No data"} hint="Only completed visible requests" />
</section>
<section className="grid-two">
<article className="panel evidence-list"><div className="panel-header"><div><span className="eyebrow">CONTRACT</span><h2>Backend-authoritative boundary</h2></div><ShieldCheck size={19} /></div><Evidence label="Input modality" value="text"/><Evidence label="Output modality" value="vector"/><Evidence label="Dimension / normalized" value={`${deployment.embedding_space.dimension} / ${deployment.embedding_space.normalized}`}/><Evidence label="Migration" value={deployment.embedding_space.migration_class}/><Evidence label="Retention" value="No request content persisted"/></article>
<article className="panel evidence-list"><div className="panel-header"><div><span className="eyebrow">RESIDENCY</span><h2>Load-on-demand state</h2></div><Activity size={19} /></div><Evidence label="Policy" value={`${deployment.residency_policy} · ${deployment.keep_warm_seconds}s`}/><Evidence label="State" value={deployment.residency.state}/><Evidence label="Active requests" value={String(deployment.residency.active_requests)}/><Evidence label="Resident since" value={formatTime(deployment.residency.resident_since)}/><Evidence label="Embedding space" value={deployment.embedding_space.id}/></article>
</section>
</>}</>;
}
function SchedulerView({ budgets, deployments, plans, policy, token, unlocked, onChanged, onError }: { budgets: SchedulerBudget[]; deployments: CapabilityDeployment[]; plans: PlacementPlan[]; policy: SchedulerPolicy | null; token: string; unlocked: boolean; onChanged: () => Promise<void>; onError: (message: string | null) => void }) {
const [latest, setLatest] = useState<Record<string, PlacementPlan>>({});
const [pendingUnload, setPendingUnload] = useState<CapabilityDeployment | null>(null);
const [unloadAcknowledged, setUnloadAcknowledged] = useState(false);
const [unloadPending, setUnloadPending] = useState(false);
const [unloadError, setUnloadError] = useState<string | null>(null);
const [unloadOutcome, setUnloadOutcome] = useState<string | null>(null);
if (!budgets.length) return <div className="state-card">No accelerator telemetry is available for scheduling.</div>;
const simulate = async (deploymentId: string) => {
try { const plan = await api.dryRunPlacement(deploymentId, "interactive", token); setLatest((current) => ({ ...current, [deploymentId]: plan })); }
catch (cause: unknown) { onError(errorMessage(cause)); }
};
const previewUnload = (deployment: CapabilityDeployment) => {
setUnloadAcknowledged(false); setUnloadError(null); setUnloadOutcome(null); setPendingUnload(deployment);
};
const confirmUnload = async (deployment: CapabilityDeployment) => {
// Guarded against a replayed handler so one acknowledgement can never evict residency twice.
if (unloadPending) return;
setUnloadPending(true); setUnloadError(null);
try {
await api.unloadDeployment(deployment.id, token);
setPendingUnload(null); setUnloadAcknowledged(false);
setUnloadOutcome(`Residency for ${deployment.capability}@${deployment.contract_version} was unloaded.`);
await onChanged();
} catch (cause: unknown) { setUnloadError(errorMessage(cause)); }
finally { setUnloadPending(false); }
};
const changePolicy = async (deployment: CapabilityDeployment, value: string) => {
try { await api.updateResidencyPolicy(deployment.id, value, token); await onChanged(); }
catch (cause: unknown) { onError(errorMessage(cause)); }
};
const pauseLab = async () => {
try { await api.updateSchedulerPolicy(!Boolean(policy?.configuration.lab_paused), token); await onChanged(); }
catch (cause: unknown) { onError(errorMessage(cause)); }
};
return <div className="capability-stack"><section className="scheduler-grid">{budgets.map((budget) => {
const segments = [
["External / unmanaged", budget.external_vram_bytes], ["Safety reserve", budget.safety_reserve_bytes],
["ModelForge resident", budget.resident_vram_bytes], ["Active leases", budget.leased_vram_bytes],
["Schedulable free", budget.schedulable_free_vram_bytes],
] as const;
return <article className="panel scheduler-card" key={budget.accelerator_id}><div className="panel-header"><div><span className="eyebrow">GPU SCHEDULING COCKPIT · {budget.node_name}</span><h2>{budget.accelerator_name}</h2></div><span className={`status-chip ${budget.pressure_state === "NORMAL" ? "active" : "degraded"}`}>{budget.pressure_state}</span></div><div className="budget-total"><strong>{formatBytes(budget.total_vram_bytes)}</strong><span>Total VRAM · attribution {budget.attribution_confidence}</span></div><div className="budget-bar" aria-label="GPU capacity distribution">{segments.map(([label, bytes], index) => <span key={label} className={`budget-segment segment-${index}`} style={{ width: `${Math.min(100, (bytes / budget.total_vram_bytes) * 100)}%` }} title={`${label}: ${formatBytes(bytes)}`} />)}</div><div className="budget-legend">{segments.map(([label, bytes]) => <Evidence key={label} label={label} value={formatBytes(bytes)} />)}</div><small>Observed {formatBytes(budget.observed_used_vram_bytes)} · invariant delta {formatBytes(budget.invariant_delta_bytes)} · policy {budget.policy_revision} · telemetry {formatTime(budget.observed_at)}. External usage is observation-only and has no controls.</small></article>;
})}</section>{unlocked ? <><article className="panel evidence-list"><div className="panel-header"><div><span className="eyebrow">RESIDENCY MAP · WHAT CAN RUN NOW?</span><h2>Managed capability placements</h2></div><button onClick={pauseLab}>{Boolean(policy?.configuration.lab_paused) ? "Resume LAB" : "Pause LAB"}</button></div>{deployments.map((item) => { const plan = latest[item.id]; return <div className="client-row" key={item.id}><div><strong>{item.capability}@{item.contract_version} · {item.residency.state.toUpperCase()}</strong><span>{item.production ? "production" : "lab"} · {formatBytes(item.residency.measured_resident_vram_bytes)} · {item.residency.active_requests} active · cold load {formatMs(item.resource_envelope.cold_load_time_ms)}</span>{plan ? <span>{plan.verdict} · {plan.reason_codes.join(", ")} · after {formatBytes(plan.headroom_after_bytes)}{plan.evictions.length ? ` · evict ${plan.evictions.map((entry) => entry.capability).join(", ")}` : ""}</span> : null}</div><div className="promotion-actions"><button onClick={() => simulate(item.id)}>Dry run</button><select aria-label={`Residency policy for ${item.capability}`} value={item.residency_policy} onChange={(event) => changePolicy(item, event.target.value)}><option value="always_warm">ALWAYS_WARM</option><option value="keep_warm">KEEP_WARM</option><option value="load_on_demand">LOAD_ON_DEMAND</option><option value="lab_only">LAB_ONLY</option></select><button className="danger" disabled={item.residency.active_requests > 0 || item.residency.state === "cold"} onClick={() => previewUnload(item)}>Unload idle</button></div></div>; })}</article><article className="panel evidence-list"><div className="panel-header"><div><span className="eyebrow">PLACEMENT HISTORY</span><h2>Recent bounded decisions</h2></div><CircleGauge size={19}/></div>{plans.slice(0, 20).map((plan) => <Evidence key={plan.id ?? plan.decision_fingerprint} label={`${plan.capability} · ${plan.verdict}`} value={`${plan.reason_codes.join(", ")} · ${formatBytes(plan.headroom_before_bytes)} → ${formatBytes(plan.headroom_after_bytes)} · ${formatTime(plan.created_at)}`}/>)}</article></> : null}
{unloadOutcome ? <p className="field-success" role="status">{unloadOutcome}</p> : null}
{pendingUnload ? <SafetyDialog
idPrefix="residency-unload"
eyebrow="DESTRUCTIVE ACTION PREVIEW"
title="Unload idle residency?"
subject={`${pendingUnload.capability}@${pendingUnload.contract_version}`}
description="ModelForge will evict this deployment from accelerator memory. Serving is not withdrawn: the next request reloads the model and pays the cold-load cost. Residency is unloaded only while no request is active."
facts={[
{ label: "Channel", value: pendingUnload.production ? "production" : "lab" },
{ label: "Residency state", value: pendingUnload.residency.state },
{ label: "Active requests", value: String(pendingUnload.residency.active_requests) },
{ label: "Resident VRAM released", value: formatBytes(pendingUnload.residency.measured_resident_vram_bytes) },
{ label: "Next cold load", value: formatMs(pendingUnload.resource_envelope.cold_load_time_ms) },
]}
acknowledgement="I understand the next request for this capability will pay the cold-load cost."
confirmLabel="Unload residency"
acknowledged={unloadAcknowledged}
onAcknowledgedChange={setUnloadAcknowledged}
pending={unloadPending}
errorTitle="Unload blocked"
error={unloadError}
closeLabel="Close residency unload preview"
onCancel={() => setPendingUnload(null)}
onConfirm={() => void confirmUnload(pendingUnload)}
/> : null}</div>;
}
function RequestHistory({ requests }: { requests: GatewayRequest[] }) {
if (!requests.length) return <div className="state-card">No gateway request metadata exists yet. Input text is never displayed or persisted.</div>;
return <article className="panel table-panel"><div className="panel-header"><div><span className="eyebrow">PRIVACY-PRESERVING HISTORY</span><h2>Gateway requests</h2></div><Clock3 size={19}/></div><div className="operation-table"><div className="table-head"><span>Request</span><span>Client</span><span>State</span><span>Path</span><span>Queue</span><span>Total</span><span>Time</span></div>{requests.map((request) => <div className="table-row" key={request.request_id}><code>{request.request_id.slice(0, 8)}…</code><span>{request.client ?? "rejected identity"}</span><span className={`registry-status ${request.status}`}>{request.failure_code ?? request.status}</span><span>{request.cold == null ? "—" : request.cold ? "cold" : "warm"}</span><span>{formatMs(request.queue_time_ms)}</span><span>{formatMs(request.total_latency_ms)}</span><span>{formatTime(request.created_at)}</span></div>)}</div></article>;
}
function Clients({ clients, token, onChanged, onError }: { clients: ServiceClient[]; token: string; onChanged: () => Promise<void>; onError: (message: string | null) => void }) {
const [name, setName] = useState("modelforge-m5-acceptance");
const [rpm, setRpm] = useState(60);
const [created, setCreated] = useState<ServiceClientCreated | null>(null);
const submit = async (event: FormEvent) => {
event.preventDefault(); onError(null);
try { setCreated(await api.createServiceClient({ name, allowed_capabilities: ["rag.embedding@1"], requests_per_minute: rpm, max_concurrent_requests: 1 }, token)); await onChanged(); }
catch (cause: unknown) { onError(errorMessage(cause)); }
};
const revoke = async (clientId: string) => {
onError(null);
try { await api.revokeServiceCredential(clientId, token); await onChanged(); }
catch (cause: unknown) { onError(errorMessage(cause)); }
};
return <section className="grid-two"><form className="panel client-form" onSubmit={submit}><span className="eyebrow">SCOPED IDENTITY</span><h2>Create service client</h2><label>Name<input required pattern="[a-z][a-z0-9-]*" value={name} onChange={(event) => setName(event.target.value)} /></label><label>Requests per minute<input type="number" min="1" max="10000" value={rpm} onChange={(event) => setRpm(Number(event.target.value))} /></label><p>Scope is fixed to <code>rag.embedding@1</code>; concurrency starts conservatively at one.</p><button type="submit"><KeyRound size={15}/>Create one-time credential</button>{created ? <div className="one-time-secret"><strong>Copy this credential now</strong><code>{created.credential}</code><small>Only its hash is stored. It cannot be retrieved again.</small></div> : null}</form><article className="panel evidence-list"><div className="panel-header"><div><span className="eyebrow">CLIENTS</span><h2>Authorized consumers</h2></div><KeyRound size={19}/></div>{clients.length ? clients.map((client) => <div className="client-row" key={client.id}><div><strong>{client.name}</strong><span>{client.allowed_capabilities.join(", ")} · {client.requests_per_minute}/min · last used {formatTime(client.last_used_at)}</span></div><button className="danger" disabled={client.status !== "active"} onClick={() => revoke(client.id)}>{client.status === "active" ? "Revoke" : "Revoked"}</button></div>) : <p>No service clients created.</p>}</article></section>;
}
function Promotion({ deployment, candidates, approvals, token, onChanged, onError }: { deployment?: CapabilityDeployment; candidates: DeploymentCandidate[]; approvals: ProductionApproval[]; token: string; onChanged: () => Promise<void>; onError: (message: string | null) => void }) {
const candidate = candidates[0];
const approval = approvals.find((item) => item.deployment_candidate_id === candidate?.id);
const reviewItems = [
["exact_revision_reviewed", "Exact upstream revision and resolved commit reviewed"],
["artifact_hashes_reviewed", "Local artifact SHA-256 digests reviewed"],
["safetensors_only", "Artifact set contains safetensors only"],
["remote_code_required", "No remote repository code is required"],
["pickle_present", "No pickle payload is present"],
["scanner_evidence_reviewed", "Supply-chain scanner evidence reviewed"],
["provenance_complete", "Artifact and derivation provenance is complete"],
["runtime_offline_reviewed", "Offline runtime behavior reviewed"],
["dependency_provenance_reviewed", "Runtime dependency provenance reviewed"],
["license_reviewed", "License evidence and production use reviewed"],
] as const;
const [reviewed, setReviewed] = useState<Record<string, boolean>>({});
const [licenseIdentifier, setLicenseIdentifier] = useState("");
const reviewComplete = reviewItems.every(([key]) => reviewed[key]) && licenseIdentifier.trim().length > 0;
const evidence = deployment ? [
["Artifact integrity", "verified"], ["Supply chain", "production approved"],
["Runtime probe", String(deployment.provenance.runtime_probe_id ?? "bound")],
["Compatibility", String(deployment.provenance.compatibility_assessment_id ?? "bound")],
["Resource envelope", `${formatBytes(deployment.resource_envelope.required_vram_bytes)} · ${deployment.resource_envelope.stale ? "stale" : "current"}`],
["Node eligibility", "production eligible"], ["Capability contract", "rag.embedding@1"],
["Migration class", deployment.embedding_space.migration_class], ["Production approval", deployment.production_approval_id],
] : [];
const approve = async () => {
if (!candidate) return;
onError(null);
try {
await api.approveProduction(candidate.id, { approved_by: "operator-ui", reason: "Exact production evidence explicitly reviewed and accepted by operator.", supply_chain_review: { exact_revision_reviewed: true, artifact_hashes_reviewed: true, safetensors_only: true, remote_code_required: false, pickle_present: false, scanner_evidence_reviewed: true, provenance_complete: true, runtime_offline_reviewed: true, dependency_provenance_reviewed: true, license_reviewed: true, license_identifier: licenseIdentifier.trim() }, deployment_config: { capability: "rag.embedding@1", max_concurrency: 1 } }, token);
await onChanged();
} catch (cause: unknown) { onError(errorMessage(cause)); }
};
const promote = async () => {
if (!candidate || !approval) return;
onError(null);
try { await api.promoteCandidate(candidate.id, { production_approval_id: approval.id, residency_policy: "keep_warm", keep_warm_seconds: 900, max_concurrency: 1, max_queue_depth: 16, routing_weight: 100 }, token); await onChanged(); }
catch (cause: unknown) { onError(errorMessage(cause)); }
};
return <article className="panel evidence-list"><div className="panel-header"><div><span className="eyebrow">AUDITED PRODUCTION GATE</span><h2>Promotion evidence</h2></div><ShieldCheck size={20}/></div>{deployment ? evidence.map(([label, value]) => <Evidence key={label} label={label} value={value}/>) : <><p>No stable deployment exists. Promotion remains two explicit, audited actions.</p><Evidence label="LAB_READY candidate" value={candidate?.id ?? "none"}/><Evidence label="Production approval" value={approval?.status ?? "required"}/>{candidate && !approval ? <details className="promotion-review" open><summary>Review the evidence being attested</summary><p>ModelForge records only claims the operator explicitly confirms below. Verify each claim in Registry, Runtime and Evaluation before approval.</p><div className="promotion-checklist">{reviewItems.map(([key, label]) => <label key={key}><input type="checkbox" checked={Boolean(reviewed[key])} onChange={(event) => setReviewed((current) => ({ ...current, [key]: event.target.checked }))}/><span>{label}</span></label>)}</div><label className="license-review">Reviewed license identifier<input value={licenseIdentifier} onChange={(event) => setLicenseIdentifier(event.target.value)} placeholder="For example: Apache-2.0" /></label></details> : null}<div className="promotion-actions"><button onClick={approve} disabled={!candidate || Boolean(approval) || !reviewComplete}>1. Record reviewed approval</button><button onClick={promote} disabled={!candidate || !approval}>2. Promote exact binding</button></div></>}</article>;
}
type ModalityResult = GatewayInvokeResponse | OCRInvokeResponse | VisionEmbeddingResponse | SpeechTranscriptionResponse;
async function fileBase64(file: File): Promise<string> {
const bytes = new Uint8Array(await file.arrayBuffer());
let binary = "";
for (const byte of bytes) binary += String.fromCharCode(byte);
return btoa(binary);
}
function Playground() {
const [capability, setCapability] = useState<"rag.embedding" | "document.ocr" | "vision.embedding" | "speech.transcription">("rag.embedding");
const [credential, setCredential] = useState("");
const [input, setInput] = useState("ModelForge capability gateway test");
const [file, setFile] = useState<File | null>(null);
const [result, setResult] = useState<ModalityResult | null>(null);
const [failure, setFailure] = useState<string | null>(null);
const [running, setRunning] = useState(false);
const invoke = async (event: FormEvent) => {
event.preventDefault(); setFailure(null); setRunning(true);
try {
if (capability === "rag.embedding") setResult(await api.invokeEmbedding(input, credential));
else {
if (!file) throw new Error("Choose a local fixture first");
const encoded = await fileBase64(file);
if (capability === "document.ocr") {
if (file.type !== "image/png" && file.type !== "image/jpeg") throw new Error("OCR accepts PNG or JPEG");
setResult(await api.invokeOcr(encoded, file.type, credential));
} else if (capability === "vision.embedding") {
if (file.type !== "image/png" && file.type !== "image/jpeg") throw new Error("Vision accepts PNG or JPEG");
setResult(await api.invokeVisionEmbedding(encoded, file.type, credential));
} else {
if (file.type !== "audio/wav" && !file.name.toLowerCase().endsWith(".wav")) throw new Error("Transcription accepts WAV");
setResult(await api.invokeTranscription(encoded, credential));
}
}
}
catch (cause: unknown) { setFailure(errorMessage(cause)); }
finally { setRunning(false); }
};
const output = result ? ("data" in result ? `${result.data.length} × ${result.dimension} finite values` : "text" in result ? result.text || "valid empty text" : "typed output") : "";
return <form className="panel playground" onSubmit={invoke}><div className="panel-header"><div><span className="eyebrow">REAL GATEWAY PATH</span><h2>Capability playground</h2></div><Play size={20}/></div><p>The client selects a capability contract. No model name, path, or runtime engine is accepted here.</p><label>Capability<select value={capability} onChange={(event) => { setCapability(event.target.value as typeof capability); setResult(null); }}><option value="rag.embedding">rag.embedding@1</option><option value="document.ocr">document.ocr@1</option><option value="vision.embedding">vision.embedding@1</option><option value="speech.transcription">speech.transcription@1</option></select></label><label>Service credential<input required type="password" autoComplete="off" value={credential} onChange={(event) => setCredential(event.target.value)} /></label>{capability === "rag.embedding" ? <label>Input text<textarea required maxLength={8192} value={input} onChange={(event) => setInput(event.target.value)} /></label> : <label>{capability === "speech.transcription" ? "WAV audio" : "PNG or JPEG image"}<input required type="file" accept={capability === "speech.transcription" ? ".wav,audio/wav" : "image/png,image/jpeg"} onChange={(event) => setFile(event.target.files?.[0] ?? null)} /></label>}<button disabled={running}>{running ? "Invoking…" : "Invoke capability"}</button>{failure ? <div className="error-banner"><strong>Typed gateway failure</strong><span>{failure}</span></div> : null}{result ? <div className="playground-result"><span className={`registry-status ${result.execution.cold ? "candidate" : "ready"}`}>{result.execution.cold ? "cold" : "warm"}</span><Evidence label="Request ID" value={result.request_id}/><Evidence label="Output" value={output}/>{"embedding_space_id" in result ? <Evidence label="Embedding space" value={result.embedding_space_id}/> : null}<Evidence label="Total / inference" value={`${formatMs(result.execution.timings.total_ms)} / ${formatMs(result.execution.timings.inference_ms)}`}/></div> : null}</form>;
}
function AdminBoundary({ unlocked, token, onToken, onSubmit, children }: { unlocked: boolean; token: string; onToken: (value: string) => void; onSubmit: (event: FormEvent) => Promise<void>; children: ReactNode }) {
if (unlocked) return <>{children}</>;
return <form className="panel admin-boundary" onSubmit={onSubmit}><ShieldCheck size={22}/><div><h2>Operator authentication required</h2><p>Administrative data and actions require the operator credential. It remains in browser memory only.</p></div><label htmlFor="capability-operator-key">Operator API key</label><input id="capability-operator-key" name="operator-api-key" required type="password" autoComplete="off" value={token} onChange={(event) => onToken(event.target.value)} /><button type="submit">Unlock operational view</button></form>;
}
function CapabilityMetric({ label, value, hint }: { label: string; value: string; hint: string }) { return <article className="metric-card"><span>{label}</span><strong>{value}</strong><small>{hint}</small></article>; }
function Evidence({ label, value }: { label: string; value: string }) { return <div className="evidence-row"><span>{label}</span><strong title={value}>{value}</strong></div>; }
function formatBytes(value: number): string { return `${(value / 1024 ** 3).toFixed(2)} GiB`; }
function formatMs(value?: number | null): string { return value == null ? "—" : `${value.toFixed(1)} ms`; }
function formatTime(value?: string | null): string { return value ? new Date(value).toLocaleString() : "never"; }
function errorMessage(cause: unknown): string { return cause instanceof ApiError ? `${cause.message}${typeof cause.details.failure_code === "string" ? ` (${cause.details.failure_code})` : ""}` : cause instanceof Error ? cause.message : "Capability operation failed"; }