Skip to main content

SubAgentManager

Struct SubAgentManager 

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

Manages sub-agent lifecycle: definitions, spawning, cancellation, and result collection.

Implementations§

Source§

impl SubAgentManager

Source

pub fn new(max_concurrent: usize) -> Self

Create a new manager with the given concurrency limit.

Source

pub fn reserve_slots(&mut self, n: usize)

Reserve n concurrency slots for the orchestration scheduler.

Reserved slots count against the concurrency limit in spawn so that the scheduler can guarantee capacity for tasks it is about to launch. Call release_reservation when the scheduler finishes.

Source

pub fn release_reservation(&mut self, n: usize)

Release n previously reserved concurrency slots.

Source

pub fn set_transcript_config(&mut self, dir: Option<PathBuf>, max_files: usize)

Configure transcript storage settings.

Source

pub fn set_stop_hooks(&mut self, hooks: Vec<HookDef>)

Set config-level lifecycle stop hooks (fired when any agent finishes or is cancelled).

Source

pub fn load_definitions( &mut self, dirs: &[PathBuf], ) -> Result<(), SubAgentError>

Load sub-agent definitions from the given directories.

Higher-priority directories should appear first. Name conflicts are resolved by keeping the first occurrence. Non-existent directories are silently skipped.

§Errors

Returns SubAgentError if any definition file fails to parse.

Source

pub fn load_definitions_with_sources( &mut self, ordered_paths: &[PathBuf], cli_agents: &[PathBuf], config_user_dir: Option<&PathBuf>, extra_dirs: &[PathBuf], ) -> Result<(), SubAgentError>

Load definitions with full scope context for source tracking and security checks.

§Errors

Returns SubAgentError if a CLI-sourced definition file fails to parse.

Source

pub fn definitions(&self) -> &[SubAgentDef]

Return all loaded definitions.

Source

pub fn definitions_mut(&mut self) -> &mut Vec<SubAgentDef>

Return mutable access to definitions, for testing and dynamic registration.

Source

pub fn insert_handle_for_test(&mut self, id: String, handle: SubAgentHandle)

Insert a pre-built handle directly into the active agents map.

Used in tests to simulate an agent that has already run and left a pending secret request in its channel without going through the full spawn lifecycle.

Source

pub fn spawn( &mut self, def_name: &str, task_prompt: &str, provider: AnyProvider, tool_executor: Arc<dyn ErasedToolExecutor>, skills: Option<Vec<String>>, config: &SubAgentConfig, ctx: SpawnContext, ) -> Result<String, SubAgentError>

Spawn a sub-agent by definition name with real background execution.

Returns the task_id (UUID string) that can be used with cancel and collect.

§Errors

Returns SubAgentError::NotFound if no definition with the given name exists, SubAgentError::ConcurrencyLimit if the concurrency limit is exceeded, or SubAgentError::Invalid if the agent requests bypass_permissions but the config does not allow it (allow_bypass_permissions: false).

Source

pub fn shutdown_all(&mut self)

Cancel all active sub-agents. Called during main agent shutdown.

Source

pub fn cancel(&mut self, task_id: &str) -> Result<(), SubAgentError>

Cancel a running sub-agent by task ID.

§Errors

Returns SubAgentError::NotFound if the task ID is unknown.

Source

pub fn cancel_all(&mut self)

Cancel all active sub-agents immediately.

Used during shutdown or Ctrl+C handling when DagScheduler may not be running. For coordinated cancellation via the scheduler, use DagScheduler::cancel_all().

Source

pub fn approve_secret( &mut self, task_id: &str, secret_key: &str, ttl: Duration, ) -> Result<(), SubAgentError>

Approve a secret request for a running sub-agent.

Called after the user approves a vault secret access prompt. The secret key must appear in the sub-agent definition’s allowed secrets list; otherwise the request is auto-denied.

§Errors

Returns SubAgentError::NotFound if the task ID is unknown, SubAgentError::Invalid if the key is not in the definition’s allowed list.

Source

pub fn deliver_secret( &mut self, task_id: &str, key: String, ) -> Result<(), SubAgentError>

Deliver a secret value to a waiting sub-agent loop.

Should be called after the user approves the request and the vault value has been resolved. Returns an error if no such agent is found.

§Errors

Returns SubAgentError::NotFound if the task ID is unknown.

Source

pub fn deny_secret(&mut self, task_id: &str) -> Result<(), SubAgentError>

Deny a pending secret request — sends None to unblock the waiting sub-agent loop.

§Errors

Returns SubAgentError::NotFound if the task ID is unknown, SubAgentError::Channel if the channel is full or closed.

Source

pub fn try_recv_secret_request(&mut self) -> Option<(String, SecretRequest)>

Try to receive a pending secret request from a sub-agent (non-blocking).

Returns Some((task_id, SecretRequest)) if a request is waiting.

Source

pub async fn collect(&mut self, task_id: &str) -> Result<String, SubAgentError>

Collect the result from a completed sub-agent, removing it from the active set.

Writes a final TranscriptMeta sidecar with the terminal state and turn count.

§Errors

Returns SubAgentError::NotFound if the task ID is unknown, SubAgentError::Spawn if the task panicked.

Source

pub fn resume( &mut self, id_prefix: &str, task_prompt: &str, provider: AnyProvider, tool_executor: Arc<dyn ErasedToolExecutor>, skills: Option<Vec<String>>, config: &SubAgentConfig, ) -> Result<(String, String), SubAgentError>

Resume a previously completed (or failed/cancelled) sub-agent session.

Loads the transcript from the original session into memory and spawns a new agent loop with that history prepended. The new session gets a fresh UUID.

Returns (new_task_id, def_name) on success so the caller can resolve skills by name.

§Errors

Returns SubAgentError::StillRunning if the agent is still active, SubAgentError::NotFound if no transcript with the given prefix exists, SubAgentError::AmbiguousId if the prefix matches multiple agents, SubAgentError::Transcript on I/O or parse failure, SubAgentError::ConcurrencyLimit if the concurrency limit is exceeded.

Source

pub fn def_name_for_resume( &self, id_prefix: &str, config: &SubAgentConfig, ) -> Result<String, SubAgentError>

Look up the definition name for a resumable transcript without spawning.

Used by callers that need to resolve skills before calling resume().

§Errors

Returns the same errors as TranscriptReader::find_by_prefix and TranscriptReader::load_meta.

Source

pub fn statuses(&self) -> Vec<(String, SubAgentStatus)>

Return a snapshot of all active sub-agent statuses.

Source

pub fn agents_def(&self, task_id: &str) -> Option<&SubAgentDef>

Return the definition for a specific agent by task_id.

Source

pub fn agent_transcript_dir(&self, task_id: &str) -> Option<&Path>

Return the transcript directory for a specific agent by task_id.

Source

pub fn spawn_for_task<F>( &mut self, def_name: &str, task_prompt: &str, provider: AnyProvider, tool_executor: Arc<dyn ErasedToolExecutor>, skills: Option<Vec<String>>, config: &SubAgentConfig, ctx: SpawnContext, on_done: F, ) -> Result<String, SubAgentError>
where F: FnOnce(String, Result<String, SubAgentError>) + Send + 'static,

Spawn a sub-agent for an orchestrated task.

Identical to spawn but wraps the JoinHandle to send a [crate::orchestration::TaskEvent] on the provided channel when the agent loop terminates. This allows the DagScheduler to receive completion notifications without polling (ADR-027).

The event_tx channel is best-effort: if the scheduler is dropped before all agents complete, the send will fail silently with a warning log.

§Errors

Same error conditions as spawn.

§Panics

Panics if the internal agent entry is missing after a successful spawn call. This is a programming error and should never occur in normal operation. Spawn a sub-agent and attach a completion callback invoked when the agent terminates.

The callback receives the agent handle ID and the agent’s result. The caller is responsible for translating this into orchestration events.

§Errors

Same error conditions as spawn.

§Panics

Panics if the internal agent entry is missing after a successful spawn call. This is a programming error and should never occur in normal operation.

Trait Implementations§

Source§

impl Debug for SubAgentManager

Source§

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

Formats the value using the given formatter. Read more

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<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> 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<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, 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