From a30681ff0e9fa3161afda8b692af044546af9e11 Mon Sep 17 00:00:00 2001 From: "openclaw-docs-sync[bot]" Date: Thu, 23 Apr 2026 17:42:28 +0000 Subject: [PATCH] chore(sync): mirror docs from openclaw/openclaw@12de62bfd831eac9ce4a1087542ab6a1ef02d120 --- .openclaw-sync/source.json | 4 +- docs/plugins/architecture.md | 203 ++++++++++++++++------------------- 2 files changed, 97 insertions(+), 110 deletions(-) diff --git a/.openclaw-sync/source.json b/.openclaw-sync/source.json index 7b57e6be3..bd38ffb78 100644 --- a/.openclaw-sync/source.json +++ b/.openclaw-sync/source.json @@ -1,5 +1,5 @@ { "repository": "openclaw/openclaw", - "sha": "0397cad89becf4684a3c8c11162be3ae20766872", - "syncedAt": "2026-04-23T17:28:59.946Z" + "sha": "12de62bfd831eac9ce4a1087542ab6a1ef02d120", + "syncedAt": "2026-04-23T17:40:48.879Z" } diff --git a/docs/plugins/architecture.md b/docs/plugins/architecture.md index 0bf082594..c3aba4ed9 100644 --- a/docs/plugins/architecture.md +++ b/docs/plugins/architecture.md @@ -5,22 +5,30 @@ read_when: - Understanding the plugin capability model or ownership boundaries - Working on the plugin load pipeline or registry - Implementing provider runtime hooks or channel plugins -title: "Plugin Internals" +title: "Plugin internals" sidebarTitle: "Internals" --- -# Plugin Internals +This is the **deep architecture reference** for the OpenClaw plugin system. For +practical guides, start with one of the focused pages below. - - This is the **deep architecture reference**. For practical guides, see: - - [Install and use plugins](/tools/plugin) — user guide - - [Getting Started](/plugins/building-plugins) — first plugin tutorial - - [Channel Plugins](/plugins/sdk-channel-plugins) — build a messaging channel - - [Provider Plugins](/plugins/sdk-provider-plugins) — build a model provider - - [SDK Overview](/plugins/sdk-overview) — import map and registration API - - -This page covers the internal architecture of the OpenClaw plugin system. + + + End-user guide for adding, enabling, and troubleshooting plugins. + + + First-plugin tutorial with the smallest working manifest. + + + Build a messaging channel plugin. + + + Build a model provider plugin. + + + Import map and registration API reference. + + ## Public capability model @@ -51,38 +59,31 @@ The capability model is landed in core and used by bundled/native plugins today, but external plugin compatibility still needs a tighter bar than "it is exported, therefore it is frozen." -Current guidance: +| Plugin situation | Guidance | +| ------------------------------------------------- | ------------------------------------------------------------------------------------------------ | +| Existing external plugins | Keep hook-based integrations working; this is the compatibility baseline. | +| New bundled/native plugins | Prefer explicit capability registration over vendor-specific reach-ins or new hook-only designs. | +| External plugins adopting capability registration | Allowed, but treat capability-specific helper surfaces as evolving unless docs mark them stable. | -- **existing external plugins:** keep hook-based integrations working; treat - this as the compatibility baseline -- **new bundled/native plugins:** prefer explicit capability registration over - vendor-specific reach-ins or new hook-only designs -- **external plugins adopting capability registration:** allowed, but treat the - capability-specific helper surfaces as evolving unless docs explicitly mark a - contract as stable - -Practical rule: - -- capability registration APIs are the intended direction -- legacy hooks remain the safest no-breakage path for external plugins during - the transition -- exported helper subpaths are not all equal; prefer the narrow documented - contract, not incidental helper exports +Capability registration is the intended direction. Legacy hooks remain the +safest no-breakage path for external plugins during the transition. Exported +helper subpaths are not all equal — prefer narrow documented contracts over +incidental helper exports. ### Plugin shapes OpenClaw classifies every loaded plugin into a shape based on its actual registration behavior (not just static metadata): -- **plain-capability** -- registers exactly one capability type (for example a - provider-only plugin like `mistral`) -- **hybrid-capability** -- registers multiple capability types (for example +- **plain-capability**: registers exactly one capability type (for example a + provider-only plugin like `mistral`). +- **hybrid-capability**: registers multiple capability types (for example `openai` owns text inference, speech, media understanding, and image - generation) -- **hook-only** -- registers only hooks (typed or custom), no capabilities, - tools, commands, or services -- **non-capability** -- registers tools, commands, services, or routes but no - capabilities + generation). +- **hook-only**: registers only hooks (typed or custom), no capabilities, + tools, commands, or services. +- **non-capability**: registers tools, commands, services, or routes but no + capabilities. Use `openclaw plugins inspect ` to see a plugin's shape and capability breakdown. See [CLI reference](/cli/plugins#inspect) for details. @@ -112,7 +113,7 @@ one of these labels: | **legacy warning** | Plugin uses `before_agent_start`, which is deprecated | | **hard error** | Config is invalid or plugin failed to load | -Neither `hook-only` nor `before_agent_start` will break your plugin today -- +Neither `hook-only` nor `before_agent_start` will break your plugin today: `hook-only` is advisory, and `before_agent_start` only triggers a warning. These signals also appear in `openclaw status --all` and `openclaw plugins doctor`. @@ -242,23 +243,19 @@ That means: - channels should consume shared core capabilities instead of re-implementing provider behavior ad hoc -Examples: - -- the bundled `openai` plugin owns OpenAI model-provider behavior and OpenAI - speech + realtime-voice + media-understanding + image-generation behavior -- the bundled `elevenlabs` plugin owns ElevenLabs speech behavior -- the bundled `microsoft` plugin owns Microsoft speech behavior -- the bundled `google` plugin owns Google model-provider behavior plus Google - media-understanding + image-generation + web-search behavior -- the bundled `firecrawl` plugin owns Firecrawl web-fetch behavior -- the bundled `minimax`, `mistral`, `moonshot`, and `zai` plugins own their - media-understanding backends -- the bundled `qwen` plugin owns Qwen text-provider behavior plus - media-understanding and video-generation behavior -- the `voice-call` plugin is a feature plugin: it owns call transport, tools, - CLI, routes, and Twilio media-stream bridging, but it consumes shared speech - plus realtime-transcription and realtime-voice capabilities instead of - importing vendor plugins directly + + - **Vendor multi-capability**: `openai` owns text inference, speech, realtime + voice, media understanding, and image generation. `google` owns text + inference plus media understanding, image generation, and web search. + `qwen` owns text inference plus media understanding and video generation. + - **Vendor single-capability**: `elevenlabs` and `microsoft` own speech; + `firecrawl` owns web-fetch; `minimax` / `mistral` / `moonshot` / `zai` own + media-understanding backends. + - **Feature plugin**: `voice-call` owns call transport, tools, CLI, routes, + and Twilio media-stream bridging, but consumes shared speech, realtime + transcription, and realtime voice capabilities instead of importing vendor + plugins directly. + The intended end state is: @@ -641,37 +638,19 @@ conversation, and it runs after core approval handling finishes. ## Provider runtime hooks -Provider plugins now have two layers: +Provider plugins have three layers: -- manifest metadata: `providerAuthEnvVars` for cheap provider env-auth lookup - before runtime load, `providerAuthAliases` for provider variants that share - auth, `channelEnvVars` for cheap channel env/setup lookup before runtime - load, plus `providerAuthChoices` for cheap onboarding/auth-choice labels and - CLI flag metadata before runtime load -- config-time hooks: `catalog` / legacy `discovery` plus `applyConfigDefaults` -- runtime hooks: `normalizeModelId`, `normalizeTransport`, - `normalizeConfig`, - `applyNativeStreamingUsageCompat`, `resolveConfigApiKey`, - `resolveSyntheticAuth`, `resolveExternalAuthProfiles`, - `shouldDeferSyntheticProfileAuth`, - `resolveDynamicModel`, `prepareDynamicModel`, `normalizeResolvedModel`, - `contributeResolvedModelCompat`, `capabilities`, - `normalizeToolSchemas`, `inspectToolSchemas`, - `resolveReasoningOutputMode`, `prepareExtraParams`, `createStreamFn`, - `wrapStreamFn`, `resolveTransportTurnState`, - `resolveWebSocketSessionPolicy`, `formatApiKey`, `refreshOAuth`, - `buildAuthDoctorHint`, `matchesContextOverflowError`, - `classifyFailoverReason`, `isCacheTtlEligible`, - `buildMissingAuthMessage`, `suppressBuiltInModel`, `augmentModelCatalog`, - `resolveThinkingProfile`, `isBinaryThinking`, `supportsXHighThinking`, - `resolveDefaultThinkingLevel`, `isModernModelRef`, `prepareRuntimeAuth`, - `resolveUsageAuth`, `fetchUsageSnapshot`, `createEmbeddingProvider`, - `buildReplayPolicy`, - `sanitizeReplayHistory`, `validateReplayTurns`, `onModelSelected` +- **Manifest metadata** for cheap pre-runtime lookup: `providerAuthEnvVars`, + `providerAuthAliases`, `providerAuthChoices`, and `channelEnvVars`. +- **Config-time hooks**: `catalog` (legacy `discovery`) plus + `applyConfigDefaults`. +- **Runtime hooks**: 40+ optional hooks covering auth, model resolution, + stream wrapping, thinking levels, replay policy, and usage endpoints. See + the full list under [Hook order and usage](#hook-order-and-usage). OpenClaw still owns the generic agent loop, failover, transcript handling, and -tool policy. These hooks are the extension surface for provider-specific behavior without -needing a whole custom inference transport. +tool policy. These hooks are the extension surface for provider-specific +behavior without needing a whole custom inference transport. Use manifest `providerAuthEnvVars` when the provider has env-based credentials that generic auth/status/model-picker paths should see without loading plugin @@ -809,33 +788,41 @@ api.registerProvider({ ### Built-in examples -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. +Bundled provider plugins combine the hooks above to fit each vendor's catalog, +auth, thinking, replay, and usage needs. The authoritative hook set lives with +each plugin under `extensions/`; this page illustrates the shapes rather than +mirroring the list. -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. + + + OpenRouter, Kilocode, Z.AI, xAI register `catalog` plus + `resolveDynamicModel` / `prepareDynamicModel` so they can surface upstream + model ids ahead of OpenClaw's static catalog. + + + GitHub Copilot, Gemini CLI, ChatGPT Codex, MiniMax, Xiaomi, z.ai pair + `prepareRuntimeAuth` or `formatApiKey` with `resolveUsageAuth` + + `fetchUsageSnapshot` to own token exchange and `/usage` integration. + + + Shared named families (`google-gemini`, `passthrough-gemini`, + `anthropic-by-model`, `hybrid-anthropic-openai`) let providers opt into + transcript policy via `buildReplayPolicy` instead of each plugin + re-implementing cleanup. + + + `byteplus`, `cloudflare-ai-gateway`, `huggingface`, `kimi-coding`, `nvidia`, + `qianfan`, `synthetic`, `together`, `venice`, `vercel-ai-gateway`, and + `volcengine` register just `catalog` and ride the shared inference loop. + + + Beta headers, `/fast` / `serviceTier`, and `context1m` live inside the + Anthropic plugin's public `api.ts` / `contract-api.ts` seam + (`wrapAnthropicProviderStream`, `resolveAnthropicBetas`, + `resolveAnthropicFastMode`, `resolveAnthropicServiceTier`) rather than in + the generic SDK. + + ## Runtime helpers