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
impl RuntimeSessionAdapter
Sourcepub fn ephemeral() -> Self
pub fn ephemeral() -> Self
Create an ephemeral adapter (all sessions use EphemeralRuntimeDriver).
Sourcepub fn persistent(
store: Arc<dyn RuntimeStore>,
blob_store: Arc<dyn BlobStore>,
) -> Self
pub fn persistent( store: Arc<dyn RuntimeStore>, blob_store: Arc<dyn BlobStore>, ) -> Self
Create a persistent adapter with a RuntimeStore.
Sourcepub fn persistent_without_blobs(store: Arc<dyn RuntimeStore>) -> Self
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.
Sourcepub async fn register_session(&self, session_id: SessionId)
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.
Sourcepub async fn set_session_silent_intents(
&self,
session_id: &SessionId,
intents: Vec<String>,
)
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).
Sourcepub async fn register_session_with_executor(
&self,
session_id: SessionId,
executor: Box<dyn CoreExecutor>,
)
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()).
Sourcepub async fn ensure_session_with_executor(
&self,
session_id: SessionId,
executor: Box<dyn CoreExecutor>,
)
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.
Sourcepub async fn unregister_session(&self, session_id: &SessionId)
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.
Sourcepub async fn contains_session(&self, session_id: &SessionId) -> bool
pub async fn contains_session(&self, session_id: &SessionId) -> bool
Check whether a runtime driver is already registered for a session.
Sourcepub async fn session_has_executor(&self, session_id: &SessionId) -> bool
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.
Sourcepub async fn session_has_comms(&self, session_id: &SessionId) -> bool
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).
Sourcepub async fn interrupt_current_run(
&self,
session_id: &SessionId,
) -> Result<(), RuntimeDriverError>
pub async fn interrupt_current_run( &self, session_id: &SessionId, ) -> Result<(), RuntimeDriverError>
Cancel the currently-running turn for a registered session.
Sourcepub async fn stop_runtime_executor(
&self,
session_id: &SessionId,
command: RunControlCommand,
) -> Result<(), RuntimeDriverError>
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.
Sourcepub 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>>,
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.
Sourcepub async fn accept_input_with_completion(
&self,
session_id: &SessionId,
input: Input,
) -> Result<(AcceptOutcome, Option<CompletionHandle>), RuntimeDriverError>
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 asErr(ValidationFailed)
Sourcepub async fn accept_input_without_wake(
&self,
session_id: &SessionId,
input: Input,
) -> Result<AcceptOutcome, RuntimeDriverError>
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.
Sourcepub async fn ops_lifecycle_registry(
&self,
session_id: &SessionId,
) -> Option<Arc<RuntimeOpsLifecycleRegistry>>
pub async fn ops_lifecycle_registry( &self, session_id: &SessionId, ) -> Option<Arc<RuntimeOpsLifecycleRegistry>>
Get the shared ops lifecycle registry for a session/runtime instance.
Sourcepub async fn prepare_bindings(
&self,
session_id: SessionId,
) -> Result<SessionRuntimeBindings, RuntimeBindingsError>
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.
Sourcepub async fn update_peer_ingress_context(
self: &Arc<Self>,
session_id: &SessionId,
keep_alive: bool,
comms_runtime: Option<Arc<dyn CommsRuntime>>,
) -> bool
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.
Sourcepub async fn notify_comms_drain_exited(
self: &Arc<Self>,
session_id: &SessionId,
reason: DrainExitReason,
)
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.
Sourcepub async fn abort_comms_drains(&self)
pub async fn abort_comms_drains(&self)
Abort all active comms drain tasks.
Sourcepub async fn abort_comms_drain(&self, session_id: &SessionId)
pub async fn abort_comms_drain(&self, session_id: &SessionId)
Abort the comms drain task for a specific session.
Sourcepub async fn wait_comms_drain(&self, session_id: &SessionId)
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.