Plugin development reference and workflows based on real development experience (Dirigent, ContractorAgent, PrismFacet). Docs: structure, entry-point, hooks, tools, state, config, debugging Workflows: create-plugin, add-hook Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2.1 KiB
2.1 KiB
Hook Registration
Available Hooks
| Hook | Purpose | Dedup Method |
|---|---|---|
before_model_resolve |
Override model/provider before LLM call | WeakSet on event |
before_prompt_build |
Inject into system prompt | WeakSet on event |
before_agent_start |
Legacy prompt injection | WeakSet on event |
agent_end |
Post-conversation actions | Set on runId |
message_received |
React to inbound messages | — |
llm_input / llm_output |
Observe LLM traffic | — |
before_tool_call / after_tool_call |
Observe tool execution | — |
gateway_start / gateway_stop |
Gateway lifecycle | globalThis flag |
Dedup Patterns
WeakSet (for event-object hooks)
const _G = globalThis as Record<string, unknown>;
const DEDUP_KEY = "_myPluginHookDedup";
if (!(_G[DEDUP_KEY] instanceof WeakSet)) _G[DEDUP_KEY] = new WeakSet<object>();
const dedup = _G[DEDUP_KEY] as WeakSet<object>;
api.on("before_model_resolve", async (event, ctx) => {
if (dedup.has(event as object)) return;
dedup.add(event as object);
// ... handler logic
});
Set with runId (for agent_end)
const DEDUP_KEY = "_myPluginAgentEndDedup";
if (!(_G[DEDUP_KEY] instanceof Set)) _G[DEDUP_KEY] = new Set<string>();
const dedup = _G[DEDUP_KEY] as Set<string>;
api.on("agent_end", async (event, ctx) => {
const runId = (event as any).runId as string;
if (runId) {
if (dedup.has(runId)) return;
dedup.add(runId);
if (dedup.size > 500) dedup.delete(dedup.values().next().value!);
}
// ... handler logic
});
Prompt Injection Hooks
before_prompt_build and before_agent_start can return prompt mutation fields:
| Field | Caching | Use for |
|---|---|---|
prependSystemContext |
Cached | Static role/identity prompts |
appendSystemContext |
Cached | Static supplementary guidance |
prependContext |
Not cached | Per-turn dynamic context |
systemPrompt |
— | Full system prompt replacement (rarely used) |
Requires plugins.entries.<id>.hooks.allowPromptInjection: true in openclaw.json.