Skip to main content

ChildSessionAdapter

Struct ChildSessionAdapter 

Source
pub struct ChildSessionAdapter { /* private fields */ }
Expand description

Server-side adapter that bridges domain ChildSessionPort to infrastructure.

Holds all shared state needed by SubAgentTool. Implements the full ChildSessionPort trait with real methods (no stubs).

Implementations§

Source§

impl ChildSessionAdapter

Source

pub fn new( session_store: Arc<SessionStoreV2>, storage: Arc<dyn Storage>, persistence: Arc<LockedSessionStore>, scheduler: Arc<SpawnScheduler>, sessions_cache: SessionCache, agent_runners: Arc<RwLock<HashMap<String, AgentRunner>>>, session_event_senders: Arc<RwLock<HashMap<String, Sender<AgentEvent>>>>, subagent_model_resolver: OptionalSubagentModelResolver, config: Arc<RwLock<Config>>, ) -> Self

Construct an adapter. Public so a self-orchestrating WORKER (Phase 6: direct nested execution) can build its OWN child-session machinery against its own store/scheduler — the struct fields are pub(crate), so out-of-crate callers (the worker binary) go through this constructor.

Source

pub async fn resolve_subagent_model( &self, subagent_type: &str, ) -> Option<ProviderModelRef>

Resolve the provider+model ref for a given subagent_type using the configured resolver.

Source

pub async fn resolve_runtime_metadata( &self, subagent_type: &str, ) -> HashMap<String, String>

Resolve runtime metadata (e.g. external agent routing) for a subagent_type.

Source

pub async fn register_parent_wait_for_child( &self, parent_session_id: &str, child_session_id: &str, tool_call_id: Option<&str>, ) -> Result<(), ChildSessionError>

Register a durable parent wait for an enqueued child session.

This is intentionally idempotent: repeated registrations for the same child merge into the existing wait set. The child runner owns timeout and liveness; the parent wait timeout is a long lease for observability.

Registrations are coalesced per parent: when several children are spawned in one round (the LLM issuing multiple SubAgent.create calls that join_all runs concurrently), the first call to win the per-parent barrier drains all currently-pending registrations and persists the parent once, instead of each child triggering its own load+write. Callers whose child was drained-and-persisted by that holder return without an extra write — and only after the holder’s write committed, so durability holds.

Source

pub async fn register_parent_wait_for_children( &self, parent_session_id: &str, child_session_ids: &[String], policy: ChildWaitPolicy, ) -> Result<usize, ChildSessionError>

Explicitly register a parent wait for an arbitrary set of children with a chosen policy. Used by the SubAgent.wait action (wait on all active children) and the end-of-turn safety net. A single parent write.

Returns the number of children the wait now covers (0 means there was nothing to wait on and no wait was registered).

Source

pub async fn active_child_ids(&self, parent_session_id: &str) -> Vec<String>

The parent’s currently-active (non-terminal) children, derived from the session index (single source of truth).

Trait Implementations§

Source§

impl ChildSessionPort for ChildSessionAdapter

Source§

fn load_root_session<'life0, 'life1, 'async_trait>( &'life0 self, root_session_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Session, ChildSessionError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Source§

fn load_child_for_parent<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, parent_session_id: &'life1 str, child_session_id: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<Session, ChildSessionError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Source§

fn save_child_session<'life0, 'life1, 'async_trait>( &'life0 self, child: &'life1 mut Session, ) -> Pin<Box<dyn Future<Output = Result<(), ChildSessionError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Source§

fn is_child_running<'life0, 'life1, 'async_trait>( &'life0 self, child_session_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = bool> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Source§

fn list_children<'life0, 'life1, 'async_trait>( &'life0 self, parent_session_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Vec<ChildSessionEntry>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Source§

fn find_resident_child<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, root_session_id: &'life1 str, resident_name: &'life2 str, ) -> Pin<Box<dyn Future<Output = Option<String>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Find an existing resident agent in the same root tree by its stable resident_name, returning its child session id if one exists. Used to reuse a resident agent for a new task instead of minting a new child. Index-backed (matches root_session_id + metadata["resident_name"]).
Source§

fn enqueue_child_run<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, parent: &'life1 Session, child: &'life2 Session, ) -> Pin<Box<dyn Future<Output = Result<(), ChildSessionError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Source§

fn cancel_child_run_and_wait<'life0, 'life1, 'async_trait>( &'life0 self, child_session_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<(), ChildSessionError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Source§

fn delete_child_session<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, parent_session_id: &'life1 str, child_id: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<DeleteChildResult, ChildSessionError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Source§

fn get_child_runner_info<'life0, 'life1, 'async_trait>( &'life0 self, child_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Option<ChildRunnerInfo>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Return live diagnostic info for a running child session, if available.
Source§

fn register_parent_wait_for_child<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, parent_session_id: &'life1 str, child_session_id: &'life2 str, tool_call_id: Option<&'life3 str>, ) -> Pin<Box<dyn Future<Output = Result<(), ChildSessionError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Register a durable parent wait for a single enqueued child. Idempotent and coalesced per parent (concurrent sibling spawns merge into one write).
Source§

fn register_parent_wait_for_children<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, parent_session_id: &'life1 str, child_session_ids: &'life2 [String], policy: ChildWaitPolicy, ) -> Pin<Box<dyn Future<Output = Result<usize, ChildSessionError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Register a durable parent wait over an explicit set of children with a chosen policy (the SubAgent.wait action). Returns the number of children the wait now covers (0 = nothing to wait on).
Source§

fn active_child_ids<'life0, 'life1, 'async_trait>( &'life0 self, parent_session_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Vec<String>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

The parent’s currently-active (non-terminal) child session ids.
Source§

fn ensure_child_indexed<'life0, 'life1, 'async_trait>( &'life0 self, child_session_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Best-effort: ensure the child’s session-index entry is visible immediately after creation (the index is otherwise eventually consistent). Failures are ignored by the caller.
Source§

impl GuardianSpawner for ChildSessionAdapter

Lets a ChildSessionAdapter act as the engine’s guardian-review spawner.

Arc<ChildSessionAdapter> therefore doubles as Arc<dyn GuardianSpawner> (wired onto AppState), so the terminal gate spawns the read-only reviewer through the same child-session machinery the SubAgent tool uses — no second spawn path. The reviewer is a real sub-agent: it fetches the diff and runs tests itself via its (read-only) toolset.

Source§

fn spawn_guardian_review<'life0, 'life1, 'async_trait>( &'life0 self, parent_session: &'life1 Session, review_prompt: String, model: String, disabled_tools: Option<BTreeSet<String>>, ) -> Pin<Box<dyn Future<Output = Result<String, String>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Create a read-only reviewer child for parent_session_id, seeded with review_prompt, enqueue it to run, and return its session id so the caller can register a wait on it.
Source§

impl SubagentResolutionPort for ChildSessionAdapter

Source§

fn resolve_subagent_model<'life0, 'life1, 'async_trait>( &'life0 self, subagent_type: &'life1 str, ) -> Pin<Box<dyn Future<Output = Option<ProviderModelRef>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Provider+model ref for a subagent_type, or None to use defaults.
Source§

fn resolve_runtime_metadata<'life0, 'life1, 'async_trait>( &'life0 self, subagent_type: &'life1 str, ) -> Pin<Box<dyn Future<Output = HashMap<String, String>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Runtime metadata (e.g. external-agent routing) for a subagent_type.

Auto Trait Implementations§

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + 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: Sized + 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> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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