package config import ( "strings" "time" ) // WorkstationConfig — the big model on the owner's desktop (workpc, a // 7900 GRE with 16GB), fronted by mavgpud. // // homesrv cannot grow a GPU, so the resident Qwen3-1.7B is the floor and this // is the preferred model above it (owner's call, 2026-08-02, docs/offload.md). // The workstation is never assumed up: its card is often held by a CPT run and // the machine sleeps. No block, or an empty URL, and homesrv behaves exactly as // it does today. // // Only the prompt crosses the LAN, and the workstation is not "the box". The // rules in CLAUDE.md about what may leave still apply. type WorkstationConfig struct { // URL — where mavgpud listens, e.g. "http://192.168.1.105:8080". Empty ⇒ // the whole block is normalised to nil and nothing probes anything. URL string `json:"url,omitempty"` // Health — the admission endpoint. Empty ⇒ URL + "/health", which is what // mavgpud serves. It answers 503 while the card is held, and that is the // signal, so it must be the supervisor's endpoint and not llama-server's. Health string `json:"health,omitempty"` // Probe — how often admission is re-checked. 0 ⇒ DefaultWorkstationProbe. // Nothing on the hot path waits for it: the answer is cached and read // atomically, so this only sets how late Maven notices the card came back. Probe Duration `json:"probe,omitempty"` // Timeout — the per-request budget for a completion on the workstation. // 0 ⇒ DefaultWorkstationTimeout. A big model on a LAN host is slower than // the resident one, and a request that overruns falls back to the floor. Timeout Duration `json:"timeout,omitempty"` } // Workstation defaults, applied in normaliseWorkstation. const ( DefaultWorkstationProbe = 15 * time.Second DefaultWorkstationTimeout = 90 * time.Second ) // normaliseWorkstation applies the block's defaults. No address, no preferred // model: an unconfigured workstation is the default deploy and must be // indistinguishable from today. func (c *Config) normaliseWorkstation() { if c.Workstation != nil && strings.TrimSpace(c.Workstation.URL) == "" { c.Workstation = nil } if c.Workstation == nil { return } w := c.Workstation if strings.TrimSpace(w.Health) == "" { w.Health = strings.TrimRight(w.URL, "/") + "/health" } if w.Probe <= 0 { w.Probe = Duration(DefaultWorkstationProbe) } if w.Timeout <= 0 { w.Timeout = Duration(DefaultWorkstationTimeout) } }