Skip to main content

Config

Struct Config 

Source
pub struct Config {
Show 35 fields pub workspace: PathBuf, pub api_base: String, pub api_key: Option<String>, pub model: String, pub provider_type: String, pub preset: Option<String>, pub max_steps: usize, pub max_tokens: u32, pub temperature: f64, pub system_prompt: String, pub retry_max: usize, pub retry_initial_backoff_secs: u64, pub retry_max_backoff_secs: u64, pub shell_timeout_secs: u64, pub wall_timeout_secs: u64, pub headless: bool, pub memory_summary_limit: usize, pub thinking_budget: Option<u32>, pub session_name: Option<String>, pub max_budget_usd: Option<f64>, pub extra_dirs: Vec<PathBuf>, pub extra_readonly_dirs: Vec<PathBuf>, pub allow_tools: Vec<String>, pub context_window_override: Option<usize>, pub subagent_max_depth: usize, pub subagent_enabled: bool, pub allow_bypass_permissions: bool, pub max_search_rounds: usize, pub stuck_window: usize, pub stuck_error_rate: f64, pub max_concurrent_runs: usize, pub goal_eval_transcript_tail: usize, pub web_search_provider: Option<String>, pub web_search_api_key: Option<String>, pub web_search_jina_key: Option<String>,
}

Fields§

§workspace: PathBuf§api_base: String§api_key: Option<String>§model: String§provider_type: String§preset: Option<String>

Preset id resolved from provider.preset in the config file. None when the user did not opt in (or the file was absent).

§max_steps: usize

Maximum agent loop iterations per turn/goal. 0 = unlimited (agent stops on NoMoreToolCalls, stuck, transcript limit, etc.).

§max_tokens: u32

Maximum tokens the model may generate per response. Mirrors the max_tokens / max_output_tokens field of OpenAI-/Anthropic-style providers. Resolved with three-tier precedence (see from_env):

  1. RECURSIVE_MAX_TOKENS env var (highest)
  2. provider ModelSpec.max_tokens / config-file agent.max_tokens
  3. crate::llm::DEFAULT_MAX_TOKENS (64K — see note below)

Historical note: this used to be a hard-coded 16384 inside each provider struct, with a stale comment claiming DeepSeek’s ceiling was “8192 for v3”. DeepSeek V4 actually supports up to 384K output tokens (flash == pro); 16384 was needlessly truncating reasoning-heavy turns (provider_stop:length with empty content). 64K aligns with the escalation ceiling other coding agents (Claude Code) use.

§temperature: f64§system_prompt: String§retry_max: usize§retry_initial_backoff_secs: u64§retry_max_backoff_secs: u64§shell_timeout_secs: u64§wall_timeout_secs: u64

Wall-clock deadline for the entire agent run (Goal 345). When > 0, the step loop checks an elapsed-time deadline and terminates cleanly with [FinishReason::WallClockExceeded] when exceeded. Default 0 = unset (no wall-clock cap). Set via --wall-timeout CLI flag or RECURSIVE_WALL_TIMEOUT_SECS env.

§headless: bool

Run in headless mode: interactive tools go through external hooks instead of waiting for terminal input. If no hook approves the call, the tool is auto-denied.

§memory_summary_limit: usize§thinking_budget: Option<u32>

Extended thinking budget for models that support it (e.g. Anthropic claude-3-7). None = model default; Some(0) = disable thinking; Some(n) = budget_tokens.

§session_name: Option<String>

Optional display name for the session, shown in the /resume picker.

§max_budget_usd: Option<f64>

Maximum total API spend in USD for this run. Checked after each turn. None = no limit.

§extra_dirs: Vec<PathBuf>

Additional workspace-root directories the agent is allowed to access (sandbox expansion via --add-dir / [sandbox] extra_dirs). Read-write: the agent can Read, Write, Edit inside them. Empty = only workspace.

§extra_readonly_dirs: Vec<PathBuf>

Additional read-only sandbox roots ([sandbox] extra_readonly_dirs). The agent can Read / Glob / Grep inside them but Write / Edit are rejected with a clear error. Empty = no read-only extras.

§allow_tools: Vec<String>

If non-empty, only tools whose names appear in this list are registered. Set via --allow-tools CLI flag or RECURSIVE_ALLOW_TOOLS env var.

§context_window_override: Option<usize>

Override the detected context window size for the configured model. When set, context_window_tokens() returns this value instead of the value from providers.toml. Useful for custom deployments where the actual context window differs from the preset default.

§subagent_max_depth: usize

Maximum nesting depth for sub-agents and parallel workers. Read from RECURSIVE_SUBAGENT_MAX_DEPTH env var, defaults to 2.

§subagent_enabled: bool

Whether the unified Agent tool (sub-agent / team coordination) is registered. Enabled by default. To disable, set RECURSIVE_SUBAGENT_ENABLED=0 (or its alias RECURSIVE_TEAM_ENABLED=0). The coordinator guidance lives on the agent tool’s own description (not the system prompt), so disabling it fully removes both the tool and its token cost. Honoured uniformly by every agent-loop channel (CLI run / loop, HTTP API, TUI).

§allow_bypass_permissions: bool

When false (default), API callers who request "bypass" permission mode are silently downgraded to Default. Set to true via RECURSIVE_ALLOW_BYPASS_PERMISSIONS=1 to honour bypass requests.

§max_search_rounds: usize

Maximum number of ToolSearchTool round-trips per complete_with_search / stream_with_search call. Defaults to 3. Set via RECURSIVE_MAX_SEARCH_ROUNDS.

§stuck_window: usize

Number of recent steps to check for stuck detection. Default 10. Set via RECURSIVE_STUCK_WINDOW.

§stuck_error_rate: f64

Fraction of steps in the window that must be errors to declare “stuck”. Default 0.8. Set via RECURSIVE_STUCK_ERROR_RATE.

§max_concurrent_runs: usize

Maximum number of concurrent agent runs across all HTTP endpoints. 0 means unlimited. Defaults to 8. Set via RECURSIVE_MAX_CONCURRENT_RUNS env var.

§goal_eval_transcript_tail: usize

Number of most-recent transcript messages passed to the goal evaluator judge on each turn. Smaller values reduce judge cost; larger values give the judge more context for long sessions. Default 12. Set via RECURSIVE_GOAL_EVAL_TRANSCRIPT_TAIL env var. Goal-291.

§web_search_provider: Option<String>

Web search provider name (brave, tavily, serper, bocha, bing). Set via RECURSIVE_WEB_SEARCH_PROVIDER env var or [search] config.

§web_search_api_key: Option<String>

API key for the web search provider. Set via RECURSIVE_WEB_SEARCH_API_KEY env var or [search] config.

§web_search_jina_key: Option<String>

Jina AI Search API key for higher quota. Set via RECURSIVE_WEB_SEARCH_JINA_KEY env var or [search] config.

Implementations§

Source§

impl Config

Source

pub fn context_window_tokens(&self) -> usize

Return the effective context window size for the configured model.

Prefers context_window_override when set; otherwise falls back to the value from the bundled providers.toml via context_window_tokens_for_model.

Source

pub fn context_window_tokens_effective(&self) -> usize

Like [context_window_tokens] but resolves the per-model fallback from the effective catalog (remote cache + bundled + providers.d/) via [context_window_tokens_for_model_effective], so the TUI context gauge matches the /model picker’s displayed window instead of the stale compile-time providers.toml value. context_window_override still wins when set.

Source

pub fn context_window_tokens_effective_for(&self, model: &str) -> usize

Effective context window for an arbitrary model name, honouring a global context_window_override when set, else the effective catalog for model. Used by the TUI gauge both at startup (for the config-default model) and on a /model hot-swap, so the window tracks the newly active model instead of staying pinned to the startup value.

Source

pub fn from_env() -> Result<Self>

Load from environment, with config file (~/.recursive/config.toml) as fallback.

Precedence (highest first), applied to api_base / api_key / model / provider_type:

  1. env var (e.g. RECURSIVE_API_BASE, OPENAI_API_KEY)
  2. explicit field in the file’s [provider] section
  3. preset field — provider.preset = "<id>" looks up the preset in the effective catalog (bundled providers.toml + user overrides from ~/.recursive/providers.d/*.toml + remote cache) and takes its api_base / default_model / provider_type. For api_key, step 3 instead consults std::env::var(preset.key_env) (e.g. DEEPSEEK_API_KEY).
  4. hardcoded default

The api_key chain is asymmetric: the generic env vars in step 1 (RECURSIVE_API_KEY / OPENAI_API_KEY) rank above the file’s explicit api_key, but a preset’s specific env var in step 3 ranks below it. Inverting step 3 would silently override a user’s api_key = "sk-old" whenever DEEPSEEK_API_KEY happened to be in their shell.

The API key is optional here so commands that don’t need the LLM (e.g. tools, config) still run.

Source

pub fn require_api_key(&self) -> Result<&str>

Return the API key or a descriptive error if none was configured.

Source

pub fn validate_for_agent(&self) -> Result<(), String>

Validate that the config has enough information to run the agent. Returns a user-friendly error message if not.

Trait Implementations§

Source§

impl Clone for Config

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

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

Performs copy-assignment from source. Read more
Source§

impl Debug for Config

Source§

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

Formats the value using the given formatter. 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> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

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

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> IntoMaybeUndefined<T> for T

Source§

fn into_maybe_undefined(self) -> MaybeUndefined<T>

Converts this value into a three-state builder argument.
Source§

impl<T> IntoOption<T> for T

Source§

fn into_option(self) -> Option<T>

Converts this value into an optional builder argument.
Source§

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

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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 = !

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

fn try_from(value: U) -> Result<T, !>

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.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more