UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

116 lines (99 loc) • 6.6 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. If the watcher already applied the exact saved source before the managed notification arrives, the RPC acknowledges that completed application without resolving secrets or scanning skills again. 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.