nanobot configuration and environment-variable index
Corresponding source
| Control surface | Source |
|---|---|
| Configuration paths and loading | nanobot/config/paths.py, nanobot/config/loader.py::load_config |
| Environment-variable expansion | nanobot/config/loader.py::resolve_config_env_vars |
| Fields, defaults, and validation | nanobot/config/schema.py |
| Agent/Runner behavior | nanobot/agent/loop.py, nanobot/agent/runner.py |
| Provider, Tool, and Channel readers | nanobot/providers/, nanobot/agent/tools/, nanobot/channels/ |
This page includes only the control points most useful while learning the source and debugging. For complete configuration fields, Providers, and Channels, consult the official configuration documentation and nanobot/config/schema.py.
1. Where configuration comes from
flowchart LR F["Configuration file"] --> L["load_config()"] L --> P["Pydantic Config"] P --> E["resolve_config_env_vars()"] E --> R["Provider / AgentLoop / Gateway / Tools"]
Key source:
nanobot/config/paths.py: configuration and workspace paths;nanobot/config/loader.py::load_config: reading and parsing;nanobot/config/loader.py::resolve_config_env_vars: recursive replacement of${VAR}within strings;nanobot/config/schema.py: fields, defaults, aliases, and validation.
Never print a key in logs or notes
Configuration can use
"apiKey": "${DEEPSEEK_API_KEY}". Parsing fails if the variable does not exist. During diagnosis, check only whether the variable exists—never output its value.
2. Default Agent behavior
Configuration paths below use their serialized camelCase names.
| Configuration path | Default | Control boundary | Primary reader |
|---|---|---|---|
agents.defaults.workspace | ~/.nanobot/workspace | Work root for Sessions, Memory, Skills, and file Tools | AgentDefaults, runtime assembly |
agents.defaults.modelPreset | null | When set, use the named preset first | nanobot/agent/model_presets.py |
agents.defaults.model | anthropic/claude-opus-4-5 | Default model when no preset is active | Provider snapshot construction |
agents.defaults.provider | auto | Explicit Provider or automatic detection | nanobot/providers/factory.py |
agents.defaults.maxTokens | 8192 | Maximum output for one generation | generation settings |
agents.defaults.contextWindowTokens | 200000 | Context budget and compaction decisions | Context and compaction |
agents.defaults.maxToolIterations | 200 | Runner model–Tool iteration limit | AgentRunner |
agents.defaults.maxConcurrentSubagents | 1 | Concurrent Subagents in one runtime | Subagent manager |
agents.defaults.maxToolResultChars | 16000 | Character limit for a Tool result fed back to the model | Runner Tool-result handling |
agents.defaults.providerRetryMode | standard | Standard or persistent retry policy | Provider call boundary |
agents.defaults.reasoningEffort | null | Passed to Providers that support it | generation settings |
agents.defaults.timezone | UTC | Timezone semantics for Cron, time prompts, and related behavior | Loop and Cron |
agents.defaults.unifiedSession | false | Whether Channels share a Session | nanobot/session/keys.py |
agents.defaults.disabledSkills | [] | Skills that must not load | SkillsLoader |
agents.defaults.idleCompactAfterMinutes | 15 | Idle delay before compaction is allowed; 0 disables it | AgentLoop |
agents.defaults.maxMessages | 120 | Replay-history record limit; 0 still uses the default 120 | Session and Context |
agents.defaults.consolidationRatio | 0.5 | Target retained-budget ratio after compaction | Consolidator |
agents.defaults.dream.enabled | true | Whether to register the periodic Dream task | Dream and Gateway |
agents.defaults.dream.intervalH | 2 | Default Dream interval | DreamConfig.build_schedule() |
3. Models and Providers
| Configuration area | Purpose |
|---|---|
modelPresets.<name> | Named combination of model, provider, maxTokens, contextWindowTokens, temperature, and reasoningEffort |
providers.<name>.apiKey | Provider credential; may reference ${VAR} |
providers.<name>.apiBase | Custom service URL |
providers.<name>.extraHeaders | Additional HTTP headers |
providers.<name>.extraBody | Additional request body |
providers.<name>.extraQuery | Additional query parameters |
providers.openai.apiType | auto, chat_completions, or responses; currently accepted only for the built-in OpenAI configuration |
DeepSeek’s registration facts are in nanobot/providers/registry.py:
Provider name: deepseek
Default credential environment variable: DEEPSEEK_API_KEYRead the registry for other Providers’ keys and default endpoints; do not infer them from names:
rg -n "ProviderSpec|env_key=|api_base=" nanobot/providers/registry.py4. Tools, security, and MCP
| Configuration path | Purpose | Note |
|---|---|---|
tools.restrictToWorkspace | Expresses an application-level workspace restriction | Does not automatically provide an OS sandbox |
tools.exec.* | Shell execution, timeout, path, and sandbox settings | Treat nanobot/agent/tools/shell.py::ExecToolConfig as authoritative |
tools.file.* | File Tool settings | Treat nanobot/agent/tools/filesystem.py::FileToolsConfig as authoritative |
tools.web.* | Search and fetch settings | Treat nanobot/agent/tools/web.py::WebToolsConfig as authoritative |
tools.mcpServers.<name> | stdio, SSE, or Streamable HTTP MCP connection | See below |
tools.ssrfWhitelist | CIDRs allowed to bypass SSRF blocking | Add only an explicitly trusted range |
tools.webuiAllowLocalServiceAccess | Whether WebUI Full Access may inspect localhost services | Do not interpret this as disabling SSRF globally |
Core fields for one MCP server:
| Field | Meaning |
|---|---|
type | stdio, sse, or streamableHttp; inferred when omitted |
command, args, env, cwd | stdio process |
url, headers | network transport |
toolTimeout | Timeout for one MCP Tool; 30 seconds by default |
enabledTools | Tools that may register; ["*"] means all and [] means none |
5. Channels, API, and Gateway
| Configuration path | Default | Meaning |
|---|---|---|
channels.sendProgress | true | Whether to send text progress to Channels |
channels.sendToolHints | false | Whether to send Tool hints |
channels.showReasoning | true | Whether to show reasoning when a Channel supports it |
channels.extractDocumentText | true | Whether to pre-extract text from document attachments |
channels.sendMaxRetries | 3 | Total delivery attempts, including the first |
channels.<name>.* | Defined by each Channel | ChannelsConfig accepts extra fields |
api.host / api.port | 127.0.0.1 / 8900 | OpenAI-compatible API |
api.timeout | 120.0 | Timeout in seconds for each API request |
gateway.host / gateway.port | 127.0.0.1 / 18790 | Gateway and WebUI service |
gateway.heartbeat.* | See HeartbeatConfig | Heartbeat enablement, interval, and retained-message count |
6. Most important environment variables for debugging
| Environment variable | Default or semantics | Reader |
|---|---|---|
DEEPSEEK_API_KEY | DeepSeek credential | Provider registry and configuration resolution |
NANOBOT_MAX_CONCURRENT_REQUESTS | Defaults to 3; <=0 removes the global concurrency limit | nanobot/agent/loop.py |
NANOBOT_LLM_TIMEOUT_S | Defaults to 300 seconds; 0 disables the Runner’s outer LLM wall timeout | nanobot/agent/runner.py |
NANOBOT_STREAM_IDLE_TIMEOUT_S | Defaults to 90 seconds, maximum 3600; invalid or non-positive values fall back to the default | nanobot/providers/base.py |
NANOBOT_OPENAI_COMPAT_TIMEOUT_S | Defaults to 120 seconds; invalid or non-positive values fall back to the default | nanobot/providers/openai_compat_provider.py |
NANOBOT_WORKSPACE_SANDBOX_PROVIDER | Records or selects workspace-sandbox Provider semantics | nanobot/security/workspace_access.py |
NANOBOT_WORKSPACE_SANDBOX_ENFORCED | Marks whether the sandbox is enforced | Same as above |
NANOBOT_SANDBOX_ENFORCED | Compatibility environment marker | Same as above |
Three “timeouts” belong to different layers
api.timeoutgoverns an HTTP request,NANOBOT_LLM_TIMEOUT_Sgoverns the Runner’s model-wait boundary, andNANOBOT_STREAM_IDLE_TIMEOUT_Sgoverns an idle pause after streaming has begun. Identify the layer that raised the error before diagnosing it.
7. When configuration appears ineffective
Check in this order:
- Which configuration path did the running process actually load?
- Does the schema accept the field name, and is its alias correct?
- Does
${VAR}exist in the launching process’s environment? - Does
modelPresetoverride the individual model or Provider fields? - Does Gateway require a restart or runtime refresh?
- Did you change a global Channel field or one Channel’s override?
- Do the active Provider and model in logs match your expectation?
Return to Quick reference.