Skip to main content

ServerMsg

Enum ServerMsg 

Source
pub enum ServerMsg {
    Ask {
        req_id: String,
        parent_req_id: Option<String>,
        task_id: String,
        question: Value,
    },
    HookBefore {
        req_id: String,
        parent_req_id: Option<String>,
        task_id: String,
        agent: String,
        attempt: u32,
    },
    HookAfter {
        req_id: String,
        parent_req_id: Option<String>,
        task_id: String,
        agent: String,
        attempt: u32,
        result: Value,
    },
    Spawn {
        req_id: String,
        parent_req_id: Option<String>,
        task_id: String,
        agent: String,
        attempt: u32,
        capability_token: String,
        worker_handle: Option<String>,
        worker: Option<WorkerBinding>,
        directive: String,
    },
}
Expand description

Server → client push messages on WS /v1/operators/:sid/ws. Each variant pairs with a ClientMsg reply carrying the same req_id (except HookAfter, which is fire-and-forget).

Variants§

§

Ask

SeniorBridge.ask request.

Fields

§req_id: String

Correlation key the client must echo back in ClientMsg::Answer.

§parent_req_id: Option<String>

Reserved for nested-ask correlation; currently always None (see [current_parent_req_id]).

§task_id: String

Task the question originates from.

§question: Value

Free-form question payload produced by the engine middleware.

§

HookBefore

SpawnHook.before request (= the client returns OK / NG via ack).

Fields

§req_id: String

Correlation key the client must echo back in ClientMsg::HookAck.

§parent_req_id: Option<String>

Reserved for nested-ask correlation; currently always None.

§task_id: String

Task whose spawn is being gated.

§agent: String

Agent ref about to be spawned.

§attempt: u32

1-based dispatch attempt counter for this agent step.

§

HookAfter

SpawnHook.after notification (= no client ack, fire-and-forget).

Fields

§req_id: String

Correlation key (informational only — no reply is expected).

§parent_req_id: Option<String>

Reserved for nested-ask correlation; currently always None.

§task_id: String

Task the spawn belonged to.

§agent: String

Agent ref that was spawned.

§attempt: u32

1-based dispatch attempt counter for this agent step.

§result: Value

Worker result payload observed after the spawn completed.

§

Spawn

Operator.execute request (= delegates the whole spawn to an external Operator, via OperatorDelegateMiddleware). The client replies with the WorkerResult-equivalent (= value + ok) in spawn_ack.

Thin control channel (the Spawn thin-control axis): the server sends only the capability_token. system_prompt / prompt are NOT carried in the WS payload. The MainAI (WS Client) forwards the token to the SubAgent, and the SubAgent hits /v1/worker/prompt + /v1/worker/result itself with Authorization: Bearer <capability_token> — fetching prompt / system and posting the result (= heavy payloads go over HTTP; WS stays purely thin control).

capability_token is CapToken::encode() form (= URL-safe base64 of serde_json): a session token with Role::Worker + ["*"] scopes + 600s TTL. The HMAC sig is verified server-side by verify_token_for_task — a self-contained capability token (= no server lookup required).

directive (= immediate instruction for the MainAI; fix for observation #7): Under thin-push discipline, if the payload were only routing fields, the MainAI (a large LLM) would fire the drift “I have a token → I should fetch it myself” / “I got the prompt → I should embed it literally into the SubAgent” 100% of the time (= bias accumulation across 50–100 parallel agents dulls decisions). To structurally remove this drift, a literal instruction text — “launch a SubAgent, hand it the token + endpoint, and let the SubAgent do the fetch / execution / post” — is explicitly embedded into the payload (= implicit convention → literal statement).

This field carries natural-language text intended for the MainAI to read (= not a JSON schema target for parsing). See operator_ws::session::default_spawn_directive() for the server-side default text.

Fields

§req_id: String

Correlation key the client must echo back in ClientMsg::SpawnAck.

§parent_req_id: Option<String>

Reserved for nested-ask correlation; currently always None.

§task_id: String

Task the delegated spawn belongs to.

§agent: String

Agent ref the Operator is asked to execute.

§attempt: u32

1-based dispatch attempt counter for this agent step.

§capability_token: String

CapToken::encode() form Bearer credential for the worker HTTP endpoints (see the variant doc above for the thin-control contract).

§worker_handle: Option<String>

Short handle (= wh-XXXXXXXX, 12 chars). An alternate Bearer path paired with capability_token. When /v1/worker/submit receives a handle in Bearer, the server resolves nonce → task_id via the worker_handles map (the short-handle switchover — removes base64 copy-paste accidents). SubAgents (mse-worker) should use this field instead of capability_token as the recommended path.

§worker: Option<WorkerBinding>

Worker binding resolved from the Blueprint at compile time. None never reaches the wire on the WS thin path (compile-time gate, see Operator::requires_worker_binding), but the field stays optional for forward compatibility.

§directive: String

Literal natural-language instruction for the MainAI (see the variant doc above for why this is embedded in the payload).

Trait Implementations§

Source§

impl Debug for ServerMsg

Source§

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

Formats the value using the given formatter. Read more
Source§

impl Serialize for ServerMsg

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. 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<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> 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> MaybeSend for T

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

Source§

fn erased_serialize(&self, serializer: &mut dyn Serializer) -> Result<(), Error>

Source§

fn do_erased_serialize( &self, serializer: &mut dyn Serializer, ) -> Result<(), ErrorImpl>

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