ModelBehavior

Struct ModelBehavior 

Source
pub struct ModelBehavior {
Show 31 fields pub thinking_in_tools: bool, pub max_thinking_budget: u32, pub effort_capped_at_ceiling: bool, pub thinking_default: bool, pub fp8_kv_calibration_tokens: usize, pub default_kv_dtype: &'static str, pub default_num_drafts: u32, pub disable_tool_steering: bool, pub disable_cwd_hint_injection: bool, pub use_sampling_presets_for_core: bool, pub tool_call_parser: &'static str, pub enable_loop_watchdog: bool, pub enable_think_loop_watchdog: bool, pub honor_eos_inside_thinking: bool, pub min_reasoning_floor_tokens: u32, pub cap_thinking_at_max_tokens: bool, pub min_p_floor: f32, pub temperature_max: f32, pub think_loop_min_repeats: u32, pub think_loop_scan_window: u32, pub confidence_early_stop: bool, pub confidence_run_length: u32, pub fuzzy_repeat_tolerance_div: u32, pub max_inter_tool_prose: u32, pub max_post_think_content_tokens: u32, pub tscg: bool, pub disable_tool_grammar: bool, pub rollback_resteer: bool, pub rom_head: &'static str, pub tool_retry: bool, pub preserve_thinking: Option<bool>,
}
Expand description

Model-specific behavior flags from MODEL.toml [behavior].

Fields§

§thinking_in_tools: bool

Allow thinking when tools are active. Default: true.

§max_thinking_budget: u32

Maximum thinking budget (tokens). Default: DEFAULT_MAX_THINKING_BUDGET.

§effort_capped_at_ceiling: bool

Clamp qualitative reasoning_effort levels at the model’s effective ceiling (high/xhigh resolve to max_thinking_budget instead of 2x/4x it). Default DEFAULT_EFFORT_CAPPED_AT_CEILING = false (historical ladder shape). See behavior_defaults.rs for when a model should set true (measured budget non-monotonicity).

§thinking_default: bool

Default thinking state for this model when the client request does not specify a reasoning_effort / thinking parameter. Typical values:

  • thinking-first models (Mistral Small 4, Qwen3.5, …): true
  • instruct-only models with no <think> tokens: false

Overridden per-request by reasoning_effort, and globally by the --disable-thinking CLI flag.

§fp8_kv_calibration_tokens: usize

Default FP8 KV calibration tokens (0 = disabled).

§default_kv_dtype: &'static str

Default KV cache dtype from MODEL.toml (e.g., “bf16”, “fp8”). When non-empty, overrides the CLI default for models that need higher precision. User can still override with explicit –kv-cache-dtype.

§default_num_drafts: u32

Default num_drafts for speculative decoding (0 = use CLI default). K = num_drafts + 1 (num_drafts=1 → K=2 verifies 2 tokens per step). Optimal K varies per model; benchmarks sometimes show K=2 beats K=3. User override with –num-drafts still wins.

§disable_tool_steering: bool

Skip the <tool_call>\n steering prefix in the chat template’s generation prompt. Some Nemotron variants (Super 120B) weren’t trained on qwen3_coder XML and emit a <tool_call> token loop when the prefix forces them into that structure. Default: false (keep the existing Nemotron-Nano-correct behavior).

§disable_cwd_hint_injection: bool

Do not append Atlas’s derived <environment>working_directory block to a client system prompt. Native agent clients may already provide the cwd; duplicating it can become a tool-selection attractor.

§use_sampling_presets_for_core: bool

Use the selected MODEL.toml sampling category for default temperature, top-k, and top-p instead of generation_config.json. Explicit request values still take precedence.

§tool_call_parser: &'static str

Per-model tool-call parser override. Empty string = use the tool_defaults.toml mapping for this model_type. Set in MODEL.toml [behavior].tool_call_parser when one variant of a model_type needs a different parser than its siblings (e.g. Nemotron-Super-120B uses bare_json while Nemotron-Nano-30B stays on qwen3_coder).

§enable_loop_watchdog: bool

Enable the content-loop watchdog (period-N token-repetition detector at decode_logits_step.rs:230). Default: false — most models terminate cleanly via EOS / max_tokens without it. Models with a known prose-attractor failure mode (Qwen3.5-35B-A3B’s “Running:bash cmdExecuting:” loop, observed during agentic Claude Code sessions) should set this true in MODEL.toml [behavior].

The watchdog has false-positives on legitimate structured output (chess board JS init {color:BLACK,type:'P'}, × 8, HTML tables, JSON arrays of similar objects, multiplication tables). Enable only when the model has been observed to need it.

§enable_think_loop_watchdog: bool

See build_parse.rs: gate for the THINKING-phase loop watchdog.

§honor_eos_inside_thinking: bool

See build_parse_behavior.rs: honor a mid-<think> EOS by implicitly closing the block. Defaults FALSE (pre-p350 behaviour).

§min_reasoning_floor_tokens: u32

A4 floor: suppress </think> until this many think tokens (16 = historical constant; 0 disables — card-native brief thinking).

§cap_thinking_at_max_tokens: bool

Cap the thinking budget at 90% of the request’s max_tokens (true), or let max_thinking_budget be the sole cap (false = vLLM single-budget: reasoning may use the full generation budget). See thinking.rs::resolve.

§min_p_floor: f32

Server-side min-p FLOOR (0.0 = disabled). Applied as min_p.max(floor) AFTER request/preset resolution, so it binds even when a client sends min_p = 0 (or omits it on a server without --default-min-p). On drift-prone quantized models (FP8 / NVFP4 lm-head) an unfloored tail lets the degenerate low-probability tail be sampled into repetition loops + argmax-flip garbling on long generation — the Claude-Code failure mode. MEASURED 2026-06-07 (nvfp4-head@64k): 0.05 turned 4 loop- watchdog fires → 0. Set in MODEL.toml [behavior].

§temperature_max: f32

Server-side temperature CEILING (0.0 = disabled). temperature.min(max) AFTER resolution — defense-in-depth net against a client sending a high temperature; min_p_floor is the dominant lever. Set in MODEL.toml.

§think_loop_min_repeats: u32

Thinking-loop watchdog: substring-occurrence count that trips a forced </think>. Default 3 (historical THINK_LOOP_MIN_REPEATS).

§think_loop_scan_window: u32

Thinking-loop watchdog: trailing-token scan window. Default 160.

§confidence_early_stop: bool

F2 confidence-run early-stop enabled. Default true. Set false for models whose deterministic code drafting trips the heuristic.

§confidence_run_length: u32

F2 confidence run length before arming forced </think>. Default 30.

§fuzzy_repeat_tolerance_div: u32

Fuzzy-repetition detector Hamming tolerance divisor: a pattern_len-token window tolerates pattern_len / div mismatches. Default 12 (~8%).

§max_inter_tool_prose: u32

Cap on free-text tokens between successive <tool_call> opens in tool_choice=auto. Default DEFAULT_MAX_INTER_TOOL_PROSE (see behavior_defaults.rs for the tuning history — #328).

§max_post_think_content_tokens: u32

Unconditional per-generation cap on post-</think> content tokens for tool-active requests (grammar attached). Bounds a runaway where a grammar-legal-but-never-closing tool value burns to max_tokens (the dominant opencode webserver_ok 360s-timeout cause). Default 100_000 — effectively unbounded, the historical no-op — so a model that sets nothing is byte-identical to before. Set a small value (e.g. 1536) per-model to backstop the runaway. Never caps plain chat: the runtime gate also requires grammar_state.is_some().

§tscg: bool

TSCG (Tool-Schema Compilation) enabled — compile tool JSON schemas to compact function signatures before prompting. Default false; the TAS operator is tokenizer-specific so enable + verify per model. arXiv:2605.04107.

§disable_tool_grammar: bool

Disable XGrammar tool-call constrained decoding for this model. Default false. Escape hatch for the “structure snowballing” alignment tax (arXiv:2604.06066) — a few models tool-call more reliably unconstrained. When true, tool calls are parsed but not grammar-enforced.

§rollback_resteer: bool

Phase-C: when a decode-time watchdog (content-loop, fuzzy-repeat, inter-tool prose) detects degeneration, roll the sequence back to the last well-formed boundary and let generation re-steer, instead of hard-stopping the response. Default true (recovers responses, especially mid-tool-call — arXiv:2603.27905 ATLAS-RTC). Set false to keep the legacy hard-stop behavior. Capped at crate::ROLLBACK_RESTEER_CAP rollbacks per sequence, after which the hard-stop fires regardless.

§rom_head: &'static str

Phase-C ROM (arXiv:2603.22016) scaffold. Path to a trained repetition-onset detection head artifact. Empty string = no ROM head; the F2 confidence heuristic stays as the fallback. A trained artifact can be dropped in later via MODEL.toml [behavior].rom_head without further code changes — the runtime loads it through the RomHead trait seam. The detector itself is intentionally NOT implemented (no per-model trained head is available); only the optional hook is wired.

§tool_retry: bool

Tier 5c (2026-05-26): one-shot tool-call re-roll on hard validation failure. When true, validate_tool_calls errors on the chat path fire a single retry inference with the same grammar spec + a correction nudge appended to the prompt. If the retry produces valid tool calls, they replace the failed call before the response leaves the server. Default true — the blocking-path canonical-probe trace shows a write-→bash recovery path that’s strictly better than the previous “[atlas] Tool call rejected” content fallback. Set false per-model when a specific model is known to ALWAYS get tool args right on the first attempt (extra inference round-trip cost is wasted there).

§preserve_thinking: Option<bool>

Jinja preserve_thinking chat-template flag (Qwen3.6+ dense family): keep historical <think> blocks in re-rendered assistant turns instead of stripping them before the last user query.

Tri-state on purpose (SSOT): None = do NOT inject the variable — the model’s own template default applies (Qwen3.6 strips unless preserve_thinking is true; Qwen3.8 KEEPS unless it is explicitly false). Some(_) pins the value for this target, changing multi-turn prompt bytes and therefore prefix-cache hit rate. Per-request chat_template_kwargs.preserve_thinking still wins.

Trait Implementations§

Source§

impl Clone for ModelBehavior

Source§

fn clone(&self) -> ModelBehavior

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ModelBehavior

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for ModelBehavior

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.