pub struct OperatorDelegateMiddleware;Expand description
When ctx.operator.operator.is_some() (the session has an Operator
backend), bypass inner.spawn, call operator.execute(ctx, prompt),
and box the result up as a WorkerHandle. In other words: the path that
hands “this spawn” to whatever external Operator backend the engine has
registered.
§Independent of OperatorKind (Operator is a generic abstraction)
An earlier implementation gated on kind == MainAi | Composite, which
tied the Operator abstraction to an “AI driver” assumption — a design
weakness. The Operator trait is a generic external processing backend
(LLM, human, external resource, side-effectful operation — anything), and
is orthogonal to the kind axis.
The current implementation decides solely on operator.is_some():
- Automate session + operator backend registered → delegate (pure external-execution delegation).
- MainAi session + operator backend registered → delegate.
- Any kind +
operatorNone→ pass through (normalinner.spawn).
kind still matters as a firing condition for SpawnHooks over in
MainAIMiddleware, but this middleware ignores it.
§Split of responsibilities with OperatorSpawner
The two axes exist for different reasons:
-
This middleware — the Blueprint-global (session) axis. Delegate every agent to the same Operator backend. The
operator_backend_idis set at session-attach time;ctx.agentis ignored and every spawn in that session is routed through the operator (e.g. a MainAI-wide driver, or a human-wide console). The Blueprint doesn’t have to talk aboutkind— it just declares the capability hint"operator_delegate"(keeping the Blueprint clean). -
OperatorSpawner— the AgentSpec axis. EachAgentDefbakes its own Operator backend.kind = OperatorAgentDefs pick a backend viaspec.operator_ref; the compiler bakes anArc<dyn Operator>intoroutes[agent_name]. Agents loaded via theagent.mdloader come in through this path (their default iskind = Operator).
§Exclusivity
When both are effective — this middleware’s hint is declared, the session
has an operator backend, and the Blueprint has a kind = Operator
AgentDef — this middleware sits at the outer end of the stack and
completely bypasses inner.spawn. The OperatorSpawner is never
reached, so a double fire cannot occur by construction; the AgentSpec
axis is inert. Consistent use means picking one axis per use case.
Implementations§
Trait Implementations§
Source§impl Default for OperatorDelegateMiddleware
impl Default for OperatorDelegateMiddleware
Source§impl SpawnerLayer for OperatorDelegateMiddleware
impl SpawnerLayer for OperatorDelegateMiddleware
Source§fn wrap(&self, inner: Arc<dyn SpawnerAdapter>) -> Arc<dyn SpawnerAdapter> ⓘ
fn wrap(&self, inner: Arc<dyn SpawnerAdapter>) -> Arc<dyn SpawnerAdapter> ⓘ
inner in this layer’s behaviour, returning a new
SpawnerAdapter that delegates to inner (directly or via
wrap_join) while adding this layer’s cross-cutting effect.Auto Trait Implementations§
impl Freeze for OperatorDelegateMiddleware
impl RefUnwindSafe for OperatorDelegateMiddleware
impl Send for OperatorDelegateMiddleware
impl Sync for OperatorDelegateMiddleware
impl Unpin for OperatorDelegateMiddleware
impl UnsafeUnpin for OperatorDelegateMiddleware
impl UnwindSafe for OperatorDelegateMiddleware
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
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