pub struct InMemoryAgenticLoop { /* private fields */ }Expand description
In-memory agentic loop for testing and prototyping
Bundles all in-memory stores and atoms into a convenient interface for running agent turns without external dependencies.
§Example
use everruns_core::in_memory_loop::InMemoryAgenticLoop;
// Simple usage with simulated LLM
let mut loop_runner = InMemoryAgenticLoop::builder()
.system_prompt("You are a helpful assistant.")
.with_simulated_response("Hello! I can help you with that.")
.build()
.await?;
let result = loop_runner.run_turn("Hi there!").await?;
assert!(result.success);
println!("Response: {}", result.response);
// With real LLM (requires API key)
let mut loop_runner = InMemoryAgenticLoop::builder()
.with_real_llm()
.tool(MyCustomTool)
.build()
.await?;Implementations§
Source§impl InMemoryAgenticLoop
impl InMemoryAgenticLoop
Sourcepub fn builder() -> InMemoryAgenticLoopBuilder
pub fn builder() -> InMemoryAgenticLoopBuilder
Create a new builder
Sourcepub fn session_id(&self) -> SessionId
pub fn session_id(&self) -> SessionId
Get the session ID
Sourcepub async fn run_turn(
&self,
input: impl Into<InputMessage>,
) -> Result<TurnResult>
pub async fn run_turn( &self, input: impl Into<InputMessage>, ) -> Result<TurnResult>
Run a turn with the given user input
Accepts either a string or an InputMessage for full control over
message options like reasoning effort.
This executes the full agentic loop using the TurnStateMachine:
- Add user message
- Record input (InputAtom)
- Reason loop (ReasonAtom → ActAtom → repeat until done)
The TurnStateMachine ensures consistent orchestration logic, proper error handling (checking success flag), and turn ID management.
§Examples
// Simple string input
let result = runner.run_turn("Hello").await?;
// Full InputMessage with controls
let input = InputMessage {
role: MessageRole::User,
content: vec![ContentPart::text("What is 2+2?")],
controls: Some(Controls {
model_id: None,
reasoning: Some(ReasoningConfig { effort: Some("medium".into()) }),
}),
metadata: None,
tags: vec![],
};
let result = runner.run_turn(input).await?;Sourcepub async fn run_conversation(
&self,
messages: &[&str],
) -> Result<Vec<TurnResult>>
pub async fn run_conversation( &self, messages: &[&str], ) -> Result<Vec<TurnResult>>
Run multiple turns in sequence
Sourcepub async fn events_by_type(&self, event_type: &str) -> Vec<Event>
pub async fn events_by_type(&self, event_type: &str) -> Vec<Event>
Get events of a specific type
Sourcepub async fn message_count(&self) -> Result<usize>
pub async fn message_count(&self) -> Result<usize>
Get the count of messages
Sourcepub async fn event_count(&self) -> usize
pub async fn event_count(&self) -> usize
Get the count of events
Sourcepub async fn clear_events(&self)
pub async fn clear_events(&self)
Clear all events (useful between tests)
Sourcepub async fn clear_messages(&self)
pub async fn clear_messages(&self)
Clear all messages (starts a fresh conversation)
Sourcepub async fn conversation_string(&self) -> Result<String>
pub async fn conversation_string(&self) -> Result<String>
Get conversation as a formatted string
Sourcepub fn message_retriever(&self) -> &InMemoryMessageRetriever
pub fn message_retriever(&self) -> &InMemoryMessageRetriever
Access the message retriever directly
Sourcepub fn tool_registry(&self) -> &ToolRegistry
pub fn tool_registry(&self) -> &ToolRegistry
Access the tool registry directly
Source§impl InMemoryAgenticLoop
impl InMemoryAgenticLoop
Sourcepub async fn with_fixed_response(response: impl Into<String>) -> Result<Self>
pub async fn with_fixed_response(response: impl Into<String>) -> Result<Self>
Sourcepub async fn with_sequence(responses: Vec<impl Into<String>>) -> Result<Self>
pub async fn with_sequence(responses: Vec<impl Into<String>>) -> Result<Self>
Create a loop with sequence of responses
§Example
let runner = InMemoryAgenticLoop::with_sequence(vec![
"First response",
"Second response",
]).await?;
let r1 = runner.run_turn("msg1").await?;
let r2 = runner.run_turn("msg2").await?;
assert_eq!(r1.response, "First response");
assert_eq!(r2.response, "Second response");Sourcepub async fn with_tool_calls(
response: impl Into<String>,
tool_calls: Vec<ToolCall>,
) -> Result<Self>
pub async fn with_tool_calls( response: impl Into<String>, tool_calls: Vec<ToolCall>, ) -> Result<Self>
Create a loop with tool call simulation
§Example
use everruns_core::ToolCall;
use serde_json::json;
let tool_call = ToolCall {
id: "call_1".to_string(),
name: "get_weather".to_string(),
arguments: json!({"city": "NYC"}),
};
let runner = InMemoryAgenticLoop::with_tool_calls(
"Let me check that.",
vec![tool_call],
).await?;Auto Trait Implementations§
impl !RefUnwindSafe for InMemoryAgenticLoop
impl !UnwindSafe for InMemoryAgenticLoop
impl Freeze for InMemoryAgenticLoop
impl Send for InMemoryAgenticLoop
impl Sync for InMemoryAgenticLoop
impl Unpin for InMemoryAgenticLoop
impl UnsafeUnpin for InMemoryAgenticLoop
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
Source§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request