pub struct ProdWorkerFacade {
workspace: Weak<Workspace>,
}Expand description
Production impl. Holds a Weak<Workspace> so construction doesn’t
close a strong cycle through the Workspace -> bridge -> MCP ->
Tool -> facade -> Workspace path. Every method starts with
upgrade() and short-circuits when the workspace has been
dropped (only possible during shutdown).
Fields§
§workspace: Weak<Workspace>Implementations§
Trait Implementations§
Source§impl WorkerFacade for ProdWorkerFacade
impl WorkerFacade for ProdWorkerFacade
Source§fn caller_project(&self, caller: &SessionSlot) -> Option<CallerProject>
fn caller_project(&self, caller: &SessionSlot) -> Option<CallerProject>
Resolve the caller’s project key + lead/worker flag.
Returns
None when caller matches no known session.Source§fn spawn_worker<'life0, 'life1, 'async_trait>(
&'life0 self,
caller: &'life1 SessionSlot,
label: String,
charter: String,
kick: Option<String>,
resume_kick: Option<String>,
interactive: bool,
resume_session: bool,
mcp_families: Option<Vec<String>>,
cwd: Option<String>,
) -> Pin<Box<dyn Future<Output = Result<WorkerSpawnReply, WorkerSpawnError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn spawn_worker<'life0, 'life1, 'async_trait>(
&'life0 self,
caller: &'life1 SessionSlot,
label: String,
charter: String,
kick: Option<String>,
resume_kick: Option<String>,
interactive: bool,
resume_session: bool,
mcp_families: Option<Vec<String>>,
cwd: Option<String>,
) -> Pin<Box<dyn Future<Output = Result<WorkerSpawnReply, WorkerSpawnError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Dispatch a
Command::SpawnWorker and await its synchronous
reply. Gating (lead-only, non-empty label, non-empty charter)
happens before dispatch. resume_kick is persisted rather than
delivered now; it replaces the generic restart note when this
worker resumes after a forge restart with a turn that was cut off.
A worker that was idle when forge stopped resumes with nothing
delivered. interactive keeps the built-in
AskUserQuestion tool, which every other worker is denied.
resume_session resumes the label’s most recent prior session
instead of starting fresh. A label with none resolves to
ResumeTarget::None, which starts a fresh session and says so in
the reply’s SessionChoice; only a lookup that failed is an
error. Read moreSource§fn update_worker(
&self,
caller: &SessionSlot,
label: &str,
charter: Option<String>,
kick: Option<String>,
resume_kick: Option<String>,
mcp_families: Option<Vec<String>>,
) -> Result<(), WorkerUpdateError>
fn update_worker( &self, caller: &SessionSlot, label: &str, charter: Option<String>, kick: Option<String>, resume_kick: Option<String>, mcp_families: Option<Vec<String>>, ) -> Result<(), WorkerUpdateError>
Merge the supplied fields onto the stored dynamic-worker row for
label in the caller’s project, leaving a None field at its
stored value. Errors with NoSuchWorker when no row exists:
update revises an existing worker, it never creates one. Takes
effect on that worker’s next respawn, since a session’s system
prompt and tool list are fixed when the session spawns.
mcp_families follows the same contract: None leaves the
stored selection alone, Some(names) replaces it - canonicalised
by the tool - and Some(empty) resets it to every family.Source§fn despawn_worker<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
caller: &'life1 SessionSlot,
label: &'life2 str,
force: bool,
) -> Pin<Box<dyn Future<Output = Result<DespawnOutcome, WorkerDespawnError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn despawn_worker<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
caller: &'life1 SessionSlot,
label: &'life2 str,
force: bool,
) -> Pin<Box<dyn Future<Output = Result<DespawnOutcome, WorkerDespawnError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Dispatch a
Command::DespawnWorker and await its result.
Gating (lead-only, non-empty label) happens before dispatch.
force removes a dirty worktree; without it a dirty worktree
blocks the despawn (DespawnOutcome::Blocked).Source§fn list_workers(&self, caller: &SessionSlot) -> Vec<WorkerStatus>
fn list_workers(&self, caller: &SessionSlot) -> Vec<WorkerStatus>
Snapshot of every worker in the caller’s project. Returns an
empty Vec when the caller resolves to no project.
Source§fn list_all_workers(&self) -> Vec<WorkerStatus>
fn list_all_workers(&self) -> Vec<WorkerStatus>
Snapshot of every project’s workers: the real workspace walks
list_projects in config order, the mock sorts its project keys.Source§fn capacity(&self, caller: &SessionSlot) -> Option<WorkerCapacity>
fn capacity(&self, caller: &SessionSlot) -> Option<WorkerCapacity>
The caller’s project worker capacity: the cap the spawn path
enforces (
max_workers in the project’s [[orgs.projects]]
entry, else DEFAULT_MAX_WORKERS_PER_PROJECT) paired with the
live count.
A plain data read - the same one the spawn path’s cap check
performs. Returns None when the caller resolves to no
project.Source§fn deliver_worker_prompt<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
caller: &'life1 SessionSlot,
target_label: &'life2 str,
wrapped: WrappedPrompt,
) -> Pin<Box<dyn Future<Output = Result<WorkerTargetStatus, WorkerDeliverError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn deliver_worker_prompt<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
caller: &'life1 SessionSlot,
target_label: &'life2 str,
wrapped: WrappedPrompt,
) -> Pin<Box<dyn Future<Output = Result<WorkerTargetStatus, WorkerDeliverError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Dispatch a worker-bound wrapped prompt.
Delivered means the
prompt was accepted - handed to the target’s session queue, held
for its turn end, or parked for its connect - which is the whole
claim the sender’s ack makes; anything that reached no session is
an error. UnknownLabel when no live worker matches.Source§fn deliver_worker_prompt_to_project<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
caller: &'life1 SessionSlot,
org: &'life2 str,
project: &'life3 str,
target_label: &'life4 str,
wrapped: WrappedPrompt,
) -> Pin<Box<dyn Future<Output = Result<WorkerTargetStatus, WorkerDeliverError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
fn deliver_worker_prompt_to_project<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
caller: &'life1 SessionSlot,
org: &'life2 str,
project: &'life3 str,
target_label: &'life4 str,
wrapped: WrappedPrompt,
) -> Pin<Box<dyn Future<Output = Result<WorkerTargetStatus, WorkerDeliverError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
Dispatch a worker-bound wrapped prompt to a project named by
its
(org, project) pair rather than the caller’s own. The
caller lives in another project, so the target cannot be
resolved from it. Mirrors deliver_worker_prompt otherwise:
an unknown label is an error and a sleeping target is not
auto-spawned.Source§fn deliver_prompt_to_lead<'life0, 'life1, 'async_trait>(
&'life0 self,
caller: &'life1 SessionSlot,
wrapped: WrappedPrompt,
) -> Pin<Box<dyn Future<Output = Result<WorkerTargetStatus, WorkerLeadDeliverError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn deliver_prompt_to_lead<'life0, 'life1, 'async_trait>(
&'life0 self,
caller: &'life1 SessionSlot,
wrapped: WrappedPrompt,
) -> Pin<Box<dyn Future<Output = Result<WorkerTargetStatus, WorkerLeadDeliverError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Dispatch a wrapped prompt from a worker back to its lead.
Caller MUST be a worker. The target lead is resolved from the
caller’s
WorkerEntry::spawned_by_session_id. Same
wire-shape contract as deliver_worker_prompt: Delivered
means the lead’s session accepted it, and one the session could
not take is an error.Auto Trait Implementations§
impl !RefUnwindSafe for ProdWorkerFacade
impl !UnwindSafe for ProdWorkerFacade
impl Freeze for ProdWorkerFacade
impl Send for ProdWorkerFacade
impl Sync for ProdWorkerFacade
impl Unpin for ProdWorkerFacade
impl UnsafeUnpin for ProdWorkerFacade
Blanket Implementations§
§impl<T> AnySync for T
impl<T> AnySync for T
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
Mutably borrows from an owned value. Read more
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
impl<S, T> Duplex<S> for Twhere
T: FromSample<S> + ToSample<S>,
§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> 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> ⓘ
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 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> ⓘ
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