Skip to main content

RuntimeSessionAdapter

Struct RuntimeSessionAdapter 

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

Wraps a SessionService to provide v9 runtime capabilities.

Maintains a per-session RuntimeDriver registry. When sessions are registered with a CoreExecutor, a RuntimeLoop task is spawned that processes queued inputs by calling CoreExecutor::apply() (which triggers SessionService::start_turn() under the hood).

Implementations§

Source§

impl RuntimeSessionAdapter

Source

pub fn ephemeral() -> Self

Create an ephemeral adapter (all sessions use EphemeralRuntimeDriver).

Source

pub fn persistent( store: Arc<dyn RuntimeStore>, blob_store: Arc<dyn BlobStore>, ) -> Self

Create a persistent adapter with a RuntimeStore.

Source

pub fn persistent_without_blobs(store: Arc<dyn RuntimeStore>) -> Self

Create a persistent adapter with a RuntimeStore but no blob store.

The driver will fall back to ephemeral mode for sessions (no durable boundary commits), but ops lifecycle recovery from the store still works. Primarily useful for tests that need to verify recovery without needing a full blob store.

Source

pub async fn register_session(&self, session_id: SessionId)

Register a runtime driver for a session (no RuntimeLoop — inputs queue but nothing processes them automatically). Useful for tests and legacy mode.

Source

pub async fn set_session_silent_intents( &self, session_id: &SessionId, intents: Vec<String>, )

Set the silent comms intents for a session’s runtime driver.

Peer requests whose intent matches one of these strings will be accepted without triggering an LLM turn (ApplyMode::Ignore, WakeMode::None).

Source

pub async fn register_session_with_executor( &self, session_id: SessionId, executor: Box<dyn CoreExecutor>, )

Register a runtime driver for a session WITH a RuntimeLoop backed by a CoreExecutor. When accept_input() queues an input and requests wake, the loop dequeues it and calls executor.apply() (which triggers SessionService::start_turn()).

Source

pub async fn ensure_session_with_executor( &self, session_id: SessionId, executor: Box<dyn CoreExecutor>, )

Ensure a runtime driver with executor exists for the session.

If a session was already registered without a loop, upgrade the existing driver in place so queued inputs remain attached to the same runtime ledger and can start draining immediately.

Source

pub async fn unregister_session(&self, session_id: &SessionId)

Unregister a session’s runtime driver.

Detaches the executor (Attached → Idle) before removal, then drops the wake channel sender, which causes the RuntimeLoop to exit.

Source

pub async fn contains_session(&self, session_id: &SessionId) -> bool

Check whether a runtime driver is already registered for a session.

Source

pub async fn session_has_executor(&self, session_id: &SessionId) -> bool

Check whether a session has an active RuntimeLoop or attachment in progress. Returns false only for Queuing sessions (registered via prepare_bindings() with no executor) and unknown sessions.

Source

pub async fn session_has_comms(&self, session_id: &SessionId) -> bool

Check whether a session already has a comms runtime configured.

Returns true if update_peer_ingress_context was previously called with a non-None comms runtime for this session (e.g., via SessionRuntime::enable_comms_drain).

Source

pub async fn interrupt_current_run( &self, session_id: &SessionId, ) -> Result<(), RuntimeDriverError>

Cancel the currently-running turn for a registered session.

Source

pub async fn stop_runtime_executor( &self, session_id: &SessionId, command: RunControlCommand, ) -> Result<(), RuntimeDriverError>

Stop the attached runtime executor through the out-of-band control channel. When no loop is attached yet, a stop command is applied directly against the driver so queued work is still terminated consistently.

Source

pub async fn accept_input_and_run<T, F, Fut>( &self, session_id: &SessionId, input: Input, op: F, ) -> Result<T, RuntimeDriverError>
where F: FnOnce(RunId, RunPrimitive) -> Fut, Fut: Future<Output = Result<(T, CoreApplyOutput), RuntimeDriverError>>,

Accept an input and execute it synchronously through the runtime driver.

This is useful for surfaces that need the legacy request/response shape while still preserving v9 input lifecycle semantics.

Source

pub async fn accept_input_with_completion( &self, session_id: &SessionId, input: Input, ) -> Result<(AcceptOutcome, Option<CompletionHandle>), RuntimeDriverError>

Accept an input and return a completion handle that resolves when the input reaches a terminal state (Consumed or Abandoned).

Returns (AcceptOutcome, Option<CompletionHandle>):

  • (Accepted, Some(handle)) — await handle for result
  • (Accepted, None) — input reached a terminal state during admission
  • (Deduplicated, Some(handle)) — joined in-flight waiter
  • (Deduplicated, None) — input already terminal; no waiter needed
  • (Rejected, _) — returned as Err(ValidationFailed)
Source

pub async fn accept_input_without_wake( &self, session_id: &SessionId, input: Input, ) -> Result<AcceptOutcome, RuntimeDriverError>

Accept an input but intentionally do not wake the runtime loop.

This is reserved for explicitly queued-only surface contracts that stage work for the next turn boundary instead of waking an idle session immediately.

Source

pub async fn ops_lifecycle_registry( &self, session_id: &SessionId, ) -> Option<Arc<RuntimeOpsLifecycleRegistry>>

Get the shared ops lifecycle registry for a session/runtime instance.

Source

pub async fn prepare_bindings( &self, session_id: SessionId, ) -> Result<SessionRuntimeBindings, RuntimeBindingsError>

Prepare canonical runtime bindings for a session.

This is the single canonical helper that replaces the hand-rolled register_session() + ops_lifecycle_registry() + manual threading dance. All runtime-backed surfaces should call this instead.

The method is idempotent: if the session is already registered, it returns bindings from the existing entry. The epoch_id is stable across repeated calls for the same session.

Source

pub async fn update_peer_ingress_context( self: &Arc<Self>, session_id: &SessionId, keep_alive: bool, comms_runtime: Option<Arc<dyn CommsRuntime>>, ) -> bool

Update the session’s peer-ingress context, then reconcile the canonical drain lifecycle.

Surfaces may call this when they learn or change keep_alive/comms context, but the adapter owns the actual drain-mode decision.

Source

pub async fn notify_comms_drain_exited( self: &Arc<Self>, session_id: &SessionId, reason: DrainExitReason, )

Notify the authority that a drain task has exited with the given reason.

Called from drain task exit paths (or by wrappers that detect task completion). The authority decides whether to enter ExitedRespawnable (PersistentHost + Failed) or Stopped.

Source

pub async fn abort_comms_drains(&self)

Abort all active comms drain tasks.

Source

pub async fn abort_comms_drain(&self, session_id: &SessionId)

Abort the comms drain task for a specific session.

Source

pub async fn wait_comms_drain(&self, session_id: &SessionId)

Wait for a session’s comms drain task to finish.

Returns immediately if no drain is active for the session. If the task already notified the authority (normal exit), this is a no-op for authority state. If the task panicked without notifying, this submits TaskExited { Failed } as a safety net.

Trait Implementations§

Source§

impl RuntimeControlPlane for RuntimeSessionAdapter

Source§

fn ingest<'life0, 'life1, 'async_trait>( &'life0 self, runtime_id: &'life1 LogicalRuntimeId, input: Input, ) -> Pin<Box<dyn Future<Output = Result<AcceptOutcome, RuntimeControlPlaneError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Ingest an input into a specific runtime.
Source§

fn publish_event<'life0, 'async_trait>( &'life0 self, event: RuntimeEventEnvelope, ) -> Pin<Box<dyn Future<Output = Result<(), RuntimeControlPlaneError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Publish a runtime event.
Source§

fn retire<'life0, 'life1, 'async_trait>( &'life0 self, runtime_id: &'life1 LogicalRuntimeId, ) -> Pin<Box<dyn Future<Output = Result<RetireReport, RuntimeControlPlaneError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Retire a runtime (no new input, drain existing).
Source§

fn recycle<'life0, 'life1, 'async_trait>( &'life0 self, runtime_id: &'life1 LogicalRuntimeId, ) -> Pin<Box<dyn Future<Output = Result<RecycleReport, RuntimeControlPlaneError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Recycle a runtime (reset driver and recover state).
Source§

fn reset<'life0, 'life1, 'async_trait>( &'life0 self, runtime_id: &'life1 LogicalRuntimeId, ) -> Pin<Box<dyn Future<Output = Result<ResetReport, RuntimeControlPlaneError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Reset a runtime (abandon all pending input).
Source§

fn recover<'life0, 'life1, 'async_trait>( &'life0 self, runtime_id: &'life1 LogicalRuntimeId, ) -> Pin<Box<dyn Future<Output = Result<RecoveryReport, RuntimeControlPlaneError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Recover a runtime from crash.
Source§

fn destroy<'life0, 'life1, 'async_trait>( &'life0 self, runtime_id: &'life1 LogicalRuntimeId, ) -> Pin<Box<dyn Future<Output = Result<DestroyReport, RuntimeControlPlaneError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Destroy a runtime (terminal state, no recovery possible).
Source§

fn runtime_state<'life0, 'life1, 'async_trait>( &'life0 self, runtime_id: &'life1 LogicalRuntimeId, ) -> Pin<Box<dyn Future<Output = Result<RuntimeState, RuntimeControlPlaneError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Get the state of a runtime.
Source§

fn load_boundary_receipt<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, runtime_id: &'life1 LogicalRuntimeId, run_id: &'life2 RunId, sequence: u64, ) -> Pin<Box<dyn Future<Output = Result<Option<RunBoundaryReceipt>, RuntimeControlPlaneError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Load a boundary receipt for verification.
Source§

impl SessionServiceRuntimeExt for RuntimeSessionAdapter

Source§

fn runtime_mode(&self) -> RuntimeMode

Get the runtime mode.
Source§

fn accept_input<'life0, 'life1, 'async_trait>( &'life0 self, session_id: &'life1 SessionId, input: Input, ) -> Pin<Box<dyn Future<Output = Result<AcceptOutcome, RuntimeDriverError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Accept an input for a session.
Source§

fn accept_input_with_completion<'life0, 'life1, 'async_trait>( &'life0 self, session_id: &'life1 SessionId, input: Input, ) -> Pin<Box<dyn Future<Output = Result<(AcceptOutcome, Option<CompletionHandle>), RuntimeDriverError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Accept an input and optionally return a completion handle that resolves when the admitted work reaches a terminal runtime outcome.
Source§

fn runtime_state<'life0, 'life1, 'async_trait>( &'life0 self, session_id: &'life1 SessionId, ) -> Pin<Box<dyn Future<Output = Result<RuntimeState, RuntimeDriverError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Get the runtime state for a session.
Source§

fn retire_runtime<'life0, 'life1, 'async_trait>( &'life0 self, session_id: &'life1 SessionId, ) -> Pin<Box<dyn Future<Output = Result<RetireReport, RuntimeDriverError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Retire a session’s runtime.
Source§

fn reset_runtime<'life0, 'life1, 'async_trait>( &'life0 self, session_id: &'life1 SessionId, ) -> Pin<Box<dyn Future<Output = Result<ResetReport, RuntimeDriverError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Reset a session’s runtime.
Source§

fn input_state<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, session_id: &'life1 SessionId, input_id: &'life2 InputId, ) -> Pin<Box<dyn Future<Output = Result<Option<InputState>, RuntimeDriverError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Get the state of a specific input.
Source§

fn list_active_inputs<'life0, 'life1, 'async_trait>( &'life0 self, session_id: &'life1 SessionId, ) -> Pin<Box<dyn Future<Output = Result<Vec<InputId>, RuntimeDriverError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

List all active (non-terminal) inputs for a session.

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> Same for T

Source§

type Output = T

Should always be Self
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<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