docs: trim gateway configuration and plugin architecture reference dumps

This commit is contained in:
Vincent Koc
2026-04-23 01:12:01 -07:00
parent 1263d4278e
commit a2d91a1a9a
2 changed files with 103 additions and 322 deletions

View File

@@ -72,26 +72,12 @@ See the [full reference](/gateway/configuration-reference) for every available f
OpenClaw only accepts configurations that fully match the schema. Unknown keys, malformed types, or invalid values cause the Gateway to **refuse to start**. The only root-level exception is `$schema` (string), so editors can attach JSON Schema metadata.
</Warning>
Schema tooling notes:
- `openclaw config schema` prints the same JSON Schema family used by Control UI
and config validation.
- Treat that schema output as the canonical machine-readable contract for
`openclaw.json`; this overview and the configuration reference summarize it.
- Field `title` and `description` values are carried into the schema output for
editor and form tooling.
- Nested object, wildcard (`*`), and array-item (`[]`) entries inherit the same
docs metadata where matching field documentation exists.
- `anyOf` / `oneOf` / `allOf` composition branches inherit the same docs
metadata too, so union/intersection variants keep the same field help.
- `config.schema.lookup` returns one normalized config path with a shallow
schema node (`title`, `description`, `type`, `enum`, `const`, common bounds,
and similar validation fields), matched UI hint metadata, and immediate child
summaries for drill-down tooling.
- Runtime plugin/channel schemas are merged in when the gateway can load the
current manifest registry.
- `pnpm config:docs:check` detects drift between docs-facing config baseline
artifacts and the current schema surface.
`openclaw config schema` prints the canonical JSON Schema used by Control UI
and validation. `config.schema.lookup` fetches a single path-scoped node plus
child summaries for drill-down tooling. Field `title`/`description` docs metadata
carries through nested objects, wildcard (`*`), array-item (`[]`), and `anyOf`/
`oneOf`/`allOf` branches. Runtime plugin and channel schemas merge in when the
manifest registry is loaded.
When validation fails:
@@ -100,23 +86,13 @@ When validation fails:
- Run `openclaw doctor` to see exact issues
- Run `openclaw doctor --fix` (or `--yes`) to apply repairs
The Gateway also keeps a trusted last-known-good copy after a successful startup. If
`openclaw.json` is later changed outside OpenClaw and no longer validates, startup
and hot reload preserve the broken file as a timestamped `.clobbered.*` snapshot,
restore the last-known-good copy, and log a loud warning with the recovery reason.
Startup read recovery also treats sharp size drops, missing config metadata, and a
missing `gateway.mode` as critical clobber signatures when the last-known-good
copy had those fields.
If a status/log line is accidentally prepended before an otherwise valid JSON
config, gateway startup and `openclaw doctor --fix` can strip the prefix,
preserve the polluted file as `.clobbered.*`, and continue with the recovered
JSON.
The next main-agent turn also receives a system-event warning telling it that the
config was restored and must not be blindly rewritten. Last-known-good promotion
is updated after validated startup and after accepted hot reloads, including
OpenClaw-owned config writes whose persisted file hash still matches the accepted
write. Promotion is skipped when the candidate contains redacted secret
placeholders such as `***` or shortened token values.
The Gateway keeps a trusted last-known-good copy after each successful startup.
If `openclaw.json` later fails validation (or drops `gateway.mode`, shrinks
sharply, or has a stray log line prepended), OpenClaw preserves the broken file
as `.clobbered.*`, restores the last-known-good copy, and logs the recovery
reason. The next agent turn also receives a system-event warning so the main
agent does not blindly rewrite the restored config. Promotion to last-known-good
is skipped when a candidate contains redacted secret placeholders such as `***`.
## Common tasks
@@ -583,75 +559,35 @@ source layout is ambiguous.
## 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)
- `config.apply` only when you intend to replace the entire config
- `update.run` for explicit self-update plus restart
<Note>
Control-plane write RPCs (`config.apply`, `config.patch`, `update.run`) are rate-limited to **3 requests per 60 seconds** per `deviceId+clientIp`. When limited, the RPC returns `UNAVAILABLE` with `retryAfterMs`.
Control-plane writes (`config.apply`, `config.patch`, `update.run`) are
rate-limited to 3 requests per 60 seconds per `deviceId+clientIp`. Restart
requests coalesce and then enforce a 30-second cooldown between restart cycles.
</Note>
Safe/default flow:
Example partial patch:
- `config.schema.lookup`: inspect one path-scoped config subtree with a shallow
schema node, matched hint metadata, and immediate child summaries
- `config.get`: fetch the current snapshot + hash
- `config.patch`: preferred partial update path
- `config.apply`: full-config replacement only
- `update.run`: explicit self-update + restart
```bash
openclaw gateway call config.get --params '{}' # capture payload.hash
openclaw gateway call config.patch --params '{
"raw": "{ channels: { telegram: { groups: { \"*\": { requireMention: false } } } } }",
"baseHash": "<hash>"
}'
```
When you are not replacing the entire config, prefer `config.schema.lookup`
then `config.patch`.
<AccordionGroup>
<Accordion title="config.apply (full replace)">
Validates + writes the full config and restarts the Gateway in one step.
<Warning>
`config.apply` replaces the **entire config**. Use `config.patch` for partial updates, or `openclaw config set` for single keys.
</Warning>
Params:
- `raw` (string) — JSON5 payload for the entire config
- `baseHash` (optional) — config hash from `config.get` (required when config exists)
- `sessionKey` (optional) — session key for the post-restart wake-up ping
- `note` (optional) — note for the restart sentinel
- `restartDelayMs` (optional) — delay before restart (default 2000)
Restart requests are coalesced while one is already pending/in-flight, and a 30-second cooldown applies between restart cycles.
```bash
openclaw gateway call config.get --params '{}' # capture payload.hash
openclaw gateway call config.apply --params '{
"raw": "{ agents: { defaults: { workspace: \"~/.openclaw/workspace\" } } }",
"baseHash": "<hash>",
"sessionKey": "agent:main:whatsapp:direct:+15555550123"
}'
```
</Accordion>
<Accordion title="config.patch (partial update)">
Merges a partial update into the existing config (JSON merge patch semantics):
- Objects merge recursively
- `null` deletes a key
- Arrays replace
Params:
- `raw` (string) — JSON5 with just the keys to change
- `baseHash` (required) — config hash from `config.get`
- `sessionKey`, `note`, `restartDelayMs` — same as `config.apply`
Restart behavior matches `config.apply`: coalesced pending restarts plus a 30-second cooldown between restart cycles.
```bash
openclaw gateway call config.patch --params '{
"raw": "{ channels: { telegram: { groups: { \"*\": { requireMention: false } } } } }",
"baseHash": "<hash>"
}'
```
</Accordion>
</AccordionGroup>
Both `config.apply` and `config.patch` accept `raw`, `baseHash`, `sessionKey`,
`note`, and `restartDelayMs`. `baseHash` is required for `config.patch` and
recommended for `config.apply` when a config already exists.
## Environment variables

View File

@@ -809,115 +809,33 @@ api.registerProvider({
### Built-in examples
- Anthropic uses `resolveDynamicModel`, `capabilities`, `buildAuthDoctorHint`,
`resolveUsageAuth`, `fetchUsageSnapshot`, `isCacheTtlEligible`,
`resolveThinkingProfile`, `applyConfigDefaults`, `isModernModelRef`,
and `wrapStreamFn` because it owns Claude 4.6 forward-compat,
provider-family hints, auth repair guidance, usage endpoint integration,
prompt-cache eligibility, auth-aware config defaults, Claude
default/adaptive thinking policy, and Anthropic-specific stream shaping for
beta headers, `/fast` / `serviceTier`, and `context1m`.
- Anthropic's Claude-specific stream helpers stay in the bundled plugin's own
public `api.ts` / `contract-api.ts` seam for now. That package surface
exports `wrapAnthropicProviderStream`, `resolveAnthropicBetas`,
`resolveAnthropicFastMode`, `resolveAnthropicServiceTier`, and the lower-level
Anthropic wrapper builders instead of widening the generic SDK around one
provider's beta-header rules.
- OpenAI uses `resolveDynamicModel`, `normalizeResolvedModel`, and
`capabilities` plus `buildMissingAuthMessage`, `suppressBuiltInModel`,
`augmentModelCatalog`, `resolveThinkingProfile`, and `isModernModelRef`
because it owns GPT-5.4 forward-compat, the direct OpenAI
`openai-completions` -> `openai-responses` normalization, Codex-aware auth
hints, Spark suppression, synthetic OpenAI list rows, and GPT-5 thinking /
live-model policy; the `openai-responses-defaults` stream family owns the
shared native OpenAI Responses wrappers for attribution headers,
`/fast`/`serviceTier`, text verbosity, native Codex web search,
reasoning-compat payload shaping, and Responses context management.
- OpenRouter uses `catalog` plus `resolveDynamicModel` and
`prepareDynamicModel` because the provider is pass-through and may expose new
model ids before OpenClaw's static catalog updates; it also uses
`capabilities`, `wrapStreamFn`, and `isCacheTtlEligible` to keep
provider-specific request headers, routing metadata, reasoning patches, and
prompt-cache policy out of core. Its replay policy comes from the
`passthrough-gemini` family, while the `openrouter-thinking` stream family
owns proxy reasoning injection and the unsupported-model / `auto` skips.
- GitHub Copilot uses `catalog`, `auth`, `resolveDynamicModel`, and
`capabilities` plus `prepareRuntimeAuth` and `fetchUsageSnapshot` because it
needs provider-owned device login, model fallback behavior, Claude transcript
quirks, a GitHub token -> Copilot token exchange, and a provider-owned usage
endpoint.
- OpenAI Codex uses `catalog`, `resolveDynamicModel`,
`normalizeResolvedModel`, `refreshOAuth`, and `augmentModelCatalog` plus
`prepareExtraParams`, `resolveUsageAuth`, and `fetchUsageSnapshot` because it
still runs on core OpenAI transports but owns its transport/base URL
normalization, OAuth refresh fallback policy, default transport choice,
synthetic Codex catalog rows, and ChatGPT usage endpoint integration; it
shares the same `openai-responses-defaults` stream family as direct OpenAI.
- Google AI Studio and Gemini CLI OAuth use `resolveDynamicModel`,
`buildReplayPolicy`, `sanitizeReplayHistory`,
`resolveReasoningOutputMode`, `wrapStreamFn`, and `isModernModelRef` because the
`google-gemini` replay family owns Gemini 3.1 forward-compat fallback,
native Gemini replay validation, bootstrap replay sanitation, tagged
reasoning-output mode, and modern-model matching, while the
`google-thinking` stream family owns Gemini thinking payload normalization;
Gemini CLI OAuth also uses `formatApiKey`, `resolveUsageAuth`, and
`fetchUsageSnapshot` for token formatting, token parsing, and quota endpoint
wiring.
- Anthropic Vertex uses `buildReplayPolicy` through the
`anthropic-by-model` replay family so Claude-specific replay cleanup stays
scoped to Claude ids instead of every `anthropic-messages` transport.
- Amazon Bedrock uses `buildReplayPolicy`, `matchesContextOverflowError`,
`classifyFailoverReason`, and `resolveThinkingProfile` because it owns
Bedrock-specific throttle/not-ready/context-overflow error classification
for Anthropic-on-Bedrock traffic; its replay policy still shares the same
Claude-only `anthropic-by-model` guard.
- OpenRouter, Kilocode, Opencode, and Opencode Go use `buildReplayPolicy`
through the `passthrough-gemini` replay family because they proxy Gemini
models through OpenAI-compatible transports and need Gemini
thought-signature sanitation without native Gemini replay validation or
bootstrap rewrites.
- MiniMax uses `buildReplayPolicy` through the
`hybrid-anthropic-openai` replay family because one provider owns both
Anthropic-message and OpenAI-compatible semantics; it keeps Claude-only
thinking-block dropping on the Anthropic side while overriding reasoning
output mode back to native, and the `minimax-fast-mode` stream family owns
fast-mode model rewrites on the shared stream path.
- Moonshot uses `catalog`, `resolveThinkingProfile`, and `wrapStreamFn` because it still uses the shared
OpenAI transport but needs provider-owned thinking payload normalization; the
`moonshot-thinking` stream family maps config plus `/think` state onto its
native binary thinking payload.
- Kilocode uses `catalog`, `capabilities`, `wrapStreamFn`, and
`isCacheTtlEligible` because it needs provider-owned request headers,
reasoning payload normalization, Gemini transcript hints, and Anthropic
cache-TTL gating; the `kilocode-thinking` stream family keeps Kilo thinking
injection on the shared proxy stream path while skipping `kilo/auto` and
other proxy model ids that do not support explicit reasoning payloads.
- Z.AI uses `resolveDynamicModel`, `prepareExtraParams`, `wrapStreamFn`,
`isCacheTtlEligible`, `resolveThinkingProfile`, `isModernModelRef`,
`resolveUsageAuth`, and `fetchUsageSnapshot` because it owns GLM-5 fallback,
`tool_stream` defaults, binary thinking UX, modern-model matching, and both
usage auth + quota fetching; the `tool-stream-default-on` stream family keeps
the default-on `tool_stream` wrapper out of per-provider handwritten glue.
- xAI uses `normalizeResolvedModel`, `normalizeTransport`,
`contributeResolvedModelCompat`, `prepareExtraParams`, `wrapStreamFn`,
`resolveSyntheticAuth`, `resolveDynamicModel`, and `isModernModelRef`
because it owns native xAI Responses transport normalization, Grok fast-mode
alias rewrites, default `tool_stream`, strict-tool / reasoning-payload
cleanup, fallback auth reuse for plugin-owned tools, forward-compat Grok
model resolution, and provider-owned compat patches such as xAI tool-schema
profile, unsupported schema keywords, native `web_search`, and HTML-entity
tool-call argument decoding.
- Mistral, OpenCode Zen, and OpenCode Go use `capabilities` only to keep
transcript/tooling quirks out of core.
- Catalog-only bundled providers such as `byteplus`, `cloudflare-ai-gateway`,
`huggingface`, `kimi-coding`, `nvidia`, `qianfan`,
`synthetic`, `together`, `venice`, `vercel-ai-gateway`, and `volcengine` use
`catalog` only.
- Qwen uses `catalog` for its text provider plus shared media-understanding and
video-generation registrations for its multimodal surfaces.
- MiniMax and Xiaomi use `catalog` plus usage hooks because their `/usage`
behavior is plugin-owned even though inference still runs through the shared
transports.
Bundled provider plugins use the hooks above in combinations tailored to each
vendor's catalog, auth, thinking, replay, and usage-tracking needs. The exact
hook set per provider lives with the plugin source under `extensions/`; treat
that as the authoritative list rather than mirroring it here.
Illustrative patterns:
- **Pass-through catalog providers** (OpenRouter, Kilocode, Z.AI, xAI) register
`catalog` plus `resolveDynamicModel`/`prepareDynamicModel` so they can surface
upstream model ids ahead of OpenClaw's static catalog.
- **OAuth + usage endpoint providers** (GitHub Copilot, Gemini CLI, ChatGPT
Codex, MiniMax, Xiaomi, z.ai) pair `prepareRuntimeAuth` or `formatApiKey`
with `resolveUsageAuth` + `fetchUsageSnapshot` to own token exchange and
`/usage` integration.
- **Replay / transcript cleanup** is shared through named families:
`google-gemini`, `passthrough-gemini`, `anthropic-by-model`,
`hybrid-anthropic-openai`. Providers opt in through `buildReplayPolicy`
instead of each implementing transcript cleanup.
- **Catalog-only** bundled providers (`byteplus`, `cloudflare-ai-gateway`,
`huggingface`, `kimi-coding`, `nvidia`, `qianfan`, `synthetic`, `together`,
`venice`, `vercel-ai-gateway`, `volcengine`) register just `catalog` and ride
the shared inference loop.
- **Anthropic-specific stream helpers** (beta headers, `/fast`/`serviceTier`,
`context1m`) live inside the Anthropic bundled plugin's public `api.ts` /
`contract-api.ts` seam (`wrapAnthropicProviderStream`, `resolveAnthropicBetas`,
`resolveAnthropicFastMode`, `resolveAnthropicServiceTier`) rather than in the
generic SDK.
## Runtime helpers
@@ -1137,121 +1055,48 @@ Notes:
## Plugin SDK import paths
Use SDK subpaths instead of the monolithic `openclaw/plugin-sdk` import when
authoring plugins:
Use narrow SDK subpaths instead of the monolithic `openclaw/plugin-sdk` root
barrel when authoring new plugins. Core subpaths:
- `openclaw/plugin-sdk/plugin-entry` for plugin registration primitives.
- `openclaw/plugin-sdk/core` for the generic shared plugin-facing contract.
- `openclaw/plugin-sdk/config-schema` for the root `openclaw.json` Zod schema
export (`OpenClawSchema`).
- Stable channel primitives such as `openclaw/plugin-sdk/channel-setup`,
`openclaw/plugin-sdk/setup-runtime`,
`openclaw/plugin-sdk/setup-adapter-runtime`,
`openclaw/plugin-sdk/setup-tools`,
`openclaw/plugin-sdk/channel-pairing`,
`openclaw/plugin-sdk/channel-contract`,
`openclaw/plugin-sdk/channel-feedback`,
`openclaw/plugin-sdk/channel-inbound`,
`openclaw/plugin-sdk/channel-lifecycle`,
`openclaw/plugin-sdk/channel-reply-pipeline`,
`openclaw/plugin-sdk/command-auth`,
`openclaw/plugin-sdk/secret-input`, and
`openclaw/plugin-sdk/webhook-ingress` for shared setup/auth/reply/webhook
wiring. `channel-inbound` is the shared home for debounce, mention matching,
inbound mention-policy helpers, envelope formatting, and inbound envelope
context helpers.
`channel-setup` is the narrow optional-install setup seam.
`setup-runtime` is the runtime-safe setup surface used by `setupEntry` /
deferred startup, including the import-safe setup patch adapters.
`setup-adapter-runtime` is the env-aware account-setup adapter seam.
`setup-tools` is the small CLI/archive/docs helper seam (`formatCliCommand`,
`detectBinary`, `extractArchive`, `resolveBrewExecutable`, `formatDocsLink`,
`CONFIG_DIR`).
- Domain subpaths such as `openclaw/plugin-sdk/channel-config-helpers`,
`openclaw/plugin-sdk/allow-from`,
`openclaw/plugin-sdk/channel-config-schema`,
`openclaw/plugin-sdk/telegram-command-config`,
`openclaw/plugin-sdk/channel-policy`,
`openclaw/plugin-sdk/approval-gateway-runtime`,
`openclaw/plugin-sdk/approval-handler-adapter-runtime`,
`openclaw/plugin-sdk/approval-handler-runtime`,
`openclaw/plugin-sdk/approval-runtime`,
`openclaw/plugin-sdk/config-runtime`,
`openclaw/plugin-sdk/infra-runtime`,
`openclaw/plugin-sdk/agent-runtime`,
`openclaw/plugin-sdk/lazy-runtime`,
`openclaw/plugin-sdk/reply-history`,
`openclaw/plugin-sdk/routing`,
`openclaw/plugin-sdk/status-helpers`,
`openclaw/plugin-sdk/text-runtime`,
`openclaw/plugin-sdk/runtime-store`, and
`openclaw/plugin-sdk/directory-runtime` for shared runtime/config helpers.
`telegram-command-config` is the narrow public seam for Telegram custom
command normalization/validation and stays available even if the bundled
Telegram contract surface is temporarily unavailable.
`text-runtime` is the shared text/markdown/logging seam, including
assistant-visible-text stripping, markdown render/chunking helpers, redaction
helpers, directive-tag helpers, and safe-text utilities.
- Approval-specific channel seams should prefer one `approvalCapability`
contract on the plugin. Core then reads approval auth, delivery, render,
native-routing, and lazy native-handler behavior through that one capability
instead of mixing approval behavior into unrelated plugin fields.
- `openclaw/plugin-sdk/channel-runtime` is deprecated and remains only as a
compatibility shim for older plugins. New code should import the narrower
generic primitives instead, and repo code should not add new imports of the
shim.
- Bundled extension internals remain private. External plugins should use only
`openclaw/plugin-sdk/*` subpaths. OpenClaw core/test code may use the repo
public entry points under a plugin package root such as `index.js`, `api.js`,
`runtime-api.js`, `setup-entry.js`, and narrowly scoped files such as
`login-qr-api.js`. Never import a plugin package's `src/*` from core or from
another extension.
- Repo entry point split:
`<plugin-package-root>/api.js` is the helper/types barrel,
`<plugin-package-root>/runtime-api.js` is the runtime-only barrel,
`<plugin-package-root>/index.js` is the bundled plugin entry,
and `<plugin-package-root>/setup-entry.js` is the setup plugin entry.
- Current bundled provider examples:
- Anthropic uses `api.js` / `contract-api.js` for Claude stream helpers such
as `wrapAnthropicProviderStream`, beta-header helpers, and `service_tier`
parsing.
- OpenAI uses `api.js` for provider builders, default-model helpers, and
realtime provider builders.
- OpenRouter uses `api.js` for its provider builder plus onboarding/config
helpers, while `register.runtime.js` can still re-export generic
`plugin-sdk/provider-stream` helpers for repo-local use.
- Facade-loaded public entry points prefer the active runtime config snapshot
when one exists, then fall back to the resolved config file on disk when
OpenClaw is not yet serving a runtime snapshot.
- Generic shared primitives remain the preferred public SDK contract. A small
reserved compatibility set of bundled channel-branded helper seams still
exists. Treat those as bundled-maintenance/compatibility seams, not new
third-party import targets; new cross-channel contracts should still land on
generic `plugin-sdk/*` subpaths or the plugin-local `api.js` /
`runtime-api.js` barrels.
| Subpath | Purpose |
| ----------------------------------- | -------------------------------------------------- |
| `openclaw/plugin-sdk/plugin-entry` | Plugin registration primitives |
| `openclaw/plugin-sdk/core` | Generic shared plugin-facing contract |
| `openclaw/plugin-sdk/config-schema` | Root `openclaw.json` Zod schema (`OpenClawSchema`) |
Compatibility note:
Channel plugins pick from a family of narrow seams — `channel-setup`,
`setup-runtime`, `setup-adapter-runtime`, `setup-tools`, `channel-pairing`,
`channel-contract`, `channel-feedback`, `channel-inbound`, `channel-lifecycle`,
`channel-reply-pipeline`, `command-auth`, `secret-input`, `webhook-ingress`,
`channel-targets`, and `channel-actions`. Approval behavior should consolidate
on one `approvalCapability` contract rather than mixing across unrelated
plugin fields. See [Channel plugins](/plugins/sdk-channel-plugins).
- Avoid the root `openclaw/plugin-sdk` barrel for new code.
- Prefer the narrow stable primitives first. The newer setup/pairing/reply/
feedback/contract/inbound/threading/command/secret-input/webhook/infra/
allowlist/status/message-tool subpaths are the intended contract for new
bundled and external plugin work.
Target parsing/matching belongs on `openclaw/plugin-sdk/channel-targets`.
Message action gates and reaction message-id helpers belong on
`openclaw/plugin-sdk/channel-actions`.
- Bundled extension-specific helper barrels are not stable by default. If a
helper is only needed by a bundled extension, keep it behind the extension's
local `api.js` or `runtime-api.js` seam instead of promoting it into
`openclaw/plugin-sdk/<extension>`.
- New shared helper seams should be generic, not channel-branded. Shared target
parsing belongs on `openclaw/plugin-sdk/channel-targets`; channel-specific
internals stay behind the owning plugin's local `api.js` or `runtime-api.js`
seam.
- Capability-specific subpaths such as `image-generation`,
`media-understanding`, and `speech` exist because bundled/native plugins use
them today. Their presence does not by itself mean every exported helper is a
long-term frozen external contract.
Runtime and config helpers live under matching `*-runtime` subpaths
(`approval-runtime`, `config-runtime`, `infra-runtime`, `agent-runtime`,
`lazy-runtime`, `directory-runtime`, `text-runtime`, `runtime-store`, etc.).
<Info>
`openclaw/plugin-sdk/channel-runtime` is deprecated — a compatibility shim for
older plugins. New code should import narrower generic primitives instead.
</Info>
Repo-internal entry points (per bundled plugin package root):
- `index.js` — bundled plugin entry
- `api.js` — helper/types barrel
- `runtime-api.js` — runtime-only barrel
- `setup-entry.js` — setup plugin entry
External plugins should only import `openclaw/plugin-sdk/*` subpaths. Never
import another plugin package's `src/*` from core or from another plugin.
Facade-loaded entry points prefer the active runtime config snapshot when one
exists, then fall back to the resolved config file on disk.
Capability-specific subpaths such as `image-generation`, `media-understanding`,
and `speech` exist because bundled plugins use them today. They are not
automatically long-term frozen external contracts — check the relevant SDK
reference page when relying on them.
## Message tool schemas