refactor: unify model residency control, gate the OpenAI UI, and remove phase jargon#236
Merged
Conversation
…ty_minutes Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Addresses the three Phase 2 follow-ups tracked in #220, all pre-release cleanups deliberately kept out of the stacked feature PRs (#217/#218/#219) to keep those diffs focused. The feature is unreleased, so the config-shape change here is migration-free.
What changed
keep_warm_inactivity_minutes, with one consistent meaning:-1keeps the model resident forever,0uses the provider's natural short default (about 5 minutes), andNunloads after N idle minutes. The redundantidle_unload_minutesfield is removed. A small tested translator maps the field onto the built-in runner's internal timer; the Ollama keep-alive path is unchanged. Settings now shows a single "Keep Warm" control for both local providers (hidden for a remote OpenAI-compatible server, whose residency Thuki does not manage). The built-in engine's effective default moves from "resident forever" to "unload after about 5 minutes idle", which frees several GB of RAM when idle now that built-in is the default provider on every fresh install; power users can set-1.VITE_ENABLE_OPENAI_PROVIDER, off by default and tree-shaken out of shipped builds. The backend stays fully active and tested (the/v1client shared with the built-in engine, Keychain storage, the routing arm, the config kind); this gates only the user-facing kind, so no end user can reach an OpenAI provider in a shipped build.phasestate and the mmproj downloadphaseare left as-is (real domain terms).How it works
The unified field is read at the two boundaries that already forward residency policy: startup engine seeding and the Settings change-forwarder. Both translate through one
warmup::builtin_idle_minuteshelper (-1to the runner's "disabled, stays resident forever",0to a fixed about-5-minute timer,Nto N minutes), so the runner's internal "0 = disabled" convention stays an implementation detail behind one tested boundary. The OpenAI gate readsimport.meta.env.VITE_ENABLE_OPENAI_PROVIDERinline at the one render site that mounts the OpenAI card and its add-a-server affordance; Vite statically replaces the value at build, so a production build folds it tofalseand tree-shakes the affordance out of the bundle.Testing
bun run test:all:coverageandbun run validate-buildboth clean: frontend at 100% across lines, branches, functions, and statements; backend 100% line coverage; lint, format, typecheck, and build all clean. The residency translator has unit tests for every arm; the OpenAI flag is tested in both enabled and disabled states.Closes #220.