Configuration Reference: Octomind TOML Config Fields and Defaults
Use this reference when editing Octomind’s TOML configuration or diagnosing a load error, with every field and its default.
Use this reference when editing Octomind’s TOML configuration or diagnosing a load error, with every field and its default. It covers the complete shipped template, optional parsed fields, and model, role, tool, and supervisor settings.
Get started
octomind config
octomind config --show
octomind config --validateThe default path is ~/.local/share/octomind/config/config.toml on macOS/Linux and
%LOCALAPPDATA%\octomind\config\config.toml on Windows. See Environment Variables for
path and credential overrides. --show displays selected settings, not a complete TOML dump. Startup can create or
migrate configuration even for inspection commands. Use default.toml for the
complete starting file.
The tables below follow template order. “Default” means the value shipped in that template, not permission to omit a required key. Examples are fragments to merge into that complete file; replace an existing table instead of declaring it twice. Arrays of named entries require complete replacements when overriding a name.
Multi-File Configuration
Octomind supports split-file configuration. All *.toml files in the config directory are merged:
config.tomlis loaded first- Other
*.tomlfiles are loaded alphabetically - Tables deep-merge; arrays of tables concatenate; scalar arrays such as
allowed_toolsreplace - Array entries with the same
nameare deduplicated (the entire last entry wins; it is not a field patch) - Scalar values are overridden by later files
This allows organizing config by concern (e.g., mcp-github.toml, commands-custom.toml).
Special Case: mcp-*.toml Override Files
Files matching the pattern mcp-*.toml are loaded AFTER all other *.toml files, regardless of their alphabetical
position. This ensures they can reliably override same-named MCP servers defined in earlier files like mcp.toml.
Without this special handling, mcp.toml would lexicographically sort after mcp-github.toml and silently overwrite
any server overrides.
This mechanism is used by the model-callable mcp tool’s persist action, which writes to
<config_dir>/mcp-<name>.toml with auto_bind = ["<role>"] when enabled. Persisting a disabled server omits auto_bind;
it stays defined but is not automatically enabled on the next startup.
The selected OCTOMIND_CONFIG_PATH determines the directory to merge and the primary migration/save path; it does not
restrict loading to one file. The file literally named config.toml still sorts first. Ordinary mutations save to the
loaded path; config --upgrade and displayed path labels use the standard <data>/config/config.toml. If no TOML
exists, loading creates the embedded default config. Existing files must collectively supply required fields; they are
not automatically overlaid on the template.
For a split config, put the following in model-local.toml beside config.toml:
[model]
reasoning_effort = "high"octomind config --validateRoot-Level Settings
| Field | Type | Default | Description |
|---|---|---|---|
version | u32 | 22 | Config version. Do not modify. Used for automatic upgrades. |
log_level | string | "info" | Logging verbosity: "none", "info", "debug" |
default | string | "assistant:concierge" | Default tag for bare run, acp, and server. See note below. |
sandbox | bool | false | Restrict writes for run, acp, and server; those commands also accept --sandbox. |
telemetry | bool | true | Anonymous usage telemetry. Overridden per-run by OCTOMIND_TELEMETRY, and by DO_NOT_TRACK=1 before either. See Telemetry for the exact field list. |
commit_attribution | string | "Co-Authored-By: Octomind <[email protected]>" | Git trailer the agent appends to commits it writes, unless the user says otherwise about attribution. "" = no trailer and no system-prompt instruction. |
About the
defaultvalue:"assistant:concierge"is a tap agent addressed ascategory:variant, shipped by the built-in default tapmuvon/tap(which resolves to the GitHub repogithub.com/muvon/octomind-tap) — not a role defined in this config file. If you search this file for aconciergerole you will not find one. A bare tag without a colon (e.g."developer") resolves against your local[[roles]]; acategory:varianttag resolves against installed taps.
version = 26
log_level = "info"
default = "assistant:concierge"
sandbox = false
telemetry = true
commit_attribution = "Co-Authored-By: Octomind <[email protected]>"Performance & Limits
| Field | Type | Default | Description |
|---|---|---|---|
mcp_response_tokens_threshold | usize | 20000 | Hard limit on MCP response tokens. Responses truncated when exceeded. Also the shared per-prompt budget for ACP embedded text resources and file links. 0 = unlimited. |
max_session_tokens_threshold | usize | 300000 | Full-context safety limit, capped further by model window minus output reservation. 0 removes this configured limit, not the model ceiling. Maximum 2,000,000; unrecoverable overflow errors before a provider request. |
cache_keepalive_enabled | bool | false | Keep the prompt cache warm with pings while the session waits for a reply or a long tool run. Interval is 0.9 × the TTL of the newest cache marker (270s for the 5m conversation cache). Each ping is a cache pre-warm (max_tokens: 0, cache read only, no output). The ping count per wait is priced from model pricing and the session's own waits (replies, background work and tool runs learned separately), bounded by (cache_write − cache_read) / cache_read × tail share pings, by two pings until three waits of a kind are measured, and by the longest wait of that kind seen; a known scheduled wake is bridged when affordable. No ping is sent when the next request compresses or trims the conversation anyway, and a ping that misses the cache or is rate-limited stops the keepalive. /info reports the pings sent, their cost and the last budget. Only providers with a keepalive policy are pinged; through octohub: (>= 0.16.3) the hub pre-warms only the lane that served the conversation, when its provider has a policy. |
mcp_response_tokens_threshold = 20000
max_session_tokens_threshold = 300000
cache_keepalive_enabled = falseUser Interface
| Field | Type | Default | Description |
|---|---|---|---|
enable_markdown_rendering | bool | true | Pretty-print AI responses with markdown rendering. |
markdown_theme | string | "default" | Theme: "default", "dark", "light", "ocean", "solarized", "monokai" |
max_session_spending_threshold | f64 | 0.0 | USD spent since last accepted checkpoint; interactive CLI asks to continue, piped/ACP/WebSocket declines. 0.0 = no limit. |
max_request_spending_threshold | f64 | 0.0 | Request spending limit. Stops execution when exceeded. 0.0 = no limit. |
enable_markdown_rendering = true
markdown_theme = "default"
max_session_spending_threshold = 0.0
max_request_spending_threshold = 0.0Capability auto-activation
| Field | Type | Default | Description |
|---|---|---|---|
auto_capabilities | bool | true | Enable automatic capability activation on user messages. Disable to require manual capability(action="enable") calls. |
# Root keys must precede the first table header.
auto_capabilities = true[model]
The complete main model profile and inheritance baseline. Persistent role, supervisor, and compression profiles use the same fields; name-only tap/workflow overrides retain the inherited parameters.
| Field | Type | Default | Description |
|---|---|---|---|
name | string | "octohub:auto" | Provider-qualified model identifier |
reasoning_effort | enum | "medium" | "none", "low", "medium", "high", "xhigh", or "max". "none" requests no reasoning and switches thinking off where the provider has a switch (Alibaba, DeepSeek, Z.AI, OpenRouter, OpenAI); the default for [compression.model], whose output is a summary, not a decision |
max_tokens | u32 | 32768 | Maximum output tokens; 0 uses provider behavior |
temperature | f32 | 0.3 | Sampling temperature, 0.0-2.0 |
top_p | f32 | 0.7 | Nucleus sampling, 0.0-1.0 |
top_k | u32 | 20 | Top-k limit, 0-1000; 0 disables it |
max_retries | u32 | 1 | Provider retry attempts |
retry_timeout | u64 | 30 | Exponential-backoff base in seconds |
request_timeout_seconds | u64 | 300 | Total deadline per HTTP/WebSocket request attempt; 0 disables it |
stream_timeout_seconds | u64 | 0 | SSE/WebSocket response inactivity limit; 0 disables it; never extends the total deadline |
request_transport | enum | "websocket" | "websocket" or "http". Applies to octohub: and chatgpt: models only; other providers ignore it. Required in the file; the v26 migration adds it as "websocket" |
request_transport applies to every octohub: and chatgpt: model call, including supervisor and compression
calls that inherit it. Set request_transport = "http" to opt out. WebSocket errors do not silently fall back to
HTTP or replay a request. The library derives the Octohub WebSocket URL from the existing Octohub HTTP(S) base URL,
preserving private hosts and ports; no separate endpoint setting is required.
ChatGPT WebSocket calls: each received response event or ping/pong resets the inactivity timer; waiting for a session connection does not consume it. Connection setup has a separate deadline.
[model]
name = "octohub:auto"
reasoning_effort = "medium"
max_tokens = 32768
temperature = 0.3
top_p = 0.7
top_k = 20
max_retries = 1
retry_timeout = 30
request_timeout_seconds = 300
stream_timeout_seconds = 0
request_transport = "websocket"[capabilities]
Map of capability name to provider override. Used by tap agents to route specific capabilities to different providers.
[capabilities]
codesearch = "octocode" # uses capabilities/codesearch/octocode.tomlType: map of strings to strings; default {}. Each key maps to a provider TOML file within the tap's capabilities/
directory.
[taps]
String-to-string map, default {}, of tap agent tag to model name. It changes only name; all other parameters come
from the main profile before any independent role override.
[taps]
"developer:general" = "ollama:glm-5.3"
"assistant:concierge" = "openai:gpt-5.6-luna"Priority (highest wins): explicit runtime override > the active role's [roles.model] > the tap name mapping >
[model].
--modelCLI flag (if provided)- The
modelthe agent's role/manifest declares (fordeveloper:general, the manifest's role model) - Main
[model]profile — itsnameis replaced by the matching tap mapping when present
[taps] only applies to tap agents (tags with :). Plain roles resolve [roles.model] directly against [model].
[[roles]]
Define custom roles that override or extend tap-provided agents.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Role identifier (e.g., "developer", "assistant") |
system | string | yes | System prompt. Supports template variables. |
welcome | string | yes | Welcome message shown on session start. Supports template variables; use "" for no banner. |
The shipped role entries are below; the full default system strings are in the linked template. None of these four
entries declares a model override. system and welcome are required strings, with no generic default for a new role.
| Name | Default system purpose / welcome | Default server_refs | Default allowed_tools |
|---|---|---|---|
assistant | Helpful assistant with working directory; Hello! Ready to code. Working in {{CWD}} (Role: {{ROLE}}) | ["core", "orchestration", "runtime", "filesystem", "agent"] | ["core:*", "orchestration:*", "runtime:*", "filesystem:*", "agent:*"] |
task_refiner | Refine the real user request; "" welcome. | [] | [] |
task_researcher | Gather focused context; "" welcome. | ["filesystem"] | ["view"] |
reduce | Retain architectural history; "" welcome. | [] | [] |
[roles.model]
Optional partial model profile for the role: name (string), reasoning_effort (enum), max_tokens (u32),
temperature/top_p (f32), top_k/max_retries (u32), and retry_timeout/request_timeout_seconds (u64). Every
omitted field inherits its [model] value. The example below changes only name and effort.
[roles.mcp]
MCP configuration for the role. Omitting the whole table gives empty lists; if the table is present, both lists are required. The shipped values vary by role as shown above.
| Field | Type | Default | Description |
|---|---|---|---|
server_refs | string[] | [] | MCP server names to enable for this role |
allowed_tools | string[] | [] | Tool access patterns. Empty = all tools. Supports wildcards: "core:*", "filesystem:view" |
[[roles]]
name = "assistant"
system = """
You are helpful and knowledgeable assistant.
Working directory: {{CWD}}
"""
welcome = "Hello! Ready to code. Working in {{CWD}} (Role: {{ROLE}})"
[roles.model]
name = "openai:gpt-5.6-sol"
reasoning_effort = "high"
[roles.mcp]
server_refs = ["core", "orchestration", "runtime", "filesystem", "agent"]
allowed_tools = ["core:*", "orchestration:*", "runtime:*", "filesystem:*", "agent:*"][mcp]
Global MCP (Model Context Protocol) configuration.
| Field | Type | Default | Description |
|---|---|---|---|
allowed_tools | string[] | [] | Global tool filter; role merging replaces it with that role’s allowed_tools, including an empty list. |
[[mcp.servers]]
MCP server definitions. Three types supported: builtin, http, stdio.
Builtin servers (declared in the template; enabled through role references or exact auto_bind, no external
process):
| Server | Tools | Description |
|---|---|---|
core | recall (when attention or governance is enabled) | Session-memory retrieval; governance defaults on and planning is supervisor-internal |
orchestration | tap, schedule, monitor | Delegation, scheduled messages, and event-stream monitoring |
runtime | mcp, agent, skill, capability | Harness and tool-surface reconfiguration |
agent | agent_<name> per [[agents]] entry | ACP sub-agent dispatch |
filesystemis not declared here. It is an externalstdioserver backed by octofs and provided through tap capabilities. Tool availability comes from the installed external server./mcp fullshows the installed server's authoritative schemas.
Common server fields
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Unique server identifier |
type | string | yes | "builtin", "http", or "stdio" |
timeout_seconds | u64 | yes | Per-operation timeout; tool-call progress resets this idle deadline, and it holds while the user answers an MCP elicitation (template: 30) |
tools | string[] | yes | Tool filter. Empty = all tools. Supports wildcards such as "github_*". |
auto_bind | string[] | no; absent | Exact role/tag strings to auto-include this server for; developer does not match developer:general. |
HTTP server fields
| Field | Type | Required | Description |
|---|---|---|---|
url | string | yes | Server endpoint URL |
headers | string map | no; {} | Headers sent on every request. Values support {{ENV:KEY}} placeholders. A configured Authorization header disables OAuth discovery. |
Authentication: Configure a static
Authorizationheader for bearer tokens or API keys. Without one, Octomind uses MCP Authorization Discovery (RFC 9728), registers via CIMD/DCR, and authenticates using PKCE.
Stdio server fields
| Field | Type | Required | Description |
|---|---|---|---|
command | string | yes | Executable to run |
args | string[] | yes | Command arguments; use [] when none |
env | string map | no; {} | Child environment entries; values support {{ENV:KEY}} placeholders |
cwd | string | no; absent | Child working directory; omitted inherits Octomind's working directory (plugins may set their root) |
The template declares core, runtime, agent, and orchestration, each with type = "builtin", timeout_seconds = 30, and tools = []. HTTP/stdio entries are commented examples, not active defaults. Timeouts must be 1–3600 seconds.
Auto-bound servers also gain server_refs and, when restricted, a server:* allowance in the merged role. Executables
in .agents/tools/ form an additional dynamically registered local tool surface; they are not another template server
entry.
[mcp]
allowed_tools = []
[[mcp.servers]]
name = "search"
type = "http"
url = "http://localhost:9000/mcp"
headers = { Authorization = "Bearer {{ENV:MY_MCP_TOKEN}}" }
timeout_seconds = 30
tools = []
auto_bind = ["developer:general"]
[[mcp.servers]]
name = "files"
type = "stdio"
command = "octofs"
args = []
env = { PROJECT_LABEL = "demo" }
cwd = "."
timeout_seconds = 30
tools = []
auto_bind = ["developer:general"]The HTTP example needs your running endpoint and MY_MCP_TOKEN; the stdio example needs octofs installed. Inspect the
actual enabled surface inside a session:
/mcp full[[hooks]]
Webhook HTTP listeners that pipe payloads through scripts and inject output into sessions.
| Field | Type | Default | Description |
|---|---|---|---|
name | string | required | Unique hook identifier |
bind | string | required | HTTP server address (e.g., "0.0.0.0:9876") |
script | string | required | Path to executable script |
timeout | u64 | 30 | Script timeout in seconds (1-3600) |
[[hooks]]
name = "github-push"
bind = "0.0.0.0:9876"
script = "/tmp/octomind-hook.sh"
timeout = 30No hooks are active in the template. To try the example, create its script, add the TOML above, then launch and send a payload (the final command goes in another terminal):
printf '#!/bin/sh\ncat\n' > /tmp/octomind-hook.sh
chmod +x /tmp/octomind-hook.sh
echo "Wait for webhook messages" | octomind run --name hooks-demo --daemon --format jsonl --hook github-push
curl --data 'Summarize the current task status' http://127.0.0.1:9876/[[commands]]
Custom session commands triggered with /run <name>. Each entry delegates to a role over ACP — the actual model, system
prompt, and MCP configuration live in [[roles]], not here. name is the token you type after /run. See the field
table below, including the required input_mode / output_mode / output_role fields.
[[commands]]
name = "reduce"
description = "Compress session history for cost optimization during ongoing work"
command = "octomind acp reduce"
input_mode = "all"
output_mode = "replace"
output_role = "assistant"The template ships only the reduce command shown above. Run it inside an existing session:
/run reduceMulti-step AI workflows are no longer defined in this config. Use the external CLI:
octomind workflow <file.toml>— see doc/usage/09-workflows.md.
| Field | Type | Default | Description |
|---|---|---|---|
name | string | required | Command name, typed after /run |
description | string | required | Human-readable description (used in help, MCP) |
command | string | required | ACP command to execute: "octomind acp <role_name>" |
workdir | string | "." | Working directory (relative to session workdir). The only optional field. |
input_mode | string | required | How input is fed: "last", "all", "summary" |
output_mode | string | required | How output affects session: "none", "append", "replace", "last", "restart" |
output_role | string | required | Role for output messages: "assistant", "user" |
input_mode,output_mode, andoutput_rolehave no default — config loading fails if any is omitted. Onlyworkdiris optional.
[[agents]]
Specialized AI agents using ACP protocol. Each becomes an MCP tool (agent_<name>).
| Field | Type | Default | Description |
|---|---|---|---|
name | string | required | Agent identifier. Tool becomes agent_<name>. |
description | string | required | MCP tool description shown to the AI |
command | string | required | Shell command starting an ACP server over stdio |
workdir | string | "." | Working directory for subprocess |
[[agents]]
name = "context_gatherer"
description = "Gather detailed context from files and codebase."
command = "octomind acp task_researcher"
workdir = "."The template’s one agent is named context_gatherer, with workdir = "." and command octomind acp context_gatherer.
It does not define a matching context_gatherer role. The example above points the same tool at the shipped
task_researcher role; that role still needs an available filesystem server.
[[prompts]]
Reusable prompt templates accessible via /prompt <name>.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Prompt identifier |
description | string | no | Optional text shown in /prompt list |
prompt | string | yes | Prompt text injected into session |
[[prompts]]
name = "review"
description = "Request code review with focus on best practices"
prompt = """Please review the code above focusing on:
- Code quality and best practices
- Security considerations
- Performance implications"""The template ships review, explain, optimize, test, and debug, each with its own description and prompt text
in default.toml. There is no generic default for name or prompt;
description is absent when omitted. Text is injected verbatim, without variable substitution.
/prompt review[skills]
Automatic skill activation and validation.
| Field | Type | Default | Description |
|---|---|---|---|
auto_activation | bool | true | Enable declarative rule-based activation (checks on every user message) |
auto_validation | bool | false | Enable validate script execution at end of assistant turns |
activation_timeout | u64 | 3 | Reserved. Rules evaluate in-process (no timeout needed) |
validation_timeout | u64 | 60 | Seconds per validate script. 0 = unlimited |
max_retries | u32 | 3 | Max validation retries per skill before giving up |
[skills]
auto_activation = true
auto_validation = false
activation_timeout = 3
validation_timeout = 60
max_retries = 3
auto_validationscope: this flag gates only thevalidatescripts declared insideSKILL.mdfiles. It does not gate the separate guardrail[[validator]]system in.agents/guardrails.toml— those end-of-turn validators run unconditionally regardless of this setting.
[timing]
Per-person calibration of the human-time and energy estimate in /report. The defaults are starting guesses; see
Human Time and Energy for the model, its sources, and the calibration
procedure. Reading, review and typing speeds and the flag thresholds are fixed research values in
timing.rs, not config.
| Field | Type | Default | Description |
|---|---|---|---|
think_overhead_min | f64 | 1.5 | Thinking time added to every turn's reading + typing estimate, minutes |
deliberation_factor | f64 | 2.0 | Cap on active time before an input, as a multiple of the turn estimate |
attention_window_min | f64 | 30.0 | Minutes after your last input during which an agent run earns wait time |
review_weight | f64 | 2.0 | Energy per minute of reading code, relative to dialog, spec writing and behavior checks (weight 1) |
wait_weight | f64 | 0.25 | Energy per minute of attended waiting |
switch_cost_dhe | f64 | 0.05 | Energy cost of one switch between parallel sessions, DHE |
[timing]
think_overhead_min = 1.5
deliberation_factor = 2.0
attention_window_min = 30.0
review_weight = 2.0
wait_weight = 0.25
switch_cost_dhe = 0.05Configs from before schema version 20 gain this section on upgrade; values already present are kept.
[compression]
Automatic context compression system.
| Field | Type | Default | Description |
|---|---|---|---|
knowledge_retention | usize | 25 | Max critical knowledge entries retained across compressions |
analysis_findings_max_tokens | usize | 6000 | Hard token budget for retained analysis findings; 0 disables retention |
threshold | usize | 105000 | Baseline automatic compression trigger in tokens; 0 disables automatic checks, while /done can still force compression |
The automatic trigger adapts within a long turn: successive folds raise the baseline geometrically, capped under the
usable ceiling; a real user turn resets it. Compression may therefore wait beyond threshold.
Depth is computed, not configured. When compression becomes eligible, how deep each compression goes is derived per cycle from the measured session growth rate and the context ceiling — the lower of
max_session_tokens_threshold(see Performance & Limits) and the session model's usable window. The derived ratio always lands in [2.0, 16.0].
[compression.attention]
Optional PACT-style provenance and archive governance around compression.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Enable provenance-labelled causal evidence selection and rendering |
validator | bool | true | Reject optional compactions whose folded units have invalid attribution |
telemetry | bool | true | Persist a content-free compression decision record beside the lossless archive |
[compression.attention.governance]
| Field | Type | Default | Description |
|---|---|---|---|
enabled | bool | true | Preserve runtime-owned task pins and active frontier around compaction. |
verify_hash | bool | true | Check governance hashes before committing compaction. |
[compression.attention]
enabled = false
validator = true
telemetry = true
[compression.attention.governance]
enabled = true
verify_hash = trueKeep scalar [compression] keys before nested [compression.attention] and [compression.model] headers; TOML assigns
later scalars to the most recent nested table.
[compression.model]
Model used for compression decisions and summary generation.
| Field | Type | Default | Description |
|---|---|---|---|
name | string | "octohub:auto" | Compression model name |
reasoning_effort | enum | "none" | Thinking effort override; compression produces summaries rather than decisions, so the shipped default disables reasoning where supported |
max_tokens | u32 | 32000 | Max tokens for decision + summary |
temperature | f32 | 0.3 | Lower = more consistent decisions |
top_p | f32 | 1.0 | Nucleus sampling |
top_k | u32 | 0 | Top-k (0 = disabled) |
max_retries | u32 | 1 | Retry attempts |
retry_timeout | u64 | 30 | Retry backoff base (seconds) |
request_timeout_seconds | u64 | 300 | Total deadline per HTTP/WebSocket request attempt; 0 disables it |
stream_timeout_seconds | u64 | 0 | SSE/WebSocket response inactivity limit; 0 disables it; never extends the total deadline |
request_transport | enum | "websocket" | "websocket" or "http" (octohub and chatgpt only) |
[compression]
knowledge_retention = 25
analysis_findings_max_tokens = 6000
threshold = 105000
[compression.model]
name = "octohub:auto"
reasoning_effort = "none"
max_tokens = 32000
temperature = 0.3
top_p = 1.0
top_k = 0
max_retries = 1
retry_timeout = 30
request_timeout_seconds = 300[decision]
Calibrated decisions use a provider-qualified model for selected routing and evaluation seams. The model gets one
attempt with a five-second timeout and no retries. An absent or empty model disables this routing. If a decision answer
is unavailable, supervisor decisions fail closed; writing still uses the shared [supervisor.model] profile. Configure
the credential required by the selected provider: CLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID, TYPESAFE_API_KEY,
or OCTOHUB_API_KEY (and optionally OCTOHUB_API_URL).
| Field | Type | Default | Description |
|---|---|---|---|
model | optional string | "cloudflare:typesafe/jev" | Provider-qualified decision model; absent or empty disables routing. |
recall | bool | false | Filter recalled scoped lessons for relevance. If unavailable, keep the candidates. |
skills | bool | false | Choose an inactive skill when rules abstain. If unavailable, activate none. |
capabilities | bool | false | Confirm or promote capability selection. If unavailable, keep the cosine result. |
compression | bool | false | Demote unneeded summarize packets before a fold. If unavailable, keep the lanes. |
supervisor | bool | false | Route supervisor decisions and evolution grading through this model. |
[decision]
model = "cloudflare:typesafe/jev"
recall = false
skills = false
capabilities = false
compression = false
supervisor = false[supervisor]
The out-of-band control plane around the agent loop. It hosts learning (distill + recall + orientation memory),
deterministic detectors, the verify-gate, the external plan manager, and condense. See the Supervisor
guide for how the mechanics fit together. Strict: the [supervisor] section and its
required keys must be present — a missing section or key is a hard parse error, not a silent default.
When the supervisor is active, deterministic detectors, goal recitation, and check-after-mutation pre-gates use fixed
internal thresholds. The enabled switches below control their respective model-driven mechanics. Detector hints are
advisory; max_identical_rounds is the one hard stop.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | bool | true | Master switch for the whole control plane |
max_identical_rounds | usize | 10 | End the turn when this many tool rounds in a row repeat calls and results already seen since the last new result (the previous round again, or a cycle through a few). The turn's final answer becomes a notice naming the repeated call and its result, with no further model request and no verify-gate re-run. 0 = off. Needs enabled |
[supervisor.model]
Optional partial profile shared by every supervisor mechanic: authorizer, gate, resolve, plan, condense, extraction, recall,
retention, verification, and evolution. It accepts every field from [model]; omitted fields inherit main. Omitting the
entire block uses [model] unchanged.
| Field | Type | Template default | Meaning |
|---|---|---|---|
name | string | "octohub:auto" | Shared supervisor model. |
reasoning_effort | enum | "medium" | Reasoning effort hint. |
max_tokens | u32 | 8192 | Output token ceiling. |
temperature | f32 | 0.0 | Sampling temperature. |
top_p | f32 | 1.0 | Nucleus sampling. |
top_k | u32 | 0 | Top-k sampling; disabled at zero. |
max_retries | u32 | 1 | Retry attempts. |
retry_timeout | u64 | 30 | Backoff base in seconds. |
request_timeout_seconds | u64 | 300 | Total deadline per HTTP/WebSocket request attempt; 0 disables it |
stream_timeout_seconds | u64 | 0 | SSE/WebSocket response inactivity limit; 0 disables it; never extends the total deadline |
request_transport | enum | "websocket" | "websocket" or "http" (octohub and chatgpt only) |
[supervisor.hindsight]
An optional, local verifier scores the session event trace when the agent hands a turn back. It estimates whether the
user's next turn will be a correction and, if so, its class. This is observe-only: scores are logged, shown in a
supervisor notice, tallied in /info, and appended to hindsight.jsonl beside the verify-gate verdict.
Hindsight inference is shared across Octomind processes using the same runtime directory.
An automatically started worker owns the model; client processes keep no Hindsight weights.
The worker exits after 15 minutes without clients. The hidden hindsight-worker command is
internal and should not be launched manually. On macOS, Octolib reuses CoreML compiled-model
cache entries; Linux and Windows retain their existing execution-provider selection.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Enable observe-only hindsight scoring. |
model | string | "muvon/hindsight" | Hugging Face repository containing files under onnx/, or a local export directory. Set HF_TOKEN for a private Hugging Face repository. |
[supervisor.hindsight]
enabled = false
model = "muvon/hindsight"[supervisor.advise]
An optional, model-written steer note. On a loop or recovery alarm, one shared supervisor-model call reads the request,
the last tool receipts, and any stuck-keyed experience records, and answers with a short observation that cites a
receipt (#N). It never gives a command or code, and it may skip, in which case the plain note goes out. One in four
eligible alarms is a control that gets the plain note. Every alarm is appended to advise.jsonl in the data directory
with the gate verdict that followed. With [decision] supervisor = true, an observe-only usefulness score is logged
beside it. See the Supervisor guide.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Enable model-written advice on loop and recovery alarms. |
[supervisor.advise]
enabled = false[supervisor.learning]
Cross-session adaptive learning. Extracts lessons and orientation memory (durable subject understanding, recalled as working assumptions to verify) from sessions and injects them into future sessions. See Learning Guide for full details.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | bool | true | Enable the learning system (lessons + orientation) |
[supervisor.learning.evolution]
Optional grounded behavior evolution. When enabled, newly stored quote-backed rules and verified experiences may produce
scoped native skill or guardrail candidates. Synthesis and admission both use the single [supervisor.model] profile,
which must support structured output. A trial randomizes each session into a control arm (trigger observed, behavior
not applied) or a treatment arm, so both arms run concurrently; it is promoted only when the treatment beats that
control by more than the noise margin and by more than 2.5 posterior standard deviations, at an acceptable API-call
cost; see Learning.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Enable detached candidate synthesis and lifecycle-managed trials |
min_samples | integer | 10 | Verify-gate verdicts in the shadow screen, then in each concurrent arm, before comparison |
noise_margin | float | 0.15 | Smallest pass-rate gain worth promoting; also the non-inferiority bound for a cheaper behavior |
cost_allowance | float | 0.10 | Relative API-call increase tolerated at negligible gain; also the saving that promotes at an unchanged pass rate |
cost_per_gain | float | 2.0 | Extra relative API-call increase allowed per unit of pass-rate gain |
max_trial_uses | integer | 40 | Live uses after which an undecided trial retires as inconclusive |
[supervisor.gate]
Verify-gate on every turn stop: a done claim, or a blocked/need_input hand-back checked for being genuine. Free
deterministic pre-gates run first (no model call); the LLM checklist runs
only if those pass.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | bool | true | Enable the verify-gate |
unsettled_advisory | bool | true | Offer one nonblocking evidence advisory per genuine user turn, then re-gate normally |
The advisory names every remaining unsettled condition. With gate evaluation enabled, a calibrated check removes conditions whose specific case a recorded action exercised (probability at least 0.5 in any evidence slice). Refused answers, unavailable evaluation, or disabled evaluation keep the conditions. Repeated uncertainty does not send another advisory within the same turn, and it never certifies success or becomes a blocking failure. Matched findings missing a verbatim citation receive one bounded protocol repair before any advisory decision; this shares the existing format-repair budget.
With [decision] supervisor = true, a working-tree diff larger than the gate's size cut is not cut by size: the evaluation
model scores every hunk in batched windows, as the condense seam scores tool-output chunks, and the verifier reads in full
the hunks the request's conditions depend on (the work itself and the checks produced for it), bounded by what the
verifier model's input window leaves. The rest become one-line stubs naming the hunk and marked unseen, so the verifier
knows they exist and does not read them as absent changes. An unavailable or empty answer falls back to the size cut. The
second-opinion refutation reads evidence over the evaluation state cap in slices and drops a finding any slice refutes.
[supervisor.authorizer]
Checks exact proposed tool operations against role + user intent after native pre-call guards and before execution.
Uses [supervisor.model]; uncertain or unavailable decisions allow calls. A block requires grounded source/argument
evidence and independent confirmation by the same shared model. Requires the supervisor master switch for root sessions.
Inherited delegation constraints remain enforced in child sessions. See Tool authorization.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Enable user-intent tool authorization |
[supervisor.plan]
Adaptive external plan manager. The specialist has no plan mutation tool; a sparse hidden signal emitted alongside real work wakes this manager only when planning or a transition is needed.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | bool | true | Enable adaptive external planning |
[supervisor.condense]
Task-aware narrowing of oversized plain-text tool outputs. A result whose own output exceeds tokens_threshold becomes
a candidate; smaller results in the same round are passed through untouched and never shown to the condenser. One shared
supervisor-model call per round selects, by original line ranges over a bounded query/diagnostic-aware view, what the
current task needs; kept lines are reconstructed verbatim, and irrelevant results get deterministic notices rather than
model-authored summaries. Full originals are spilled to session files first when the active role can read them back. The
mcp_response_tokens_threshold prefix-cut is applied before condensation.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | bool | true | Enable condensation |
adaptive | bool | false | Adapt a process-local multiplier from realized savings, bounded to 0.5x–2.0x of the configured baseline |
tokens_threshold | usize | 5000 | Per-result trigger (estimated tokens of that single result); 0 = off. Keep well below mcp_response_tokens_threshold |
[supervisor]
enabled = true
max_identical_rounds = 10
[supervisor.model]
name = "octohub:auto"
reasoning_effort = "medium"
max_tokens = 8192
temperature = 0.0
top_p = 1.0
top_k = 0
max_retries = 1
retry_timeout = 30
request_timeout_seconds = 300
[supervisor.hindsight]
enabled = false
model = "muvon/hindsight"
[supervisor.advise]
enabled = false
[supervisor.learning]
enabled = true
[supervisor.learning.evolution]
enabled = false
min_samples = 10
noise_margin = 0.15
cost_allowance = 0.10
cost_per_gain = 2.0
max_trial_uses = 40
[supervisor.gate]
enabled = true
[supervisor.authorizer]
enabled = false
[supervisor.plan]
enabled = true
[supervisor.condense]
enabled = true
adaptive = false
tokens_threshold = 5000Parsed fields absent from active template settings
These are accepted configuration surfaces, not additional shipped defaults. Runtime-only role_map,
runtime_output_mode, working_directory, and config_path are skipped by serde and cannot be set in TOML.
| Path | Type | Omitted behavior | Meaning |
|---|---|---|---|
Root system | optional string | Absent | Legacy serialized prompt; session prompts still come from roles. Mentioned only in template comments; place it before any table. |
roles.model | partial profile or model string | Inherit main profile | All nine [model] fields are accepted; the template roles omit it. |
roles.temperature, roles.top_p, roles.top_k | optional f32, f32, u32 | Inherit main | Legacy flat sampling input; nested model values win and new serialization uses the nested profile. |
mcp.servers.auto_bind | optional string array | No automatic binding | Exact-match role/tag activation. |
Stdio mcp.servers.env | string map | {} | Child environment overrides. |
Stdio mcp.servers.cwd | optional string | Inherit working directory | Child process directory. |
commands.workdir | string | "." | Execution directory relative to session workdir. |
Legacy compression.decision | partial profile | Used only if compression.model is absent | Load normalization maps it to [compression.model]; a nested model string becomes name. |
| Legacy flat model fields on root/role/supervisor | Same eight parameter types as [model] | Fill nested-profile gaps | reasoning_effort, max_tokens, temperature, top_p, top_k, max_retries, retry_timeout, request_timeout_seconds. |
Legacy supervisor.learning.model and flat model parameters | Ignored | Removed during normalization | Learning uses the shared supervisor profile. |
registry.cache_ttl_hours | u64 | 24 | Manifest refresh interval, described below. |
The root model string and historical flat model parameters are migration/normalization inputs, not the version-12
output format; use [model]. The ProvidersConfig/OpenRouterConfig compatibility types in src/config/providers.rs
are not fields of the loaded Config; they do not enable TOML credential storage.
[registry]
Controls caching of agent manifests fetched from taps. Registry sources themselves are managed with octomind tap <user/repo> [path] and octomind untap <user/repo>.
| Field | Type | Default | Description |
|---|---|---|---|
cache_ttl_hours | u64 | 24 | How long a fetched tap manifest is cached before re-checking. |
Fetched manifests are cached at <data>/agents/<category>/<variant>.toml. Within the TTL the cached manifest is served
immediately; once stale, the cached copy is still served (stale-serve) while a background refresh fetches the latest
version. See Tap System for the registry behavior.
[registry]
cache_ttl_hours = 24Guardrails (.agents/guardrails.toml)
This separate project file is parsed by src/config/guardrails.rs; none of these keys belongs in the main config. Each
table is an optional array, defaulting to empty. The complete operating guide and script examples are in
Guardrails.
| Table | Required keys (string) | Optional keys (type; default) | Meaning |
|---|---|---|---|
[[pipe]] | name, command | match (regex string; absent), when (first/any; any), roles (string array; []) | Transform input before the model. |
[[guard]] | match, message | has (string or string array; []), when (string array; []) | Deny matching tool calls subject to capability/history conditions. |
[[hook]] | script | match (target string; absent), result (regex string; absent), on (success/error/any; any) | Process tool results. |
[[validator]] | name, script | match (final-message regex string; absent), when (string array; []), roles (string array; []) | Validate assistant turns. |
when conditions on guards/validators use +target (used) or -target (not used). Role filters here accept an exact
tag or domain prefix. Main-config MCP auto_bind remains exact-match only. Project [[hook]] is distinct from the
main-config HTTP listener [[hooks]].
# .agents/guardrails.toml
[[guard]]
match = 'shell(command=^rm\s+-rf)'
message = "Recursive force deletion is blocked in this project."Template Variables
These variables are substituted in role system and welcome fields at prompt-expansion time:
| Variable | Description |
|---|---|
{{CWD}} | Current working directory |
{{ROLE}} | Active role name |
{{DATE}} | Current date |
{{SHELL}} | User's shell |
{{OS}} | Operating system |
{{BINARIES}} | Available binary tools |
{{GIT_STATUS}} | Git repository status |
{{GIT_TREE}} | Project file tree |
{{README}} | Contents of README.md in project root |
{{CONTEXT}} | Project context bundle (README, Git status, tracked tree) |
{{SYSTEM}} | Current system information (shell, OS, working directory, binaries) |
{{HOME}}is not substituted here. It is only resolved by theoctomind varscommand listing, not insystem/welcomeprompts. Using{{HOME}}in a role prompt leaves the literal text in place — use an absolute path or{{CWD}}instead.
octomind vars --preview[[roles]]
name = "brief"
system = "Answer briefly. Working directory: {{CWD}}. Role: {{ROLE}}."
welcome = "Ready in {{CWD}}"
[roles.mcp]
server_refs = []
allowed_tools = []octomind run briefCommon questions
- Why did an override lose fields? Same-name array entries replace the entire earlier entry. Copy the
complete role/server/command before changing it; scalar tables such as
[model]deep-merge instead. - Why is a tool missing? Check role
server_refs, exactauto_bindtags, servertools, and roleallowed_tools, then inspect/mcp full. A template role reference does not install an external server. - Why is a compression setting ignored? Root compression keys must precede its nested table headers.
Use
[compression.model];[compression.decision]is only a legacy load alias when the current table is absent. - Why did validation reject a short config? Existing configs are strict, not sparse overlays on built-in defaults. Start from the complete template, then split it if needed.
Source map
Defaults and long prompt strings: default.toml. Loading and merging: loading.rs, merge.rs. Schemas: config/mod.rs, model.rs, roles.rs, mcp.rs, layer_trait.rs, supervisor/mod.rs.