Skip to content

Latest commit

 

History

History
653 lines (491 loc) · 27.3 KB

File metadata and controls

653 lines (491 loc) · 27.3 KB

ZeroBuild Config Reference (Operator-Oriented)

This is a high-signal reference for common config sections and defaults.

Last verified: February 21, 2026.

Config path resolution at startup:

  1. ZEROBUILD_WORKSPACE override (if set)
  2. persisted ~/.zerobuild/active_workspace.toml marker (if present)
  3. default ~/.zerobuild/config.toml

ZeroBuild logs the resolved config on startup at INFO level:

  • Config loaded with fields: path, workspace, source, initialized

Schema export command:

  • zerobuild config schema (prints JSON Schema draft 2020-12 to stdout)

Core Keys

Key Default Notes
default_provider openrouter provider ID or alias
default_model anthropic/claude-sonnet-4-6 model routed through selected provider
default_temperature 0.7 model temperature

[observability]

Key Default Purpose
backend none Observability backend: none, noop, log, prometheus, otel, opentelemetry, or otlp
otel_endpoint http://localhost:4318 OTLP HTTP endpoint used when backend is otel
otel_service_name zerobuild Service name emitted to OTLP collector
runtime_trace_mode none Runtime trace storage mode: none, rolling, or full
runtime_trace_path state/runtime-trace.jsonl Runtime trace JSONL path (relative to workspace unless absolute)
runtime_trace_max_entries 200 Maximum retained events when runtime_trace_mode = "rolling"

Notes:

  • backend = "otel" uses OTLP HTTP export with a blocking exporter client so spans and metrics can be emitted safely from non-Tokio contexts.
  • Alias values opentelemetry and otlp map to the same OTel backend.
  • Runtime traces are intended for debugging tool-call failures and malformed model tool payloads. They can contain model output text, so keep this disabled by default on shared hosts.
  • Query runtime traces with:
    • zerobuild doctor traces --limit 20
    • zerobuild doctor traces --event tool_call_result --contains \"error\"
    • zerobuild doctor traces --id <trace-id>

Example:

[observability]
backend = "otel"
otel_endpoint = "http://localhost:4318"
otel_service_name = "zerobuild"
runtime_trace_mode = "rolling"
runtime_trace_path = "state/runtime-trace.jsonl"
runtime_trace_max_entries = 200

Environment Provider Overrides

Provider selection can also be controlled by environment variables. Precedence is:

  1. ZEROBUILD_PROVIDER (explicit override, always wins when non-empty)
  2. PROVIDER (legacy fallback, only applied when config provider is unset or still openrouter)
  3. default_provider in config.toml

Operational note for container users:

  • If your config.toml sets an explicit custom provider like custom:https://.../v1, a default PROVIDER=openrouter from Docker/container env will no longer replace it.
  • Use ZEROBUILD_PROVIDER when you intentionally want runtime env to override a non-default configured provider.

[agent]

Key Default Purpose
compact_context false When true: bootstrap_max_chars=6000, rag_chunk_limit=2. Use for 13B or smaller models
max_tool_iterations 10 Maximum tool-call loop turns per user message across CLI, gateway, and channels
max_history_messages 50 Maximum conversation history messages retained per session
parallel_tools false Enable parallel tool execution within a single iteration
tool_dispatcher auto Tool dispatch strategy

Notes:

  • Setting max_tool_iterations = 0 falls back to safe default 10.
  • If a channel message exceeds this value, the runtime returns: Agent exceeded maximum tool iterations (<value>).
  • In CLI, gateway, and channel tool loops, multiple independent tool calls are executed concurrently by default when the pending calls do not require approval gating; result order remains stable.
  • parallel_tools applies to the Agent::turn() API surface. It does not gate the runtime loop used by CLI, gateway, or channel handlers.

[security.otp]

Key Default Purpose
enabled false Enable OTP gating for sensitive actions/domains
method totp OTP method (totp, pairing, cli-prompt)
token_ttl_secs 30 TOTP time-step window in seconds
cache_valid_secs 300 Cache window for recently validated OTP codes
gated_actions ["shell","file_write","browser_open","browser","memory_forget"] Tool actions protected by OTP
gated_domains [] Explicit domain patterns requiring OTP (*.example.com, login.example.com)
gated_domain_categories [] Domain preset categories (banking, medical, government, identity_providers)

Notes:

  • Domain patterns support wildcard *.
  • Category presets expand to curated domain sets during validation.
  • Invalid domain globs or unknown categories fail fast at startup.
  • When enabled = true and no OTP secret exists, ZeroBuild generates one and prints an enrollment URI once.

Example:

[security.otp]
enabled = true
method = "totp"
token_ttl_secs = 30
cache_valid_secs = 300
gated_actions = ["shell", "browser_open"]
gated_domains = ["*.chase.com", "accounts.google.com"]
gated_domain_categories = ["banking"]

[security.estop]

Key Default Purpose
enabled false Enable emergency-stop state machine and CLI
state_file ~/.zerobuild/estop-state.json Persistent estop state path
require_otp_to_resume true Require OTP validation before resume operations

Notes:

  • Estop state is persisted atomically and reloaded on startup.
  • Corrupted/unreadable estop state falls back to fail-closed kill_all.
  • Use CLI command zerobuild estop to engage and zerobuild estop resume to clear levels.

[agents.<name>]

Delegate sub-agent configurations. Each key under [agents] defines a named sub-agent that the primary agent can delegate to.

Key Default Purpose
provider required Provider name (e.g. "ollama", "openrouter", "anthropic")
model required Model name for the sub-agent
system_prompt unset Optional system prompt override for the sub-agent
api_key unset Optional API key override (stored encrypted when secrets.encrypt = true)
temperature unset Temperature override for the sub-agent
max_depth 3 Max recursion depth for nested delegation
agentic false Enable multi-turn tool-call loop mode for the sub-agent
allowed_tools [] Tool allowlist for agentic mode
max_iterations 10 Max tool-call iterations for agentic mode

Notes:

  • agentic = false preserves existing single prompt→response delegate behavior.
  • agentic = true requires at least one matching entry in allowed_tools.
  • The delegate tool is excluded from sub-agent allowlists to prevent re-entrant delegation loops.
[agents.researcher]
provider = "openrouter"
model = "anthropic/claude-sonnet-4-6"
system_prompt = "You are a research assistant."
max_depth = 2
agentic = true
allowed_tools = ["web_search", "http_request", "file_read"]
max_iterations = 8

[agents.coder]
provider = "ollama"
model = "qwen2.5-coder:32b"
temperature = 0.2

[runtime]

Key Default Purpose
reasoning_enabled unset (None) Global reasoning/thinking override for providers that support explicit controls

Notes:

  • reasoning_enabled = false explicitly disables provider-side reasoning for supported providers (currently ollama, via request field think: false).
  • reasoning_enabled = true explicitly requests reasoning for supported providers (think: true on ollama).
  • Unset keeps provider defaults.

[skills]

Key Default Purpose
open_skills_enabled false Opt-in loading/sync of community open-skills repository
open_skills_dir unset Optional local path for open-skills (defaults to $HOME/open-skills when enabled)
prompt_injection_mode full Skill prompt verbosity: full (inline instructions/tools) or compact (name/description/location only)

Notes:

  • Security-first default: ZeroBuild does not clone or sync open-skills unless open_skills_enabled = true.
  • Environment overrides:
    • ZEROBUILD_OPEN_SKILLS_ENABLED accepts 1/0, true/false, yes/no, on/off.
    • ZEROBUILD_OPEN_SKILLS_DIR overrides the repository path when non-empty.
    • ZEROBUILD_SKILLS_PROMPT_MODE accepts full or compact.
  • Precedence for enable flag: ZEROBUILD_OPEN_SKILLS_ENABLEDskills.open_skills_enabled in config.toml → default false.
  • prompt_injection_mode = "compact" is recommended on low-context local models to reduce startup prompt size while keeping skill files available on demand.
  • Skill loading and zerobuild skills install both apply a static security audit. Skills that contain symlinks, script-like files, high-risk shell payload snippets, or unsafe markdown link traversal are rejected.

[composio]

Key Default Purpose
enabled false Enable Composio managed OAuth tools
api_key unset Composio API key used by the composio tool
entity_id default Default user_id sent on connect/execute calls

Notes:

  • Backward compatibility: legacy enable = true is accepted as an alias for enabled = true.
  • If enabled = false or api_key is missing, the composio tool is not registered.
  • ZeroBuild requests Composio v3 tools with toolkit_versions=latest and executes tools with version="latest" to avoid stale default tool revisions.
  • Typical flow: call connect, complete browser OAuth, then run execute for the desired tool action.
  • If Composio returns a missing connected-account reference error, call list_accounts (optionally with app) and pass the returned connected_account_id to execute.

[cost]

Key Default Purpose
enabled false Enable cost tracking
daily_limit_usd 10.00 Daily spending limit in USD
monthly_limit_usd 100.00 Monthly spending limit in USD
warn_at_percent 80 Warn when spending reaches this percentage of limit
allow_override false Allow requests to exceed budget with --override flag

Notes:

  • When enabled = true, the runtime tracks per-request cost estimates and enforces daily/monthly limits.
  • At warn_at_percent threshold, a warning is emitted but requests continue.
  • When a limit is reached, requests are rejected unless allow_override = true and the --override flag is passed.

[identity]

Key Default Purpose
format openclaw Identity format: "openclaw" (default) or "aieos"
aieos_path unset Path to AIEOS JSON file (relative to workspace)
aieos_inline unset Inline AIEOS JSON (alternative to file path)

Notes:

  • Use format = "aieos" with either aieos_path or aieos_inline to load an AIEOS / OpenClaw identity document.
  • Only one of aieos_path or aieos_inline should be set; aieos_path takes precedence.

[multimodal]

Key Default Purpose
max_images 4 Maximum image markers accepted per request
max_image_size_mb 5 Per-image size limit before base64 encoding
allow_remote_fetch false Allow fetching http(s) image URLs from markers

Notes:

  • Runtime accepts image markers in user messages with syntax: [IMAGE:<source>].
  • Supported sources:
    • Local file path (for example [IMAGE:/tmp/screenshot.png])
  • Data URI (for example [IMAGE:data:image/png;base64,...])
  • Remote URL only when allow_remote_fetch = true
  • Allowed MIME types: image/png, image/jpeg, image/webp, image/gif, image/bmp.
  • When the active provider does not support vision, requests fail with a structured capability error (capability=vision) instead of silently dropping images.

[browser]

Key Default Purpose
enabled false Enable browser_open tool (opens URLs without scraping)
allowed_domains [] Allowed domains for browser_open (exact/subdomain match, or "*" for all public domains)
session_name unset Browser session name (for agent-browser automation)
backend agent_browser Browser automation backend: "agent_browser", "rust_native", "computer_use", or "auto"
native_headless true Headless mode for rust-native backend
native_webdriver_url http://127.0.0.1:9515 WebDriver endpoint URL for rust-native backend
native_chrome_path unset Optional Chrome/Chromium executable path for rust-native backend

[browser.computer_use]

Key Default Purpose
endpoint http://127.0.0.1:8787/v1/actions Sidecar endpoint for computer-use actions (OS-level mouse/keyboard/screenshot)
api_key unset Optional bearer token for computer-use sidecar (stored encrypted)
timeout_ms 15000 Per-action request timeout in milliseconds
allow_remote_endpoint false Allow remote/public endpoint for computer-use sidecar
window_allowlist [] Optional window title/process allowlist forwarded to sidecar policy
max_coordinate_x unset Optional X-axis boundary for coordinate-based actions
max_coordinate_y unset Optional Y-axis boundary for coordinate-based actions

Notes:

  • When backend = "computer_use", the agent delegates browser actions to the sidecar at computer_use.endpoint.
  • allow_remote_endpoint = false (default) rejects any non-loopback endpoint to prevent accidental public exposure.
  • Use window_allowlist to restrict which OS windows the sidecar can interact with.

[http_request]

Key Default Purpose
enabled false Enable http_request tool for API interactions
allowed_domains [] Allowed domains for HTTP requests (exact/subdomain match, or "*" for all public domains)
max_response_size 1000000 Maximum response size in bytes (default: 1 MB)
timeout_secs 30 Request timeout in seconds

Notes:

  • Deny-by-default: if allowed_domains is empty, all HTTP requests are rejected.
  • Use exact domain or subdomain matching (e.g. "api.example.com", "example.com"), or "*" to allow any public domain.
  • Local/private targets are still blocked even when "*" is configured.

[gateway]

Key Default Purpose
host 127.0.0.1 bind address
port 42617 gateway listen port
require_pairing true require pairing before bearer auth
allow_public_bind false block accidental public exposure

[autonomy]

Key Default Purpose
level supervised read_only, supervised, or full
workspace_only true reject absolute path inputs unless explicitly disabled
allowed_commands required for shell execution allowlist of executable names
forbidden_paths built-in protected list explicit path denylist (system paths + sensitive dotdirs by default)
allowed_roots [] additional roots allowed outside workspace after canonicalization
max_actions_per_hour 20 per-policy action budget
max_cost_per_day_cents 500 per-policy spend guardrail
require_approval_for_medium_risk true approval gate for medium-risk commands
block_high_risk_commands true hard block for high-risk commands
auto_approve [] tool operations always auto-approved
always_ask [] tool operations that always require approval

Notes:

  • level = "full" skips medium-risk approval gating for shell execution, while still enforcing configured guardrails.
  • Access outside the workspace requires allowed_roots, even when workspace_only = false.
  • allowed_roots supports absolute paths, ~/..., and workspace-relative paths.
  • Shell separator/operator parsing is quote-aware. Characters like ; inside quoted arguments are treated as literals, not command separators.
  • Unquoted shell chaining/operators are still enforced by policy checks (;, |, &&, ||, background chaining, and redirects).
[autonomy]
workspace_only = false
forbidden_paths = ["/etc", "/root", "/proc", "/sys", "~/.ssh", "~/.gnupg", "~/.aws"]
allowed_roots = ["~/Desktop/projects", "/opt/shared-repo"]

[memory]

Key Default Purpose
backend sqlite sqlite, lucid, markdown, none
auto_save true persist user-stated inputs only (assistant outputs are excluded)
embedding_provider none none, openai, or custom endpoint
embedding_model text-embedding-3-small embedding model ID, or hint:<name> route
embedding_dimensions 1536 expected vector size for selected embedding model
vector_weight 0.7 hybrid ranking vector weight
keyword_weight 0.3 hybrid ranking keyword weight

Notes:

  • Memory context injection ignores legacy assistant_resp* auto-save keys to prevent old model-authored summaries from being treated as facts.

[[model_routes]] and [[embedding_routes]]

Use route hints so integrations can keep stable names while model IDs evolve.

[[model_routes]]

Key Default Purpose
hint required Task hint name (e.g. "reasoning", "fast", "code", "summarize")
provider required Provider to route to (must match a known provider name)
model required Model to use with that provider
api_key unset Optional API key override for this route's provider

[[embedding_routes]]

Key Default Purpose
hint required Route hint name (e.g. "semantic", "archive", "faq")
provider required Embedding provider ("none", "openai", or "custom:<url>")
model required Embedding model to use with that provider
dimensions unset Optional embedding dimension override for this route
api_key unset Optional API key override for this route's provider
[memory]
embedding_model = "hint:semantic"

[[model_routes]]
hint = "reasoning"
provider = "openrouter"
model = "provider/model-id"

[[embedding_routes]]
hint = "semantic"
provider = "openai"
model = "text-embedding-3-small"
dimensions = 1536

Upgrade strategy:

  1. Keep hints stable (hint:reasoning, hint:semantic).
  2. Update only model = "...new-version..." in the route entries.
  3. Validate with zerobuild doctor before restart/rollout.

Natural-language config path:

  • During normal agent chat, ask the assistant to rewire routes in plain language.
  • The runtime can persist these updates via tool model_routing_config (defaults, scenarios, and delegate sub-agents) without manual TOML editing.

Example requests:

  • Set conversation to provider kimi, model moonshot-v1-8k.
  • Set coding to provider openai, model gpt-5.3-codex, and auto-route when message contains code blocks.
  • Create a coder sub-agent using openai/gpt-5.3-codex with tools file_read,file_write,shell.

[query_classification]

Automatic model hint routing — maps user messages to [[model_routes]] hints based on content patterns.

Key Default Purpose
enabled false Enable automatic query classification
rules [] Classification rules (evaluated in priority order)

Each rule in rules:

Key Default Purpose
hint required Must match a [[model_routes]] hint value
keywords [] Case-insensitive substring matches
patterns [] Case-sensitive literal matches (for code fences, keywords like "fn ")
min_length unset Only match if message length ≥ N chars
max_length unset Only match if message length ≤ N chars
priority 0 Higher priority rules are checked first
[query_classification]
enabled = true

[[query_classification.rules]]
hint = "reasoning"
keywords = ["explain", "analyze", "why"]
min_length = 200
priority = 10

[[query_classification.rules]]
hint = "fast"
keywords = ["hi", "hello", "thanks"]
max_length = 50
priority = 5

[channels_config]

Top-level channel options are configured under channels_config.

Key Default Purpose
message_timeout_secs 300 Base timeout in seconds for channel message processing; runtime scales this with tool-loop depth (up to 4x)

Examples:

  • [channels_config.telegram]
  • [channels_config.discord]
  • [channels_config.whatsapp]
  • [channels_config.linq]
  • [channels_config.nextcloud_talk]
  • [channels_config.email]
  • [channels_config.nostr]

Notes:

  • Default 300s is optimized for on-device LLMs (Ollama) which are slower than cloud APIs.
  • Runtime timeout budget is message_timeout_secs * scale, where scale = min(max_tool_iterations, 4) and a minimum of 1.
  • This scaling avoids false timeouts when the first LLM turn is slow/retried but later tool-loop turns still need to complete.
  • If using cloud APIs (OpenAI, Anthropic, etc.), you can reduce this to 60 or lower.
  • Values below 30 are clamped to 30 to avoid immediate timeout churn.
  • When a timeout occurs, users receive: ⚠️ Request timed out while waiting for the model. Please try again.
  • Telegram-only interruption behavior is controlled with channels_config.telegram.interrupt_on_new_message (default false). When enabled, a newer message from the same sender in the same chat cancels the in-flight request and preserves interrupted user context.
  • While zerobuild channel start is running, updates to default_provider, default_model, default_temperature, api_key, api_url, and reliability.* are hot-applied from config.toml on the next inbound message.

[channels_config.nostr]

Key Default Purpose
private_key required Nostr private key (hex or nsec1… bech32); encrypted at rest when secrets.encrypt = true
relays see note List of relay WebSocket URLs; defaults to relay.damus.io, nos.lol, relay.primal.net, relay.snort.social
allowed_pubkeys [] (deny all) Sender allowlist (hex or npub1…); use "*" to allow all senders

Notes:

  • Supports both NIP-04 (legacy encrypted DMs) and NIP-17 (gift-wrapped private messages). Replies mirror the sender's protocol automatically.
  • The private_key is a high-value secret; keep secrets.encrypt = true (the default) in production.

See detailed channel matrix and allowlist behavior in channels-reference.md.

[channels_config.whatsapp]

WhatsApp supports two backends under one config table.

Cloud API mode (Meta webhook):

Key Required Purpose
access_token Yes Meta Cloud API bearer token
phone_number_id Yes Meta phone number ID
verify_token Yes Webhook verification token
app_secret Optional Enables webhook signature verification (X-Hub-Signature-256)
allowed_numbers Recommended Allowed inbound numbers ([] = deny all, "*" = allow all)

WhatsApp Web mode (native client):

Key Required Purpose
session_path Yes Persistent SQLite session path
pair_phone Optional Pair-code flow phone number (digits only)
pair_code Optional Custom pair code (otherwise auto-generated)
allowed_numbers Recommended Allowed inbound numbers ([] = deny all, "*" = allow all)

Notes:

  • WhatsApp Web requires build flag whatsapp-web.
  • If both Cloud and Web fields are present, Cloud mode wins for backward compatibility.

[channels_config.linq]

Linq Partner V3 API integration for iMessage, RCS, and SMS.

Key Required Purpose
api_token Yes Linq Partner API bearer token
from_phone Yes Phone number to send from (E.164 format)
signing_secret Optional Webhook signing secret for HMAC-SHA256 signature verification
allowed_senders Recommended Allowed inbound phone numbers ([] = deny all, "*" = allow all)

Notes:

  • Webhook endpoint is POST /linq.
  • ZEROBUILD_LINQ_SIGNING_SECRET overrides signing_secret when set.
  • Signatures use X-Webhook-Signature and X-Webhook-Timestamp headers; stale timestamps (>300s) are rejected.
  • See channels-reference.md for full config examples.

[channels_config.nextcloud_talk]

Native Nextcloud Talk bot integration (webhook receive + OCS send API).

Key Required Purpose
base_url Yes Nextcloud base URL (e.g. https://cloud.example.com)
app_token Yes Bot app token used for OCS bearer auth
webhook_secret Optional Enables webhook signature verification
allowed_users Recommended Allowed Nextcloud actor IDs ([] = deny all, "*" = allow all)

Notes:

  • Webhook endpoint is POST /nextcloud-talk.
  • ZEROBUILD_NEXTCLOUD_TALK_WEBHOOK_SECRET overrides webhook_secret when set.
  • See nextcloud-talk-setup.md for setup and troubleshooting.

[hardware]

Hardware wizard configuration for physical-world access (STM32, probe, serial).

Key Default Purpose
enabled false Whether hardware access is enabled
transport none Transport mode: "none", "native", "serial", or "probe"
serial_port unset Serial port path (e.g. "/dev/ttyACM0")
baud_rate 115200 Serial baud rate
probe_target unset Probe target chip (e.g. "STM32F401RE")
workspace_datasheets false Enable workspace datasheet RAG (index PDF schematics for AI pin lookups)

Notes:

  • Use transport = "serial" with serial_port for USB-serial connections.
  • Use transport = "probe" with probe_target for debug-probe flashing (e.g. ST-Link).
  • See hardware-peripherals-design.md for protocol details.

[peripherals]

Higher-level peripheral board configuration. Boards become agent tools when enabled.

Key Default Purpose
enabled false Enable peripheral support (boards become agent tools)
boards [] Board configurations
datasheet_dir unset Path to datasheet docs (relative to workspace) for RAG retrieval

Each entry in boards:

Key Default Purpose
board required Board type: "nucleo-f401re", "rpi-gpio", "esp32", etc.
transport serial Transport: "serial", "native", "websocket"
path unset Path for serial: "/dev/ttyACM0", "/dev/ttyUSB0"
baud 115200 Baud rate for serial
[peripherals]
enabled = true
datasheet_dir = "docs/datasheets"

[[peripherals.boards]]
board = "nucleo-f401re"
transport = "serial"
path = "/dev/ttyACM0"
baud = 115200

[[peripherals.boards]]
board = "rpi-gpio"
transport = "native"

Notes:

  • Place .md/.txt datasheet files named by board (e.g. nucleo-f401re.md, rpi-gpio.md) in datasheet_dir for RAG retrieval.
  • See hardware-peripherals-design.md for board protocol and firmware notes.

Security-Relevant Defaults

  • deny-by-default channel allowlists ([] means deny all)
  • pairing required on gateway by default
  • public bind disabled by default

Validation Commands

After editing config:

zerobuild status
zerobuild doctor
zerobuild channel doctor
zerobuild service restart

Related Docs