1use super::*;
2use crate::input_state::StoredInputState;
3
4#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
5#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
6impl SessionServiceRuntimeExt for MeerkatMachine {
7 fn runtime_mode(&self) -> RuntimeMode {
8 self.mode
9 }
10
11 async fn accept_input(
12 &self,
13 session_id: &SessionId,
14 input: Input,
15 ) -> Result<AcceptOutcome, RuntimeDriverError> {
16 let runtime_id = MeerkatMachine::logical_runtime_id(session_id);
17 match self
18 .execute_meerkat_machine_command(
19 None,
20 MeerkatMachineCommand::Ingest { runtime_id, input },
21 )
22 .await
23 .map_err(MeerkatMachine::driver_error_from_command_error)?
24 {
25 MeerkatMachineCommandResult::AcceptOutcome(outcome) => Ok(outcome),
26 other => Err(RuntimeDriverError::Internal(format!(
27 "unexpected MeerkatMachineCommandResult for SessionServiceRuntimeExt::accept_input: {other:?}"
28 ))),
29 }
30 }
31
32 async fn accept_input_with_completion(
33 &self,
34 session_id: &SessionId,
35 input: Input,
36 ) -> Result<(AcceptOutcome, Option<crate::completion::CompletionHandle>), RuntimeDriverError>
37 {
38 Box::pin(MeerkatMachine::accept_input_with_completion(
39 self, session_id, input,
40 ))
41 .await
42 }
43
44 async fn runtime_state(
45 &self,
46 session_id: &SessionId,
47 ) -> Result<RuntimeState, RuntimeDriverError> {
48 let runtime_id = MeerkatMachine::logical_runtime_id(session_id);
49 match self
50 .execute_meerkat_machine_command(
51 None,
52 MeerkatMachineCommand::RuntimeState { runtime_id },
53 )
54 .await
55 .map_err(MeerkatMachine::driver_error_from_command_error)?
56 {
57 MeerkatMachineCommandResult::RuntimeState(state) => Ok(state),
58 other => Err(RuntimeDriverError::Internal(format!(
59 "unexpected MeerkatMachineCommandResult for SessionServiceRuntimeExt::runtime_state: {other:?}"
60 ))),
61 }
62 }
63
64 async fn retire_runtime(
65 &self,
66 session_id: &SessionId,
67 ) -> Result<RetireReport, RuntimeDriverError> {
68 let runtime_id = MeerkatMachine::logical_runtime_id(session_id);
69 match self
70 .execute_meerkat_machine_command(None, MeerkatMachineCommand::Retire { runtime_id })
71 .await
72 .map_err(MeerkatMachine::driver_error_from_command_error)?
73 {
74 MeerkatMachineCommandResult::RetireReport(report) => Ok(report),
75 other => Err(RuntimeDriverError::Internal(format!(
76 "unexpected MeerkatMachineCommandResult for SessionServiceRuntimeExt::retire_runtime: {other:?}"
77 ))),
78 }
79 }
80
81 async fn reset_runtime(
82 &self,
83 session_id: &SessionId,
84 ) -> Result<ResetReport, RuntimeDriverError> {
85 let runtime_id = MeerkatMachine::logical_runtime_id(session_id);
86 match self
87 .execute_meerkat_machine_command(None, MeerkatMachineCommand::Reset { runtime_id })
88 .await
89 .map_err(MeerkatMachine::driver_error_from_command_error)?
90 {
91 MeerkatMachineCommandResult::ResetReport(report) => Ok(report),
92 other => Err(RuntimeDriverError::Internal(format!(
93 "unexpected MeerkatMachineCommandResult for SessionServiceRuntimeExt::reset_runtime: {other:?}"
94 ))),
95 }
96 }
97
98 async fn input_state(
99 &self,
100 session_id: &SessionId,
101 input_id: &InputId,
102 ) -> Result<Option<StoredInputState>, RuntimeDriverError> {
103 match self
104 .execute_meerkat_machine_command(
105 None,
106 MeerkatMachineCommand::InputState {
107 session_id: session_id.clone(),
108 input_id: input_id.clone(),
109 },
110 )
111 .await
112 .map_err(MeerkatMachine::driver_error_from_command_error)?
113 {
114 MeerkatMachineCommandResult::InputState(state) => Ok(state),
115 other => Err(RuntimeDriverError::Internal(format!(
116 "unexpected MeerkatMachineCommandResult for SessionServiceRuntimeExt::input_state: {other:?}"
117 ))),
118 }
119 }
120
121 async fn list_active_inputs(
122 &self,
123 session_id: &SessionId,
124 ) -> Result<Vec<InputId>, RuntimeDriverError> {
125 match self
126 .execute_meerkat_machine_command(
127 None,
128 MeerkatMachineCommand::ListActiveInputs {
129 session_id: session_id.clone(),
130 },
131 )
132 .await
133 .map_err(MeerkatMachine::driver_error_from_command_error)?
134 {
135 MeerkatMachineCommandResult::ActiveInputs(inputs) => Ok(inputs),
136 other => Err(RuntimeDriverError::Internal(format!(
137 "unexpected MeerkatMachineCommandResult for SessionServiceRuntimeExt::list_active_inputs: {other:?}"
138 ))),
139 }
140 }
141
142 async fn reconfigure_session_llm_identity(
143 &self,
144 session_id: &SessionId,
145 request: SessionLlmReconfigureRequest,
146 ) -> Result<SessionLlmReconfigureReport, RuntimeDriverError> {
147 let command = self
148 .prepare_reconfigure_session_llm_command(session_id, request)
149 .await?;
150 match self
151 .execute_meerkat_machine_command(None, command)
152 .await
153 .map_err(MeerkatMachine::driver_error_from_command_error)?
154 {
155 MeerkatMachineCommandResult::LlmReconfigured(report) => Ok(report),
156 other => Err(RuntimeDriverError::Internal(format!(
157 "unexpected MeerkatMachineCommandResult for SessionServiceRuntimeExt::reconfigure_session_llm_identity: {other:?}"
158 ))),
159 }
160 }
161
162 async fn realtime_attachment_status(
163 &self,
164 session_id: &SessionId,
165 ) -> Result<crate::meerkat_machine_types::RealtimeAttachmentStatus, RuntimeDriverError> {
166 match self
167 .execute_meerkat_machine_command(
168 None,
169 MeerkatMachineCommand::RuntimeRealtimeAttachmentStatus {
170 session_id: session_id.clone(),
171 },
172 )
173 .await
174 .map_err(MeerkatMachine::driver_error_from_command_error)?
175 {
176 MeerkatMachineCommandResult::RealtimeAttachmentStatus(status) => Ok(status),
177 other => Err(RuntimeDriverError::Internal(format!(
178 "unexpected MeerkatMachineCommandResult for SessionServiceRuntimeExt::realtime_attachment_status: {other:?}"
179 ))),
180 }
181 }
182
183 async fn resolved_session_llm_capabilities(
184 &self,
185 session_id: &SessionId,
186 ) -> Result<Option<SessionLlmCapabilitySurface>, RuntimeDriverError> {
187 match self
188 .execute_meerkat_machine_command(
189 None,
190 MeerkatMachineCommand::ResolvedSessionLlmCapabilities {
191 session_id: session_id.clone(),
192 },
193 )
194 .await
195 .map_err(MeerkatMachine::driver_error_from_command_error)?
196 {
197 MeerkatMachineCommandResult::ResolvedSessionLlmCapabilities(capabilities) => {
198 Ok(capabilities)
199 }
200 other => Err(RuntimeDriverError::Internal(format!(
201 "unexpected MeerkatMachineCommandResult for SessionServiceRuntimeExt::resolved_session_llm_capabilities: {other:?}"
202 ))),
203 }
204 }
205
206 async fn realtime_channel_status(
210 &self,
211 session_id: &SessionId,
212 ) -> Result<meerkat_contracts::RealtimeChannelStatus, RuntimeDriverError> {
213 match self
214 .execute_meerkat_machine_command(
215 None,
216 MeerkatMachineCommand::RuntimeRealtimeChannelStatus {
217 session_id: session_id.clone(),
218 },
219 )
220 .await
221 .map_err(MeerkatMachine::driver_error_from_command_error)?
222 {
223 MeerkatMachineCommandResult::RealtimeChannelStatus(status) => Ok(status),
224 other => Err(RuntimeDriverError::Internal(format!(
225 "unexpected MeerkatMachineCommandResult for SessionServiceRuntimeExt::realtime_channel_status: {other:?}"
226 ))),
227 }
228 }
229
230 async fn realtime_bootstrap_eligibility(
231 &self,
232 session_id: &SessionId,
233 ) -> Result<crate::meerkat_machine_types::RealtimeBootstrapEligibility, RuntimeDriverError>
234 {
235 MeerkatMachine::realtime_bootstrap_eligibility(self, session_id).await
236 }
237
238 async fn configure_model_routing_baseline(
239 &self,
240 session_id: &SessionId,
241 baseline_model: meerkat_core::lifecycle::run_primitive::ModelId,
242 realtime_capable: bool,
243 ) -> Result<(), RuntimeDriverError> {
244 match self
245 .execute_meerkat_machine_command(
246 None,
247 MeerkatMachineCommand::ConfigureModelRoutingBaseline {
248 session_id: session_id.clone(),
249 baseline_model,
250 realtime_capable,
251 },
252 )
253 .await
254 .map_err(MeerkatMachine::driver_error_from_command_error)?
255 {
256 MeerkatMachineCommandResult::Unit => Ok(()),
257 other => Err(RuntimeDriverError::Internal(format!(
258 "unexpected MeerkatMachineCommandResult for SessionServiceRuntimeExt::configure_model_routing_baseline: {other:?}"
259 ))),
260 }
261 }
262
263 async fn session_model_routing_status(
264 &self,
265 session_id: &SessionId,
266 ) -> Result<meerkat_core::image_generation::SessionModelRoutingStatus, RuntimeDriverError> {
267 match self
268 .execute_meerkat_machine_command(
269 None,
270 MeerkatMachineCommand::SessionModelRoutingStatus {
271 session_id: session_id.clone(),
272 },
273 )
274 .await
275 .map_err(MeerkatMachine::driver_error_from_command_error)?
276 {
277 MeerkatMachineCommandResult::SessionModelRoutingStatus(status) => Ok(status),
278 other => Err(RuntimeDriverError::Internal(format!(
279 "unexpected MeerkatMachineCommandResult for SessionServiceRuntimeExt::session_model_routing_status: {other:?}"
280 ))),
281 }
282 }
283
284 async fn request_switch_turn(
285 &self,
286 session_id: &SessionId,
287 request: crate::meerkat_machine_types::SwitchTurnRequest,
288 ) -> Result<meerkat_core::image_generation::SwitchTurnControlResult, RuntimeDriverError> {
289 match self
290 .execute_meerkat_machine_command(
291 None,
292 MeerkatMachineCommand::RequestSwitchTurn {
293 session_id: session_id.clone(),
294 request: Box::new(request),
295 },
296 )
297 .await
298 .map_err(MeerkatMachine::driver_error_from_command_error)?
299 {
300 MeerkatMachineCommandResult::SwitchTurnControlResult(result) => Ok(result),
301 other => Err(RuntimeDriverError::Internal(format!(
302 "unexpected MeerkatMachineCommandResult for SessionServiceRuntimeExt::request_switch_turn: {other:?}"
303 ))),
304 }
305 }
306
307 async fn admit_model_routing_assistant_turn(
308 &self,
309 session_id: &SessionId,
310 ) -> Result<(), RuntimeDriverError> {
311 match self
312 .execute_meerkat_machine_command(
313 None,
314 MeerkatMachineCommand::AdmitModelRoutingAssistantTurn {
315 session_id: session_id.clone(),
316 },
317 )
318 .await
319 .map_err(MeerkatMachine::driver_error_from_command_error)?
320 {
321 MeerkatMachineCommandResult::Unit => Ok(()),
322 other => Err(RuntimeDriverError::Internal(format!(
323 "unexpected MeerkatMachineCommandResult for SessionServiceRuntimeExt::admit_model_routing_assistant_turn: {other:?}"
324 ))),
325 }
326 }
327
328 async fn begin_image_operation(
329 &self,
330 session_id: &SessionId,
331 request: crate::meerkat_machine_types::ImageOperationRoutingRequest,
332 ) -> Result<crate::meerkat_machine_types::ImageOperationRoutingResult, RuntimeDriverError> {
333 match self
334 .execute_meerkat_machine_command(
335 None,
336 MeerkatMachineCommand::BeginImageOperation {
337 session_id: session_id.clone(),
338 request: Box::new(request),
339 },
340 )
341 .await
342 .map_err(MeerkatMachine::driver_error_from_command_error)?
343 {
344 MeerkatMachineCommandResult::ImageOperationRoutingResult(result) => Ok(result),
345 other => Err(RuntimeDriverError::Internal(format!(
346 "unexpected MeerkatMachineCommandResult for SessionServiceRuntimeExt::begin_image_operation: {other:?}"
347 ))),
348 }
349 }
350
351 async fn activate_image_operation_override(
352 &self,
353 session_id: &SessionId,
354 operation_id: meerkat_core::image_generation::ImageOperationId,
355 ) -> Result<meerkat_core::image_generation::ImageOperationPhase, RuntimeDriverError> {
356 match self
357 .execute_meerkat_machine_command(
358 None,
359 MeerkatMachineCommand::ActivateImageOperationOverride {
360 session_id: session_id.clone(),
361 operation_id,
362 },
363 )
364 .await
365 .map_err(MeerkatMachine::driver_error_from_command_error)?
366 {
367 MeerkatMachineCommandResult::ImageOperationPhase(phase) => Ok(phase),
368 other => Err(RuntimeDriverError::Internal(format!(
369 "unexpected MeerkatMachineCommandResult for SessionServiceRuntimeExt::activate_image_operation_override: {other:?}"
370 ))),
371 }
372 }
373
374 async fn complete_image_operation(
375 &self,
376 session_id: &SessionId,
377 operation_id: meerkat_core::image_generation::ImageOperationId,
378 terminal: meerkat_core::image_generation::ImageOperationTerminalClass,
379 ) -> Result<meerkat_core::image_generation::ImageOperationPhase, RuntimeDriverError> {
380 match self
381 .execute_meerkat_machine_command(
382 None,
383 MeerkatMachineCommand::CompleteImageOperation {
384 session_id: session_id.clone(),
385 operation_id,
386 terminal,
387 },
388 )
389 .await
390 .map_err(MeerkatMachine::driver_error_from_command_error)?
391 {
392 MeerkatMachineCommandResult::ImageOperationPhase(phase) => Ok(phase),
393 other => Err(RuntimeDriverError::Internal(format!(
394 "unexpected MeerkatMachineCommandResult for SessionServiceRuntimeExt::complete_image_operation: {other:?}"
395 ))),
396 }
397 }
398
399 async fn restore_image_operation_override(
400 &self,
401 session_id: &SessionId,
402 operation_id: meerkat_core::image_generation::ImageOperationId,
403 ) -> Result<meerkat_core::image_generation::ImageOperationPhase, RuntimeDriverError> {
404 match self
405 .execute_meerkat_machine_command(
406 None,
407 MeerkatMachineCommand::RestoreImageOperationOverride {
408 session_id: session_id.clone(),
409 operation_id,
410 },
411 )
412 .await
413 .map_err(MeerkatMachine::driver_error_from_command_error)?
414 {
415 MeerkatMachineCommandResult::ImageOperationPhase(phase) => Ok(phase),
416 other => Err(RuntimeDriverError::Internal(format!(
417 "unexpected MeerkatMachineCommandResult for SessionServiceRuntimeExt::restore_image_operation_override: {other:?}"
418 ))),
419 }
420 }
421}
422
423impl MeerkatMachine {
428 pub(crate) fn logical_runtime_id(session_id: &SessionId) -> LogicalRuntimeId {
429 LogicalRuntimeId::for_session(session_id)
430 }
431
432 pub(super) fn post_admission_signal_from_effects(
433 effects: &[crate::meerkat_machine::dsl::MeerkatMachineEffect],
434 ) -> crate::driver::ephemeral::PostAdmissionSignal {
435 effects
436 .iter()
437 .find_map(|effect| match effect {
438 crate::meerkat_machine::dsl::MeerkatMachineEffect::PostAdmissionSignal {
439 signal,
440 } => Some(match signal {
441 crate::meerkat_machine::dsl::PostAdmissionSignalKind::WakeLoop => {
442 crate::driver::ephemeral::PostAdmissionSignal::WakeLoop
443 }
444 crate::meerkat_machine::dsl::PostAdmissionSignalKind::InterruptYielding => {
445 crate::driver::ephemeral::PostAdmissionSignal::InterruptYielding
446 }
447 crate::meerkat_machine::dsl::PostAdmissionSignalKind::RequestImmediateProcessing => {
448 crate::driver::ephemeral::PostAdmissionSignal::RequestImmediateProcessing
449 }
450 }),
451 _ => None,
452 })
453 .unwrap_or(crate::driver::ephemeral::PostAdmissionSignal::None)
454 }
455
456 pub(super) fn driver_error_from_command_error(
457 err: MeerkatMachineCommandError,
458 ) -> RuntimeDriverError {
459 match err {
460 MeerkatMachineCommandError::Driver(err) => err,
461 MeerkatMachineCommandError::Control(err) => {
462 Self::driver_error_from_control_plane_error(err)
463 }
464 }
465 }
466
467 pub(super) fn control_plane_error_from_command_error(
468 err: MeerkatMachineCommandError,
469 ) -> RuntimeControlPlaneError {
470 match err {
471 MeerkatMachineCommandError::Control(err) => err,
472 MeerkatMachineCommandError::Driver(err) => {
473 RuntimeControlPlaneError::Internal(err.to_string())
474 }
475 }
476 }
477
478 pub(super) fn driver_error_from_control_plane_error(
479 err: RuntimeControlPlaneError,
480 ) -> RuntimeDriverError {
481 match err {
482 RuntimeControlPlaneError::NotFound(_) => RuntimeDriverError::NotReady {
483 state: RuntimeState::Destroyed,
484 },
485 RuntimeControlPlaneError::InvalidState { state } => {
486 RuntimeDriverError::NotReady { state }
487 }
488 RuntimeControlPlaneError::StoreError(message)
489 | RuntimeControlPlaneError::Internal(message) => RuntimeDriverError::Internal(message),
490 }
491 }
492
493 pub(super) async fn resolve_session_id(
495 &self,
496 runtime_id: &LogicalRuntimeId,
497 ) -> Result<SessionId, RuntimeControlPlaneError> {
498 let sessions = self.sessions.read().await;
499 sessions
500 .iter()
501 .find_map(|(session_id, entry)| {
502 (&entry.runtime_id == runtime_id).then(|| session_id.clone())
503 })
504 .ok_or_else(|| RuntimeControlPlaneError::NotFound(runtime_id.clone()))
505 }
506
507 pub(super) async fn existing_session_runtime_state(
508 &self,
509 session_id: &SessionId,
510 ) -> Option<RuntimeState> {
511 let sessions = self.sessions.read().await;
512 let entry = sessions.get(session_id)?;
513 let control = entry.control_snapshot();
518 let authority = entry
519 .dsl_authority
520 .lock()
521 .unwrap_or_else(std::sync::PoisonError::into_inner);
522 let dsl_phase = dsl_authority::runtime_phase_from_authority(&authority);
523 let dsl_pre_run_phase = dsl_authority::pre_run_phase_from_authority(&authority);
524 if self.has_runtime_persistence()
525 && dsl_authority::should_publish_control_over_dsl(
526 control.phase,
527 dsl_phase,
528 dsl_pre_run_phase,
529 )
530 {
531 Some(control.phase)
532 } else {
533 Some(dsl_phase)
534 }
535 }
536
537 pub(super) async fn existing_session_visible_runtime_state(
538 &self,
539 session_id: &SessionId,
540 ) -> Option<RuntimeState> {
541 let sessions = self.sessions.read().await;
542 let entry = sessions.get(session_id)?;
543 let control = entry.control_snapshot();
544 let authority = entry
545 .dsl_authority
546 .lock()
547 .unwrap_or_else(std::sync::PoisonError::into_inner);
548 let dsl_phase = dsl_authority::runtime_phase_from_authority(&authority);
549 let dsl_pre_run_phase = dsl_authority::pre_run_phase_from_authority(&authority);
550 if self.has_runtime_persistence()
551 && dsl_authority::should_publish_control_over_dsl(
552 control.phase,
553 dsl_phase,
554 dsl_pre_run_phase,
555 )
556 {
557 Some(dsl_authority::visible_runtime_phase(
558 control.phase,
559 control.pre_run_phase,
560 ))
561 } else {
562 Some(dsl_authority::visible_runtime_phase(
563 dsl_phase,
564 dsl_pre_run_phase,
565 ))
566 }
567 }
568
569 pub(super) async fn lookup_entry(
572 &self,
573 runtime_id: &LogicalRuntimeId,
574 ) -> Result<
575 (
576 SessionId,
577 SharedDriver,
578 SharedCompletionRegistry,
579 Option<mpsc::Sender<()>>,
580 ),
581 RuntimeControlPlaneError,
582 > {
583 let sessions = self.sessions.read().await;
584 let (session_id, entry) = sessions
585 .iter()
586 .find(|(_, entry)| &entry.runtime_id == runtime_id)
587 .ok_or_else(|| RuntimeControlPlaneError::NotFound(runtime_id.clone()))?;
588 Ok((
589 session_id.clone(),
590 entry.driver.clone(),
591 entry.completions.clone(),
592 entry.wake_sender(),
593 ))
594 }
595}
596
597#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
598#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
599impl crate::traits::RuntimeControlPlane for MeerkatMachine {
600 async fn ingest(
601 &self,
602 runtime_id: &LogicalRuntimeId,
603 input: Input,
604 ) -> Result<AcceptOutcome, RuntimeControlPlaneError> {
605 match self
606 .execute_meerkat_machine_command(
607 None,
608 MeerkatMachineCommand::Ingest {
609 runtime_id: runtime_id.clone(),
610 input,
611 },
612 )
613 .await
614 .map_err(MeerkatMachine::control_plane_error_from_command_error)?
615 {
616 MeerkatMachineCommandResult::AcceptOutcome(outcome) => Ok(outcome),
617 other => Err(RuntimeControlPlaneError::Internal(format!(
618 "unexpected MeerkatMachineCommandResult for ingest: {other:?}"
619 ))),
620 }
621 }
622
623 async fn publish_event(
624 &self,
625 event: crate::runtime_event::RuntimeEventEnvelope,
626 ) -> Result<(), RuntimeControlPlaneError> {
627 match self
628 .execute_meerkat_machine_command(None, MeerkatMachineCommand::PublishEvent { event })
629 .await
630 .map_err(MeerkatMachine::control_plane_error_from_command_error)?
631 {
632 MeerkatMachineCommandResult::Unit => Ok(()),
633 other => Err(RuntimeControlPlaneError::Internal(format!(
634 "unexpected MeerkatMachineCommandResult for publish_event: {other:?}"
635 ))),
636 }
637 }
638
639 async fn retire(
640 &self,
641 runtime_id: &LogicalRuntimeId,
642 ) -> Result<RetireReport, RuntimeControlPlaneError> {
643 match self
644 .execute_meerkat_machine_command(
645 None,
646 MeerkatMachineCommand::Retire {
647 runtime_id: runtime_id.clone(),
648 },
649 )
650 .await
651 .map_err(MeerkatMachine::control_plane_error_from_command_error)?
652 {
653 MeerkatMachineCommandResult::RetireReport(report) => Ok(report),
654 other => Err(RuntimeControlPlaneError::Internal(format!(
655 "unexpected MeerkatMachineCommandResult for retire: {other:?}"
656 ))),
657 }
658 }
659
660 async fn recycle(
661 &self,
662 runtime_id: &LogicalRuntimeId,
663 ) -> Result<RecycleReport, RuntimeControlPlaneError> {
664 match self
665 .execute_meerkat_machine_command(
666 None,
667 MeerkatMachineCommand::Recycle {
668 runtime_id: runtime_id.clone(),
669 },
670 )
671 .await
672 .map_err(MeerkatMachine::control_plane_error_from_command_error)?
673 {
674 MeerkatMachineCommandResult::RecycleReport(report) => Ok(report),
675 other => Err(RuntimeControlPlaneError::Internal(format!(
676 "unexpected MeerkatMachineCommandResult for recycle: {other:?}"
677 ))),
678 }
679 }
680
681 async fn reset(
682 &self,
683 runtime_id: &LogicalRuntimeId,
684 ) -> Result<crate::traits::ResetReport, RuntimeControlPlaneError> {
685 match self
686 .execute_meerkat_machine_command(
687 None,
688 MeerkatMachineCommand::Reset {
689 runtime_id: runtime_id.clone(),
690 },
691 )
692 .await
693 .map_err(MeerkatMachine::control_plane_error_from_command_error)?
694 {
695 MeerkatMachineCommandResult::ResetReport(report) => Ok(report),
696 other => Err(RuntimeControlPlaneError::Internal(format!(
697 "unexpected MeerkatMachineCommandResult for reset: {other:?}"
698 ))),
699 }
700 }
701
702 async fn recover(
703 &self,
704 runtime_id: &LogicalRuntimeId,
705 ) -> Result<RecoveryReport, RuntimeControlPlaneError> {
706 match self
707 .execute_meerkat_machine_command(
708 None,
709 MeerkatMachineCommand::Recover {
710 runtime_id: runtime_id.clone(),
711 },
712 )
713 .await
714 .map_err(MeerkatMachine::control_plane_error_from_command_error)?
715 {
716 MeerkatMachineCommandResult::RecoveryReport(report) => Ok(report),
717 other => Err(RuntimeControlPlaneError::Internal(format!(
718 "unexpected MeerkatMachineCommandResult for recover: {other:?}"
719 ))),
720 }
721 }
722
723 async fn destroy(
724 &self,
725 runtime_id: &LogicalRuntimeId,
726 ) -> Result<DestroyReport, RuntimeControlPlaneError> {
727 match self
728 .execute_meerkat_machine_command(
729 None,
730 MeerkatMachineCommand::Destroy {
731 runtime_id: runtime_id.clone(),
732 },
733 )
734 .await
735 .map_err(MeerkatMachine::control_plane_error_from_command_error)?
736 {
737 MeerkatMachineCommandResult::DestroyReport(report) => Ok(report),
738 other => Err(RuntimeControlPlaneError::Internal(format!(
739 "unexpected MeerkatMachineCommandResult for destroy: {other:?}"
740 ))),
741 }
742 }
743
744 async fn runtime_state(
745 &self,
746 runtime_id: &LogicalRuntimeId,
747 ) -> Result<RuntimeState, RuntimeControlPlaneError> {
748 match self
749 .execute_meerkat_machine_command(
750 None,
751 MeerkatMachineCommand::RuntimeState {
752 runtime_id: runtime_id.clone(),
753 },
754 )
755 .await
756 .map_err(MeerkatMachine::control_plane_error_from_command_error)?
757 {
758 MeerkatMachineCommandResult::RuntimeState(state) => Ok(state),
759 other => Err(RuntimeControlPlaneError::Internal(format!(
760 "unexpected MeerkatMachineCommandResult for runtime_state: {other:?}"
761 ))),
762 }
763 }
764
765 async fn load_boundary_receipt(
766 &self,
767 runtime_id: &LogicalRuntimeId,
768 run_id: &RunId,
769 sequence: u64,
770 ) -> Result<Option<meerkat_core::lifecycle::RunBoundaryReceipt>, RuntimeControlPlaneError> {
771 match self
772 .execute_meerkat_machine_command(
773 None,
774 MeerkatMachineCommand::LoadBoundaryReceipt {
775 runtime_id: runtime_id.clone(),
776 run_id: run_id.clone(),
777 sequence,
778 },
779 )
780 .await
781 .map_err(MeerkatMachine::control_plane_error_from_command_error)?
782 {
783 MeerkatMachineCommandResult::BoundaryReceipt(receipt) => Ok(receipt),
784 other => Err(RuntimeControlPlaneError::Internal(format!(
785 "unexpected MeerkatMachineCommandResult for load_boundary_receipt: {other:?}"
786 ))),
787 }
788 }
789}