use async_trait::async_trait;
use super::{Plugin, PluginResult};
use crate::context::InvocationContext;
pub struct GlobalInstructionPlugin {
prepend: Option<String>,
append: Option<String>,
}
impl GlobalInstructionPlugin {
pub fn new() -> Self {
Self {
prepend: None,
append: None,
}
}
pub fn with_prepend(mut self, instruction: impl Into<String>) -> Self {
self.prepend = Some(instruction.into());
self
}
pub fn with_append(mut self, instruction: impl Into<String>) -> Self {
self.append = Some(instruction.into());
self
}
pub fn prepend(&self) -> Option<&str> {
self.prepend.as_deref()
}
pub fn append(&self) -> Option<&str> {
self.append.as_deref()
}
}
impl Default for GlobalInstructionPlugin {
fn default() -> Self {
Self::new()
}
}
#[async_trait]
impl Plugin for GlobalInstructionPlugin {
fn name(&self) -> &str {
"global_instruction"
}
async fn before_model(
&self,
_request: &crate::llm::LlmRequest,
_ctx: &InvocationContext,
) -> PluginResult {
PluginResult::Continue
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_empty() {
let plugin = GlobalInstructionPlugin::new();
assert!(plugin.prepend().is_none());
assert!(plugin.append().is_none());
}
#[test]
fn with_instructions() {
let plugin = GlobalInstructionPlugin::new()
.with_prepend("Safety first.")
.with_append("Always be helpful.");
assert_eq!(plugin.prepend(), Some("Safety first."));
assert_eq!(plugin.append(), Some("Always be helpful."));
}
#[test]
fn plugin_name() {
let plugin = GlobalInstructionPlugin::new();
assert_eq!(plugin.name(), "global_instruction");
}
}