pub struct Config {Show 27 fields
pub backends: Vec<BackendConfig>,
pub providers: Vec<ProviderConfig>,
pub scratch: Option<ScratchConfig>,
pub default_tier_order: Vec<Tier>,
pub lifecycle: Option<PhaseCommands>,
pub dgx: Option<DgxConfig>,
pub tui: Option<TuiConfig>,
pub shell: Option<ShellConfig>,
pub context: Option<ContextConfig>,
pub tools: Option<ToolsConfig>,
pub pricing: Option<PricingConfig>,
pub memory: Option<MemoryConfig>,
pub agents: AgentsConfig,
pub mcp_servers: Vec<McpServerEntry>,
pub logs: Option<LogConfig>,
pub skills: Option<SkillsConfig>,
pub model_tuning: Vec<ModelTuning>,
pub conversations: Option<ConversationsConfig>,
pub merge: Option<MergeConfig>,
pub permission_presets: BTreeMap<String, NamedPermissionPreset>,
pub modes: BTreeMap<String, ModeConfig>,
pub profiles: BTreeMap<String, ProfileConfig>,
pub bundles: BTreeMap<String, BundleConfig>,
pub loadouts: BTreeMap<String, Loadout>,
pub crews: BTreeMap<String, Crew>,
pub crew: Option<CrewPolicyConfig>,
pub plan: Option<PlanConfig>,
}Expand description
Top-level Newt-Agent configuration.
Fields§
§backends: Vec<BackendConfig>Inference backends (Ollama, vLLM, etc.).
Absent [[backends]] deserializes to empty (not the struct-level
default’s localhost fallback) so a config that defines its backends as
per-file ~/.newt/backends/*.toml drop-ins does NOT also pick up a
spurious synthesized ollama entry. The localhost fallback is restored
in Config::resolve only if backends are still empty after the disk
merge (so a truly bare setup still talks to a local Ollama).
providers: Vec<ProviderConfig>External provider-plugin definitions.
scratch: Option<ScratchConfig>[scratch] — where ephemeral state (crew worktrees, the crew cargo
target, per-session plans) lives (#844). dir may be relative (under the
repo, default .scratch) or absolute (/tmp, a k8s PVC mount) for
read-only checkouts. NEWT_SCRATCH_DIR overrides it. Applied in
Config::resolve via crate::scratch::set_scratch_dir.
default_tier_order: Vec<Tier>Default tier ordering used by the router when no per-backend override is specified.
lifecycle: Option<PhaseCommands>[lifecycle] — the repo’s build/dev commands per lifecycle phase
(format, check, clean, …), #880. Overrides the per-ecosystem tooling
packs. Applied in Config::resolve via
crate::tooling::set_lifecycle_override.
dgx: Option<DgxConfig>Optional NVIDIA DGX endpoint-management config powering the
newt dgx command suite. None when unconfigured — newt never
dials a DGX endpoint unless this (or a NEWT_DGX_* env var) is set.
tui: Option<TuiConfig>TUI appearance and behaviour. None → built-in defaults apply.
Overridable at runtime via NEWT_CHAT_STYLE and NEWT_PROMPT.
shell: Option<ShellConfig>[shell] — which engine runs run_command (ADR 0005 D2 seam). None /
unset → the safe-subset default, except --full-access auto-upgrades to
host. Overridable per-session by --shell-engine. The L3 backend
(Landlock/Seatbelt/AppContainer) is a separate, auto-selected axis.
context: Option<ContextConfig>[context] — context-management strategy selection (Step 24.8, #559).
tools: Option<ToolsConfig>[tools] — tool-execution behaviour (#726). None → built-in defaults
(notably max_output_tokens = 10000). See ToolsConfig.
pricing: Option<PricingConfig>Inference cost modeling. None → built-in rate table only.
memory: Option<MemoryConfig>Memory / context-window management. None → RollingWindow(20).
agents: AgentsConfigProject-instruction loading (AGENTS.md / CLAUDE.md) into the system
prompt. Enabled by default. Overridable via --agents-file /
--no-agents-file.
mcp_servers: Vec<McpServerEntry>newt-native MCP servers ([[mcp_servers]]). Merged with the servers
discovered from Claude Code’s config by crate::mcp::discover; these
take precedence on a name clash. Empty by default.
logs: Option<LogConfig>Usage-log rotation policy. None → built-in defaults apply
(keep last 7 sessions, no size/age limit).
skills: Option<SkillsConfig>Skill discovery search path — the ordered list of directories newt
reads SKILL.md folders from. None → just ~/.newt/skills.
model_tuning: Vec<ModelTuning>Per-model inference tuning overrides ([[model_tuning]]).
Each entry locks specific parameters for a named model. Values here
take precedence over empirically derived values from
model-capabilities.json and over global [tui] defaults.
Example ~/.newt/config.toml:
[[model_tuning]]
model = "nemotron3:33b"
num_ctx = 24576 # explicit Ollama context window
mid_loop_trim_threshold = 12
max_tool_rounds = 20Human-authored entries are never overwritten by the auto-tuner.
Auto-tuned entries are appended by the harness when
tune_confidence reaches High; delete or edit them freely.
conversations: Option<ConversationsConfig>Durable conversation save/restore policy. None uses built-in defaults.
merge: Option<MergeConfig>How a project-local .newt/config.toml is layered over the global
config (issue #222). None → built-in default (arrays replace).
permission_presets: BTreeMap<String, NamedPermissionPreset>Named permission presets ([permission_presets.<name>], issue #307).
Each maps onto the role-profile caveat mechanism (a
crate::NamedPermissionPreset) and, when applied via /mode, clamps
the session’s authority as a hard floor. Empty by default — no preset,
behavior unchanged.
modes: BTreeMap<String, ModeConfig>Named modes ([modes.<name>], issue #307) for the /mode command. Each
mode atomically binds a skill body to preload, a permission preset to
apply as an authority floor, and a one-line system-prompt framing. Empty
by default. See ModeConfig.
profiles: BTreeMap<String, ProfileConfig>Named profiles ([profiles.<name>]) — a composition of harness
techniques plus each technique’s tunable knob settings (the technique
library, docs/design/technique-library.md). A profile is selected by
--profile <name> and tunes the harness per model family / context.
Empty by default — no profile, behavior unchanged. See ProfileConfig.
bundles: BTreeMap<String, BundleConfig>Named bundles ([bundles.<name>]) — the loadable unit of the model support
kit (docs/design/model-support-kit.md). A bundle pins which model families
it applies to and which profile each resolves to. Selected by --bundle <name> or inferred from the model via applies_to. Empty by default — no
bundle, behavior unchanged. See BundleConfig.
loadouts: BTreeMap<String, Loadout>Named loadouts ([loadouts.<name>] or ~/.newt/loadouts/<name>.toml) — the
top-level composition of provider → model → kit → role → settings
(docs/design/loadout-composition.md). Inert until the resolver is wired
(Slice 1): this carries the data model + reference validation + /loadout
show. Empty by default. See Loadout.
crews: BTreeMap<String, Crew>Named crews ([crews.<name>] or crews/<name>.toml) — role-specialized
ensembles over the backend pool (docs/design/crew-loadout.md). Each role
names a [loadouts.<name>]. Empty by default. See Crew.
crew: Option<CrewPolicyConfig>[crew] — crew/team dispatch policy (#749). Carries the authority
clamp every dispatched crew is met against, so a crew’s effective
authority is session ⊓ clamp — never above the session ceiling, and as
tight as the operator configures. None (and the default clamp) is
Caveats::top(), i.e. the meet is the identity and behavior is unchanged.
This is the structural tightening point the per-subtask team_clamp
(#749 step 8) plugs into. See CrewPolicyConfig.
plan: Option<PlanConfig>[plan] — plan-authoring policy. Today: the [plan.prune] droppable
override for the decompose prune’s anti-pattern lexicon (#801/#803 →
#819). None = compiled defaults, behavior unchanged. See
PlanPruneConfig.
Implementations§
Source§impl Config
impl Config
Sourcepub fn find_model_tuning(&self, name: &str) -> Option<&ModelTuning>
pub fn find_model_tuning(&self, name: &str) -> Option<&ModelTuning>
Find the first [[model_tuning]] entry whose model field matches
name exactly. Returns None when no entry exists.
Sourcepub fn resolve_profile(&self, name: &str) -> Result<&ProfileConfig, String>
pub fn resolve_profile(&self, name: &str) -> Result<&ProfileConfig, String>
Look up and validate a named profile ([profiles.<name>]). The caller
selects it via --profile <name> / NEWT_PROFILE.
§Errors
no such profile when the name is undefined; the validation error when
the profile names an unknown technique — a --profile that silently did
nothing would be a false claim, so both fail loudly.
Sourcepub fn resolve_bundle(&self, name: &str) -> Result<&BundleConfig, String>
pub fn resolve_bundle(&self, name: &str) -> Result<&BundleConfig, String>
Look up a named bundle ([bundles.<name>]).
§Errors
no such bundle when undefined — a --bundle that silently did nothing
would be a false claim.
Sourcepub fn bundle_profile_for_model<'a>(
&self,
bundle: &'a BundleConfig,
model: &str,
) -> Option<&'a str>
pub fn bundle_profile_for_model<'a>( &self, bundle: &'a BundleConfig, model: &str, ) -> Option<&'a str>
The profile name bundle yields for model: the longest-prefix families
match, else default_profile. None ⇒ the bundle applies no profile here.
Sourcepub fn infer_bundle(&self, model: &str) -> Option<(&str, &BundleConfig)>
pub fn infer_bundle(&self, model: &str) -> Option<(&str, &BundleConfig)>
Infer the bundle for model from applies_to (longest-prefix-wins). Only
bundles with a non-empty applies_to participate — a use-case bundle (empty
applies_to) is never auto-inferred, only chosen explicitly via --bundle.
Sourcepub fn pick_active_profile(
&self,
profile_flag: Option<&str>,
bundle_flag: Option<&str>,
model: &str,
) -> Result<Option<ProfilePick>, String>
pub fn pick_active_profile( &self, profile_flag: Option<&str>, bundle_flag: Option<&str>, model: &str, ) -> Result<Option<ProfilePick>, String>
Resolve the active profile from the selectors + the active model:
--profile (explicit) > --bundle (its profile for this model) > an
inferred bundle (applies_to) > None (today’s no-profile behavior).
Returns the profile NAME + how it was chosen (for the banner).
§Errors
An unknown explicit --bundle is a hard error. An unknown explicit
--profile is left for the caller’s resolve_profile
so the message stays profile-specific.
Source§impl Config
impl Config
Sourcepub const REDACTED: &'static str = "<redacted>"
pub const REDACTED: &'static str = "<redacted>"
Placeholder substituted for redacted secret values in Self::to_redacted_toml.
Sourcepub fn resolve() -> Result<Self>
pub fn resolve() -> Result<Self>
Resolve configuration by searching well-known locations, then layering a project-local override on top.
Base search order (first match wins):
$NEWT_CONFIGenvironment variable./newt.toml$NEWT_CONFIG_DIR/config.tomlor~/.newt/config.toml/etc/newt/config.toml
Then, if a project-local .newt/config.toml is found by walking up from
the current directory (see Config::project_config_path), it is
deep-merged over the base so a repo can pin its own models, endpoints,
rules, and local stdio MCP services without copying the whole global
config. Tables merge recursively (project keys win) and scalars are
replaced by the project value. Arrays follow [merge] arrays —
"replace" (default) or "append" (see ArrayMergeStrategy). The
project config’s [merge] setting takes precedence, then the base’s.
See issue #222.
When no project override exists this is byte-for-byte the legacy
first-match behavior. Returns Config::default() if nothing is found.
Sourcepub fn max_output_tokens(&self) -> usize
pub fn max_output_tokens(&self) -> usize
The configured model-facing output token budget ([tools] max_output_tokens), or the built-in default when [tools] is absent
(#726). 0 means “no cap”. See ToolsConfig.
Sourcepub fn output_head_tokens(&self) -> usize
pub fn output_head_tokens(&self) -> usize
The configured head allocation for oversized run_command output
([tools] output_head_tokens), or the built-in tail-biased default.
Sourcepub fn project_config_path() -> Option<PathBuf>
pub fn project_config_path() -> Option<PathBuf>
Locate a project-local .newt/config.toml by walking up from the current
directory toward the filesystem root, stopping before $HOME so the
global ~/.newt/config.toml is never mistaken for a project override.
Returns the nearest match (innermost project wins). See issue #222.
Sourcepub fn user_config_dir() -> Option<PathBuf>
pub fn user_config_dir() -> Option<PathBuf>
The user-writable config root: $NEWT_CONFIG_DIR or ~/.newt.
Sourcepub fn user_config_path() -> Option<PathBuf>
pub fn user_config_path() -> Option<PathBuf>
The user-writable config path: $NEWT_CONFIG_DIR/config.toml or
~/.newt/config.toml.
This is the first path resolve() reads and the target for save().
Sourcepub fn to_redacted_toml(&self) -> Result<String>
pub fn to_redacted_toml(&self) -> Result<String>
Serialize the config to pretty TOML for audit, with inline secret
material redacted. The values of every [[mcp_servers]] env and
headers entry are replaced with Self::REDACTED — those maps are the
only place Config can carry a raw secret inline (e.g. an
Authorization: Bearer … header or an API_KEY=… child env var). Keys
are kept so an auditor sees which variables/headers are set without the
values. Secret references (api_key_file / api_key_env) are left as-is
— they name where a secret lives, not the secret itself.
§Errors
A TOML serialization failure (should not happen for a valid Config).
Sourcepub fn skill_search_dirs(&self) -> Vec<PathBuf>
pub fn skill_search_dirs(&self) -> Vec<PathBuf>
The ordered skill-discovery search path, with ~/ expanded.
Resolves [skills].search when configured; otherwise defaults to the
single host-scoped ~/.newt/skills. Order is preserved — earlier
directories win on a name collision (see newt_skills::discover_paths).
The default falls back to a relative .newt/skills only when $HOME
can’t be resolved, so the list is never empty.
Sourcepub fn save(&self, path: &Path) -> Result<()>
pub fn save(&self, path: &Path) -> Result<()>
Serialize this config and write it to path, creating parent dirs if needed.
Sourcepub fn with_net_host(text: &str, host: &str) -> Result<String>
pub fn with_net_host(text: &str, host: &str) -> Result<String>
#904: append host to [tui.permissions] net in the TOML text,
preserving comments and formatting — unlike Config::save, which
re-serializes the whole typed struct and drops the user’s comments,
ordering, and any keys newt does not model. Creates the
[tui.permissions] table and its net array if absent; a no-op if the
host is already listed. PURE (no I/O), so it unit-tests without a
filesystem. This is the durable “allow permanently” grant path — it is
only ever driven by an explicit human keypress at the permission prompt.
Sourcepub fn append_permission_net_host(path: &Path, host: &str) -> Result<()>
pub fn append_permission_net_host(path: &Path, host: &str) -> Result<()>
Durably grant a net host by appending it to [tui.permissions] net in the
config file at path, comment-preserving (see Config::with_net_host).
A missing file is treated as empty (the table is created). Creates parent
dirs as needed. Used by the interactive gate’s “allow permanently” choice.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for Config
impl<'de> Deserialize<'de> for Config
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Auto Trait Implementations§
impl Freeze for Config
impl RefUnwindSafe for Config
impl Send for Config
impl Sync for Config
impl Unpin for Config
impl UnsafeUnpin for Config
impl UnwindSafe for Config
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
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
impl<T> ErasedDestructor for Twhere
T: 'static,
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