mesh_llm_runtime_event_contracts/
fact_data.rs1use std::time::Duration;
2
3const MAX_ID_BYTES: usize = 256;
4const MAX_STATE_BYTES: usize = 64;
5const MAX_REASON_BYTES: usize = 128;
6const MAX_SUMMARY_KEY_BYTES: usize = 64;
7const MAX_HUMAN_SUMMARY_BYTES: usize = 512;
8const MAX_NUMERIC_SUMMARIES: usize = 16;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum BoundedTextError {
12 Empty,
13 TooLong,
14}
15
16fn bounded_text(value: &str, max_bytes: usize) -> Result<String, BoundedTextError> {
17 if value.is_empty() {
18 return Err(BoundedTextError::Empty);
19 }
20 if value.len() > max_bytes {
21 return Err(BoundedTextError::TooLong);
22 }
23 Ok(value.to_owned())
24}
25
26macro_rules! string_value {
27 ($name:ident, $max:expr) => {
28 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
29 pub struct $name(String);
30
31 impl $name {
32 pub fn new(value: &str) -> Result<Self, BoundedTextError> {
33 bounded_text(value, $max).map(Self)
34 }
35
36 #[must_use]
37 pub fn as_str(&self) -> &str {
38 &self.0
39 }
40 }
41 };
42}
43
44string_value!(LogicalModelId, MAX_ID_BYTES);
45string_value!(TopologyId, MAX_ID_BYTES);
46string_value!(StageId, MAX_ID_BYTES);
47string_value!(SessionId, MAX_ID_BYTES);
48string_value!(RequestId, MAX_ID_BYTES);
49string_value!(DeviceId, MAX_ID_BYTES);
50string_value!(StateName, MAX_STATE_BYTES);
51string_value!(UnknownReasonCode, MAX_REASON_BYTES);
52string_value!(NumericSummaryKey, MAX_SUMMARY_KEY_BYTES);
53string_value!(HumanSummary, MAX_HUMAN_SUMMARY_BYTES);
54
55#[derive(Debug, Clone, PartialEq, Eq)]
56pub struct StageIdentity {
57 pub id: StageId,
58 pub index: u32,
59}
60
61impl StageIdentity {
62 #[must_use]
63 pub const fn new(id: StageId, index: u32) -> Self {
64 Self { id, index }
65 }
66}
67
68#[derive(Debug, Clone, PartialEq, Eq, Default)]
69pub struct ScopeIdentities {
70 pub model_id: Option<LogicalModelId>,
71 pub topology_id: Option<TopologyId>,
72 pub stage: Option<StageIdentity>,
73 pub session_id: Option<SessionId>,
74 pub request_id: Option<RequestId>,
75 pub device_id: Option<DeviceId>,
76}
77
78#[derive(Debug, Clone, PartialEq, Eq)]
79pub struct StateTransition {
80 pub previous: Option<StateName>,
81 pub current: StateName,
82}
83
84impl StateTransition {
85 #[must_use]
86 pub const fn new(previous: Option<StateName>, current: StateName) -> Self {
87 Self { previous, current }
88 }
89}
90
91#[derive(Debug, Clone, Copy, PartialEq, Eq)]
92pub enum ProgressUnit {
93 None,
94 Bytes,
95 Items,
96 Tensors,
97 Steps,
98 Tokens,
99}
100
101#[derive(Debug, Clone, Copy, PartialEq, Eq)]
102pub struct Progress {
103 pub current: u64,
104 pub total: Option<u64>,
105 pub unit: ProgressUnit,
106}
107
108impl Progress {
109 #[must_use]
110 pub const fn new(current: u64, total: Option<u64>, unit: ProgressUnit) -> Self {
111 Self {
112 current,
113 total,
114 unit,
115 }
116 }
117}
118
119#[derive(Debug, Clone, Copy, PartialEq, Eq)]
120pub enum Outcome {
121 Success,
122 Failure,
123 Rejected,
124 Cancelled,
125 Unknown,
126}
127
128#[derive(Debug, Clone, PartialEq, Eq)]
129pub enum ReasonCode {
130 InvalidConfiguration,
131 UnsupportedCapability,
132 MissingArtifact,
133 ArtifactIoFailure,
134 ModelFormatOrLoadFailure,
135 BackendInitializationFailure,
136 DeviceUnavailable,
137 ResourceAllocationFailure,
138 OutOfMemory,
139 ContextExhausted,
140 StageUnavailable,
141 Timeout,
142 Cancellation,
143 ProcessCrash,
144 IncompatibleAbiOrFeatureSet,
145 InternalRuntimeFailure,
146 UnknownFailure,
147 TerminalNotDelivered,
148 ReservationExhausted,
149 Unknown(UnknownReasonCode),
150}
151
152#[derive(Debug, Clone, Copy, PartialEq)]
153pub enum NumericValue {
154 Unsigned(u64),
155 Signed(i64),
156 Floating(f64),
157}
158
159#[derive(Debug, Clone, PartialEq)]
160pub struct NumericSummary {
161 pub key: NumericSummaryKey,
162 pub value: NumericValue,
163}
164
165impl NumericSummary {
166 #[must_use]
167 pub const fn new(key: NumericSummaryKey, value: NumericValue) -> Self {
168 Self { key, value }
169 }
170}
171
172#[derive(Debug, Clone, Copy, PartialEq, Eq)]
173pub struct TooManyNumericSummaries;
174
175#[derive(Debug, Clone, PartialEq, Default)]
176pub struct BoundedNumericSummaries(Vec<NumericSummary>);
177
178impl BoundedNumericSummaries {
179 pub fn new(values: Vec<NumericSummary>) -> Result<Self, TooManyNumericSummaries> {
180 if values.len() > MAX_NUMERIC_SUMMARIES {
181 return Err(TooManyNumericSummaries);
182 }
183 Ok(Self(values))
184 }
185
186 #[must_use]
187 pub fn as_slice(&self) -> &[NumericSummary] {
188 &self.0
189 }
190}
191
192#[derive(Debug, Clone, PartialEq, Default)]
193pub struct FactData {
194 pub scope: ScopeIdentities,
195 pub state: Option<StateTransition>,
196 pub progress: Option<Progress>,
197 pub outcome: Option<Outcome>,
198 pub reason: Option<ReasonCode>,
199 pub duration: Option<Duration>,
200 pub numeric_summaries: BoundedNumericSummaries,
201 pub summary: Option<HumanSummary>,
202}