Skip to main content

rlmesh_runtime/hooks/
events.rs

1//! Event payloads the driver hands to each [`RuntimeHooks`](super::RuntimeHooks)
2//! callback. Each carries its route/session identity inline, since one hooks
3//! instance serves every concurrent route.
4
5use std::sync::Arc;
6
7use prost::bytes::Bytes;
8use rlmesh_proto::spaces::v1::MetaMap;
9use rlmesh_proto::spaces::v1::SpaceSpec;
10
11#[derive(Debug, Clone, Default, PartialEq, Eq)]
12pub struct RuntimeEnvContext {
13    pub env_id: String,
14    pub env_component_id: String,
15    pub model_component_id: String,
16}
17
18#[derive(Debug, Clone, PartialEq, Eq)]
19pub struct EnvConnectedEvent {
20    pub session_id: String,
21    pub route: RuntimeEnvContext,
22    pub env_id: String,
23}
24
25#[derive(Debug, Clone, PartialEq, Eq)]
26pub struct ModelConnectedEvent {
27    pub session_id: String,
28    pub route: RuntimeEnvContext,
29}
30
31#[derive(Debug, Clone, PartialEq, Eq)]
32pub struct SessionStartedEvent {
33    pub session_id: String,
34    pub route: RuntimeEnvContext,
35    pub env_id: String,
36}
37
38#[derive(Debug, Clone, PartialEq, Eq)]
39pub struct SessionEndedEvent {
40    pub session_id: String,
41    pub route: RuntimeEnvContext,
42    pub reason: String,
43    pub total_steps: i64,
44    pub total_episodes: i64,
45}
46
47#[derive(Debug, Clone, PartialEq, Eq)]
48pub struct SessionFailedEvent {
49    pub session_id: String,
50    pub route: RuntimeEnvContext,
51    pub reason: String,
52}
53
54#[derive(Debug, Clone, PartialEq, Eq)]
55pub struct LogEvent {
56    pub session_id: String,
57    pub route: RuntimeEnvContext,
58    pub level: LogLevel,
59    pub message: String,
60    pub source: Option<String>,
61}
62
63#[derive(Debug, Clone, Copy, PartialEq, Eq)]
64pub enum LogLevel {
65    Debug,
66    Info,
67    Warn,
68    Error,
69}
70
71#[derive(Debug, Clone, PartialEq, Eq)]
72pub struct EpisodeStartedEvent {
73    pub session_id: String,
74    pub route: RuntimeEnvContext,
75    pub episode_id: String,
76    pub episode_record_id: String,
77    pub episode_index: i64,
78    pub env_index: i32,
79    pub started_from_auto_reset: bool,
80}
81
82#[derive(Debug, Clone, PartialEq)]
83pub struct EpisodeCompletedEvent {
84    pub session_id: String,
85    pub route: RuntimeEnvContext,
86    pub episode_id: String,
87    pub episode_record_id: String,
88    pub episode_index: i64,
89    pub env_index: i32,
90    pub step_count: i64,
91    pub cumulative_reward: f64,
92    pub terminated: bool,
93    pub truncated: bool,
94    pub duration_ms: i64,
95    pub final_info: Option<MetaMap>,
96}
97
98#[derive(Debug, Clone, PartialEq)]
99pub struct ActionReceivedEvent {
100    pub session_id: String,
101    pub route: RuntimeEnvContext,
102    pub episode_id: String,
103    pub episode_record_id: String,
104    pub episode_ids: Vec<String>,
105    pub episode_record_ids: Vec<String>,
106    pub step: i64,
107    pub env_index: i32,
108    /// Shared so the per-step, per-hook event fan-out clones an `Arc` pointer
109    /// rather than deep-copying the action space spec on every step.
110    pub action_space: Arc<SpaceSpec>,
111    /// Opaque per-leaf wire bytes; the relay is content-blind (§13).
112    ///
113    /// To persist as a single artifact, use `rlmesh-grpc`'s
114    /// `wire::leaves_to_blob` — plain concatenation loses the leaf
115    /// boundaries, which cannot be recovered for variable-length leaves.
116    pub action: Option<Vec<Bytes>>,
117}
118
119#[derive(Debug, Clone, PartialEq)]
120pub struct StepCompletedEvent {
121    pub session_id: String,
122    pub route: RuntimeEnvContext,
123    pub episode_id: String,
124    pub episode_record_id: String,
125    pub step: i64,
126    pub env_index: i32,
127    pub rewards: Vec<f64>,
128}
129
130#[derive(Debug, Clone, PartialEq)]
131pub struct ObservationEmittedEvent {
132    pub session_id: String,
133    pub route: RuntimeEnvContext,
134    pub episode_id: String,
135    pub episode_record_id: String,
136    pub episode_ids: Vec<String>,
137    pub episode_record_ids: Vec<String>,
138    pub step: i64,
139    pub env_index: i32,
140    pub is_reset: bool,
141    pub num_envs: u32,
142    /// Shared so the per-step, per-hook event fan-out clones an `Arc` pointer
143    /// rather than deep-copying the observation space spec on every step.
144    pub observation_space: Arc<SpaceSpec>,
145    /// Opaque per-leaf wire bytes; the relay is content-blind (§13).
146    ///
147    /// To persist as a single artifact, use `rlmesh-grpc`'s
148    /// `wire::leaves_to_blob` — plain concatenation loses the leaf
149    /// boundaries, which cannot be recovered for variable-length leaves.
150    pub observation: Option<Vec<Bytes>>,
151}
152
153/// A live telemetry snapshot tagged with the route/session it belongs to.
154///
155/// The managed runner shares one `RuntimeHooks` across concurrent routes, so —
156/// like every other event — the snapshot carries identity inline. Identity
157/// lives on the event, not on the `Snapshot` itself, which stays a pure metrics
158/// payload (it is also the durable `RuntimeReport.telemetry`). Use
159/// `snapshot.horizon` to tell a window tick from the cumulative session.
160#[derive(Debug, Clone, PartialEq)]
161pub struct TelemetrySnapshotEvent {
162    pub session_id: String,
163    pub route: RuntimeEnvContext,
164    pub snapshot: crate::telemetry::Snapshot,
165}