pub trait AgentLoopPort: Send + Sync {
// Required method
fn run<'life0, 'async_trait>(
&'life0 self,
messages: Vec<AgentMessage>,
config: AgentConfig,
tx: Sender<AgentEvent>,
) -> Pin<Box<dyn Future<Output = Result<AgentRunOutput, AgentError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
}Expand description
Port: drives the full backend agentic loop.
§Usage
ⓘ
use tokio::sync::mpsc;
use gglib_core::ports::AgentLoopPort;
use gglib_core::domain::{AgentConfig, AgentEvent, AgentMessage};
async fn run_loop(agent: &dyn AgentLoopPort) {
let (tx, mut rx) = mpsc::channel::<AgentEvent>(64);
// Spawn a task to consume the event stream (e.g. SSE or logging).
tokio::spawn(async move {
while let Some(event) = rx.recv().await {
println!("{:?}", event);
}
// rx.recv() returns None when tx is dropped (loop ended).
});
let messages = vec![AgentMessage::User { content: "Hello".into() }];
let output = agent.run(messages, AgentConfig::default(), tx).await?;
println!("Final: {}", output.answer);
// `history` contains the full accumulated message list including all
// assistant and tool-result messages appended during the loop — safe
// to pass directly as the `messages` argument for the next turn.
}§Channel ownership and stream termination
events is taken by value. When run returns (whether Ok or Err)
the Sender is dropped, which closes the channel and signals None to
the Receiver. Axum SSE handlers and CLI consumers can rely on this to
know the stream has ended without needing an explicit sentinel event.
Required Methods§
Sourcefn run<'life0, 'async_trait>(
&'life0 self,
messages: Vec<AgentMessage>,
config: AgentConfig,
tx: Sender<AgentEvent>,
) -> Pin<Box<dyn Future<Output = Result<AgentRunOutput, AgentError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn run<'life0, 'async_trait>(
&'life0 self,
messages: Vec<AgentMessage>,
config: AgentConfig,
tx: Sender<AgentEvent>,
) -> Pin<Box<dyn Future<Output = Result<AgentRunOutput, AgentError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Execute the agentic loop and return the final answer.
§Parameters
messages— The initial conversation history (system prompt + user message at minimum).config— Loop control parameters (iteration limits, timeouts, etc.).tx— Async channel over which the loop streamsAgentEvents. Taken by value; dropped on completion to close the SSE stream.
§Returns
Ok(AgentRunOutput)— The final answer and full accumulated message history (safe to pass back asmessageson the next turn).Err(AgentError)— A fatal loop-level failure (max iterations reached, loop detection, stagnation, or internal error). No partial history is returned on failure; the caller’s existing history is left intact.