pub struct Agent<S>{ /* private fields */ }Expand description
Production agent runtime.
Construct via Agent::builder; finalize with
AgentBuilder::build. See module docs for the abstraction
model and information-density discipline.
Implementations§
Source§impl<S> Agent<S>
impl<S> Agent<S>
Sourcepub fn builder() -> AgentBuilder<S>
pub fn builder() -> AgentBuilder<S>
Start a fluent builder.
Sourcepub fn name(&self) -> &str
pub fn name(&self) -> &str
Borrow the agent’s stable name. Always non-empty —
AgentBuilder::build rejects empty / unset names so trace
correlation never silently breaks.
Sourcepub fn inner(&self) -> &Arc<dyn Runnable<S, S>> ⓘ
pub fn inner(&self) -> &Arc<dyn Runnable<S, S>> ⓘ
Borrow the underlying runnable. Useful when an agent is embedded as a node in a larger graph and the parent needs direct access to the inner shape (e.g. for checkpointing).
Sourcepub async fn execute(
&self,
input: S,
ctx: &ExecutionContext,
) -> Result<AgentRunResult<S>>
pub async fn execute( &self, input: S, ctx: &ExecutionContext, ) -> Result<AgentRunResult<S>>
Run to completion, returning the terminal state.
Emits a Started{run_id} opener, fires every registered
observer at the appropriate lifecycle point, then emits
either Complete{run_id, state} or Failed{run_id, error}
on the sink — every run produces exactly one terminal event
.
The run_id is inherited from ctx.run_id() when present,
otherwise a fresh UUID v7 is generated and propagated to the
inner runnable through a cloned context.
Sourcepub async fn execute_with(
&self,
input: S,
overrides: RunOverrides,
ctx: &ExecutionContext,
) -> Result<AgentRunResult<S>>
pub async fn execute_with( &self, input: S, overrides: RunOverrides, ctx: &ExecutionContext, ) -> Result<AgentRunResult<S>>
Convenience entry that attaches a entelix_core::RunOverrides extension
to the context for the duration of the call. Equivalent to
agent.execute(input, &ctx.add_extension(overrides)) —
shorter at the call site and signals the per-call shape at
a glance.
Asymmetric by design — RunOverrides is the
agent-loop carrier (model / system prompt / max iterations
owned by the loop the Agent itself drives) so a typed
convenience belongs on Agent. RequestOverrides
(temperature / top_p / top_k / max_tokens / stop_sequences /
reasoning_effort / tool_choice / response_format /
parallel_tool_calls) is ChatModel-shaped — the dispatch
layer downstream picks it up via
ExecutionContext::add_extension(RequestOverrides::new()…),
no agent-side convenience is needed (and adding one would
duplicate the orthogonality that the carrier split S99
established).
Operators threading multiple per-call extensions stay on
Self::execute with their own add_extension chain.
Sourcepub const fn execution_mode(&self) -> ExecutionMode
pub const fn execution_mode(&self) -> ExecutionMode
Borrow the configured execution mode.
Sourcepub fn approver(&self) -> Option<&Arc<dyn Approver>>
pub fn approver(&self) -> Option<&Arc<dyn Approver>>
Borrow the configured approver (None in Auto mode).
Sourcepub fn observer_count(&self) -> usize
pub fn observer_count(&self) -> usize
Number of registered lifecycle observers.
Sourcepub fn execute_stream<'a>(
&'a self,
input: S,
ctx: &'a ExecutionContext,
) -> BoxStream<'a, Result<AgentEvent<S>>>
pub fn execute_stream<'a>( &'a self, input: S, ctx: &'a ExecutionContext, ) -> BoxStream<'a, Result<AgentEvent<S>>>
Run with AgentEvent book-ends as a stream. Sinks
attached at construction time receive the same events for
fan-out telemetry.
The returned stream is the caller-facing view; the sink
is the observability-facing view. Both observe the same
Started → Complete(state) sequence that
Self::execute produces — the only difference is the
return shape (a stream of events vs the awaited terminal
state).
Drives the inner runnable via Runnable::invoke rather
than Runnable::stream so the lifecycle is identical to
execute and the Complete event always fires on
successful runs (a previous design routed through
Runnable::stream’s Updates mode and could silently skip
Complete for runnables that emit no per-node updates).
Construction is synchronous and infallible — every event
(including the initial Started) yields lazily as the
stream is polled. Callers consume with .next().await like
any Stream; no extra .await on the constructor itself.
Trait Implementations§
Source§impl<S> Runnable<S, S> for Agent<S>
Agent<S> is itself a Runnable<S, S> so it composes inside
larger graphs (recursive sub-agent dispatch).
impl<S> Runnable<S, S> for Agent<S>
Agent<S> is itself a Runnable<S, S> so it composes inside
larger graphs (recursive sub-agent dispatch).
The composition contract is S → S, so the AgentRunResult
envelope is unwrapped here — composing graphs see only the
terminal state. Callers that need the per-run UsageSnapshot
or run_id go through Agent::execute directly.
Source§fn invoke<'life0, 'life1, 'async_trait>(
&'life0 self,
input: S,
ctx: &'life1 ExecutionContext,
) -> Pin<Box<dyn Future<Output = Result<S>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn invoke<'life0, 'life1, 'async_trait>(
&'life0 self,
input: S,
ctx: &'life1 ExecutionContext,
) -> Pin<Box<dyn Future<Output = Result<S>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn batch<'life0, 'life1, 'async_trait>(
&'life0 self,
inputs: Vec<I>,
ctx: &'life1 ExecutionContext,
) -> Pin<Box<dyn Future<Output = Result<Vec<O>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn batch<'life0, 'life1, 'async_trait>(
&'life0 self,
inputs: Vec<I>,
ctx: &'life1 ExecutionContext,
) -> Pin<Box<dyn Future<Output = Result<Vec<O>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
invoke sequentially over the input
vector. Implementors that can parallelize (e.g. independent provider
calls) override this.Source§fn stream<'life0, 'life1, 'async_trait>(
&'life0 self,
input: I,
mode: StreamMode,
ctx: &'life1 ExecutionContext,
) -> Pin<Box<dyn Future<Output = Result<Pin<Box<dyn Stream<Item = Result<StreamChunk<O>, Error>> + Send + 'life0>>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn stream<'life0, 'life1, 'async_trait>(
&'life0 self,
input: I,
mode: StreamMode,
ctx: &'life1 ExecutionContext,
) -> Pin<Box<dyn Future<Output = Result<Pin<Box<dyn Stream<Item = Result<StreamChunk<O>, Error>> + Send + 'life0>>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Auto Trait Implementations§
impl<S> Freeze for Agent<S>
impl<S> !RefUnwindSafe for Agent<S>
impl<S> Send for Agent<S>
impl<S> Sync for Agent<S>
impl<S> Unpin for Agent<S>
impl<S> UnsafeUnpin for Agent<S>
impl<S> !UnwindSafe for Agent<S>
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
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> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
Source§impl<T, I, O> RunnableExt<I, O> for T
impl<T, I, O> RunnableExt<I, O> for T
Source§fn pipe<P, R>(self, next: R) -> RunnableSequence<I, O, P>
fn pipe<P, R>(self, next: R) -> RunnableSequence<I, O, P>
next. The output O of self
becomes the input of next, producing a Runnable<I, P>. Read moreSource§fn with_retry(self, policy: RetryPolicy) -> Retrying<Self, I, O>where
I: Clone,
fn with_retry(self, policy: RetryPolicy) -> Retrying<Self, I, O>where
I: Clone,
self with retry semantics. The returned runnable
re-invokes the inner on transient errors per the policy.
The input must be Clone because each retry receives a
fresh copy. Read moreSource§fn with_fallbacks<F>(self, fallbacks: Vec<F>) -> Fallback<Self, F, I, O>
fn with_fallbacks<F>(self, fallbacks: Vec<F>) -> Fallback<Self, F, I, O>
self with an ordered fallback chain. On a transient
error from the primary, the adapter tries each fallback in
turn. Permanent errors surface immediately. The classifier
is the same trait used by Self::with_retry —
entelix_core::transports::DefaultRetryClassifier by default. Read moreSource§fn map<F, P>(self, f: F) -> Mapping<Self, F, I, O, P>
fn map<F, P>(self, f: F) -> Mapping<Self, F, I, O, P>
RunnableLambda but skipping the
async wrapper. Read moreSource§fn with_config<F>(self, configurer: F) -> Configured<Self, F, I, O>
fn with_config<F>(self, configurer: F) -> Configured<Self, F, I, O>
configurer on a cloned ExecutionContext before
delegating to the inner. The caller’s ctx is not mutated. Read moreSource§fn with_timeout(self, timeout: Duration) -> Timed<Self, I, O>
fn with_timeout(self, timeout: Duration) -> Timed<Self, I, O>
Error::DeadlineExceeded;
caller cancellation still wins. Read moreSource§fn stream_with<'life0, 'life1, 'async_trait>(
&'life0 self,
input: I,
mode: StreamMode,
ctx: &'life1 ExecutionContext,
) -> Pin<Box<dyn Future<Output = Result<Pin<Box<dyn Stream<Item = Result<StreamChunk<O>, Error>> + Send + 'life0>>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: Sync + 'async_trait,
fn stream_with<'life0, 'life1, 'async_trait>(
&'life0 self,
input: I,
mode: StreamMode,
ctx: &'life1 ExecutionContext,
) -> Pin<Box<dyn Future<Output = Result<Pin<Box<dyn Stream<Item = Result<StreamChunk<O>, Error>> + Send + 'life0>>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: Sync + 'async_trait,
Runnable::stream — same
arguments, no trait import needed at the call site.