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: usizeMaximum agent loop iterations per turn/goal.
0 = unlimited (agent stops on NoMoreToolCalls, stuck, transcript limit, etc.).
max_tokens: u32Maximum 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):
RECURSIVE_MAX_TOKENSenv var (highest)- provider
ModelSpec.max_tokens/ config-fileagent.max_tokens 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: u64Wall-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: boolRun 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: usizeMaximum nesting depth for sub-agents and parallel workers.
Read from RECURSIVE_SUBAGENT_MAX_DEPTH env var, defaults to 2.
subagent_enabled: boolWhether 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: boolWhen 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: usizeMaximum number of ToolSearchTool round-trips per
complete_with_search / stream_with_search call.
Defaults to 3. Set via RECURSIVE_MAX_SEARCH_ROUNDS.
stuck_window: usizeNumber of recent steps to check for stuck detection. Default 10.
Set via RECURSIVE_STUCK_WINDOW.
stuck_error_rate: f64Fraction of steps in the window that must be errors to declare “stuck”.
Default 0.8. Set via RECURSIVE_STUCK_ERROR_RATE.
max_concurrent_runs: usizeMaximum 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: usizeNumber 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
impl Config
Sourcepub fn context_window_tokens(&self) -> usize
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.
Sourcepub fn context_window_tokens_effective(&self) -> usize
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.
Sourcepub fn context_window_tokens_effective_for(&self, model: &str) -> usize
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.
Sourcepub fn from_env() -> Result<Self>
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:
- env var (e.g.
RECURSIVE_API_BASE,OPENAI_API_KEY) - explicit field in the file’s
[provider]section - preset field —
provider.preset = "<id>"looks up the preset in the effective catalog (bundledproviders.toml+ user overrides from~/.recursive/providers.d/*.toml+ remote cache) and takes itsapi_base/default_model/provider_type. Forapi_key, step 3 instead consultsstd::env::var(preset.key_env)(e.g.DEEPSEEK_API_KEY). - 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.
Sourcepub fn require_api_key(&self) -> Result<&str>
pub fn require_api_key(&self) -> Result<&str>
Return the API key or a descriptive error if none was configured.
Sourcepub fn validate_for_agent(&self) -> Result<(), String>
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.