import { useEffect, useRef } from "preact/hooks"; import { brainHas, BRAINS, closeUpgrade, getBrain, olderBrain, onMobileData, startUpgrade, } from "../app/brain.ts"; import { CFG, FEATURE_TEXT } from "../app/config.ts"; import { brain, store, ui, upgrade } from "../app/store.ts"; import { fmtMB } from "../app/utils.ts"; import { isRemote } from "../app/hosting.ts"; export function BrainNotice() { if (ui.hostingBusy || isRemote()) return ( ); const name = store.state.pet?.name; const up = upgrade.state, dozing = brain.state === "off" || brain.state === "error"; const hidden = !name || !(dozing || olderBrain() || up === "swapping"); const text = dozing ? `${name} is dozing: its brain isn't in this browser yet. It downloads once and stays here.${onMobileData() ? " (You seem to be on mobile data.)" : ""}` : up === "downloading" ? `Downloading ${name}'s new brain… ${fmtMB(upgrade.loaded)} of ${fmtMB(CFG.size)}` : up === "swapping" ? `${name} is waking up with its new brain…` : up === "error" ? `The new brain didn't download (${upgrade.error}). ${name} still has its old one.` : `A new brain is ready for ${name}. ${CFG.news || ""}`.trim(); return ( ); } export function UpgradeDialog() { const dialog = useRef(null), name = store.state.pet?.name || "your pet"; useEffect(() => { const d = dialog.current; if (ui.upgradeOpen && !d?.open) d?.showModal(); else if (!ui.upgradeOpen && d?.open) d.close(); }, [ui.upgradeOpen]); const gains = BRAINS[0].features.filter((f) => !brainHas(f)).map((f) => FEATURE_TEXT[f] || f); return (

A new brain for {name}

{CFG.news || `${CFG.modelId} is ready.`}

{!!gains.length &&

It can also: {gains.join("; ")}.

}

Download: about {fmtMB(CFG.size)}. {name} keeps its memories, chat and diary; only the brain changes, and {name} stays awake while it downloads.

{onMobileData() && (

You seem to be on mobile data. You can keep the current brain and upgrade later on Wi-Fi.

)}
); } export function brainStatus() { if (isRemote()) return ( ui.remoteError || (brain.state === "ready" ? `${brain.id || CFG.modelId}, connected to your server. Your pet keeps thinking while this app is closed.` : "Connecting to the server's brain…") ); const id = brain.id || CFG.modelId, up = upgrade.state; return { off: "Not downloaded. Without it your pet just dozes.", downloading: brain.progress ? `Downloading ${id}… ${fmtMB(brain.progress.loaded)} of ${fmtMB(brain.progress.total)}` : "Starting…", warming: "Waking up…", ready: `${id}, awake and running on this device${brain.threads === 1 ? " (one thread)" : ""}${brain.tps ? ` · ${brain.tps.toFixed(1)} tokens/s` : ""}.` + (olderBrain() ? ` A newer brain, ${CFG.modelId}, is available${up === "downloading" ? `: downloading, ${fmtMB(upgrade.loaded)} of ${fmtMB(CFG.size)}` : up === "error" ? ` (the download failed: ${upgrade.error})` : ""}.` : ""), error: `Could not load: ${brain.error}`, }[brain.state]; }