* feat: describe decision capabilities in model catalogs Keep task, protocol, modalities, reasoning, grounding, probability semantics, abstention and route billing distinct without changing chat Model types. Co-authored-by: steipete <58493+steipete@users.noreply.github.com> Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com> * fix: apply shared plugin model policy to decisions Co-authored-by: steipete <58493+steipete@users.noreply.github.com> Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com> * feat: support plugin-owned model credentials Co-authored-by: steipete <58493+steipete@users.noreply.github.com> Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com> * feat(decisions): preserve richer answers with versioned data codecs Co-authored-by: steipete <58493+steipete@users.noreply.github.com> Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com> * feat(decisions): run typed tasks with prepared model credentials Preserve V1 while moving typed decision execution, both bundled engines, catalog projection and physical credential ownership onto the shared runtime. Co-authored-by: steipete <58493+steipete@users.noreply.github.com> Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com> * fix(decisions): preserve native headers and route-aware accounting Keep existing request/auth owners, first-class V1/V2 SDK contracts and actual provider USD precedence. Capture only legitimate effective-route prices; preserve missing usage and the established diagnostic scope. Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com> Co-authored-by: steipete <58493+steipete@users.noreply.github.com> * feat(catalog): publish typed decisions on a versioned feed Preserve v1/v2 chat projections and standalone pricing while adding explicit v3 publication and consumption. Carry the reviewed upstream v2 publisher/wire/pricing prerequisites without rebasing the published stack or changing state-store lifecycle. Preserve source-qualified zeros and qualified tariffs. Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com> Co-authored-by: steipete <58493+steipete@users.noreply.github.com> * chore(sdk): record approved Decision V2 data allowance Apply only the +14 exports / +6 callables for the existing decisions data contract. Peter Steinberger explicitly approved the complete +18/+6 stack allowance on 2026-09-26; the remaining four execution types belong to the dependent PR. No additional API or guard exception. Co-authored-by: steipete <58493+steipete@users.noreply.github.com> * fix(models): include inference metadata in extracted tooling * fix(decisions): preserve explicit owner-agent selection * fix(decisions): resolve V2 credentials for the operation agent * test(decisions): align accounting fixtures with captured rates Declare free output in estimable native fixtures, keep decimal precision assertions numeric, and mark the injected catalog fetch for the existing hermetic transport guard. Keep the publisher validator bound to its validated bundle type. * fix(decisions): preserve prepared route and auth facts * test(model-catalog): verify retained caches with released readers * test(decisions): handle optional normalized catalog providers * chore(decisions): satisfy scoped runtime lint * fix(model-catalog): keep manifest auth ownership out of published feeds * fix(decisions): authorize model identity independently of auth profile * fix(auth): retain plugin credential authority through dispatch * fix(decisions): retain credential authority through prepared dispatch * refactor(decisions): assert resolved credential authority directly * test(auth): preserve health probe exports in lifecycle fixture * fix(decisions): distinguish plain record validation * fix(decisions): repair v2 CI integration * fix(decisions): align accounting ratchet evidence --------- Co-authored-by: steipete <58493+steipete@users.noreply.github.com> Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com> Co-authored-by: Vincent Koc <vincentkoc@ieee.org> Co-authored-by: roboclaw-bot <roboclaw-bot@users.noreply.github.com>
13 KiB
summary, read_when, title
| summary | read_when | title | |||
|---|---|---|---|---|---|
| Runtime config: worktree storage, capacity, and acceleration, model routing, discovery, updates, ACP, and the wizard |
|
Configuration — runtime basics |
Top-level runtime keys: worktreeRoot, worktreeAcceleration, worktreeMaxCount, models.*, discovery.*, update.*, acp.*, and wizard.*.
For the full key index and the other top-level config domains, see Configuration reference.
worktreeRoot
Optional global root directory for managed worktree checkouts. Defaults to <openclaw-state-dir>/worktrees.
{
worktreeRoot: "/mnt/workspaces/openclaw-worktrees",
}
Use an absolute Gateway-host path, ~ for the Gateway user's home directory, or ~/ followed by a folder inside it; relative paths are rejected. OpenClaw creates checkouts at <worktreeRoot>/<repo-fingerprint>/<name>. This setting applies to all agents and all managed-worktree owners, with no per-agent override. The shared state database and allocation limits remain under the existing state directory.
Changes affect new allocations only. Registered worktrees retain their original paths for reuse, cleanup, and snapshot restore; existing checkouts are not moved automatically. Keep their original storage available while those records are still needed.
worktreeAcceleration
Optional global boolean for managed worktree filesystem acceleration. Defaults to true, which selects an available filesystem backend automatically and otherwise uses normal Git checkout.
{
worktreeAcceleration: false,
}
Set false to use normal Git checkout and file copying for new worktrees. This option applies across agents and managed-worktree owners; existing checkouts are unchanged. Supported backends are Btrfs snapshots on Linux, APFS directory clones on macOS, and ReFS block clones on Windows. Repository setup and dependencies remain per-worktree.
worktreeMaxCount
Optional positive integer limiting live managed worktrees across all agents, repositories, and owners in the same OpenClaw state directory. Defaults to 4096. Removed checkouts with retained recovery snapshots do not count toward this limit.
{
worktreeMaxCount: 4096,
}
The cap is enforced: cleanup purges merged or squashed branches first, then idle worktrees by last-used age, including manual checkouts and unsaved data. Snapshot capture is best effort during cap eviction; a failed snapshot does not prevent purge. Lowering the cap can therefore remove existing checkouts. Live runs remain protected; if no other checkout can be evicted, creation fails with the cap and live owners in the error. Raise worktreeMaxCount or let those runs finish before retrying.
Background maintenance and creation use the same eviction owner. Concurrent creates cannot each claim the final slot. Disk-space admission remains a separate guard even when the configured count leaves room.
Models
Provider definitions, model allowlists, and custom provider setup live in
Configuration - tools and custom providers.
The models root also owns global model-catalog behavior.
{
models: {
// Optional. Hosted catalog updates default on.
catalogRefresh: {
enabled: true,
// url: "https://catalog.example.com/openclaw/catalog.json",
},
},
}
models.mode: provider catalog behavior (mergeorreplace).models.providers: custom provider map keyed by provider id.models.providers.*.localService: optional on-demand process manager for local model servers. OpenClaw checks the configured health endpoint, starts the absolutecommandwhen needed, waits for readiness, then sends the model request. See Local model services.models.catalogRefresh.enabled: controls the hosted model catalog refresh (default:true). Set it tofalseto prevent all remote catalog requests; model metadata and pricing then stay at the values shipped in the installed release or declared undermodels.providers.*.models[].cost.models.catalogRefresh.url: optional HTTPS mirror override (plain HTTP is accepted only for explicit localhost testing). The default ishttps://catalog.openclaw.ai/models/v2/catalog.json. Mirrors can serve v1, v2, or v3. The Gateway checks in the background at startup and every six hours. A compatible download is prepared and published as one model-and-pricing generation without a Gateway restart. Readers retain the current generation until preparation succeeds; a release whose bundled catalog is newer always wins.
Unknown input modalities are dropped from individual remote model rows with a
warning naming the row. Malformed model rows are skipped without rejecting the
other models; required bundle and provider fields remain strictly validated.
If no valid model rows remain, the download is rejected and the previous catalog
stays active. Pricing-only v1 catalogs without model providers remain supported.
The v1 and v2 publisher outputs keep the text, image, and document input
modalities accepted by released clients. They omit native-only decision models
and inference capabilities. V3 preserves those capabilities and newer supported
input modalities. Chat defaults and recommendations exclude native-only models.
Rows with only unsupported input modalities are omitted rather than exposed as
text models; defaults and recommendations do not reference omitted hosted rows.
To use a v3 mirror, set models.catalogRefresh.url to its catalog URL. The default
feed remains v2. Downloads use a separate SQLite cache key; existing v1 and v2
cache entries remain intact for older clients. Catalog publishers can add
--out-v3 <file> alongside --out <v1-file> and --out-v2 <v2-file> when running
scripts/publish-model-catalog.mts.
V2 includes pricing in each model row. Unknown or unavailable pricing does not mean a model is free. Models outside the catalog, such as older model IDs or models routed through a gateway, use standalone rates in the same file: a gateway that charges the vendor's price reads that vendor's rate once, without a per-gateway copy. Explicit model costs still take precedence.
Native decision usage keeps the provider's reported USD cost, including zero. Without a reported cost, estimation uses token rates captured from the prepared provider route. Missing rates or billable counters, request-based billing, and native non-token units leave the cost unknown.
Pricing updates ship in the same hosted catalog file as model metadata. The
retired models.pricing toggle is removed automatically by openclaw doctor --fix; use models.catalogRefresh.enabled: false when OpenClaw must avoid all
hosted catalog traffic.
Discovery
mDNS (Bonjour)
{
discovery: {
mdns: {
mode: "minimal", // minimal | full | off
},
},
}
minimal(default): omitcliPath+sshPortfrom TXT records.full: includecliPath+sshPort; LAN multicast advertising still requires the bundledbonjourplugin to be enabled.off: suppress LAN multicast advertising without changing plugin enablement.- The bundled
bonjourplugin auto-starts on macOS hosts and is opt-in on Linux, Windows, and containerized Gateway deployments. - Hostname defaults to the system hostname when it is a valid DNS label, falling back to
openclaw. Override withOPENCLAW_MDNS_HOSTNAME. OPENCLAW_DISABLE_BONJOUR=1disables mDNS advertising outright, overridingdiscovery.mdns.mode.
Wide-area (DNS-SD)
{
discovery: {
wideArea: { domain: "openclaw.internal" },
},
}
Setting discovery.wideArea.domain enables wide-area discovery and writes a unicast DNS-SD zone under ~/.openclaw/dns/. For cross-network discovery, pair with a DNS server (CoreDNS recommended) + Tailscale split DNS.
Setup: openclaw dns setup --apply.
Update
{
update: {
channel: "stable", // stable | extended-stable | beta | dev
checkOnStart: true,
auto: {
enabled: false,
},
},
}
channel: release channel -"stable","extended-stable","beta", or"dev". Extended-stable is package-only: foreground commands own installation, while the Gateway may emit read-only update hints.checkOnStart: check for updates throughhttps://telemetry.openclaw.ai/api/latest-versionwhen the Gateway starts and at most once every 24 hours afterward (default:true). The default request shares only the OpenClaw version and platform information in itsUser-Agent; anonymous feature statistics are included only whentelemetry.enabledistrue. Setting this tofalse, or settingOPENCLAW_NO_AUTO_UPDATE=1, prevents all automatic update requests, feature statistics, and update notices, even whenauto.enabledistrue. Stored extended-stable selections use the same read-only hint and 24-hour hint schedule.auto.enabled: enable background auto-update campaigns for stable and beta package installs and dev git installs whencheckOnStartis also enabled (default:false). Extended-stable never applies automatically.
Headless nodes have a separate default-on nodeHost.autoUpdate.enabled policy
with hourly checks and idle-only activation. update.checkOnStart: false and
OPENCLAW_NO_AUTO_UPDATE=1 disable that policy too. See
Headless node updates.
ACP
{
acp: {
enabled: true,
dispatch: { enabled: true },
backend: "acpx",
fallbacks: ["acpx-secondary"],
defaultAgent: "main",
allowedAgents: ["main", "ops"],
stream: {
repeatSuppression: true,
deliveryMode: "live", // live | final_only
},
},
}
enabled: global ACP feature gate (default:true; setfalseto hide ACP dispatch and spawn affordances).dispatch.enabled: independent gate for ACP session turn dispatch (default:true). Setfalseto keep ACP commands available while blocking execution.backend: default ACP runtime backend id (must match a registered ACP runtime plugin). Install the backend plugin first, and ifplugins.allowis set, include the backend plugin id (for exampleacpx) or the ACP backend will not load.fallbacks: ordered list of fallback ACP backend ids tried when the primary backend fails early with a transient-looking error (unavailable, rate-limited, quota exhausted, or overloaded) before it produced any output. Each entry must match a registered ACP runtime plugin backend.defaultAgent: fallback ACP target agent id when spawns do not specify an explicit target.allowedAgents: allowlist of agent ids permitted for ACP runtime sessions; empty means no additional restriction.stream.repeatSuppression: suppress repeated status/tool lines per turn (default:true).stream.deliveryMode:"live"streams incrementally;"final_only"buffers until turn terminal events.stream.tagVisibility: record of tag names to boolean visibility overrides for streamed events.runtime.installCommand: optional install command to run when bootstrapping an ACP runtime environment.
Wizard
Behavior and metadata for CLI guided setup flows (onboard, configure, doctor):
{
wizard: {
accessMode: "full",
appRecommendations: true,
lastRunAt: "2026-01-01T00:00:00.000Z",
lastRunVersion: "2026.1.4",
lastRunCommit: "abc1234",
lastRunCommand: "configure",
lastRunMode: "local",
securityAcknowledgedAt: "2026-01-01T00:00:00.000Z",
},
}
-
wizard.accessMode: discovery consent chosen at the start of guided onboarding."full"(recommended) lets setup look for AI apps, keys, and local runtimes automatically;"guarded"makes setup ask once before looking around and offers manual configuration instead. -
wizard.appRecommendationsdefaults totrue. Set it tofalseto disable installed-application recommendations during guided or classic onboarding and block Gatewaydevice.appsaccess. Node hosts still require their separate, default-off installed-app sharing flag before they advertise the command.
Bridge (legacy, removed)
Current builds no longer include the TCP bridge. Nodes connect over the Gateway WebSocket. bridge.* keys are no longer part of the config schema (validation fails until removed; openclaw doctor --fix can strip unknown keys).
{
"bridge": {
"enabled": true,
"port": 18790,
"bind": "tailnet",
"tls": {
"enabled": true,
"autoGenerate": true
}
}
}