/** Browser/host state and the local worker protocol. Saves and world states * mirror the serde types in core/src/types.rs. */ export type HostingMode = "local" | "remote"; export interface Hosting { mode: HostingMode; brainId: string | null; timeZone: string; } export type Stage = "baby" | "kid" | "teen" | "adult"; export type Stat = "tummy" | "fun" | "energy" | "clean"; export type Stats = Record; export type TurnKind = "react" | "idle"; export type Disturbance = "talk" | "touch" | "light"; export type OfferKind = "feed" | "bath" | "medicine" | "play"; export type Action = OfferKind | "pat" | "clean" | "lights"; export interface Pet { name: string; traits: string[]; color: string; toy: string; hatched: number; stage: Stage; } export interface DayLog { log: string[]; weather: string; day: number; } export interface DiaryPage extends Omit { date: string; stage: Stage; text: string; doodles: string[]; } export interface Offer { kind: OfferKind; item: string | null; } export interface PetState { v: number; created: number; owner: string; pet: Pet | null; egg: { laid: number } | null; stats: Stats; sick: boolean; poop: number; asleep: boolean; lightsOff: boolean; memories: string[]; shelf: string[]; chat: string[]; diary: DiaryPage[]; today: { date: string; log: string[]; day?: number; weather?: string }; history: Record; offer: Offer | null; wokeAt: number; lastTick: number; lastActive: number; grimeSince: number; nextPoop: number; /** chatter belongs to the pet; the other keys are this device's preferences. */ settings: { chatter: boolean; alerts?: boolean; alertsAsked?: boolean; installAsked?: boolean }; counts: { fed: number; pats: number; games: number; baths: number }; hosting: Hosting; } export interface WorldState { pet: string; owner: string; stage: Stage; day: number; traits: string[]; hh: number; mm: number; weather: string; stats: Stats; memories: string[]; today: string[]; shelf: string[]; toy: string; poop: number; asleep: boolean; sick: boolean; yesterday: string; } export interface BrainInfo { id: string; size?: number; features: string[]; } export interface Config { runtime: string; models: string; modelId: string; size: number; news?: string; features?: string[]; older?: BrainInfo[]; sw?: string; icon?: string; weatherSeed?: string; remoteEndpoint?: string; } export interface Generation { header: string; lines: string[]; prefix: string; mode: "line" | "diary"; maxNew: number; temperature: number; topK: number; topP: number; ctx: number; } export interface Generated { id: number; text: string; prompt: string; reason: string; promptTokens: number; prefillMs: number; tps: number; } export type WorkerRequest = | { type: "load"; runtime: string; models: string; modelId: string; dtype: "q4"; threads?: number; } | ({ type: "generate"; id: number } & Generation); export type WorkerResponse = | ({ type: "done" } & Generated) | { type: "progress"; loaded: number; total: number; file: string } | { type: "loading"; stage: string } | { type: "file"; file: string } | { type: "ready"; dtype: string; resources: string[] } | { type: "token"; id: number; text: string } | { type: "error"; id?: number; message: string }; export interface BrainState { worker: Worker | null; state: "off" | "downloading" | "warming" | "ready" | "error"; busy: boolean; tps: number; prefillMs: number; progress: { loaded: number; total: number } | null; threads: number; id: string | null; error: string; remoteFeatures?: string[]; } export interface RemoteSnapshot { state: PetState; epoch: number; revision: number; authority: HostingMode; localDevice: string | null; effects: { seq: number; kind: string; arg: string }[]; game: { id: string; started: number } | null; thinking: boolean; lastError: string | null; modelId: string; features: string[]; serverNow: number; weather: string; } /** Owner commands, run by the local engine or sent to the host unchanged. */ export type PetCommand = | { type: "hatch"; name: string } | { type: "message"; text: string } | { type: "care"; kind: Action; item: string | null } | { type: "rename"; name: string } | { type: "chatter"; value: boolean } | { type: "forgetMemory"; index: number; fact: string } | { type: "gameComplete"; gameId: string; score: number }; export interface Animation { name: string; t0: number; until: number; } export type Effect = | { kind: "float"; item: string; x: number; y: number; t0: number; until: number } | { kind: "bubble"; x: number; y: number; t0: number; until: number } | { kind: "food"; item: string; t0: number; until: number }; export interface Game { stars: { x: number; y: number; v: number; bad: boolean; done?: boolean }[]; score: number; timeLeft: number; last: number; spawn: number; dir: number; held: Map; } export interface View { x: number; facing: number; walking: boolean; target: number; anim: Animation | null; queue: { name: string; ms: number }[]; effects: Effect[]; want: string | null; wantUntil: number; dream: string | null; dreamUntil: number; game: Game | null; thinking: boolean; } export interface ScenePet { stage: Stage; color: string; x: number; facing: number; walking: boolean; anim: Animation | null; asleep: boolean; sick: boolean; } export interface EggView { progress: number; ready: boolean; bad?: boolean; } export interface Scene { lightsOff: boolean; weather: string; hour: number; shelf: string[]; poop: number; egg: EggView | null; pet: ScenePet | null; effects: Effect[]; game: Game | null; want: string | null; dream: string | null; offer: string | null; thinking: boolean; clock: string | null; } export interface InstallPrompt extends Event { prompt(): Promise; userChoice: Promise<{ outcome: string }>; } declare global { interface Navigator { connection?: { saveData?: boolean; type?: string }; standalone?: boolean; } interface ServiceWorkerRegistration { periodicSync?: { register(tag: string, options: { minInterval: number }): Promise }; } interface Window { tokenling: import("./app/debug.ts").TestControls; } }