Skip to main content

NativeEffectShell

Struct NativeEffectShell 

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

Executes native effects and returns exactly one completion observation for each accepted effect. Logical lifecycle state remains owned by the engine.

Implementations§

Source§

impl NativeEffectShell

Source

pub fn new(catalog: AgentRegistry) -> Self

Source

pub fn new_with_runtime_adapters( catalog: AgentRegistry, legacy_adapters: AdapterRuntimeRegistry<CliTool>, ) -> Self

Builds a native shell with consumer-provided compatibility runtimes.

The runtime registry is deliberately separate from the declarative catalog: both the adapter family and revision must resolve before a process is spawned.

Source

pub fn take_efficiency_facts(&mut self) -> ShellEfficiencyFacts

Hand the caller everything collect_terminal_frames and reclassify_foreground recorded since the last call, and reset the facts back to empty. Called once per worker-loop iteration by gate4agent-runtime-native::publish_shell_observations, the only place with somewhere to fold these into a distribution.

Source

pub fn active_session_count(&self) -> usize

Source

pub fn spawn_operation_id(&self, key: NativeSessionKey) -> Option<OperationId>

Source

pub fn terminal_snapshot( &self, key: NativeSessionKey, ) -> Result<PtyTerminalSnapshot, String>

Source

pub async fn execute(&mut self, envelope: EffectEnvelope) -> ObservationEnvelope

Source

pub async fn execute_with_pty_env( &mut self, envelope: EffectEnvelope, pty_env: Vec<EnvMutation>, ) -> ObservationEnvelope

Backward-compatible name for PTY-only callers. OneShot launches now receive the same shell-owned mutations.

Source

pub async fn execute_with_environment( &mut self, envelope: EffectEnvelope, environment: Vec<EnvMutation>, ) -> ObservationEnvelope

Execute an effect with shell-owned environment injected only into a newly spawned provider process. The canonical start request cannot set these authority variables itself.

Source

pub async fn execute_with_launch_overlay( &mut self, envelope: EffectEnvelope, environment: Vec<EnvMutation>, extra_args: Vec<OsString>, ) -> ObservationEnvelope

Execute an effect with host-only environment and optional PTY argv applied only to a newly spawned provider process.

Source

pub async fn execute_with_launch_overlay_and_persistence( &mut self, envelope: EffectEnvelope, environment: Vec<EnvMutation>, extra_args: Vec<OsString>, one_shot_session_persistence: OneShotSessionPersistence, ) -> ObservationEnvelope

Execute an effect with host-only launch mutations and an explicit OneShotText session persistence policy.

Source

pub async fn execute_with_launch_context( &mut self, envelope: EffectEnvelope, environment: Vec<EnvMutation>, extra_args: Vec<OsString>, one_shot_session_persistence: OneShotSessionPersistence, mcp_server: Option<McpServerSpec>, ) -> ObservationEnvelope

Source

pub async fn collect_exits(&mut self) -> Vec<ObservationEnvelope>

Convert naturally exited PTY children into generation-bound lifecycle observations. Runtime ticks call this before accepting new commands.

Source

pub fn collect_provider_events(&mut self) -> Vec<ObservationEnvelope>

Drain normalized provider events without mixing them with replaceable terminal frames. Broadcast lag is converted into an explicit stale gap.

Source

pub fn collect_terminal_frames(&mut self) -> Vec<ObservationEnvelope>

Capture only changed terminal frames. Snapshot failures become an explicit stale observation once, until a later successful frame heals it.

The sequence is checked BEFORE the capture, not after. This runs on the per-session worker tick (20ms, so ~50 times a second per live PTY session), and terminal_state is not a cheap read: it renders the visible screen twice and clones the whole vt100::Screen to walk its scrollback row by row. Asking it first and comparing sequences afterwards meant every idle session rebuilt its entire screen fifty times a second purely to discover nothing had changed, and then dropped the result – with a couple of dozen sessions open that is the machine’s time, all of it wasted. terminal_sequence answers the same question by reading one integer.

Source

pub async fn reclassify_foreground(&mut self) -> Vec<ObservationEnvelope>

Refresh the foreground half of PtyScreenState for whichever sessions are due, per next_foreground_probe.

Deliberately not folded into collect_terminal_frames: that method is synchronous and only pays for a real capture when the terminal sequence says the screen changed, but PtySession::observe_foreground_timed is async and walks the live OS process tree (CreateToolhelp32Snapshot on Windows) unconditionally every time it is called. Running that walk once per changed frame would scale a syscall with output rate – exactly the cost collect_terminal_frames’s own sequence gate exists to avoid. The cost here is bounded by the count of sessions NOT currently Ready, never by output rate and never by total session count: a session that reaches Ready disarms itself (see foreground_probe_schedule) and is never probed again until its text disagrees.

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, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

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