Files
openclaw/docs/tools/capability-cookbook.md
Vincent Koc 6981922254 docs(plugins): replace seam terminology with capability language
Align with the decided convention: use capabilities, entry points,
and extension surfaces instead of seams.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 15:00:33 -07:00

113 lines
3.3 KiB
Markdown

---
summary: "Cookbook for adding a new shared capability to OpenClaw"
read_when:
- Adding a new core capability and plugin registration surface
- Deciding whether code belongs in core, a vendor plugin, or a feature plugin
- Wiring a new runtime helper for channels or tools
title: "Capability Cookbook"
---
# Capability Cookbook
Use this when OpenClaw needs a new domain such as image generation, video
generation, or some future vendor-backed feature area.
The rule:
- plugin = ownership boundary
- capability = shared core contract
That means you should not start by wiring a vendor directly into a channel or a
tool. Start by defining the capability.
## When to create a capability
Create a new capability when all of these are true:
1. more than one vendor could plausibly implement it
2. channels, tools, or feature plugins should consume it without caring about
the vendor
3. core needs to own fallback, policy, config, or delivery behavior
If the work is vendor-only and no shared contract exists yet, stop and define
the contract first.
## The standard sequence
1. Define the typed core contract.
2. Add plugin registration for that contract.
3. Add a shared runtime helper.
4. Wire one real vendor plugin as proof.
5. Move feature/channel consumers onto the runtime helper.
6. Add contract tests.
7. Document the operator-facing config and ownership model.
## What goes where
Core:
- request/response types
- provider registry + resolution
- fallback behavior
- config schema and labels/help
- runtime helper surface
Vendor plugin:
- vendor API calls
- vendor auth handling
- vendor-specific request normalization
- registration of the capability implementation
Feature/channel plugin:
- calls `api.runtime.*` or the matching `plugin-sdk/*-runtime` helper
- never calls a vendor implementation directly
## File checklist
For a new capability, expect to touch these areas:
- `src/<capability>/types.ts`
- `src/<capability>/...registry/runtime.ts`
- `src/plugins/types.ts`
- `src/plugins/registry.ts`
- `src/plugins/captured-registration.ts`
- `src/plugins/contracts/registry.ts`
- `src/plugins/runtime/types-core.ts`
- `src/plugins/runtime/index.ts`
- `src/plugin-sdk/<capability>.ts`
- `src/plugin-sdk/<capability>-runtime.ts`
- one or more `extensions/<vendor>/...`
- config/docs/tests
## Example: image generation
Image generation follows the standard shape:
1. core defines `ImageGenerationProvider`
2. core exposes `registerImageGenerationProvider(...)`
3. core exposes `runtime.imageGeneration.generate(...)`
4. the `openai` and `google` plugins register vendor-backed implementations
5. future vendors can register the same contract without changing channels/tools
The config key is separate from vision-analysis routing:
- `agents.defaults.imageModel` = analyze images
- `agents.defaults.imageGenerationModel` = generate images
Keep those separate so fallback and policy remain explicit.
## 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
If a PR skips the capability layer and hardcodes vendor behavior into a
channel/tool, send it back and define the contract first.