Skip to content

feat(init): add flynn init --local, a first-run wizard for a local model - #642

Merged
ion-alpha-dev merged 5 commits into
mainfrom
feat/init-local
Nov 1, 2026
Merged

ion-alpha-dev merged 5 commits into
mainfrom
feat/init-local

Conversation

@ion-alpha-dev

@ion-alpha-dev ion-alpha-dev commented Oct 31, 2026 •

Copy link
Copy Markdown
Collaborator

What

Adds flynn init --local, which takes a fresh install to a working local default model by composing what the flynn models subcommands already do. It also lists providers.json servers in the cloud onboarding prompt, and brings the usage text up to date (models add, models remove, bless saving to the user overlay).

Why

A new user with a GPU has to know the order of models --local --fit, models install llama.cpp, models fetch, models probe and models use. The wizard detects GPU, free VRAM, RAM, OS and runtimes, recommends up to three models using the same fit verdicts as models --local --fit, lists models a running Ollama or LM Studio already holds as an alternative to downloading, installs the runtime if none is present, fetches or adopts, probes, and only then sets the default. Every download asks first and shows its size. Ctrl-C or a declined prompt leaves the default unchanged. --yes, --model <id> and --data-dir are honoured, and there is one prompt path shared with the other prompts.

How to verify

Run go test ./cmd/flynn -run 'TestInit|TestServerModelSpec|TestOnboardListsConfiguredServers|TestLiveInitEnv|TestProbeServerModel'; the wizard is driven through an injectable environment, so no GPU is needed. By hand: flynn --data-dir <dir> init --local --yes --model <id> (the global flag goes before the subcommand).

Notes for reviewers

Run on Windows 11 with an RTX 4070 Ti (12 GB): it detected 11.0G free of 12.9G VRAM, installed the cuda-13.3 runtime, and fetched and digest-verified gemma4:12b. The probe then failed with a client timeout while checking the launched listener, so the default was correctly left unset. flynn models probe gemma4:12b fails the same way without the wizard, in internal/localmodel, which this PR does not touch; a follow-up is filed.

Recommendations follow the catalog ranking (largest first), so the Enter default under --yes can be a split GPU+RAM placement. I kept the ranking so the verdicts match models --fit; whether the default pick should change is left to the maintainer.

probeServerModel is covered by TestProbeServerModelStoresProfileUnderServerSpec: a fake OpenAI-compatible server reached through OLLAMA_BASE_URL, a temp data dir store, and an assertion that the profile is stored under the provider:model spec and not the bare model id. Replacing the spec passed to probeAndStore with a bare-id entry makes it fail.

Uncovered lines (codecov/patch)

The remaining uncovered changed lines are live wiring that needs a machine CI does not have. runInit builds a signal context and the live environment from os.Stdin and os.Stdout, so a test would have to take over the process terminal and interrupt signal. The closures in liveInitEnv open a host, install a runtime, download weights or start a model server; each one only forwards to a function the flynn models commands already use and test (installRuntime, fetchWeights, modelProbe, runModelUse, openHost). The wizard's own logic runs against an injected environment in the TestInit* tests, and TestLiveInitEnvReadsThisInstall runs the detection closures (catalog, profiles, servers, discovery) against an empty data directory. The live path was exercised by hand on the RTX 4070 Ti run above.

The context ladder from #646 measures up to the context the server was started with. Ollama and LM Studio do not report that, so for a model adopted from either the served context is unknown and only the overflow error from the server ends the ladder.

…model

The wizard takes a machine with no model configured to a working
local default. It detects the GPU, free VRAM, RAM, platform, the
llama.cpp runtime and any running Ollama or LM Studio server, then
offers up to three catalog models ranked by the same fit verdicts as
`flynn models --local --fit`, plus the models a running server already
holds (adopted with no download).

Every download shows its size and asks first; --yes accepts the
defaults and still prints the size. The chosen model is probed, and
the default is written only after the probe: a model scoring under 90%
on tool calls or schemas is set only on an explicit yes, never under
--yes. A declined prompt, Ctrl-C or a failed step leaves the previous
default as it was.

It reuses the models commands for fit, runtime install, fetch, probe
and `models use`, and the onboarding prompt reader, so there is one
prompt path.

Also list the servers named in providers.json in first-run onboarding,
point onboarding at `flynn init --local`, and document `models add`,
`models remove` and the user overlay in the usage text.

Signed-off-by: Ion Alpha <[email protected]>
Signed-off-by: Ion Alpha <[email protected]>
Document the first-run wizard beside the runtime it installs: what it
reports, that every download asks first, and that the default is only
set after the probe passes.

Signed-off-by: Ion Alpha <[email protected]>
@codecov

codecov Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.38028% with 33 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
cmd/flynn/init_local.go 88.08% 33 Missing ⚠️

📢 Thoughts on this report? Let us know!

The adopted-model probe had no test. This one reaches a fake server through
the provider's base URL reference, probes it into a temp data dir store and
asserts the profile is recorded under the provider:model spec and not under
the bare model id.

Signed-off-by: Ion Alpha <[email protected]>
@ion-alpha-dev
ion-alpha-dev merged commit 110dcbe into main Nov 1, 2026
33 of 34 checks passed
@ion-alpha-dev
ion-alpha-dev deleted the feat/init-local branch November 1, 2026 09:07
@github-actions github-actions Bot locked and limited conversation to collaborators Nov 1, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant