use async_trait::async_trait;
use thiserror::Error;
use crate::run::AgentRunState;
pub type DynDynamicInstruction = std::sync::Arc<dyn DynamicInstruction>;
#[derive(Debug, Error)]
pub enum DynamicInstructionError {
#[error("dynamic instruction failed: {0}")]
Failed(String),
}
impl DynamicInstructionError {
#[must_use]
pub fn failed(message: impl Into<String>) -> Self {
Self::Failed(message.into())
}
}
pub type DynamicInstructionResult<T> = Result<T, DynamicInstructionError>;
#[async_trait]
pub trait DynamicInstruction: Send + Sync {
async fn instruction(&self, state: &AgentRunState) -> DynamicInstructionResult<String>;
}
pub struct FunctionDynamicInstruction<F> {
function: F,
}
impl<F> FunctionDynamicInstruction<F> {
#[must_use]
pub const fn new(function: F) -> Self {
Self { function }
}
}
#[async_trait]
impl<F, Fut> DynamicInstruction for FunctionDynamicInstruction<F>
where
F: Send + Sync + Fn(AgentRunState) -> Fut,
Fut: Send + std::future::Future<Output = DynamicInstructionResult<String>>,
{
async fn instruction(&self, state: &AgentRunState) -> DynamicInstructionResult<String> {
(self.function)(state.clone()).await
}
}