neuron-loop
The agentic while-loop for the neuron ecosystem. Composes a Provider, a
ToolRegistry, and a ContextStrategy into a loop that sends messages to an
LLM, executes tool calls, manages context compaction, and repeats until the
model produces a final response or a turn limit is reached.
Installation
Key Types
AgentLoop<P, C>-- the core loop, generic overProviderandContextStrategyAgentLoopBuilder<P, C>-- builder for constructing anAgentLoopwith optional configurationLoopConfig-- system prompt, max turns, parallel tool execution flag, optionalUsageLimitsAgentResult-- final output: response text, all messages, cumulative token usage, turn countTurnResult-- per-turn result for step-by-step iteration:ToolsExecuted { calls, results }— tool calls were made and executedFinalResponse(AgentResult)— model produced a final text responseCompactionOccurred { old_tokens, new_tokens }— context was compactedMaxTurnsReached— turn limit hitError(LoopError)— something failed
Usage
Build an AgentLoop using the builder pattern. Only provider and context
are required; tools, config, hooks, and durability are optional with sensible
defaults.
use ;
use ToolRegistry;
use SlidingWindowStrategy;
use ToolContext;
// Set up components
let provider = new;
let context = new;
let mut tools = new;
tools.register;
// Build and run
let mut agent = builder
.tools
.system_prompt
.max_turns
.parallel_tool_execution
.build;
let tool_ctx = ToolContext ;
let result = agent.run_text.await?;
println!;
println!;
println!;
For step-by-step iteration (streaming UIs, custom control flow, or injecting messages between turns):
use ;
use ;
let mut agent = builder.tools.build;
let user_msg = Message ;
let tool_ctx = default;
let mut steps = agent.run_step;
while let Some = steps.next.await
Add observability hooks to log, meter, or control loop execution:
let agent = builder
.hook
.durability
.build;
Cancellation
The loop respects ToolContext.cancellation_token (a tokio_util::sync::CancellationToken).
Cancellation is checked at the top of each iteration and before tool execution.
When cancelled, the loop returns LoopError::Cancelled.
use CancellationToken;
let token = new;
let tool_ctx = ToolContext ;
// Cancel from another task
spawn;
let result = agent.run_text.await;
// Returns Err(LoopError::Cancelled) if cancelled
Parallel Tool Execution
When LoopConfig.parallel_tool_execution is true and the model returns
multiple tool calls in a single response, all calls execute concurrently.
When false (the default), tool calls execute sequentially in order.
let mut agent = builder
.parallel_tool_execution
.build;
Usage Limits
Set LoopConfig.usage_limits to enforce token budget constraints across the
entire loop. When cumulative usage exceeds any configured limit, the loop
returns LoopError::UsageLimitExceeded.
use ;
use UsageLimits;
let limits = default
.with_input_tokens_limit
.with_output_tokens_limit
.with_total_tokens_limit;
let mut agent = builder
.usage_limits
.build;
// The loop will return Err(LoopError::UsageLimitExceeded(_))
// if any limit is exceeded during execution.
Limits are checked after each LLM response and after tool execution. This is inspired by Pydantic AI's usage limit pattern, ported to Rust with compile-time type safety.
Architecture
AgentLoop depends on neuron-types (traits) and
neuron-tool (ToolRegistry).
RPITIT traits (Provider, ObservabilityHook, DurableContext) are
type-erased internally via BoxedHook and BoxedDurable wrappers for
dyn-compatibility — you never construct these directly; they're created by
.hook() and .durability() on the builder. The ContextStrategy is used as
a generic parameter.
Part of neuron
This crate is part of neuron, a composable building-blocks library for AI agents in Rust.
License
Licensed under either of Apache License, Version 2.0 or MIT License at your option.