use crate::callbacks::*;
use adk_core::{
AfterAgentCallback, AfterModelCallback, AfterToolCallback, BeforeAgentCallback,
BeforeModelCallback, BeforeToolCallback,
};
use std::future::Future;
use std::pin::Pin;
pub type CloseFn = Box<dyn Fn() -> Pin<Box<dyn Future<Output = ()> + Send>> + Send + Sync>;
pub struct PluginConfig {
pub name: String,
pub on_user_message: Option<OnUserMessageCallback>,
pub on_event: Option<OnEventCallback>,
pub before_run: Option<BeforeRunCallback>,
pub after_run: Option<AfterRunCallback>,
pub before_agent: Option<BeforeAgentCallback>,
pub after_agent: Option<AfterAgentCallback>,
pub before_model: Option<BeforeModelCallback>,
pub after_model: Option<AfterModelCallback>,
pub on_model_error: Option<OnModelErrorCallback>,
pub before_tool: Option<BeforeToolCallback>,
pub after_tool: Option<AfterToolCallback>,
pub on_tool_error: Option<OnToolErrorCallback>,
pub close_fn: Option<CloseFn>,
}
impl Default for PluginConfig {
fn default() -> Self {
Self {
name: "unnamed".to_string(),
on_user_message: None,
on_event: None,
before_run: None,
after_run: None,
before_agent: None,
after_agent: None,
before_model: None,
after_model: None,
on_model_error: None,
before_tool: None,
after_tool: None,
on_tool_error: None,
close_fn: None,
}
}
}
pub struct Plugin {
config: PluginConfig,
}
impl Plugin {
pub fn new(config: PluginConfig) -> Self {
Self { config }
}
pub fn name(&self) -> &str {
&self.config.name
}
pub fn on_user_message(&self) -> Option<&OnUserMessageCallback> {
self.config.on_user_message.as_ref()
}
pub fn on_event(&self) -> Option<&OnEventCallback> {
self.config.on_event.as_ref()
}
pub fn before_run(&self) -> Option<&BeforeRunCallback> {
self.config.before_run.as_ref()
}
pub fn after_run(&self) -> Option<&AfterRunCallback> {
self.config.after_run.as_ref()
}
pub fn before_agent(&self) -> Option<&BeforeAgentCallback> {
self.config.before_agent.as_ref()
}
pub fn after_agent(&self) -> Option<&AfterAgentCallback> {
self.config.after_agent.as_ref()
}
pub fn before_model(&self) -> Option<&BeforeModelCallback> {
self.config.before_model.as_ref()
}
pub fn after_model(&self) -> Option<&AfterModelCallback> {
self.config.after_model.as_ref()
}
pub fn on_model_error(&self) -> Option<&OnModelErrorCallback> {
self.config.on_model_error.as_ref()
}
pub fn before_tool(&self) -> Option<&BeforeToolCallback> {
self.config.before_tool.as_ref()
}
pub fn after_tool(&self) -> Option<&AfterToolCallback> {
self.config.after_tool.as_ref()
}
pub fn on_tool_error(&self) -> Option<&OnToolErrorCallback> {
self.config.on_tool_error.as_ref()
}
pub async fn close(&self) {
if let Some(ref close_fn) = self.config.close_fn {
close_fn().await;
}
}
}
impl std::fmt::Debug for Plugin {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Plugin")
.field("name", &self.config.name)
.field("has_on_user_message", &self.config.on_user_message.is_some())
.field("has_on_event", &self.config.on_event.is_some())
.field("has_before_run", &self.config.before_run.is_some())
.field("has_after_run", &self.config.after_run.is_some())
.field("has_before_agent", &self.config.before_agent.is_some())
.field("has_after_agent", &self.config.after_agent.is_some())
.field("has_before_model", &self.config.before_model.is_some())
.field("has_after_model", &self.config.after_model.is_some())
.field("has_before_tool", &self.config.before_tool.is_some())
.field("has_after_tool", &self.config.after_tool.is_some())
.finish()
}
}
pub struct PluginBuilder {
config: PluginConfig,
}
impl PluginBuilder {
pub fn new(name: impl Into<String>) -> Self {
Self { config: PluginConfig { name: name.into(), ..Default::default() } }
}
pub fn on_user_message(mut self, callback: OnUserMessageCallback) -> Self {
self.config.on_user_message = Some(callback);
self
}
pub fn on_event(mut self, callback: OnEventCallback) -> Self {
self.config.on_event = Some(callback);
self
}
pub fn before_run(mut self, callback: BeforeRunCallback) -> Self {
self.config.before_run = Some(callback);
self
}
pub fn after_run(mut self, callback: AfterRunCallback) -> Self {
self.config.after_run = Some(callback);
self
}
pub fn before_agent(mut self, callback: BeforeAgentCallback) -> Self {
self.config.before_agent = Some(callback);
self
}
pub fn after_agent(mut self, callback: AfterAgentCallback) -> Self {
self.config.after_agent = Some(callback);
self
}
pub fn before_model(mut self, callback: BeforeModelCallback) -> Self {
self.config.before_model = Some(callback);
self
}
pub fn after_model(mut self, callback: AfterModelCallback) -> Self {
self.config.after_model = Some(callback);
self
}
pub fn on_model_error(mut self, callback: OnModelErrorCallback) -> Self {
self.config.on_model_error = Some(callback);
self
}
pub fn before_tool(mut self, callback: BeforeToolCallback) -> Self {
self.config.before_tool = Some(callback);
self
}
pub fn after_tool(mut self, callback: AfterToolCallback) -> Self {
self.config.after_tool = Some(callback);
self
}
pub fn on_tool_error(mut self, callback: OnToolErrorCallback) -> Self {
self.config.on_tool_error = Some(callback);
self
}
pub fn close_fn(
mut self,
f: impl Fn() -> Pin<Box<dyn Future<Output = ()> + Send>> + Send + Sync + 'static,
) -> Self {
self.config.close_fn = Some(Box::new(f));
self
}
pub fn build(self) -> Plugin {
Plugin::new(self.config)
}
}