Skip to main content

openclaw_plugins/
api.rs

1//! Plugin API.
2
3use async_trait::async_trait;
4use serde::{Deserialize, Serialize};
5use thiserror::Error;
6
7/// Plugin errors.
8#[derive(Error, Debug)]
9pub enum PluginError {
10    /// Plugin not found.
11    #[error("Plugin not found: {0}")]
12    NotFound(String),
13
14    /// Plugin load failed.
15    #[error("Load failed: {0}")]
16    LoadFailed(String),
17
18    /// Hook execution failed.
19    #[error("Hook failed: {0}")]
20    HookFailed(String),
21
22    /// General execution error.
23    #[error("Execution error: {0}")]
24    ExecutionError(String),
25
26    /// IPC error.
27    #[error("IPC error: {0}")]
28    Ipc(String),
29}
30
31/// Plugin lifecycle hooks.
32#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
33#[serde(rename_all = "camelCase")]
34pub enum PluginHook {
35    /// Before agent processes message.
36    BeforeMessage,
37    /// After agent processes message.
38    AfterMessage,
39    /// Before tool execution.
40    BeforeToolCall,
41    /// After tool execution.
42    AfterToolCall,
43    /// Session started.
44    SessionStart,
45    /// Session ended.
46    SessionEnd,
47    /// Agent response generated.
48    AgentResponse,
49    /// Error occurred.
50    Error,
51}
52
53/// Plugin trait.
54#[async_trait]
55pub trait Plugin: Send + Sync {
56    /// Plugin ID.
57    fn id(&self) -> &str;
58
59    /// Plugin name.
60    fn name(&self) -> &str;
61
62    /// Plugin version.
63    fn version(&self) -> &str;
64
65    /// Supported hooks.
66    fn hooks(&self) -> &[PluginHook];
67
68    /// Execute a hook.
69    async fn execute_hook(
70        &self,
71        hook: PluginHook,
72        data: serde_json::Value,
73    ) -> Result<serde_json::Value, PluginError>;
74
75    /// Activate the plugin.
76    async fn activate(&self) -> Result<(), PluginError>;
77
78    /// Deactivate the plugin.
79    async fn deactivate(&self) -> Result<(), PluginError>;
80}
81
82/// Plugin API exposed to plugins.
83pub struct PluginApi {
84    // Context available to plugins
85}
86
87impl PluginApi {
88    /// Create a new plugin API.
89    #[must_use]
90    pub const fn new() -> Self {
91        Self {}
92    }
93}
94
95impl Default for PluginApi {
96    fn default() -> Self {
97        Self::new()
98    }
99}