Skip to main content

AgentEvent

Enum AgentEvent 

Source
#[non_exhaustive]
pub enum AgentEvent<S> { Started { run_id: String, tenant_id: TenantId, parent_run_id: Option<String>, agent: String, }, ToolStart { run_id: String, tenant_id: TenantId, tool_use_id: String, tool: String, tool_version: Option<String>, input: Value, }, ToolComplete { run_id: String, tenant_id: TenantId, tool_use_id: String, tool: String, tool_version: Option<String>, duration_ms: u64, output: Value, }, ToolError { run_id: String, tenant_id: TenantId, tool_use_id: String, tool: String, tool_version: Option<String>, error: String, error_for_llm: RenderedForLlm<String>, envelope: ErrorEnvelope, duration_ms: u64, }, Failed { run_id: String, tenant_id: TenantId, error: String, envelope: ErrorEnvelope, }, Complete { run_id: String, tenant_id: TenantId, state: S, usage: Option<UsageSnapshot>, }, ToolCallApproved { run_id: String, tenant_id: TenantId, tool_use_id: String, tool: String, }, ToolCallDenied { run_id: String, tenant_id: TenantId, tool_use_id: String, tool: String, reason: String, }, }
Expand description

Runtime events emitted by the agent during a single execute / execute_stream call.

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Started

Run opened. Sinks use this to mark span beginnings, allocate per-run state, and emit “session opened” telemetry.

Fields

§run_id: String

Per-run correlation id (UUID v7). Stable for the duration of the run; matches the id on every subsequent event for this same call.

§tenant_id: TenantId

Tenant scope this event belongs to (invariant 11 — every emit site stamps ctx.tenant_id().clone()). Audit / billing / replay consumers key off this field directly instead of correlating through a separate run_idtenant_id lookup.

§parent_run_id: Option<String>

Run id of the calling agent when this run was dispatched from a parent (sub-agent fan-out, supervisor handoff). None for top-level runs. LangSmith-style trace-tree consumers reconstruct the hierarchy from (run_id, parent_run_id) edges across these events.

§agent: String

Agent identifier configured on AgentBuilder::name(...).

§

ToolStart

One tool dispatch began. Emitted by crate::agent::tool_event_layer::ToolEventLayer when wired into the tool registry. Absent when the layer is not wired (the agent runtime itself does not generate tool events).

Fields

§run_id: String

Run correlation id.

§tenant_id: TenantId

Tenant scope this event belongs to (see Started).

§tool_use_id: String

Stable tool-use id matching the originating ContentPart::ToolUse.

§tool: String

Tool name being dispatched.

§tool_version: Option<String>

Tool version (Tool::version()) when the tool advertises one — useful for distinguishing behaviour changes between otherwise-identically-named tool revisions.

§input: Value

Tool input (already JSON-validated by the tool’s schema).

§

ToolComplete

One tool dispatch finished successfully.

Fields

§run_id: String

Run correlation id.

§tenant_id: TenantId

Tenant scope this event belongs to (see Started).

§tool_use_id: String

Stable tool-use id matching the corresponding ToolStart.

§tool: String

Tool name (echoed for sink convenience).

§tool_version: Option<String>

Tool version echoed from the matching ToolStart so sinks can correlate completion telemetry without retaining per-tool_use_id state.

§duration_ms: u64

Wall-clock duration measured by the layer.

§output: Value

JSON output the tool produced. Sinks that persist tool audit logs read this directly; PII redaction happens at the policy layer before this event is emitted, so the payload is safe for storage.

§

ToolError

One tool dispatch failed.

Fields

§run_id: String

Run correlation id.

§tenant_id: TenantId

Tenant scope this event belongs to (see Started).

§tool_use_id: String

Stable tool-use id matching the corresponding ToolStart.

§tool: String

Tool name (echoed for sink convenience).

§tool_version: Option<String>

Tool version echoed from the matching ToolStart so sinks see the same provenance on the failure path as on success.

§error: String

Operator-facing error message (Display form, includes vendor status, source chain). Sinks, OTel, and log destinations consume this.

§error_for_llm: RenderedForLlm<String>

LLM-facing error message wrapped in a sealed RenderedForLlm carrier. The carrier’s constructor is pub(crate) to entelix-core, so the only path from a raw String to this field is entelix_core::LlmRenderable::for_llm — emit sites cannot fabricate model-facing content. The audit-log projection (Self::to_graph_event) extracts the inner rendering into GraphEvent::ToolResult so replay reconstructs the model’s view without re-leaking operator content (invariant #16).

§envelope: ErrorEnvelope

Typed wire shape produced by entelix_core::Error::envelope. Bundles wire_code (i18n key / metric label), wire_class (responsibility split), retry_after_secs (vendor Retry-After hint), and provider_status (raw HTTP status) so sinks, audit replay, SSE adapters, and FE rate-limit timers all read one Copy value instead of pattern-matching the inner error variant. Patch-version-stable.

§duration_ms: u64

Wall-clock duration measured by the layer.

§

Failed

Run terminated with the inner runnable’s error. The matching Started{run_id} is always present in the same stream. Caller-facing streams additionally surface the typed error via Result::Err; sinks see only this event.

Fields

§run_id: String

Run correlation id.

§tenant_id: TenantId

Tenant scope this event belongs to (see Started).

§error: String

Lean error message (Display form).

§envelope: ErrorEnvelope

Typed wire shape produced by entelix_core::Error::envelope — see ToolError for the field roster. Replay / audit / metric / SSE consumers route off this field instead of parsing error prose.

§

Complete

Run terminated successfully with the agent’s terminal state.

Fields

§run_id: String

Run correlation id.

§tenant_id: TenantId

Tenant scope this event belongs to (see Started).

§state: S

Final state returned by the inner runnable.

§usage: Option<UsageSnapshot>

Frozen UsageSnapshot of the entelix_core::RunBudget counters at the moment the inner runnable returned. None when no budget was attached to the entelix_core::ExecutionContext. Mirrors the usage field on crate::AgentRunResult so streaming and one-shot surfaces observe the same terminal artifact.

§

ToolCallApproved

HITL approver decided to permit one tool dispatch. Emitted by crate::agent::ApprovalLayer before the matching ToolStart fires. Only present when an Approver is wired (default agents skip approval and never emit this variant).

Fields

§run_id: String

Run correlation id.

§tenant_id: TenantId

Tenant scope this event belongs to (see Started).

§tool_use_id: String

Stable tool-use id matching the originating ContentPart::ToolUse. Pairs with the subsequent ToolStart / ToolComplete / ToolError.

§tool: String

Tool name being approved.

§

ToolCallDenied

HITL approver decided to reject one tool dispatch. The matching ToolStart does NOT fire — denial short-circuits the dispatch path. The agent observes the rejection as Error::InvalidRequest carrying the same reason.

Fields

§run_id: String

Run correlation id.

§tenant_id: TenantId

Tenant scope this event belongs to (see Started).

§tool_use_id: String

Stable tool-use id of the rejected dispatch.

§tool: String

Tool name being denied.

§reason: String

Approver-supplied rationale.

Implementations§

Source§

impl<S> AgentEvent<S>

Source

pub fn to_graph_event(&self, timestamp: DateTime<Utc>) -> Option<GraphEvent>

Project this runtime event onto the durable audit-log shape GraphEvent. Returns None when the variant has no audit projection — Started, Complete, Failed are runtime-only lifecycle markers that do not belong in the per-thread audit trail.

The timestamp argument is supplied by the caller (typically Utc::now() at emit time) so this method stays pure: a single runtime event projected at two different points in time produces two distinct (but otherwise equal) GraphEvents.

Lossy projection notes — run_id, tool_version, and duration_ms are dropped because the audit log keys correlation by tool_use_id + timestamp and is not the home for runtime metrics. Operators who need run-level correlation in audit do it at the sink layer (e.g. by stamping a thread tag prior to append).

ToolError is mapped onto a GraphEvent::ToolResult with is_error: true and the error message carried as text content — preserving the same correlation key (tool_use_id) so a session replay can pair the failed dispatch back with the originating ToolCall.

Source

pub fn erase_state(self) -> AgentEvent<()>

Erase the agent-state type parameter, replacing Self::Complete::state with the unit value. Every other variant rebuilds with identical field values — they carry no state. Enables a single audit / SSE / OTel sink (typed AgentEventSink<()>) to fan in from heterogeneous agents (Agent<ReActState>, Agent<SupervisorState>, …) through the StateErasureSink adapter.

Operators consuming the post-erasure event tree retain access to every header field (run_id, tenant_id, parent_run_id) and every per-variant payload (tool inputs / outputs, error envelope, usage snapshot) — only the agent’s terminal state is dropped, which is the field a state-agnostic sink could not type-erase anyway.

§Examples
use entelix_agents::AgentEvent;
use entelix_core::TenantId;

let typed: AgentEvent<u32> = AgentEvent::Complete {
    run_id: "r1".into(),
    tenant_id: TenantId::new("t1"),
    state: 42_u32,
    usage: None,
};
let erased: AgentEvent<()> = typed.erase_state();
match erased {
    AgentEvent::Complete { state, .. } => assert_eq!(state, ()),
    _ => unreachable!(),
}

Trait Implementations§

Source§

impl<S> Clone for AgentEvent<S>
where S: Clone,

Source§

fn clone(&self) -> AgentEvent<S>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<S> Debug for AgentEvent<S>
where S: Debug,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl<S> PartialEq for AgentEvent<S>
where S: PartialEq,

Source§

fn eq(&self, other: &AgentEvent<S>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<S> Eq for AgentEvent<S>
where S: Eq,

Source§

impl<S> StructuralPartialEq for AgentEvent<S>

Auto Trait Implementations§

§

impl<S> Freeze for AgentEvent<S>
where S: Freeze,

§

impl<S> RefUnwindSafe for AgentEvent<S>
where S: RefUnwindSafe,

§

impl<S> Send for AgentEvent<S>
where S: Send,

§

impl<S> Sync for AgentEvent<S>
where S: Sync,

§

impl<S> Unpin for AgentEvent<S>
where S: Unpin,

§

impl<S> UnsafeUnpin for AgentEvent<S>
where S: UnsafeUnpin,

§

impl<S> UnwindSafe for AgentEvent<S>
where S: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> FutureExt for T

Source§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
Source§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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 more
Source§

impl<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<Unshared, Shared> IntoShared<Shared> for Unshared
where Shared: FromUnshared<Unshared>,

Source§

fn into_shared(self) -> Shared

Creates a shared type from an unshared type.
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more