#[non_exhaustive]pub struct ExecutionContext { /* private fields */ }Expand description
Carrier for request-scope state that every Runnable, Tool,
and codec sees.
Marked #[non_exhaustive]: fields are private; callers always go
through Self::new and the with_* builder methods, so adding
a new field is a non-breaking change.
tenant_id is a TenantId (validating Arc<str> newtype, see
crate::tenant_id). Cloning the context — done implicitly per
tool dispatch and per sub-agent — bumps the underlying refcount
instead of allocating. The default-tenant TenantId is shared
process-wide via a OnceLock, so a freshly-built context
allocates zero strings on the hot path.
Implementations§
Source§impl ExecutionContext
impl ExecutionContext
Sourcepub fn new() -> Self
pub fn new() -> Self
Create a fresh context with a new cancellation token, no deadline,
no thread ID, and the TenantId::default() tenant scope
(which is the process-wide shared "default" TenantId).
Sourcepub fn with_cancellation(cancellation: CancellationToken) -> Self
pub fn with_cancellation(cancellation: CancellationToken) -> Self
Create a context bound to an existing cancellation token (e.g. a parent agent’s token, so cancelling the parent cascades to children).
Sourcepub const fn with_deadline(self, deadline: Instant) -> Self
pub const fn with_deadline(self, deadline: Instant) -> Self
Attach a deadline. Returns self for builder-style chaining.
Sourcepub fn with_thread_id(self, thread_id: impl Into<String>) -> Self
pub fn with_thread_id(self, thread_id: impl Into<String>) -> Self
Attach a thread_id — the durable conversation key used by
Checkpointers to scope persistence.
Sourcepub fn with_tenant_id(self, tenant_id: TenantId) -> Self
pub fn with_tenant_id(self, tenant_id: TenantId) -> Self
Override the tenant scope. Multi-tenant operators set this per
request; single-tenant deployments leave it at
TenantId::default() (invariant 11).
Sourcepub fn with_run_id(self, run_id: impl Into<String>) -> Self
pub fn with_run_id(self, run_id: impl Into<String>) -> Self
Attach a run_id — the per-execute correlation key the agent
runtime stamps on every AgentEvent, OTel span, and tool
invocation event. Agent::execute generates a fresh UUID v7
on entry when none is set; recipes pre-allocate it only when
they need to correlate the run with an external reservation
(a workflow id minted by the caller, a database row id chosen
before dispatch). Sub-agents do not inherit the parent’s
run_id — they mint their own and the parent’s flows
through Self::with_parent_run_id for trace-tree
reconstruction.
Sourcepub fn with_parent_run_id(self, parent_run_id: impl Into<String>) -> Self
pub fn with_parent_run_id(self, parent_run_id: impl Into<String>) -> Self
Attach a parent_run_id — the run id of the calling agent
when this context represents a sub-agent dispatch. The
runtime sets this automatically when a parent Agent::execute
recurses into a child via crate::AgentContext; recipes
rarely call this directly. LangSmith-style trace-tree
consumers reconstruct hierarchy from (run_id, parent_run_id)
edges across AgentEvent::Started.
Sourcepub fn with_run_budget(self, budget: RunBudget) -> Self
pub fn with_run_budget(self, budget: RunBudget) -> Self
Attach a crate::RunBudget — six-axis usage cap shared
across the run (parent agent + every sub-agent it
dispatches). Cloning the context bumps the budget’s
internal Arc refcount so sub-agent dispatches accumulate
into the same counters.
Stored in Extensions under RunBudget’s TypeId, so
a second call replaces the prior budget. Read sites
reach for it via Self::run_budget; absent budget
makes every dispatch site’s check / observe a no-op.
Sourcepub fn run_budget(&self) -> Option<Arc<RunBudget>>
pub fn run_budget(&self) -> Option<Arc<RunBudget>>
Borrow the crate::RunBudget attached via
Self::with_run_budget, if any. Dispatch sites
(ChatModel::complete_full / complete_typed /
stream_deltas, ToolRegistry::dispatch_*) gate budget
checks on Some(_) so a context without a budget incurs
zero overhead beyond the TypeId lookup.
Sourcepub fn with_idempotency_key(self, key: impl Into<String>) -> Self
pub fn with_idempotency_key(self, key: impl Into<String>) -> Self
Attach an idempotency key — the vendor-side dedupe identifier
shared across every retry attempt of one logical call.
Operators that pre-allocate the key (e.g. for cross-process
dedupe through a sticky job id) call this before dispatch;
otherwise RetryService stamps a UUID on first entry.
Sourcepub fn ensure_idempotency_key<F>(&mut self, generate: F) -> &str
pub fn ensure_idempotency_key<F>(&mut self, generate: F) -> &str
Mutable handle to the idempotency-key slot — RetryService
uses this to stamp a fresh key on first entry of a retry
loop (so attempts 2..N share the slot the first attempt set).
Outside the retry middleware, prefer
Self::with_idempotency_key.
Sourcepub fn with_audit_sink(self, handle: AuditSinkHandle) -> Self
pub fn with_audit_sink(self, handle: AuditSinkHandle) -> Self
Attach an AuditSinkHandle for the current run. Sub-agents,
supervisors, and memory tools look it up via
Self::audit_sink and emit typed
crate::audit::AuditSink events; the absent handle makes
every emit site a no-op.
Stored in Extensions under AuditSinkHandle’s TypeId,
so a second call replaces the prior handle (single sink per
run by design — recipes that need fan-out wrap two sinks
behind one impl).
Sourcepub fn audit_sink(&self) -> Option<Arc<AuditSinkHandle>>
pub fn audit_sink(&self) -> Option<Arc<AuditSinkHandle>>
Borrow the AuditSinkHandle for the current run, if one
has been attached via Self::with_audit_sink. Emit sites
gate on Some(_) so a context without a sink incurs no
overhead beyond the TypeId lookup.
Sourcepub fn with_tool_progress_sink(self, handle: ToolProgressSinkHandle) -> Self
pub fn with_tool_progress_sink(self, handle: ToolProgressSinkHandle) -> Self
Attach a ToolProgressSinkHandle for the current run.
Long-running tools emit phase transitions through
Self::record_phase / Self::record_phase_with and the
SDK fans the transition into this sink. Absent handle makes
every emit site a silent no-op.
Stored in Extensions under ToolProgressSinkHandle’s
TypeId, so a second call replaces the prior handle (single
sink per run by design — recipes that need fan-out wrap two
sinks behind one impl).
Sourcepub fn tool_progress_sink(&self) -> Option<Arc<ToolProgressSinkHandle>>
pub fn tool_progress_sink(&self) -> Option<Arc<ToolProgressSinkHandle>>
Borrow the ToolProgressSinkHandle for the current run, if
one has been attached.
Sourcepub async fn record_phase(
&self,
phase: impl Into<String> + Send,
status: ToolProgressStatus,
)
pub async fn record_phase( &self, phase: impl Into<String> + Send, status: ToolProgressStatus, )
Emit a tool-phase transition with no metadata.
Silent no-op when no ToolProgressSinkHandle is attached or
when the call is outside a tool dispatch (no
CurrentToolInvocation marker on the context). See
Self::record_phase_with for the metadata-bearing variant.
Fire-and-forget — sink failures stay inside the sink and never
propagate to the tool body (invariant 4 + 18).
Sourcepub async fn record_phase_with(
&self,
phase: impl Into<String> + Send,
status: ToolProgressStatus,
metadata: Value,
)
pub async fn record_phase_with( &self, phase: impl Into<String> + Send, status: ToolProgressStatus, metadata: Value, )
Emit a tool-phase transition with structured metadata.
metadata flows through to the sink alongside the phase
identity — UIs render percent-complete / item-counts /
partial-result counts from this field. Tools that have nothing
to attach pass Self::record_phase instead. Fire-and-forget —
sink failures stay inside the sink.
Sourcepub fn add_extension<T>(self, value: T) -> Self
pub fn add_extension<T>(self, value: T) -> Self
Attach a typed cross-cutting value to the context’s
Extensions slot. The returned context carries a fresh
Extensions Arc with value registered under T’s
TypeId; the caller’s previous context is unchanged
(copy-on-write).
One entry per type — calling this twice with the same T
replaces the earlier value. Operators threading multiple
values of the same logical category wrap them in a domain
type (struct WorkspaceCtx { repo: ..., flags: ... }) so
T stays the canonical key.
Read back via Self::extension inside any tool, codec,
or runnable that sees the context.
Invariant 10: do not stash credentials or bearer
tokens here — ExecutionContext flows into Tool::execute
and an extension carrying a token would surface it to
every tool the agent dispatches. Credentials live in
transports (CredentialProvider).
Sourcepub const fn cancellation(&self) -> &CancellationToken
pub const fn cancellation(&self) -> &CancellationToken
Borrow the cancellation token. Long-running tools should periodically
check is_cancelled() and cooperatively shut down.
Sourcepub const fn tenant_id(&self) -> &TenantId
pub const fn tenant_id(&self) -> &TenantId
Borrow the tenant identifier (invariant 11). Always present —
defaults to the process-shared TenantId::default() when
not explicitly set.
Sourcepub fn run_id(&self) -> Option<&str>
pub fn run_id(&self) -> Option<&str>
Borrow the per-execute correlation id, if one has been
stamped (typically by Agent::execute on entry, or by a
caller pre-allocating via Self::with_run_id).
Sourcepub fn parent_run_id(&self) -> Option<&str>
pub fn parent_run_id(&self) -> Option<&str>
Borrow the parent run id, if this context represents a
sub-agent or tool-driven dispatch under a parent
Agent::execute. None at the root.
Sourcepub fn idempotency_key(&self) -> Option<&str>
pub fn idempotency_key(&self) -> Option<&str>
Borrow the idempotency key for the current logical call, if
one has been stamped (by RetryService on first entry of a
retry loop, or by a caller pre-allocating via
Self::with_idempotency_key). DirectTransport and the
cloud transports forward this on the Idempotency-Key
request header so vendors dedupe retries server-side.
Sourcepub const fn extensions(&self) -> &Extensions
pub const fn extensions(&self) -> &Extensions
Borrow the typed cross-cutting carrier. Use
Self::extension for the common single-type lookup;
reach for the carrier directly only when iterating over
cardinality or composing a downstream context that should
inherit the same set.
Sourcepub fn extension<T>(&self) -> Option<Arc<T>>
pub fn extension<T>(&self) -> Option<Arc<T>>
Look up the extension entry registered for T, returning
a refcounted handle independent of the context’s lifetime.
Returns None when the entry is absent — operators reading
optional cross-cutting state code their own default.
Sourcepub fn is_cancelled(&self) -> bool
pub fn is_cancelled(&self) -> bool
Convenience: did the cancellation token fire?
Sourcepub fn child(&self) -> Self
pub fn child(&self) -> Self
Derive a scoped child context. The child inherits deadline,
thread_id, and tenant_id but holds a child cancellation
token: cancelling the child does NOT cancel the parent, but
cancelling the parent cascades to the child.
Use for scope-bounded fan-out (e.g. scatter) where a
fail-fast branch should signal still-running siblings to
abort cooperatively without tearing the whole request down.
Trait Implementations§
Source§impl Clone for ExecutionContext
impl Clone for ExecutionContext
Source§fn clone(&self) -> ExecutionContext
fn clone(&self) -> ExecutionContext
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more