Skip to main content

rlmesh_runtime/hooks/
traits.rs

1use async_trait::async_trait;
2use rlmesh_proto::common::v1::MessageBytes;
3
4use super::{
5    ActionReceivedEvent, EnvConnectedEvent, EpisodeCompletedEvent, EpisodeStartedEvent, LogEvent,
6    ModelConnectedEvent, ObservationEmittedEvent, SessionEndedEvent, SessionFailedEvent,
7    SessionStartedEvent, StepCompletedEvent, TelemetrySummaryEvent, TelemetryWindowEvent,
8};
9
10#[derive(Debug, thiserror::Error)]
11pub enum HookError {
12    #[error("{0}")]
13    Message(String),
14}
15
16#[derive(Debug, Default)]
17pub struct NoopRuntimeHooks;
18
19#[async_trait]
20impl RuntimeHooks for NoopRuntimeHooks {}
21
22#[async_trait]
23pub trait RuntimeHooks: Send + Sync {
24    // Lifecycle/progress/telemetry/log hooks are best-effort. The runtime logs
25    // failures from these hooks and keeps the route moving.
26    async fn env_connected(&self, _event: EnvConnectedEvent) -> Result<(), HookError> {
27        Ok(())
28    }
29
30    async fn model_connected(&self, _event: ModelConnectedEvent) -> Result<(), HookError> {
31        Ok(())
32    }
33
34    async fn session_started(&self, _event: SessionStartedEvent) -> Result<(), HookError> {
35        Ok(())
36    }
37
38    async fn episode_started(&self, _event: EpisodeStartedEvent) -> Result<(), HookError> {
39        Ok(())
40    }
41
42    async fn episode_completed(&self, _event: EpisodeCompletedEvent) -> Result<(), HookError> {
43        Ok(())
44    }
45
46    async fn action_received(&self, _event: ActionReceivedEvent) -> Result<(), HookError> {
47        Ok(())
48    }
49
50    // Transform hooks are fatal. A failed transform means the runtime cannot
51    // safely define the next wire payload, so the route fails and shuts down.
52    async fn transform_action(
53        &self,
54        event: ActionReceivedEvent,
55    ) -> Result<Option<MessageBytes>, HookError> {
56        Ok(event.action)
57    }
58
59    async fn step_completed(&self, _event: StepCompletedEvent) -> Result<(), HookError> {
60        Ok(())
61    }
62
63    async fn observation_emitted(&self, _event: ObservationEmittedEvent) -> Result<(), HookError> {
64        Ok(())
65    }
66
67    // See transform_action: transform failures are fatal by design.
68    async fn transform_observation(
69        &self,
70        event: ObservationEmittedEvent,
71    ) -> Result<Option<MessageBytes>, HookError> {
72        Ok(event.observation)
73    }
74
75    async fn telemetry_window(&self, _event: TelemetryWindowEvent) -> Result<(), HookError> {
76        Ok(())
77    }
78
79    async fn telemetry_summary(&self, _event: TelemetrySummaryEvent) -> Result<(), HookError> {
80        Ok(())
81    }
82
83    async fn session_ended(&self, _event: SessionEndedEvent) -> Result<(), HookError> {
84        Ok(())
85    }
86
87    async fn session_failed(&self, _event: SessionFailedEvent) -> Result<(), HookError> {
88        Ok(())
89    }
90
91    async fn log(&self, _event: LogEvent) -> Result<(), HookError> {
92        Ok(())
93    }
94}