UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

113 lines (96 loc) • 6.41 kB
--- summary: "Writing config over the gateway API: config.get, config.patch, config.apply, and replacePaths" title: "Config RPC (programmatic updates)" sidebarTitle: "Config RPC (programmatic updates)" read_when: - Writing config from tooling instead of by hand - Choosing between config.patch and config.apply - Handling baseHash, replacePaths, and deferred reload responses --- ## Config RPC (programmatic updates) For tooling that writes config over the gateway API, prefer this flow: - `config.schema.lookup` to inspect one subtree (shallow schema node + child summaries) - `config.get` to fetch the current snapshot plus `hash` - `config.patch` for partial updates (JSON merge patch: objects merge, `null` deletes, arrays replace when explicitly confirmed with `replacePaths` if entries would be removed) - `config.apply` only when you intend to replace the entire config - `update.run` for explicit self-update plus restart; include `continuationMessage` when the post-restart session should run one follow-up turn - `update.status` to inspect the latest update restart sentinel and verify the running version after a restart Agents should treat `config.schema.lookup` as the first stop for exact field-level docs and constraints. Use [Configuration reference](/gateway/configuration-reference) when they need the broader config map, defaults, or links to dedicated subsystem references. The built-in `gateway` tool dispatches config reads directly through the Gateway that admitted the agent run, without opening a loopback WebSocket. Explicit `gatewayUrl` or `gatewayToken` overrides and standalone local agents still use the Gateway client. Both paths use the same config handlers and read scopes. <Note> Control-plane writes (`config.apply`, `config.patch`, `update.run`) are rate-limited to 30 requests per 60 seconds, per method, per `deviceId+clientIp`; see [Rate limiting](/gateway/security/rate-limiting). Restart requests coalesce and then enforce a 30-second cooldown between restart cycles. `update.status` is read-only but admin-scoped because the restart sentinel can include update step summaries and command output tails. </Note> Example partial patch: ```bash openclaw gateway call config.get --params '{}' # capture payload.hash openclaw gateway call config.patch --params '{ "raw": "{ channels: { telegram: { groups: { \"*\": { requireMention: false } } } } }", "baseHash": "<hash>" }' ``` `config.patch` records explicitly supplied values in the config file even when they equal the current runtime defaults. Unchanged runtime defaults stay omitted. Its successful response includes `changedPaths`, the effective runtime paths changed after validation and secret restoration, or `[]` for a no-op. These paths contain no configuration values; clients can use them to distinguish a channel change from an unrelated write even when secret values are redacted. Both `config.apply` and `config.patch` accept `raw`, `baseHash`, `sessionKey`, `note`, and `restartDelayMs`. `baseHash` is required for both methods once a config file already exists (a first write with no existing config skips the check). For hot-applied changes, these RPCs wait until the active Gateway applies the exact write. Channel or plugin reloads may defer for unrelated active work. Policy-only writes covered by a plugin's dynamic-read contract, such as Discord allowlists and DM/group policies, publish without a channel restart or drain wait. Writes that also contain restart-required settings remain one deferred transaction. If the file watcher takes over the same unapplied write during that wait, the RPC stays pending through replay; persistence alone is not an application acknowledgment. Shutdown, supersession by different content, or failed application returns `UNAVAILABLE` with recovery guidance. `config.set` acknowledges persistence only. When a committed write cannot finish runtime application, the error's `details.persistedConfig` contains the redacted committed `config` and its public `hash` when available. This receipt confirms persistence, not application. Clients can preserve unrelated draft edits and use that revision for subsequent writes; the usual `baseHash` check still rejects intervening changes. Retrying an unchanged patch may return a no-op, which does not reapply the saved config. Follow the error's `config.apply` or restart guidance to recover application. Publication failures with a rollback outcome do not include this receipt. `channels.status` reports active-work deferrals in `statusIssues`, alongside channel policy diagnostics shown in the Control UI and `openclaw channels status`. `channels.start` also returns a diagnostic when that channel's reload is deferred; manual stop/start continues to use the published runtime configuration. Wait for active work to finish and refresh status. These diagnostics describe deferred channel reloads, not every persisted-but-unapplied configuration state. Once a reload has committed, it finishes its model and channel work before a newer config is applied. If that work needs restart recovery, the RPC returns `UNAVAILABLE`; wait for the Gateway to restart, then use `config.get` to verify the active revision. `config.patch` also accepts `replacePaths`, an array of config paths whose array replacement or deletion is intentional. If a patch removes existing array entries or deletes an array, the Gateway rejects the write unless that exact array path appears in `replacePaths`. Deleting a containing object requires its contained array paths, including empty arrays. Deleting a whole array requires only its own path, not paths to arrays nested inside its entries. Use exact record keys, such as `agents.entries.main.skills`. For ID-merged entry updates, nested array paths use `[]`, such as `models.providers.custom.models[].input`. Parent paths and `*` wildcards do not authorize descendant arrays. This prevents truncated `config.get` snapshots from silently clobbering routing or allowlist arrays. Use `config.apply` when you intend to replace the full config. Arrays of objects with stable `id` fields merge by ID unless their path appears in `replacePaths`. These updates preserve authored fields in untouched entries; runtime defaults, such as model catalog compatibility and context budgets, are not saved into sibling entries. Explicitly configured values remain authoritative.