Openclaw Plugin Dev

Guide for creating OpenClaw plugins using hooks like llm_input and llm_output, with logging, request tracking, and config management.

MIT-0 · Free to use, modify, and redistribute. No attribution required.
1 · 38 · 0 current installs · 0 all-time installs
MIT-0
Security Scan
VirusTotalVirusTotal
Benign
View report →
OpenClawOpenClaw
Benign
high confidence
Purpose & Capability
Name/description match the content: the SKILL.md is a plugin development guide and only references plugin-related APIs, manifest layout, config, and logging. It does not request unrelated credentials, binaries, or services.
Instruction Scope
Instructions stay within plugin development scope (register hooks, correlate runId, write plugin logs, check gateway logs). Note: the guide explicitly shows logging LLM prompts/responses and grepping gateway logs under ~/.openclaw, which is appropriate for debugging but can capture sensitive user data — the guide does not include redaction guidance.
Install Mechanism
No install spec and no code files are provided (instruction-only). Nothing is downloaded or written by the skill itself, minimizing installation risk.
Credentials
The skill declares no required environment variables, credentials, or config paths beyond referencing conventional OpenClaw locations (~/.openclaw). That is proportional for a plugin developer guide.
Persistence & Privilege
always is false and the skill is user-invocable only; it does not request persistent or elevated privileges or modify other skills' configuration.
Assessment
This is a coherent developer guide for building OpenClaw plugins. Before enabling or using any plugin built from these instructions, review the plugin's actual code (especially anything that implements logging) because logs can contain prompts, history, and LLM outputs (potentially secrets). If you install a plugin based on this guide, restrict its log file permissions, consider redaction of sensitive fields, and validate that it only writes under its own ~/.openclaw path. Also review the referenced GitHub project (or any other source) before enabling in production.

Like a lobster shell, security has layers — review code before you run it.

Current versionv1.0.0
Download zip
latestvk97ecq4whptntxks3sfne3060n83vk52

License

MIT-0
Free to use, modify, and redistribute. No attribution required.

SKILL.md

OpenClaw Plugin Development Guide

Core Concepts

Hook Mechanism

OpenClaw provides various hooks to intercept and process events:

HookTrigger TimingUsage
llm_inputBefore an LLM request is sentCapture requests (prompt, systemPrompt, historyMessages)
llm_outputAfter an LLM response is completedCapture responses (assistantTexts, usage)
agent_startWhen an Agent session startsInitialize session state
agent_endWhen an Agent session endsClean up resources and record statistics

Request-Response Correlation

Use runId to correlate requests and responses:

const inFlightRequests = new Map<string, RequestData>();

api.on("llm_input", (event: any) => {
  const runId = event.runId;
  inFlightRequests.set(runId, { timestamp: Date.now(), input: event });
});

api.on("llm_output", (event: any) => {
  const runId = event.runId;
  const request = inFlightRequests.get(runId);
  // Successfully paired, record the complete request-response
  inFlightRequests.delete(runId);
});

Plugin Structure

~/.openclaw/extensions/plugin-name/
├── openclaw.plugin.json    # Plugin manifest
├── index.ts                # Main entry
├── logger.ts               # Utility module (optional)
└── README.md               # Documentation (optional)

Manifest Example

{
  "id": "plugin-name",
  "name": "Plugin Name",
  "version": "1.0.0",
  "main": "index.ts",
  "description": "Plugin description"
}

Main Entry Template

type OpenClawPluginApi = {
  config?: any;
  pluginConfig?: unknown;
  logger: { info: (msg: string) => void; warn: (msg: string) => void; error: (msg: string) => void };
  on: (hookName: string, handler: (event: any, ctx?: any) => void, opts?: { priority?: number }) => void;
};

const plugin = {
  id: "plugin-name",
  name: "Plugin Name",
  description: "Plugin description",
  
  register(api: OpenClawPluginApi) {
    // Get configuration
    const config = api.config?.plugins?.entries?.["plugin-name"]?.config ?? {};
    
    // Register hooks
    api.on("llm_input", (event) => { /* Handle request */ });
    api.on("llm_output", (event) => { /* Handle response */ });
  },
};

export default plugin;

Common Patterns

Logging

// JSONL format, split files by date
const logPath = path.join(basePath, `${new Date().toISOString().split('T')[0]}.jsonl`);
fs.appendFileSync(logPath, JSON.stringify(entry) + "\n");

Configuration Management

const DEFAULT_CONFIG = {
  enabled: true,
  logPath: "~/.openclaw/logs/plugin-name",
};

const config = { ...DEFAULT_CONFIG, ...rawConfig };

Notes

Hook Lifecycle

  • llm_output depends on normal session termination
  • llm_output may not fire if the session is interrupted (gateway restart, user sends a new message)
  • Design for interruption scenarios to avoid resource leaks

Debugging Methods

# Check gateway logs to confirm hook triggering
grep "llm_output" ~/.openclaw/logs/gateway.log

# Check plugin loading
grep "plugin-name" ~/.openclaw/logs/gateway.log

Configuration Location

Enable the plugin in openclaw.json:

{
  "plugins": {
    "entries": {
      "plugin-name": {
        "enabled": true,
        "config": {
          "option1": "value1"
        }
      }
    }
  }
}

Example: LLM API Logger

Full example available at https://github.com/cicadaFang/openclaw-llm-api-logger

Features:

  • Log all LLM API requests and responses
  • JSONL formatted logs, split by date
  • Correlate requests and responses using runId
  • Record metrics such as durationMs and usage

Files

1 total
Select a file
Select a file to preview.

Comments

Loading comments…