Skip to main content

starweaver_runtime/
instructions.rs

1//! Dynamic instructions for agent runs.
2
3use async_trait::async_trait;
4use thiserror::Error;
5
6use crate::run::AgentRunState;
7
8/// Shared dynamic instruction reference.
9pub type DynDynamicInstruction = std::sync::Arc<dyn DynamicInstruction>;
10
11/// Dynamic instruction generation error.
12#[derive(Debug, Error)]
13pub enum DynamicInstructionError {
14    /// Dynamic instruction generation failed.
15    #[error("dynamic instruction failed: {0}")]
16    Failed(String),
17}
18
19impl DynamicInstructionError {
20    /// Create a dynamic instruction failure.
21    #[must_use]
22    pub fn failed(message: impl Into<String>) -> Self {
23        Self::Failed(message.into())
24    }
25}
26
27/// Dynamic instruction result.
28pub type DynamicInstructionResult<T> = Result<T, DynamicInstructionError>;
29
30/// Instruction generator called per agent run.
31#[async_trait]
32pub trait DynamicInstruction: Send + Sync {
33    /// Generate instruction text for the current run state.
34    ///
35    /// # Errors
36    ///
37    /// Returns an error when instruction generation fails.
38    async fn instruction(&self, state: &AgentRunState) -> DynamicInstructionResult<String>;
39}
40
41/// Function-backed dynamic instruction.
42pub struct FunctionDynamicInstruction<F> {
43    function: F,
44}
45
46impl<F> FunctionDynamicInstruction<F> {
47    /// Build a dynamic instruction from a function.
48    #[must_use]
49    pub const fn new(function: F) -> Self {
50        Self { function }
51    }
52}
53
54#[async_trait]
55impl<F, Fut> DynamicInstruction for FunctionDynamicInstruction<F>
56where
57    F: Send + Sync + Fn(AgentRunState) -> Fut,
58    Fut: Send + std::future::Future<Output = DynamicInstructionResult<String>>,
59{
60    async fn instruction(&self, state: &AgentRunState) -> DynamicInstructionResult<String> {
61        (self.function)(state.clone()).await
62    }
63}