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
HookBefore
SpawnHook.before request (= the client returns OK / NG via ack).
Fields
HookAfter
SpawnHook.after notification (= no client ack, fire-and-forget).
Fields
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
capability_token: StringCapToken::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.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for ServerMsg
impl RefUnwindSafe for ServerMsg
impl Send for ServerMsg
impl Sync for ServerMsg
impl Unpin for ServerMsg
impl UnsafeUnpin for ServerMsg
impl UnwindSafe for ServerMsg
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