This is a contributor guide for OpenClaw core developers. If you are
building an external plugin, see Building plugins
instead. For the deep architecture reference (capability model, ownership,
load pipeline, runtime helpers), see Plugin internals.
- plugin = ownership boundary
- capability = shared core contract
When to create a capability
Create a new capability only when all of these are true:- More than one vendor could plausibly implement it.
- Channels, tools, or feature plugins should consume it without caring about the vendor.
- Core needs to own fallback, policy, config, or delivery behavior.
The standard sequence
- Define the typed core contract.
- Add plugin registration for that contract.
- Add a shared runtime helper.
- Wire one real vendor plugin as proof.
- Move feature/channel consumers onto the runtime helper.
- Add contract tests.
- Document the operator-facing config and ownership model.
What goes where
| 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. |
Provider and harness seams
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:- Core owns the retry/fallback policy.
- Provider plugins own provider-specific request/auth/routing hints.
- Harness plugins own runtime-specific attempt classification.
- Third-party plugins return hints, not direct mutations of core state.
File checklist
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.ts- One or more bundled plugin packages.
- Config, docs, tests.
Worked example: image generation
Image generation follows the standard shape:- Core defines
ImageGenerationProvider. - Core exposes
registerImageGenerationProvider(...). - Core exposes
api.runtime.imageGeneration.generate(...)and.listProviders(...). - Vendor plugins (
comfy,deepinfra,fal,google,litellm,microsoft-foundry,minimax,openai,openrouter,vydra,xai) register vendor-backed implementations. - Future vendors register the same contract without changing channels/tools.
agents.defaults.imageModelanalyzes images.agents.defaults.imageGenerationModelgenerates images.
Embedding providers
UseregisterEmbeddingProvider(...) / 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.
Review checklist
Before shipping a new capability, verify:- No channel/tool imports vendor code directly.
- The runtime helper is the shared path.
- At least one contract test asserts bundled ownership.
- Config docs name the new model/config key.
- Plugin docs explain the ownership boundary.
Related
- Plugin internals — capability model, ownership, load pipeline, runtime helpers.
- Building plugins — first-plugin tutorial.
- SDK overview — import map and registration API reference.
- Creating skills — companion contributor surface.