use std::any::Any;
use std::future::Future;
use std::path::PathBuf;
use std::pin::Pin;
use std::sync::Arc;
use crate::llm::LmProvider;
use crate::tool::Tool;
use crate::{HealthStatus, PluginMeta, ScheduledTask, SetupPrompt};
pub type PluginResult<'a> =
Pin<Box<dyn Future<Output = Result<(), Box<dyn std::error::Error + Send + Sync>>> + Send + 'a>>;
pub struct PluginContext {
pub entity_root: PathBuf,
pub entity_name: String,
pub provider: Arc<dyn LmProvider>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum PluginRole {
Memory,
Pipeline,
Cognitive,
Outcome,
Interface,
Extension,
}
pub trait Plugin: Send + Sync {
fn meta(&self) -> PluginMeta;
fn role(&self) -> PluginRole;
fn start(&mut self) -> PluginResult<'_>;
fn stop(&mut self) -> PluginResult<'_>;
fn health(&self) -> Pin<Box<dyn Future<Output = HealthStatus> + Send + '_>>;
fn scheduled_tasks(&self) -> Vec<ScheduledTask> {
Vec::new()
}
fn setup_prompts(&self) -> Vec<SetupPrompt> {
Vec::new()
}
fn tools(&self) -> Vec<Box<dyn Tool>> {
Vec::new()
}
fn as_any(&self) -> &dyn Any;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn plugin_role_equality() {
assert_eq!(PluginRole::Memory, PluginRole::Memory);
assert_ne!(PluginRole::Memory, PluginRole::Pipeline);
}
#[test]
fn plugin_role_is_copy() {
let role = PluginRole::Memory;
let copy = role;
assert_eq!(role, copy);
}
#[test]
fn plugin_role_debug() {
let debug = format!("{:?}", PluginRole::Interface);
assert_eq!(debug, "Interface");
}
}