// Compute — where runs execute: BYOK GPU providers (Modal, TensorPool, Lambda // Labs, Prime Intellect, Vast.ai, RunPod), your own SSH hosts, and local/remote // model endpoints. // // Backend: routes/settings/compute.ts. Provider keys are encrypted at rest // under ~/.openscience/ (AES-256-GCM, machine-local key) and never returned to the // browser — the panel only ever sees connection state + metadata. import { Component, For, Show, createResource, createSignal, type JSX } from "solid-js" import { Button } from "@synsci/ui/button" import { Select } from "@synsci/ui/select" import { Icon } from "@synsci/ui/icon" import { showToast } from "@synsci/ui/toast" import { useGlobalSDK } from "@/context/global-sdk" import { usePlatform } from "@/context/platform" import { StatusDot } from "@/thesis/shared/StatusDot" import { settingsApi } from "./api" interface SshHost { id: string label: string host: string user?: string port?: number } interface Endpoint { id: string label: string url: string kind: "local" | "remote" } interface Provider { id: string name: string verified: boolean placeholder: string hint: string connected: boolean connected_at: string | null last_used: string | null } interface ComputeInfo { providers: Provider[] ssh_hosts: SshHost[] endpoints: Endpoint[] } const fmtDate = (iso: string | null) => { if (!iso) return null const d = new Date(iso) if (Number.isNaN(d.getTime())) return null return d.toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric" }) } const Compute: Component = () => { const sdk = useGlobalSDK() const platform = usePlatform() const fetchFn = platform.fetch ?? fetch const call = (path: string, init?: RequestInit) => settingsApi(sdk.url, fetchFn, `/settings/compute${path}`, init) const [info, { mutate, refetch }] = createResource(() => call("")) const [busy, setBusy] = createSignal(false) const run = async (fn: () => Promise, failure: string) => { setBusy(true) try { mutate(await fn()) } catch (err) { showToast({ title: failure, description: err instanceof Error ? err.message : String(err) }) refetch() } setBusy(false) } // ── Provider connect ── const [connecting, setConnecting] = createSignal() const [keyValue, setKeyValue] = createSignal("") const openConnect = (id: string) => { setKeyValue("") setConnecting((v) => (v === id ? undefined : id)) } const connectProvider = async (id: string) => { if (!keyValue().trim()) return await run( () => call(`/provider/${id}`, { method: "POST", body: JSON.stringify({ key: keyValue().trim() }) }), "Failed to connect provider", ) setKeyValue("") setConnecting(undefined) } const removeProvider = (id: string) => run(() => call(`/provider/${id}`, { method: "DELETE" }), "Failed to remove provider") // ── SSH host add form ── const [addingHost, setAddingHost] = createSignal(false) const [hLabel, setHLabel] = createSignal("") const [hHost, setHHost] = createSignal("") const [hUser, setHUser] = createSignal("") const [hPort, setHPort] = createSignal("") const resetHost = () => { setHLabel("") setHHost("") setHUser("") setHPort("") setAddingHost(false) } const saveHost = async () => { if (!hLabel().trim() || !hHost().trim()) return await run( () => call("/ssh", { method: "POST", body: JSON.stringify({ label: hLabel().trim(), host: hHost().trim(), user: hUser().trim() || undefined, port: hPort().trim() ? Number(hPort().trim()) : undefined, }), }), "Failed to add SSH host", ) resetHost() } // ── Endpoint add form ── const [addingEp, setAddingEp] = createSignal(false) const [epLabel, setEpLabel] = createSignal("") const [epUrl, setEpUrl] = createSignal("") const [epKind, setEpKind] = createSignal<"local" | "remote">("remote") const resetEp = () => { setEpLabel("") setEpUrl("") setEpKind("remote") setAddingEp(false) } const saveEp = async () => { if (!epLabel().trim() || !epUrl().trim()) return await run( () => call("/endpoint", { method: "POST", body: JSON.stringify({ label: epLabel().trim(), url: epUrl().trim(), kind: epKind() }), }), "Failed to add model endpoint", ) resetEp() } const kindOptions: { value: "local" | "remote"; label: string }[] = [ { value: "remote", label: "Remote" }, { value: "local", label: "Local" }, ] return (

Compute

GPU providers for sandboxes and training. Add your own key to run on your account for free — or skip the key and provision from the Compute tab, funded by your CLI wallet.

{/* ── GPU providers (BYOK) ── */}
{(p) => ( openConnect(p.id)} onConnect={() => connectProvider(p.id)} onRemove={() => removeProvider(p.id)} /> )}

Everything is BYOK — connect a provider once and work runs under your account. Your provider bills you directly — we never store a key in plaintext. encrypted at rest · your provider, your bill · revoke anytime.

{/* ── SSH hosts ── */}
setAddingHost((v) => !v)} > add SSH host } >
0} fallback={} > {(h) => ( run(() => call(`/ssh/${h.id}`, { method: "DELETE" }), "Failed to remove host") } /> )}
{/* ── Model endpoints ── */}
setAddingEp((v) => !v)} > add model endpoint } >
0} fallback={} > {(e) => ( run( () => call(`/endpoint/${e.id}`, { method: "DELETE" }), "Failed to remove endpoint", ) } /> )}
Kind props.onInput(e.currentTarget.value)} /> )