Configuration Reference

Holon stores runtime configuration in JSON files under ~/.holon/:

FilePurpose
~/.holon/config.jsonProviders, model defaults, TUI, web, and runtime settings
~/.holon/credentials.jsonPermission-protected credential storage (managed via config credentials)

Configuration Keys

Use holon config get/set/unset/list to read and write keys. When a local daemon is running, these commands prefer the daemon runtime config API; when no daemon is reachable, they fall back to the offline config store. set and unset print applied_via=daemon_api or applied_via=offline_store on stderr, while stdout remains the script-facing JSON value/status. Unsupported daemon updates fail with the daemon-provided rejection reason. Accepted daemon updates are persisted to config.json; the running daemon may continue using its current effective config until restart/reload support is available, and the CLI surfaces that daemon note on stderr. Use holon config schema to see every available key with its type, default, and description.

Model & Provider Settings

KeyTypeDescription
vision.defaultmodel_route_ref_or_autoRoute ref for ViewImage visual observation. Unset auto-discovers an image-capable provider
image_generation.defaultmodel_route_ref_or_autoRoute ref for GenerateImage requests. Unset selects the first turn model that supports image generation
model.defaultmodel_route_refDefault executable route, e.g. "anthropic@default/claude-sonnet-4-6"
model.fallbacksmodel_route_ref_listOrdered executable fallback routes
runtime.disable_provider_fallbackbooleanDisable provider/model fallback; require deterministic single-provider execution
# Set the default model
holon config set model.default "deepseek-anthropic@default/deepseek-v4-pro"

# Add fallback models (JSON array)
holon config set model.fallbacks '["anthropic@default/claude-sonnet-4-6","minimax@default/MiniMax-M2.7"]'

# Read current default
holon config get model.default

# See all current config
holon config list

# Remove a config key (reverts to default)
holon config unset model.fallbacks

Per-Model Policy

The models.catalog key lets you override runtime metadata for specific provider/model refs. Keys under model.unknown_fallback.* control policy for models without built-in metadata.

Model metadata and executable selection use distinct identities:

Legacy provider/model selection values remain accepted, but all new writes include the endpoint. Inspect or explicitly rewrite existing config and agent state with:

holon config migrate-model-routes          # dry-run
holon config migrate-model-routes --write  # validated canonical rewrite

The write creates a one-time config backup and updates all agent state in a SQLite transaction. Invalid or ambiguous refs prevent partial writes.

Authentication & Session Settings

Holon supports session-based authentication for browser and Web UI clients alongside bearer token authentication.

KeyTypeDefaultDescription
auth.modestring ("local" | "oidc")"local"Authentication mode. "local" supports bearer tokens and local cookie sessions; "oidc" enables OpenID Connect login flows. Changes require daemon restart.
auth.oidc.issuer_urlstringunsetOIDC issuer discovery URL (e.g. https://auth.example.com/realms/holon)
auth.oidc.client_idstringunsetOIDC client identifier registered with the issuer
auth.oidc.client_secret_envstringunsetEnvironment variable containing the OIDC client secret
auth.oidc.redirect_uristringunsetCallback redirect URI (e.g. http://localhost:7878/api/auth/oidc/callback)
auth.session.absolute_ttl_secondspositive_integer_or_nullunset (null)Absolute session lifetime in seconds (null means unlimited)
auth.session.idle_ttl_secondspositive_integer86400 (24h)Inactivity timeout in seconds before a session expires

For a step-by-step guide covering IdP setup and session audits, see Configure OIDC authentication.

Session Lifetime Rules:

  • When configured, auth.session.absolute_ttl_seconds must be greater than or equal to auth.session.idle_ttl_seconds.
  • Setting auth.session.absolute_ttl_seconds to null (or omitting it) disables the absolute cutoff. For backwards compatibility, setting 0 normalizes to null.
  • Production deployments require HTTPS for both issuer_url and callback endpoints. HTTP is only permitted when the callback host is localhost.
  • Daemon restart is required when changing auth.mode or OIDC parameters.
# Configure session timeouts
holon config set auth.session.idle_ttl_seconds 43200

# Enable OIDC authentication
holon config set auth.mode "oidc"
holon config set auth.oidc.issuer_url "https://auth.example.com/realms/holon"
holon config set auth.oidc.client_id "holon-client"
holon config set auth.oidc.client_secret_env "HOLON_OIDC_CLIENT_SECRET"

HTTP API CORS

CORS is enabled by default for localhost/loopback browser origins on any port: http://localhost:<port>, https://localhost:<port>, http://127.0.0.1:<port>, and http://[::1]:<port>. This lets local Web UIs call a local or remote Holon HTTP/control API when they provide the required Authorization: Bearer <token> header.

Configure api.cors.allowed_origins to add non-local browser origins such as a LAN-hosted Web UI. These origins are added to the built-in localhost/loopback allowlist. For LAN access, the API must also bind to a reachable address such as 0.0.0.0:7878 or a specific LAN IP; a 127.0.0.1 bind is not reachable from other devices. Set api.cors.enabled=false to disable CORS entirely.

holon config set api.cors.allowed_origins '["http://192.168.1.10:5173"]'
holon config set api.cors.allowed_methods '["GET","POST","PATCH","DELETE","OPTIONS"]'
holon config set api.cors.allowed_headers '["content-type","authorization"]'
holon config set api.cors.allow_credentials false
holon config set api.cors.max_age_seconds 600

Do not combine api.cors.allow_credentials=true with api.cors.allowed_origins=["*"]; Holon rejects that unsafe combination.

Projection Gate

KeyTypeDefaultDescription
api.projection.max_leadersinteger16Max concurrent projection builds; more distinct keys get 429 projection_busy until a leader frees up
api.projection.cache_ttl_msinteger500Milliseconds a finished projection build is cached and reused

Scheduler

The canonical scheduler is always enabled. runtime.scheduler is no longer a configurable key. For one minor release, an existing persisted runtime.scheduler=canonical value or HOLON_SCHEDULER=canonical environment value is accepted with a deprecation warning. legacy and all other values fail startup. Remove the obsolete selector from deployment configuration.

Migration 40 marked the rollout tables as retired compatibility data. The follow-up cleanup migration removes them after recovery reaches a fixed point. They do not decide authority during startup, ordinary scheduler transactions, or typed repair.

The follow-up cleanup migration fails closed while any canonical execution is open, any execution work item is in flight, or any queue entry is dequeued. The error lists the affected agent IDs. Stop Holon and run holon debug scheduler-recovery --agent <agent> to report, apply the typed recovery, and report again. This command can open the immediately preceding schema without triggering cleanup; other current-binary commands cannot.

Holon v0.31.1 is the rollback release for deployments that still require the legacy scheduler. Use it only with a pre-migration database backup; a database migrated by the follow-up schema cleanup is not downgrade-compatible.

Decision Subsystem Settings

KeyTypeDefaultDescription
decision.enabledbooleanfalseEnable the optional Decision provider subsystem
decision.modelmodel_route_refunsetShared provider model route used by Decision; must explicitly advertise Decision capability
decision.local_onnx.enabledbooleanfalseEnable the embedded local ONNX Decision provider
decision.local_onnx.presetstringjev-selector-q4f16Built-in local ONNX model preset name
decision.local_onnx.model_dirstringunsetLocal directory containing ONNX model files and manifest
decision.local_onnx.variantstringq4f16Model quantization or variant identifier
decision.local_onnx.num_threadsinteger1CPU thread count for local ONNX inference
decision.local_onnx.checksumstringunsetOptional SHA-256 verification digest for the model directory
decision.timeout_msintegerunsetProvider deadline in milliseconds
decision.max_tokensintegerunsetMaximum output tokens for Decision responses
decision.concurrencyintegerunsetMaximum concurrent Decision provider requests
decision.queue_capacityintegerunsetMaximum queued Decision provider requests
decision.tools.enabledbooleanfalseExpose the advisory Decision tool (AdvisoryDecision) to agents
decision.tools.max_calls_per_turnintegerunsetMaximum advisory tool calls allowed in one turn (unset means unlimited)
decision.tools.timeout_msintegerunsetAdvisory tool timeout in milliseconds
decision.tools.min_confidencefloatunsetMinimum confidence threshold (0.0 to 1.0); decisions below this threshold abstain
# Enable the Decision subsystem and advisory tool
holon config set decision.enabled true
holon config set decision.tools.enabled true

# Route decisions to a dedicated provider model
holon config set decision.model "typesafe@default/typesafe-ai/jev"

# Or enable the zero-egress local ONNX provider
holon config set decision.local_onnx.enabled true
holon config set decision.local_onnx.preset "jev-selector-q4f16"

# Set safety guardrails
holon config set decision.tools.max_calls_per_turn 3
holon config set decision.tools.min_confidence 0.65

Credential Management

Credentials are stored securely in ~/.holon/credentials.json. Use config credentials subcommands — never edit this file directly.

Setting Credentials

# Preferred: use --stdin to avoid shell history leakage
holon config credentials set --kind api_key --stdin deepseek
# Paste your API key and press Enter (Ctrl+D to finish)

# Alternative: --material (visible in shell history — not recommended)
holon config credentials set --kind api_key --material "sk-..." deepseek

The <PROFILE> argument is a label you choose (e.g. deepseek, bigmodel, openai).

Listing & Removing

holon config credentials list
holon config credentials remove deepseek

Environment Variables

As an alternative to the credential store, Holon reads API keys from environment variables:

ProviderEnvironment Variable
AnthropicANTHROPIC_AUTH_TOKEN
DeepSeekDEEPSEEK_API_KEY
OpenAIOPENAI_API_KEY
BigModel (Zhipu)BIGMODEL_API_KEY
MiniMaxMINIMAX_API_KEY
Xiaomi MiMoXIAOMI_API_KEY
OpenRouterOPENROUTER_API_KEY
FireworksFIREWORKS_API_KEY
TogetherTOGETHER_API_KEY
MistralMISTRAL_API_KEY
xAIXAI_API_KEY
MoonshotMOONSHOT_API_KEY
NEAR AI Cloud (TEE inference)NEARAI_API_KEY
VolcengineVOLCENGINE_API_KEY or ARK_API_KEY
StepFunSTEPFUN_API_KEY
QwenQWEN_API_KEY or DASHSCOPE_API_KEY
HuggingFaceHUGGINGFACE_API_KEY or HF_TOKEN
VeniceVENICE_API_KEY
ChutesCHUTES_API_KEY
NVIDIANVIDIA_API_KEY

For a complete, up-to-date list, run holon config providers list.

Credential sources

SourceDescription
noneNo credential required (local-only providers)
envRead credential from an environment variable
credential_profileRead credential from ~/.holon/credentials.json by profile name
external_cliRun an external CLI (e.g., codex) to obtain a credential

Provider Configuration

Holon ships with built-in provider definitions for 40+ providers. You can add or override providers in config.json.

Listing Registered Providers

holon config providers list

Each provider entry shows its transport protocol (anthropic_messages, openai_chat_completions, etc.), base URL, and credential requirement.

Ollama (local)

Holon includes a built-in ollama provider for running models locally with Ollama. It requires no API key and targets a local Ollama server at http://127.0.0.1:11434 over the Anthropic Messages transport.

  1. Install and start Ollama, then pull a model, for example ollama pull qwen3.8:latest.
  2. Select Ollama during holon onboard, or set it directly:
holon config set model.default "ollama/qwen3.8:latest"

The Web GUI discovers locally running Ollama models without any credential configuration, and ViewImage automatically discovers Ollama vision models for image analysis.

Adding a Custom Provider

holon config providers set my-proxy \
  --transport openai_chat_completions \
  --base-url "https://my-proxy.example.com/v1" \
  --credential-source env \
  --credential-env "MY_PROXY_API_KEY" \
  --credential-kind api_key

Options:

Provider Endpoints and Plans

Provider configuration separates a provider account from its concrete endpoints. The legacy provider keys still configure the default endpoint:

holon config set providers.openai.transport openai_responses
holon config set providers.openai.base_url "https://api.openai.com/v1"

These are shortcuts for providers.openai.endpoints.default.transport and providers.openai.endpoints.default.base_url. Use endpoint keys when the same provider account needs another transport, base URL, or credential policy:

holon config set providers.volcengine.endpoints.image-openai.transport openai_chat_completions
holon config set providers.volcengine.endpoints.image-openai.base_url "https://ark.cn-beijing.volces.com/api/plan/v3"
holon config set providers.volcengine.plans.image-openai.endpoint image-openai

A plan maps a stable provider alias such as volcengine-image-openai onto a named endpoint. Canonical selections persist that route explicitly, for example volcengine@image-openai/model-id. Existing built-in aliases and older provider/model references continue to work as compatible inputs.

Removing a Provider

holon config providers remove my-proxy

Provider OAuth and login flows

Some providers use OAuth or browser-based login instead of static API keys. Holon supports two OAuth-style flows:

OpenAI Codex OAuth

Codex supports two OAuth flows:

The provider uses credential_source: external_cli and credential_kind: oauth for browser OAuth, or device OAuth via the onboarding wizard.

If your credential expires, run holon onboard again — the wizard detects the expiry and guides you through re-authentication.

Vercel AI Gateway OIDC

Vercel AI Gateway uses OpenID Connect (OIDC) for authentication. The onboarding wizard supports this flow when Vercel is selected as the provider.

For both OAuth and OIDC flows, the recommended setup path is:

holon onboard

The wizard handles the entire OAuth flow and stores the credential securely. You should not attempt to configure OAuth providers manually in config.json unless you are scripting a headless deployment.

Listing Available Models

holon config models list

This shows each model's availability, credential status, provider, transport, and policy (context window, max output tokens, capabilities).

Agent-Level Model Overrides

Each agent can override the default model:

holon agent model set "anthropic@default/claude-sonnet-4-6" reviewer

The override is stored in the agent's own configuration, not the global model.default.

Diagnostics

# Full system health check including model availability
holon config doctor

# List all configuration keys with types and defaults
holon config schema

config doctor reports: default model, fallback models, per-model availability, provider settings, and retry policy.

Configuration File Location

Holon resolves its configuration directory as follows:

  1. $HOLON_HOME/config.json (if HOLON_HOME is set)
  2. ~/.holon/config.json (fallback)

Credentials follow the same pattern with credentials.json.

TUI Settings

KeyValuesDefaultDescription
tui.alternate_screenauto, always, neverautoAlternate screen buffer behavior

TUI debug instrumentation is controlled by environment variables:

Environment variableValuesDefaultDescription
HOLON_TUI_PRESENTATION_LOG1, true, yes, on, debugunsetEnable <HOLON_HOME>/logs/tui/presentation.jsonl debug logging for stream-driven presentation decisions
HOLON_TUI_PRESENTATION_LOG_MAX_BYTESpositive integer bytes5242880Rotate the presentation debug log when it reaches this size

Runtime Observability

OTLP trace export is optional and disabled by default. OpenMetrics is exposed through the protected /api/control/runtime/metrics endpoint whenever the control API is running.

KeyTypeDefaultDescription
runtime.observability.otlp.enabledbooleanfalseEnable the bounded OTLP/HTTP JSON trace exporter
runtime.observability.otlp.endpointstringunsetFull HTTP or HTTPS OTLP trace endpoint, commonly ending in /v1/traces
runtime.observability.otlp.headersjson_object{}Static non-secret request headers
runtime.observability.otlp.credential_profilestringunsetCredential profile materialized as a bearer authorization header
runtime.observability.otlp.queue_capacitypositive integer1024Maximum spans waiting in the non-blocking exporter queue
runtime.observability.otlp.batch_sizepositive integer128Maximum spans in one export request
runtime.observability.otlp.batch_interval_mspositive integer1000Maximum batching delay
runtime.observability.otlp.timeout_mspositive integer5000Per-request export timeout

OTLP settings take effect when the daemon starts. See the runtime observability guide for Collector, Prometheus, Grafana, alerting, and troubleshooting examples.

Web Fetch/Search Settings

KeyTypeDefaultDescription
web.fetch.enabledbooleantrueEnable WebFetch tool
web.fetch.max_charsinteger20000Max characters returned to model
web.fetch.max_response_bytesinteger750000Max response bytes before truncation
web.fetch.timeout_secondsinteger20Per-request timeout
web.fetch.max_redirectsinteger5Max redirect hops
web.fetch.allowed_hostsstring_list[]Hosts allowed (empty = all)
web.fetch.denied_hostsstring_list[]Hosts blocked
web.search.enabledbooleantrueEnable WebSearch tool
web.search.builtin_provider.enabledbooleantrueEnable provider-declared builtin web search by default when active provider supports it
web.search.providerstring"auto"Default search provider or auto
web.search.modeenum"fallback"Routing mode: single, fallback, or aggregate
web.search.providersstring_list[]Explicit auto-mode provider attempt order
web.search.max_resultsinteger5Max results returned
web.search.max_provider_attemptsinteger3Max providers attempted by fallback/aggregate routing
x_search.enabledbooleantrueEnable XSearch automatically when xAI credentials are available; set false to hide it
x_search.modelmodel_ref—Optional xAI model route for isolated XSearch requests
x_search.timeout_secondsinteger60Timeout for isolated xAI XSearch requests
web.providers.<name>.kindstringrequiredProvider kind: duck_duck_go, searxng, brave, tencent_cloud_wsa, bocha, tavily, exa, perplexity, firecrawl, open_ai_native, anthropic_native, gemini_native, or command
web.providers.<name>.base_urlstringunsetCustom provider endpoint
web.providers.<name>.credential_profilestringunsetCredential profile for API-backed providers
web.providers.<name>.capabilitiesjson_objectderivedRead-only capability metadata surfaced by holon config get and routing diagnostics
web.providers.<name>.command.argvstring_listunsetCommand argv template for kind=command WebSearch providers (supports {{query}} and {{max_results}})
web.providers.<name>.output.formatenum"json"Command provider stdout format
web.providers.<name>.output.mapping.titlestringunsetJSON path to map result title
web.providers.<name>.output.mapping.urlstringunsetJSON path to map result URL
web.providers.<name>.output.mapping.snippetstringunsetJSON path to map result snippet
web.providers.<name>.output.mapping.published_atstringunsetOptional JSON path to map result publication timestamp
web.providers.<name>.limits.timeout_msinteger10000Command provider execution timeout in milliseconds
web.providers.<name>.limits.max_output_bytesinteger200000Command provider stdout byte limit

Runtime Database Retention

Configure automatic retention cleanup for SQLite runtime events, transcripts, and tool executions:

KeyTypeDefaultDescription
runtime.retention.enabledbooleanfalseEnable bounded runtime SQLite retention. Disabled unless explicitly configured.
runtime.retention.interval_hourspositive integer6Hours between daemon retention passes while retention is enabled.
runtime.retention.audit_events_dayspositive integer30Age window in days for audit event retention.
runtime.retention.audit_events_min_rows_per_scopepositive integer4096Minimum audit event rows retained independently for each agent or host scope.
runtime.retention.transcript_entries_dayspositive integer90Age window in days for transcript entry retention.
runtime.retention.transcript_entries_min_rowspositive integer20000Minimum transcript rows retained globally.
runtime.retention.tool_executions_dayspositive integer90Age window in days for tool execution retention.
runtime.retention.tool_executions_min_rowspositive integer15000Minimum tool execution rows retained globally.
runtime.retention.incremental_vacuum_pagespositive integer256Maximum pages requested from SQLite incremental vacuum after a retention pass.

Command Task Output Safety

Configure on-disk output limits, execution quotas, and filesystem free-space waterlines for background command tasks:

KeyTypeDefaultDescription
runtime.command_task_output_retention_bytesinteger bytes8388608 (8 MiB)Maximum combined stdout/stderr bytes retained on disk per command task. Overflow preserves a bounded head and tail with an explicit truncation marker. Minimum 4096 bytes.
runtime.command_task_output_quota_bytesinteger bytes67108864 (64 MiB)Hard execution quota for total emitted bytes across stdout and stderr. Exceeding this quota terminates the command task with an execution failure. Must be $\ge$ retention limit.
runtime.command_task_min_free_disk_bytesinteger bytes536870912 (512 MiB)Minimum required free disk space on the task artifact filesystem. If free space drops below this limit, the task terminates to protect the host.
runtime.command_task_min_free_disk_percentinteger (0-100)5Minimum free disk space percentage (0–100) on the task artifact filesystem.

Environment Variables

Each command task setting can also be overridden via environment variables:

VariableDescription
HOLON_COMMAND_TASK_OUTPUT_RETENTION_BYTESOverride runtime.command_task_output_retention_bytes
HOLON_COMMAND_TASK_OUTPUT_QUOTA_BYTESOverride runtime.command_task_output_quota_bytes
HOLON_COMMAND_TASK_MIN_FREE_DISK_BYTESOverride runtime.command_task_min_free_disk_bytes
HOLON_COMMAND_TASK_MIN_FREE_DISK_PERCENTOverride runtime.command_task_min_free_disk_percent

Agent Template Remote Sources

Configure remote Git repositories that Holon syncs to populate the agent template catalog:

KeyTypeDefaultDescription
agent_templates.remote_sourcesjson_object{}Map of source IDs to remote source configs
agent_templates.remote_sources.<id>.urlstringrequiredGit repository URL (HTTPS)
agent_templates.remote_sources.<id>.refstringunsetGit ref (branch, tag, or commit); defaults to repository default branch
agent_templates.remote_sources.<id>.enabledbooleantrueWhether this source is enabled for sync
agent_templates.remote_sources.<id>.credential_profilestringunsetCredential profile for private repositories

The daemon runs a sync job at startup to fetch remote source templates into the local template library (~/.agents/agent_templates). Re-syncs reuse recorded install mappings and refuse to overwrite locally-edited templates.

HTTP Addressing

Holon separates the listen address from the advertised address:

KeyTypeDefaultDescription
http_addrstring127.0.0.1:7878TCP listen address for the HTTP/control API
advertise_urlstringunsetPublicly reachable URL advertised to clients (e.g., https://holon.example.com)
callback_base_urlstringderivedLocal loopback URL for same-host webhook callbacks

advertise_url is the URL remote clients (CLI, Web GUI) use to reach the daemon. Set it when the daemon is behind a reverse proxy, tunnel, or on a different network interface than the default localhost address.

callback_base_url is always derived from the listen port as http://127.0.0.1:<port> unless overridden via the HOLON_CALLBACK_BASE_URL environment variable. This keeps same-host webhook callbacks working even when advertise_url is set to a remote address.

Decision Subsystem

The Decision subsystem provides non-authoritative advisory second opinions to agents facing high-ambiguity choices. It is isolated from the primary conversation loop:

See Also