Skip to main content

meerkat_runtime/
service_ext.rs

1//! SessionServiceRuntimeExt — v9 runtime extension for SessionService.
2//!
3//! This trait extends the existing SessionService with runtime-specific
4//! operations. It lives in meerkat-runtime (NOT in core) to maintain
5//! the separation: core owns SessionService, runtime owns runtime extensions.
6
7use meerkat_core::lifecycle::InputId;
8use meerkat_core::types::SessionId;
9
10use crate::accept::AcceptOutcome;
11use crate::completion::CompletionHandle;
12use crate::input::Input;
13use crate::input_state::StoredInputState;
14use crate::meerkat_machine_types::{
15    ImageOperationRoutingRequest, ImageOperationRoutingResult, SessionLlmReconfigureReport,
16    SessionLlmReconfigureRequest, SwitchTurnRequest,
17};
18use crate::runtime_state::RuntimeState;
19use crate::traits::{ResetReport, RetireReport, RuntimeDriverError};
20
21/// v9 runtime extensions for SessionService.
22///
23/// This branch is runtime-backed only: every implementation is a v9
24/// runtime surface, so the methods below are unconditionally available.
25#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
26#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
27pub trait SessionServiceRuntimeExt: Send + Sync {
28    /// Accept an input for a session.
29    async fn accept_input(
30        &self,
31        session_id: &SessionId,
32        input: Input,
33    ) -> Result<AcceptOutcome, RuntimeDriverError>;
34
35    /// Accept an input and optionally return a completion handle that resolves
36    /// when the admitted work reaches a terminal runtime outcome.
37    async fn accept_input_with_completion(
38        &self,
39        session_id: &SessionId,
40        input: Input,
41    ) -> Result<(AcceptOutcome, Option<CompletionHandle>), RuntimeDriverError>;
42
43    /// Get the runtime state for a session.
44    async fn runtime_state(
45        &self,
46        session_id: &SessionId,
47    ) -> Result<RuntimeState, RuntimeDriverError>;
48
49    /// Get the runtime-owned resolved LLM capability surface for a session.
50    async fn resolved_session_llm_capabilities(
51        &self,
52        _session_id: &SessionId,
53    ) -> Result<Option<crate::meerkat_machine_types::SessionLlmCapabilitySurface>, RuntimeDriverError>
54    {
55        Err(RuntimeDriverError::Internal(
56            "resolved session llm capabilities are not implemented by this runtime adapter".into(),
57        ))
58    }
59
60    /// Retire a session's runtime.
61    async fn retire_runtime(
62        &self,
63        session_id: &SessionId,
64    ) -> Result<RetireReport, RuntimeDriverError>;
65
66    /// Reset a session's runtime.
67    async fn reset_runtime(
68        &self,
69        session_id: &SessionId,
70    ) -> Result<ResetReport, RuntimeDriverError>;
71
72    /// Get the state of a specific input, bundled with its DSL-owned seed
73    /// (phase / run association / boundary sequence).
74    async fn input_state(
75        &self,
76        session_id: &SessionId,
77        input_id: &InputId,
78    ) -> Result<Option<StoredInputState>, RuntimeDriverError>;
79
80    /// Resolve a caller-supplied idempotency key to its admitted input and
81    /// return that input's stored state (terminal outcome, last run id,
82    /// boundary sequence).
83    ///
84    /// This is the durable reconciliation query for interrupted work: the
85    /// machine-owned idempotency binding and the input's terminal facts
86    /// survive restart (persistent runtimes re-enter them on recovery), so
87    /// after re-registering a session a host can ask "did the interaction I
88    /// submitted under this key reach a terminal state, and which?" without
89    /// keeping its own run journal. Read-only: never registers a binding.
90    async fn input_state_by_idempotency_key(
91        &self,
92        session_id: &SessionId,
93        idempotency_key: &str,
94    ) -> Result<Option<StoredInputState>, RuntimeDriverError>;
95
96    /// List all active (non-terminal) inputs for a session.
97    async fn list_active_inputs(
98        &self,
99        session_id: &SessionId,
100    ) -> Result<Vec<InputId>, RuntimeDriverError>;
101
102    /// Canonically reconfigure the LLM identity for a registered live session.
103    async fn reconfigure_session_llm_identity(
104        &self,
105        session_id: &SessionId,
106        request: SessionLlmReconfigureRequest,
107    ) -> Result<SessionLlmReconfigureReport, RuntimeDriverError>;
108
109    async fn configure_model_routing_baseline(
110        &self,
111        _session_id: &SessionId,
112        _baseline_model: meerkat_core::lifecycle::run_primitive::ModelId,
113        _realtime_capable: bool,
114    ) -> Result<(), RuntimeDriverError> {
115        Err(RuntimeDriverError::Internal(
116            "model routing baseline is not supported by this runtime adapter".into(),
117        ))
118    }
119
120    async fn session_model_routing_status(
121        &self,
122        _session_id: &SessionId,
123    ) -> Result<meerkat_core::image_generation::SessionModelRoutingStatus, RuntimeDriverError> {
124        Err(RuntimeDriverError::Internal(
125            "model routing status is not supported by this runtime adapter".into(),
126        ))
127    }
128
129    async fn request_switch_turn(
130        &self,
131        _session_id: &SessionId,
132        _request: SwitchTurnRequest,
133    ) -> Result<meerkat_core::image_generation::SwitchTurnControlResult, RuntimeDriverError> {
134        Err(RuntimeDriverError::Internal(
135            "switch_turn is not supported by this runtime adapter".into(),
136        ))
137    }
138
139    async fn admit_model_routing_assistant_turn(
140        &self,
141        _session_id: &SessionId,
142    ) -> Result<(), RuntimeDriverError> {
143        Err(RuntimeDriverError::Internal(
144            "model routing turn admission is not supported by this runtime adapter".into(),
145        ))
146    }
147
148    async fn begin_image_operation(
149        &self,
150        _session_id: &SessionId,
151        _request: ImageOperationRoutingRequest,
152    ) -> Result<ImageOperationRoutingResult, RuntimeDriverError> {
153        Err(RuntimeDriverError::Internal(
154            "image operation routing is not supported by this runtime adapter".into(),
155        ))
156    }
157
158    async fn deny_image_operation_plan(
159        &self,
160        _session_id: &SessionId,
161        _operation_id: meerkat_core::image_generation::ImageOperationId,
162        _reason: meerkat_core::image_generation::ImageOperationDenialReason,
163    ) -> Result<meerkat_core::image_generation::ImageOperationPhase, RuntimeDriverError> {
164        Err(RuntimeDriverError::Internal(
165            "image operation plan denial is not supported by this runtime adapter".into(),
166        ))
167    }
168
169    async fn activate_image_operation_override(
170        &self,
171        _session_id: &SessionId,
172        _operation_id: meerkat_core::image_generation::ImageOperationId,
173    ) -> Result<meerkat_core::image_generation::ImageOperationPhase, RuntimeDriverError> {
174        Err(RuntimeDriverError::Internal(
175            "image operation activation is not supported by this runtime adapter".into(),
176        ))
177    }
178
179    async fn classify_image_operation_terminal(
180        &self,
181        _session_id: &SessionId,
182        _operation_id: meerkat_core::image_generation::ImageOperationId,
183        _observation: meerkat_core::image_generation::ImageProviderTerminalObservation,
184        _provider_text: meerkat_core::image_generation::ProviderTextDisposition,
185    ) -> Result<meerkat_core::image_generation::ImageOperationTerminalClass, RuntimeDriverError>
186    {
187        Err(RuntimeDriverError::Internal(
188            "image operation terminal classification is not supported by this runtime adapter"
189                .into(),
190        ))
191    }
192
193    async fn complete_image_operation(
194        &self,
195        _session_id: &SessionId,
196        _operation_id: meerkat_core::image_generation::ImageOperationId,
197        _terminal: meerkat_core::image_generation::ImageOperationTerminalClass,
198    ) -> Result<meerkat_core::image_generation::ImageOperationPhase, RuntimeDriverError> {
199        Err(RuntimeDriverError::Internal(
200            "image operation completion is not supported by this runtime adapter".into(),
201        ))
202    }
203
204    async fn restore_image_operation_override(
205        &self,
206        _session_id: &SessionId,
207        _operation_id: meerkat_core::image_generation::ImageOperationId,
208    ) -> Result<meerkat_core::image_generation::ImageOperationPhase, RuntimeDriverError> {
209        Err(RuntimeDriverError::Internal(
210            "image operation restore is not supported by this runtime adapter".into(),
211        ))
212    }
213}
214
215#[cfg(test)]
216mod tests {
217    use super::*;
218
219    // Verify trait is object-safe
220    fn _assert_object_safe(_: &dyn SessionServiceRuntimeExt) {}
221}