pub struct AgentContext {Show 33 fields
pub agent_id: String,
pub config: Arc<AgentConfig>,
pub broker: AnyBroker,
pub sessions: Arc<SessionManager>,
pub memory: Option<Arc<LongTermMemory>>,
pub router: Option<Arc<AgentRouter>>,
pub peers: Option<Arc<PeerDirectory>>,
pub mcp: Option<Arc<SessionMcpRuntime>>,
pub session_id: Option<Uuid>,
pub effective: Option<Arc<EffectiveBindingPolicy>>,
pub effective_tools: Option<Arc<ToolRegistry>>,
pub credentials: Option<Arc<AgentCredentialResolver>>,
pub breakers: Option<Arc<BreakerRegistry>>,
pub redactor: Option<Arc<Redactor>>,
pub transcripts_index: Option<Arc<TranscriptsIndex>>,
pub link_extractor: Option<Arc<LinkExtractor>>,
pub web_search_router: Option<Arc<WebSearchRouter>>,
pub context_optimization: Option<ResolvedContextOptimization>,
pub event_emitter: Option<Arc<dyn AgentEventEmitter>>,
pub dispatch: Option<Arc<DispatchToolContext>>,
pub repl_registry: Option<Arc<ReplRegistry>>,
pub sender_trusted: bool,
pub inbound_origin: Option<(String, String, String)>,
pub plan_mode: Arc<RwLock<PlanModeState>>,
pub plan_approval_registry: Arc<PlanApprovalRegistry>,
pub todos: Arc<RwLock<TodoList>>,
pub team_id: Option<String>,
pub team_member_name: Option<String>,
pub inbox: Arc<RwLock<Vec<DmMessage>>>,
pub proactive_enabled: bool,
pub binding_role: Option<String>,
pub binding: Option<BindingContext>,
pub inbound: Option<InboundMessageMeta>,
/* private fields */
}Fields§
§agent_id: String§config: Arc<AgentConfig>§broker: AnyBroker§sessions: Arc<SessionManager>§memory: Option<Arc<LongTermMemory>>§router: Option<Arc<AgentRouter>>§peers: Option<Arc<PeerDirectory>>Snapshot of peer agents running in this process. Feeds the
auto-generated # PEERS system-prompt block so the LLM knows
which ids to pass to delegate(...). None in test/bootstrap
contexts where peer discovery doesn’t apply.
mcp: Option<Arc<SessionMcpRuntime>>Phase 12.4 — MCP runtime scoped to this session (if MCP is enabled).
session_id: Option<Uuid>Phase 11.5 follow-up — active session id when the context is built inside an LLM turn. None for contexts built outside the loop (heartbeat bootstrap, tests). Used by tool handlers that opt into context passthrough.
effective: Option<Arc<EffectiveBindingPolicy>>Per-binding capability snapshot resolved at intake. Some when the
runtime matched the inbound event to an InboundBinding for this
agent; None for paths without a binding match (delegation
receive, heartbeat, tests). Use AgentContext::effective_policy
to access a policy that always has a value — it synthesises one
from the agent-level config when effective is None.
effective_tools: Option<Arc<ToolRegistry>>Per-binding tool registry — shares handlers with the agent’s base
registry but only exposes tools that survive the binding’s
allowed_tools filter. None on code paths without a binding
match (delegation receive, heartbeat, tests); consumers fall
back to the behavior’s base registry in that case.
credentials: Option<Arc<AgentCredentialResolver>>Phase 17 — resolver that maps this agent’s id to the opaque
credential handles it is allowed to use for outbound traffic.
None in early-boot / test contexts; consumers must treat that
as “no credentials configured” (tools return an unbound error
rather than publishing from an arbitrary account).
breakers: Option<Arc<BreakerRegistry>>Phase 17 — per-(channel, instance) breaker registry shared by
plugin outbound tools. None for runtimes without credentials.
redactor: Option<Arc<Redactor>>Pre-persistence redactor for transcript content. None in
test/bootstrap contexts → behavior keeps content untouched.
transcripts_index: Option<Arc<TranscriptsIndex>>FTS5 index over transcript content. None when the subsystem
is disabled or initialization failed; consumers fall back to
JSONL-only persistence + substring scan.
link_extractor: Option<Arc<LinkExtractor>>Phase 21 — shared link extractor (HTTP client + LRU cache).
None in early-boot / test contexts; llm_behavior treats
that as “link understanding disabled regardless of config”.
web_search_router: Option<Arc<WebSearchRouter>>Phase 25 — shared multi-provider web-search router. None
when no provider is configured for this process; the
web_search tool errors out cleanly in that case.
context_optimization: Option<ResolvedContextOptimization>Phase F follow-up (hot-reload) — current effective enables for
the four context-optimization mechanisms. Set per-event by
AgentRuntime from RuntimeSnapshot::context_optimization, so
a config reload that flips a flag is observed on the next
turn without restarting the behavior. None for legacy /
test contexts that haven’t been wired through the snapshot —
in that case llm_behavior falls back to the boot-time
prompt_cache_enabled / compaction_runtime.enabled flags.
event_emitter: Option<Arc<dyn AgentEventEmitter>>Phase 82.11.c — agent event emitter threaded from the
AgentRuntime so llm_behavior can attach it to
per-turn TranscriptWriter instances. Without this,
transcript appends emit through the default
NoopAgentEventEmitter and never reach the bootstrap’s
broadcast firehose, leaving subscribers (microapps with
agent_events_subscribe_all) silent on live updates.
None for test/bootstrap contexts; consumers fall back
to no-op emission in that case.
dispatch: Option<Arc<DispatchToolContext>>PT-1 — bundle of services consumed by the dispatch tool
handlers (program_phase, list_agents, etc.). Populated at
boot when the project tracker is enabled. None keeps the
dispatch tools off — handlers return a friendly error so
the LLM doesn’t pretend they worked.
repl_registry: Option<Arc<ReplRegistry>>Phase 79.12 — REPL session registry. Some when repl-tool
feature is enabled AND the binding config has repl.enabled.
Holds persistent Python/Node/bash subprocesses.
sender_trusted: boolB3 — sender’s pairing-trust bit, set by intake after the
pairing gate runs (Phase 26). Defaults to false so any
path that forgets to thread it through fails closed under
require_trusted=true. Read-only tools bypass this gate.
inbound_origin: Option<(String, String, String)>B3 — (plugin, instance, sender_id) of the inbound event
that produced this turn, when the runtime matched a binding.
Lets the dispatch handler synthesise an OriginChannel for
program_phase so notify_origin lands back in the chat.
plan_mode: Arc<RwLock<PlanModeState>>Phase 79.1 — plan-mode state for this goal. Shared across the
dispatcher (read on every tool call) and the EnterPlanMode /
ExitPlanMode tools (write). SQLite is canonical (column on
agent_registry.goals.plan_mode); this is a hot cache. New
contexts default to Off; the runtime hydrates the value from
the registry at goal spawn / reattach (Phase 71).
plan_approval_registry: Arc<PlanApprovalRegistry>Phase 79.1 — process-shared registry of pending plan-mode
approvals. EnterPlanMode does not touch it; ExitPlanMode
installs a waiter when plan_mode.require_approval is on; the
plan_mode_resolve operator tool fires the matching waiter.
Tests construct their own registry to avoid cross-test races.
todos: Arc<RwLock<TodoList>>Phase 79.4 — intra-turn scratch todo list. Owned by the model
(mutated via TodoWrite). Distinct from Phase 14 TaskFlow:
Todo is in-memory + per-goal + flat; TaskFlow is persistent
- cross-session + DAG. Reattach does not restore todos — they die with the goal because re-deriving them mid-turn is cheap and stale items are confusing.
team_id: Option<String>Phase 79.6 — when set, this goal is running as a member
of a named team. The lead’s team_id is its own team’s
id; ordinary sub-agents stay None.
team_member_name: Option<String>Phase 79.6 — human-readable member name within
team_id (e.g. "researcher"). None ⇔ team_id.is_none().
Some(TEAM_LEAD_NAME) for the lead’s own goal.
inbox: Arc<RwLock<Vec<DmMessage>>>Phase 79.6 — DMs the team router delivered while this goal was running. Consumed at the start of each turn by the prompt-assembly path. Concurrent appends are serialised by the goal’s tokio task scheduler — there is no inner lock because the consume is single-threaded per-goal.
proactive_enabled: boolPhase 77.20 — whether this goal runs in proactive tick-loop mode.
Set at goal spawn from EffectiveBindingPolicy::proactive().enabled.
Read by llm_behavior to inject the proactive system hint.
binding_role: Option<String>Phase 77.20 — binding role tag ("coordinator", "worker", "proactive",
or None). Stored here so llm_behavior can inject the coordinator
hint without re-reading the binding config on every turn.
binding: Option<BindingContext>Phase 82.1 Step 3 — composed binding context propagated
to tool calls via _meta.nexo.binding. Some when
intake matched an InboundBinding; None for
bindingless paths (delegation receive, heartbeat
bootstrap, tests).
Construct via super::binding_context_from_effective(&policy, agent_id, session_id) at the intake site that matches
the binding (Step 4). Tool dispatch reads this through
inject_context_meta to populate the JSON-RPC
params._nexo_context block (Step 5).
inbound: Option<InboundMessageMeta>Phase 82.5 — per-turn metadata about the inbound message
that triggered this agent turn (sender id, msg id,
timestamp, …). Some when the intake site populated it
(whatsapp plugin, event-subscriber binding, webhook
receiver, delegation receive, heartbeat tick, …); None
for legacy producers not yet migrated and for tests.
Surfaces under _meta.nexo.inbound via
AgentContext::build_meta_value.
Implementations§
Source§impl AgentContext
impl AgentContext
pub fn new( agent_id: impl Into<String>, config: Arc<AgentConfig>, broker: AnyBroker, sessions: Arc<SessionManager>, ) -> Self
Sourcepub fn with_team(
self,
team_id: impl Into<String>,
name: impl Into<String>,
) -> Self
pub fn with_team( self, team_id: impl Into<String>, name: impl Into<String>, ) -> Self
Phase 79.6 — mark this context as running as a teammate.
name is the human-readable handle within the team
("researcher", "tester", or TEAM_LEAD_NAME).
Sourcepub fn is_teammate(&self) -> bool
pub fn is_teammate(&self) -> bool
Phase 79.6 — true when both team_id and
team_member_name are set. The runtime’s
teammate-cannot-spawn-teammate guard inspects this.
Sourcepub fn with_plan_mode(self, state: Arc<RwLock<PlanModeState>>) -> Self
pub fn with_plan_mode(self, state: Arc<RwLock<PlanModeState>>) -> Self
Phase 79.1 — install a pre-built plan-mode handle. Used at
goal hydration so the runtime can share the same Arc<RwLock>
between the dispatcher (gate) and the registry mirror (write
path).
Sourcepub fn with_plan_approval_registry(
self,
registry: Arc<PlanApprovalRegistry>,
) -> Self
pub fn with_plan_approval_registry( self, registry: Arc<PlanApprovalRegistry>, ) -> Self
Phase 79.1 — install a process-shared plan-mode approval
registry. Production wiring constructs one per process and
hands it to every AgentContext; tests build their own to
avoid cross-test races.
Sourcepub fn is_interactive(&self) -> bool
pub fn is_interactive(&self) -> bool
Phase 79.1 — true when this goal is rooted in a live channel
that can deliver an operator approval message. Sub-agent goals
(delegations, future TeamCreate workers), cron / poller /
heartbeat-spawned goals, and bootstrap contexts all return
false because they have no inbound channel through which an
operator could approve a plan.
Reference: research/src/acp/session-interaction-mode.ts:4-15
— same intent, “interactive” vs “parent-owned-background”.
pub fn with_sender_trusted(self, v: bool) -> Self
pub fn with_inbound_origin( self, plugin: impl Into<String>, instance: impl Into<String>, sender_id: impl Into<String>, ) -> Self
Sourcepub fn with_inbound_meta(self, meta: InboundMessageMeta) -> Self
pub fn with_inbound_meta(self, meta: InboundMessageMeta) -> Self
Phase 82.5 — install per-turn InboundMessageMeta on the
context. Producers (channel plugins, event-subscriber,
delegation, heartbeat) build the meta at the intake site and
the per-turn dispatch loop layers it on the cloned context
before invoking tools / hooks.
pub fn with_dispatch(self, d: Arc<DispatchToolContext>) -> Self
pub fn with_web_search_router(self, router: Arc<WebSearchRouter>) -> Self
Sourcepub fn with_context_optimization(self, co: ResolvedContextOptimization) -> Self
pub fn with_context_optimization(self, co: ResolvedContextOptimization) -> Self
Set the per-turn context-optimization snapshot. Called by the
agent runtime intake after loading the active RuntimeSnapshot,
so a hot-reload that swaps the snapshot is observed without
rebuilding the behavior.
pub fn with_redactor(self, redactor: Arc<Redactor>) -> Self
Sourcepub fn with_event_emitter(self, emitter: Arc<dyn AgentEventEmitter>) -> Self
pub fn with_event_emitter(self, emitter: Arc<dyn AgentEventEmitter>) -> Self
Phase 82.11.c — install the firehose emitter so per-turn
TranscriptWriter instances built in llm_behavior can
chain .with_emitter() and broadcast TranscriptAppended
to subscribers.
pub fn with_transcripts_index(self, index: Arc<TranscriptsIndex>) -> Self
pub fn with_link_extractor(self, ext: Arc<LinkExtractor>) -> Self
pub fn with_memory(self, memory: Arc<LongTermMemory>) -> Self
pub fn with_router(self, router: Arc<AgentRouter>) -> Self
pub fn with_peers(self, peers: Arc<PeerDirectory>) -> Self
pub fn with_mcp(self, mcp: Arc<SessionMcpRuntime>) -> Self
pub fn with_session_id(self, id: Uuid) -> Self
pub fn with_effective(self, effective: Arc<EffectiveBindingPolicy>) -> Self
Sourcepub fn with_mcp_channel_source(self, source: impl Into<String>) -> Self
pub fn with_mcp_channel_source(self, source: impl Into<String>) -> Self
Phase 82.1 Step 4 — layer the Phase 80.9 MCP channel
source on top of the BindingContext after
with_effective has run. No-op if binding is None
(paths without a binding match cannot have an
MCP-channel source — the source rides alongside an
already-matched binding, not as a substitute).
pub fn with_effective_tools(self, tools: Arc<ToolRegistry>) -> Self
Sourcepub fn with_event_source(self, meta: EventSourceMeta) -> Self
pub fn with_event_source(self, meta: EventSourceMeta) -> Self
Phase 82.4.b.b — populate binding.event_source when the
inbound was synthesised from a NATS event subscriber.
No-op when self.binding is None; logged at debug level
so the call-site can stay branchless if the caller doesn’t
want to gate the call. Caller is expected to gate at the
call site for hot paths (every native-channel inbound
passing through the resolver).
pub fn with_credentials(self, credentials: Arc<AgentCredentialResolver>) -> Self
pub fn with_breakers(self, breakers: Arc<BreakerRegistry>) -> Self
Sourcepub fn effective_policy(&self) -> Arc<EffectiveBindingPolicy> ⓘ
pub fn effective_policy(&self) -> Arc<EffectiveBindingPolicy> ⓘ
Returns the active effective policy, synthesising one from the
agent-level config when no binding was matched. Cheap to call in
hot paths: returns an existing Arc when available and builds a
fresh one only for unbound contexts.
Sourcepub fn build_meta_value(&self) -> Value
pub fn build_meta_value(&self) -> Value
Phase 82.1 Step 6 — single source of truth for the _meta
payload exposed to extension tools (Phase 11 stdio JSON-RPC)
and MCP tools (tools/call params._meta). Both surfaces
must emit identical wire shapes so a microapp speaks the
same dialect regardless of which transport delivered the
call.
Returned value is a JSON object with two layers:
- flat
agent_id+session_idfor backward-compat with pre-Phase-82 consumers, - nested
nexo.bindingcarryingBindingContextwhen the intake matched a binding (omitted otherwise to keep the wire compact for delegation receive / heartbeat bootstrap / tests).
Trait Implementations§
Source§impl Clone for AgentContext
impl Clone for AgentContext
Source§fn clone(&self) -> AgentContext
fn clone(&self) -> AgentContext
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for AgentContext
impl !RefUnwindSafe for AgentContext
impl Send for AgentContext
impl Sync for AgentContext
impl Unpin for AgentContext
impl UnsafeUnpin for AgentContext
impl !UnwindSafe for AgentContext
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> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
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 more