Skip to main content

lc_agents/
adapter.rs

1// lc-agents/src/adapter.rs
2//! AgentRunnable adapter - bridges AgentExecutor to the Runnable trait.
3//!
4//! This allows agents to participate in LCEL pipelines via `pipe()`.
5
6use async_trait::async_trait;
7use lc_core::runnables::{LcelError, Runnable, RunnableConfig};
8use std::sync::Arc;
9
10use crate::base::AgentExecutor;
11
12/// Adapter that wraps an `AgentExecutor` as a `Runnable<String, String>`.
13///
14/// This enables agents to participate in LCEL pipelines:
15///
16/// ```rust,ignore
17/// let agent_runnable = AgentRunnable::new(Arc::new(executor));
18/// let pipeline = prompt.pipe(agent_runnable).pipe(parser);
19/// ```
20pub struct AgentRunnable {
21    executor: Arc<AgentExecutor>,
22}
23
24impl AgentRunnable {
25    /// Create a new adapter wrapping the given executor.
26    pub fn new(executor: Arc<AgentExecutor>) -> Self {
27        Self { executor }
28    }
29}
30
31#[async_trait]
32impl Runnable<String, String> for AgentRunnable {
33    type Error = LcelError;
34
35    async fn invoke(
36        &self,
37        input: String,
38        _config: Option<RunnableConfig>,
39    ) -> Result<String, LcelError> {
40        self.executor.invoke(input).await.map_err(|e| LcelError::Agent(e.to_string()))
41    }
42
43    // stream, batch, transform use default implementations
44    // (single-element stream, sequential batch, buffer-and-invoke)
45}
46
47/// Allow `AgentError` to convert into `LcelError`.
48impl From<crate::base::AgentError> for LcelError {
49    fn from(err: crate::base::AgentError) -> Self {
50        LcelError::Agent(err.to_string())
51    }
52}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57
58    #[test]
59    fn agent_error_into_lcel_error() {
60        let agent_err = crate::base::AgentError::MaxIterationsReached;
61        let lcel_err: LcelError = agent_err.into();
62        assert!(matches!(lcel_err, LcelError::Agent(_)));
63        assert!(lcel_err.to_string().contains("Max iterations"));
64    }
65}