Files
Luna/Documentation/References/OpenClaw/Plugin Architecture.md
T
darman 9929941748 Add project documentation and reference materials
Include Luna AI Assistant design docs covering channels, configuration,
core architecture, memory, scheduler, and skills. Add reference docs
from OpenClaw and ZeroClaw projects, plus Mistral and OpenAI API specs.
2026-04-04 04:14:06 +02:00

6.2 KiB

Plugin Architecture

OpenClaw employs a multi-tiered plugin architecture designed for high extensibility across model providers, messaging channels, and agent capabilities. The system is built on a massive type system that allows plugins to hook into almost every stage of the AI lifecycle, from initial message receipt to final inference and tool execution.


Plugin Type System

The core of the architecture is defined in src/plugins/types.ts. It provides a unified contract for different plugin flavors: ProviderPlugin, WebSearchProviderPlugin, SpeechProviderPlugin, and the general OpenClawPluginDefinition.

Provider Plugin Hooks

The ProviderPlugin is the most complex type, featuring over 40 hooks for deep integration with LLM providers. These are categorized into distinct functional areas:

  • Catalog & Discovery: Hooks like catalog and augmentModelCatalog allow plugins to publish model definitions dynamically.
  • Auth & Credentials: prepareRuntimeAuth and resolveSyntheticAuth handle the exchange of source credentials for runtime tokens.
  • Model Resolution: resolveDynamicModel and normalizeResolvedModel provide last-mile control over how model IDs are mapped to API endpoints.
  • Streaming & Transport: createStreamFn and wrapStreamFn allow plugins to replace or wrap the default transport layer with provider-specific logic.
  • Usage & Billing: resolveUsageAuth and fetchUsageSnapshot enable integrated quota tracking.
export type ProviderPlugin = {
  id: string;
  label: string;
  auth: ProviderAuthMethod[];
  catalog?: ProviderPluginCatalog;
  resolveDynamicModel?: (ctx: ProviderResolveDynamicModelContext) => ProviderRuntimeModel | null | undefined;
  prepareRuntimeAuth?: (ctx: ProviderPrepareRuntimeAuthContext) => Promise<ProviderPreparedRuntimeAuth | null | undefined>;
  createStreamFn?: (ctx: ProviderCreateStreamFnContext) => StreamFn | null | undefined;
  fetchUsageSnapshot?: (ctx: ProviderFetchUsageSnapshotContext) => Promise<ProviderUsageSnapshot | null | undefined>;
  // ... and 30+ more hooks
};

Tool Factories

Plugins expose agent-level capabilities through OpenClawPluginToolFactory. This pattern allows tools to be instantiated with a trusted execution context that includes workspace paths, session identifiers, and security boundaries.

export type OpenClawPluginToolContext = {
  config?: OpenClawConfig;
  workspaceDir?: string;
  agentId?: string;
  sessionId?: string;
  deliveryContext?: DeliveryContext;
  senderIsOwner?: boolean;
};

export type OpenClawPluginToolFactory = (
  ctx: OpenClawPluginToolContext,
) => AnyAgentTool | AnyAgentTool[] | null | undefined;

Config Schema

Plugins declare their configuration requirements using a Zod-like validation system. The OpenClawPluginConfigSchema allows the host to validate plugin settings, generate UI forms, and provide help text without loading the plugin's full implementation.

export type OpenClawPluginConfigSchema = {
  safeParse?: (value: unknown) => {
    success: boolean;
    data?: unknown;
    error?: { issues?: Array<{ path: Array<string | number>; message: string }> };
  };
  uiHints?: Record<string, PluginConfigUiHint>;
  jsonSchema?: Record<string, unknown>;
};

Channel Handlers

Interactive platform support (Telegram, Discord, Slack) is handled via specialized interactive handlers. These allow plugins to respond to platform-specific events like button clicks or modal submissions through a unified context.

export type PluginInteractiveTelegramHandlerContext = {
  channel: "telegram";
  callback: { data: string; namespace: string; payload: string };
  respond: {
    reply: (params: { text: string; buttons?: PluginInteractiveButtons }) => Promise<void>;
    editMessage: (params: { text: string; buttons?: PluginInteractiveButtons }) => Promise<void>;
  };
};

Conversation Bindings

Plugins can request "Conversation Bindings" to take over the message flow for a specific thread or user. This is used for interactive wizards or stateful interactions that bypass the general LLM dispatcher.

  • requestConversationBinding: Attaches a plugin to the current conversation.
  • detachConversationBinding: Releases the conversation back to the general agent.
  • getCurrentConversationBinding: Checks if the conversation is currently owned by a plugin.

Plugin Lifecycle

The lifecycle is managed through several stages, primarily defined in the OpenClawPluginApi provided during registration:

  1. Discovery: Plugins are found in bundled, global, or workspace directories.
  2. Registration: register(api) is called. The plugin registers its tools, hooks, and services.
  3. Activation: activate(api) is called when the plugin is enabled and ready for service.
  4. Runtime: The plugin responds to lifecycle hooks such as before_agent_start, llm_input, and agent_end.
  5. Uninstallation: Managed via the ClawHub registry or local file deletion.

Specialized Plugin Types

Web Search Providers

WebSearchProviderPlugin defines how the agent interacts with search engines. It requires specific credential resolution logic and a createTool factory that returns a standardized search tool definition.

Speech Providers

SpeechProviderPlugin handles text-to-speech (TTS) capabilities. It includes hooks for voice listing, directive parsing (e.g., for custom SSML or tokens), and synthesis for both standard and telephony audio formats.


Relevance to Luna

While Luna does not require the full overhead of OpenClaw's provider ecosystem, it can adopt several key patterns:

  • Manifest-Based Registration: Luna could use a simplified version of OpenClawPluginDefinition to allow for Skills that declare their dependencies and config schemas upfront.
  • Hook Interceptors: Adopting the before_prompt_build and llm_output hook patterns would allow Luna's Core to support middleware for logging, safety filtering, or memory injection.
  • Trusted Contexts: Passing a ToolContext similar to OpenClaw's would ensure that Luna's tools have consistent access to session and workspace state without relying on global variables.