docs/plugins/adding-capabilities.md
Use this when OpenClaw needs a new shared domain such as embeddings, image generation, video generation, or some future vendor-backed feature area.
The rule:
Do not wire a vendor directly into a channel or a tool. Define the capability first.
Create a new capability only when all of these are true:
If the work is vendor-only and no shared contract exists yet, define the contract first.
| Layer | Owns |
|---|---|
| Core | Request/response types; provider registry and resolution; fallback behavior; config schema with propagated title/description docs metadata on nested object, wildcard, array-item, and composition nodes; runtime helper surface. |
| Vendor plugin | Vendor API calls, vendor auth handling, vendor-specific request normalization, and registration of the capability implementation. |
| Feature/channel plugin | Calls api.runtime.* or the matching plugin-sdk/*-runtime helper. Never calls a vendor implementation directly. |
Use provider hooks when the behavior belongs to the model provider contract rather than the generic agent loop. Examples include provider-specific request params after transport selection, auth-profile preference, prompt overlays, and follow-up fallback routing after model/profile failover.
Use agent harness hooks when the behavior belongs to the runtime that is executing a turn. Harnesses can classify explicit protocol outcomes such as empty output, reasoning without visible output, or a structured plan without a final answer so the outer model fallback policy can make the retry decision.
Keep both seams narrow:
For a new capability, expect to touch these areas:
src/<capability>/types.tssrc/<capability>/...registry/runtime.tssrc/plugins/types.tssrc/plugins/registry.tssrc/plugins/captured-registration.tssrc/plugins/contracts/registry.tssrc/plugins/runtime/types-core.tssrc/plugins/runtime/index.tssrc/plugin-sdk/<capability>.tssrc/plugin-sdk/<capability>-runtime.tsImage generation follows the standard shape:
ImageGenerationProvider.registerImageGenerationProvider(...).api.runtime.imageGeneration.generate(...) and .listProviders(...).comfy, deepinfra, fal, google, litellm, microsoft-foundry, minimax, openai, openrouter, vydra, xai) register vendor-backed implementations.The config key is intentionally separate from vision-analysis routing:
agents.defaults.imageModel analyzes images.agents.defaults.imageGenerationModel generates images.Keep those separate so fallback and policy remain explicit.
Use registerEmbeddingProvider(...) / contract embeddingProviders for
reusable vector embedding providers. This contract is intentionally broader
than memory: tools, search, retrieval, importers, or future feature plugins
can consume embeddings without depending on the memory engine. Memory search
also consumes generic embeddingProviders.
The older memory-specific registration API and memoryEmbeddingProviders
contract are deprecated. Use registerEmbeddingProvider and
embeddingProviders for all new embedding providers.
Before shipping a new capability, verify:
If a PR skips the capability layer and hardcodes vendor behavior into a channel/tool, send it back and define the contract first.