pub struct Wizard {Show 28 fields
pub step: Step,
pub cursor: usize,
pub providers: Vec<ProviderRow>,
pub detail: usize,
pub defaults: Vec<Field>,
pub limits: Vec<Field>,
pub agents: Vec<AgentRow>,
pub mcp: Vec<McpRow>,
pub mcp_scan_errors: Vec<String>,
pub edit: Option<Edit>,
pub reveal: bool,
pub show_help: bool,
pub confirm: Option<PendingConfirm>,
pub dirty: bool,
pub claude_code_tos_accepted: bool,
pub should_quit: bool,
pub finished: bool,
pub message: Option<String>,
pub base: Config,
pub env_only: HashMap<&'static str, String>,
pub opener: BrowserOpener,
pub verify_tx: UnboundedSender<VerifyRequest>,
pub reply_rx: UnboundedReceiver<VerifyReply>,
pub ticks: u64,
pub scroll: usize,
pub show_advanced: bool,
pub help_scroll: Cell<usize>,
pub picker: Option<Picker>,
/* private fields */
}Expand description
The whole wizard.
Fields§
§step: StepThe screen currently shown.
cursor: usizeSelected row within the current step.
providers: Vec<ProviderRow>Every provider the wizard offers, picked or not.
detail: usizeWhich selected provider the credential screen is showing.
defaults: Vec<Field>The Defaults screen’s settings.
limits: Vec<Field>The Limits screen’s settings.
agents: Vec<AgentRow>Every bundled blueprint the wizard offers.
mcp: Vec<McpRow>MCP servers found in other harnesses’ configs.
mcp_scan_errors: Vec<String>Harnesses whose config could not be read, shown rather than swallowed so an empty MCP list is distinguishable from a failed scan.
edit: Option<Edit>The text edit in progress, if any. While this is set, typing goes here rather than to the screen’s own key bindings.
reveal: boolShow credentials in clear text.
show_help: boolThe help overlay is on screen.
confirm: Option<PendingConfirm>A confirmation dialog is on screen, and (after Ctrl-C) it is the only thing keys mean until it is answered.
dirty: boolThe user has changed something since the wizard opened, so quitting silently would discard real choices.
claude_code_tos_accepted: boolThe user has acknowledged the Claude Code transport’s terms risk. A hard gate on saving: the transport cannot be written to the config without it, and deselecting the transport withdraws it.
should_quit: boolThe user asked to leave and the loop should stop.
finished: boolSet once the plan has been applied, so the loop knows to stop.
message: Option<String>A one-line status message.
base: ConfigThe config as loaded from the file, which is what the plan is diffed against and built on.
env_only: HashMap<&'static str, String>Credentials present only in the environment. Shown, never written.
opener: BrowserOpenerOpens a provider’s signup page. Injected rather than called directly:
lev dash once had a unit test launch a real browser, and this is the
same shape of hazard.
verify_tx: UnboundedSender<VerifyRequest>Where a credential check is sent. Verification runs off the UI thread so a slow provider cannot freeze the wizard.
reply_rx: UnboundedReceiver<VerifyReply>Where finished checks arrive, drained once per tick.
ticks: u64Tick counter, for the spinner.
scroll: usizeFirst visible row of the current step, so a screen taller than the
terminal can still be reached. Head-anchored, unlike the log panel’s
tail-anchored ScrollState the log panel uses: a wizard
screen is read from the top, and the cursor decides what must be shown.
show_advanced: boolWhether the tuning screen is on the path.
Off by default. Every one of those limits has a working default, so
walking a first-time user through them taught them that setup is long
rather than that Leviath is configurable. Turned on from the Defaults
screen, it slots the Limits step back into the flow.
help_scroll: Cell<usize>How far the help overlay is scrolled. See the dashboard’s field for
why it is a Cell.
picker: Option<Picker>The open chooser for a Defaults value, if one is open.
Implementations§
Source§impl Wizard
impl Wizard
Sourcepub fn handle_key(&mut self, key: KeyEvent) -> Action
pub fn handle_key(&mut self, key: KeyEvent) -> Action
Handle one key press.
Sourcepub fn handle_mouse(&mut self, mouse: MouseEvent, area: Rect) -> Action
pub fn handle_mouse(&mut self, mouse: MouseEvent, area: Rect) -> Action
Handle one mouse event against the window it was clicked in.
A click acts on what it lands on rather than only selecting it, which
is the point: the wizard leaned on o and v and a footer nobody
read, and a row you can press is the version of that a first-time user
finds on their own. Clicks are ignored while a dialog, an edit or the
help overlay is up, because a click cannot mean anything there and
dismissing them by accident would lose typed input.
Source§impl Wizard
impl Wizard
Sourcepub const PAGE: isize = 8
pub const PAGE: isize = 8
How many rows a page key moves. Smaller than most windows on purpose: a page that overshoots the pane is indistinguishable from a jump.
Sourcepub const PROVIDER_FIELD: usize = 0
pub const PROVIDER_FIELD: usize = 0
Where the provider choice sits on the Defaults screen.
Sourcepub const ADVANCED_FIELD: usize = 3
pub const ADVANCED_FIELD: usize = 3
Where the advanced-tuning toggle sits on the Defaults screen.
Sourcepub const NO_DEFAULT_MODEL: &'static str = "(each blueprint decides)"
pub const NO_DEFAULT_MODEL: &'static str = "(each blueprint decides)"
The model field’s “no default” option.
It read “(provider default)”, which is a thing that does not exist: no provider default model is consulted anywhere at run time. A stage that names no model of its own falls back to a model built into Leviath, not to anything your provider chose, so the old label promised a mechanism and delivered the opposite of what it said.
Sourcepub fn new(
base: Config,
env_lookup: &dyn Fn(&str) -> Option<String>,
candidates: Vec<(String, Candidate)>,
scan_errors: Vec<String>,
agents_dir: &Path,
opener: BrowserOpener,
) -> Self
pub fn new( base: Config, env_lookup: &dyn Fn(&str) -> Option<String>, candidates: Vec<(String, Candidate)>, scan_errors: Vec<String>, agents_dir: &Path, opener: BrowserOpener, ) -> Self
Build the wizard from the config file and the surrounding environment.
base must come from reading the file, not from Config::load():
load folds $ANTHROPIC_API_KEY and friends into the struct, and the
old wizard then re-serialized the whole thing - silently writing a key
the user had deliberately kept in their environment into
~/.leviath/config.toml. Environment-supplied credentials are tracked
separately in env_only and shown as such.
Sourcepub fn take_verify_ends(
&mut self,
) -> Option<(UnboundedReceiver<VerifyRequest>, UnboundedSender<VerifyReply>)>
pub fn take_verify_ends( &mut self, ) -> Option<(UnboundedReceiver<VerifyRequest>, UnboundedSender<VerifyReply>)>
Hand the background verifier loop its channel ends. Returns None if
already taken.
Sourcepub fn selected_providers(&self) -> Vec<usize>
pub fn selected_providers(&self) -> Vec<usize>
Providers the user picked, in table order.
Sourcepub fn detail_row(&self) -> Option<usize>
pub fn detail_row(&self) -> Option<usize>
The provider row the credential screen is currently showing.
Sourcepub fn claude_code_selected(&self) -> bool
pub fn claude_code_selected(&self) -> bool
Whether the Claude Code transport is one of the picked providers.
Sourcepub fn needs_tos_confirmation(&self) -> bool
pub fn needs_tos_confirmation(&self) -> bool
Whether saving must first ask the user to acknowledge Anthropic’s terms. Enabling the transport routes inference through a subscription session, so the risk is confirmed once, explicitly, rather than being buried in a paragraph nobody reads.
Sourcepub fn detail_actions(&self) -> Vec<DetailAction>
pub fn detail_actions(&self) -> Vec<DetailAction>
The credential screen’s action rows, after the credential itself.
They exist as rows rather than as shortcut keys alone because that is
how they become discoverable: a row can be seen, moved onto, and
clicked, and o and v still work for anyone who knows them.
How many cursor positions the current step has: its rows plus the Continue/action button that every step ends with.
Sourcepub fn on_continue(&self) -> bool
pub fn on_continue(&self) -> bool
Whether the cursor sits on the step’s Continue/action button (the virtual row after the last real one).
Sourcepub fn continue_label(&self) -> String
pub fn continue_label(&self) -> String
The label of the current step’s Continue/action button. It carries state (selection counts, what screen is next) so advancing is never a surprise.
Sourcepub fn move_cursor(&mut self, delta: isize)
pub fn move_cursor(&mut self, delta: isize)
Move the selection, clamped to the step’s rows plus its button.
Sourcepub fn scroll_by(&mut self, rows: isize)
pub fn scroll_by(&mut self, rows: isize)
Scroll by whole rows.
Where there is something to select, this moves the selection and lets the renderer follow it, so the view and the cursor can never disagree about what the user is looking at. Welcome and Review have no rows, so there the offset moves on its own.
Sourcepub fn scroll_home(&mut self)
pub fn scroll_home(&mut self)
Jump to the top of the current step.
Sourcepub fn scroll_end(&mut self)
pub fn scroll_end(&mut self)
Jump to the end of the current step, which is always its button.
The offset is set past any possible content and clamped when drawn, because the number of lines a step occupies depends on the window it is drawn into and is not known here.
Sourcepub fn next_step(&mut self)
pub fn next_step(&mut self)
Advance to the next step, skipping ones with nothing to show. Skipping the credential screen is announced rather than silent: it looks exactly like a bug when a screen the breadcrumb promises never appears.
Sourcepub fn next_detail(&mut self) -> bool
pub fn next_detail(&mut self) -> bool
Within the credential screen, move to the next selected provider; returns false when there is no next one.
Sourcepub fn prev_detail(&mut self) -> bool
pub fn prev_detail(&mut self) -> bool
The reverse of Self::next_detail.
Sourcepub fn request_verification(&mut self, index: usize)
pub fn request_verification(&mut self, index: usize)
Ask the background verifier about the provider at index.
A provider with nothing to check is left alone rather than queued: a blank API key would fail with a message about the key rather than saying the obvious, that none was given.
Sourcepub fn verify_all(&mut self)
pub fn verify_all(&mut self)
Ask about every selected provider at once.
Sourcepub fn drain_verifications(&mut self)
pub fn drain_verifications(&mut self)
Take whatever the background verifier has answered.
Sourcepub fn discovered_models(&self) -> Vec<String>
pub fn discovered_models(&self) -> Vec<String>
Every model id any provider reported, deduplicated, for the picker.
Sourcepub fn rebuild_defaults(&mut self)
pub fn rebuild_defaults(&mut self)
Rebuild the Defaults screen. Called on entry, since both the provider list and the discovered models can change between visits.
Sourcepub fn apply_provider_concurrency_default(&mut self)
pub fn apply_provider_concurrency_default(&mut self)
Set the concurrency default that suits the chosen provider.
A local Ollama serves one model at a time, so eight concurrent inferences against it queue and thrash rather than going faster. Only applied while the field still holds the general default, so a number the user typed is never overwritten.
Sourcepub fn open_quit_confirm(&mut self)
pub fn open_quit_confirm(&mut self)
q/Ctrl-C with unsaved choices: ask before discarding them.
Sourcepub fn open_tos_confirm(&mut self)
pub fn open_tos_confirm(&mut self)
Saving with the Claude Code transport selected: the terms risk is confirmed once, explicitly, on a dialog with real buttons.
Sourcepub fn open_no_providers_confirm(&mut self)
pub fn open_no_providers_confirm(&mut self)
Leaving the Providers screen with nothing selected: Leviath cannot run an agent without a provider, so this is almost always a slip.
Sourcepub fn commit_edit(&mut self)
pub fn commit_edit(&mut self)
Commit an edited text buffer into wherever it belongs.
Sourcepub fn build_config(&self) -> Config
pub fn build_config(&self) -> Config
Fold every choice into the config that will be written.
Sourcepub fn build_plan(&self) -> SetupPlan
pub fn build_plan(&self) -> SetupPlan
The plan this wizard describes.
Sourcepub fn review_lines(&self) -> Vec<String>
pub fn review_lines(&self) -> Vec<String>
Lines for the review screen.
Sourcepub fn selected_inline_secrets(&self) -> Vec<String>
pub fn selected_inline_secrets(&self) -> Vec<String>
MCP rows carrying a credential copied verbatim out of another tool’s
config, which importing would duplicate into ~/.leviath/config.toml.
Auto Trait Implementations§
impl !Freeze for Wizard
impl !RefUnwindSafe for Wizard
impl !Sync for Wizard
impl !UnwindSafe for Wizard
impl Send for Wizard
impl Unpin for Wizard
impl UnsafeUnpin for Wizard
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
impl<T> ConditionalSend for Twhere
T: Send,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
Source§fn with_current_context(self) -> WithContext<Self> ⓘ
fn with_current_context(self) -> WithContext<Self> ⓘ
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more