Skip to main content

ferrin_core/telemetry/
events.rs

1//! Telemetry event payloads.
2
3use std::collections::BTreeMap;
4use std::sync::Arc;
5use std::time::Duration;
6
7use ferrin_message::Message;
8use ferrin_spec::FinishReason;
9use ferrin_spec::JsonValue;
10use ferrin_spec::ModelId;
11use ferrin_spec::ProviderId;
12use ferrin_spec::ResponseMetadata;
13use ferrin_spec::ToolCallId;
14use ferrin_spec::ToolName;
15use ferrin_spec::Usage;
16use ferrin_spec::Warning;
17use ferrin_spec::language_model::CallOptionsRecord;
18use serde::Deserialize;
19use serde::Serialize;
20
21use crate::error::Error;
22use crate::generate_text::StepContent;
23use crate::generate_text::StepPerformance;
24use crate::generate_text::StepResult;
25use crate::generate_text::ToolErrorInfo;
26
27/// Provider and model ids of the model handling a call.
28#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
29pub struct ModelIdentity {
30    /// Provider id.
31    pub provider: ProviderId,
32    /// Model id.
33    pub model_id: ModelId,
34}
35
36impl ModelIdentity {
37    /// Creates an identity.
38    #[must_use]
39    pub fn new(provider: impl Into<ProviderId>, model_id: impl Into<ModelId>) -> Self {
40        Self {
41            provider: provider.into(),
42            model_id: model_id.into(),
43        }
44    }
45}
46
47/// Inputs recorded when `record_inputs` is enabled.
48#[derive(Debug, Clone, PartialEq)]
49pub struct RecordedInputs {
50    /// System instructions.
51    pub system: Option<crate::prompt::Instructions>,
52    /// The initial messages.
53    pub messages: Arc<[Message]>,
54}
55
56/// A call started.
57#[derive(Debug, Clone)]
58pub struct StartEvent {
59    /// Application runtime state (available to hooks; telemetry requires `include_runtime_context`).
60    pub runtime_context: Option<JsonValue>,
61    /// Call id.
62    pub call_id: String,
63    /// Function id from the telemetry options.
64    pub function_id: Option<String>,
65    /// The model.
66    pub model: ModelIdentity,
67    /// Inputs (only when `record_inputs`).
68    pub inputs: Option<RecordedInputs>,
69    /// Metadata from the telemetry options.
70    pub metadata: BTreeMap<String, JsonValue>,
71}
72
73/// A step started.
74#[derive(Debug, Clone)]
75pub struct StepStartEvent {
76    /// Application runtime state (available to hooks; telemetry requires `include_runtime_context`).
77    pub runtime_context: Option<JsonValue>,
78    /// Call id.
79    pub call_id: String,
80    /// Zero-based step index.
81    pub step_number: u32,
82    /// The model of this step.
83    pub model: ModelIdentity,
84    /// Messages sent to the model (only when `record_inputs`).
85    pub messages: Option<Arc<[Message]>>,
86}
87
88/// A model call is about to be made.
89#[derive(Debug, Clone)]
90pub struct ModelCallStartEvent {
91    /// Application runtime state (available to hooks; telemetry requires `include_runtime_context`).
92    pub runtime_context: Option<JsonValue>,
93    /// Call id.
94    pub call_id: String,
95    /// Zero-based step index.
96    pub step_number: u32,
97    /// The model.
98    pub model: ModelIdentity,
99    /// Serializable snapshot of the call options (only when `record_inputs`).
100    pub call_options: Option<CallOptionsRecord>,
101}
102
103/// A model call finished and its tool calls were parsed.
104#[derive(Debug, Clone)]
105pub struct ModelCallEndEvent {
106    /// Application runtime state (available to hooks; telemetry requires `include_runtime_context`).
107    pub runtime_context: Option<JsonValue>,
108    /// Call id.
109    pub call_id: String,
110    /// Zero-based step index.
111    pub step_number: u32,
112    /// The model.
113    pub model: ModelIdentity,
114    /// Parsed content (only when `record_outputs`).
115    pub content: Option<Vec<StepContent>>,
116    /// Finish reason.
117    pub finish_reason: FinishReason,
118    /// Usage.
119    pub usage: Usage,
120    /// Response metadata.
121    pub response: ResponseMetadata,
122    /// Timing.
123    pub performance: StepPerformance,
124    /// Warnings.
125    pub warnings: Vec<Warning>,
126}
127
128/// A tool execution is about to start.
129#[derive(Debug, Clone)]
130pub struct ToolExecutionStartEvent {
131    /// Application runtime state (available to hooks; telemetry requires `include_runtime_context`).
132    pub runtime_context: Option<JsonValue>,
133    /// Call id.
134    pub call_id: String,
135    /// Tool call id.
136    pub tool_call_id: ToolCallId,
137    /// Tool name.
138    pub tool_name: ToolName,
139    /// Input (only when `record_inputs`).
140    pub input: Option<JsonValue>,
141}
142
143/// A tool execution finished.
144#[derive(Debug, Clone)]
145pub struct ToolExecutionEndEvent {
146    /// Application runtime state (available to hooks; telemetry requires `include_runtime_context`).
147    pub runtime_context: Option<JsonValue>,
148    /// Call id.
149    pub call_id: String,
150    /// Tool call id.
151    pub tool_call_id: ToolCallId,
152    /// Tool name.
153    pub tool_name: ToolName,
154    /// Output on success (only when `record_outputs`).
155    pub output: Option<ToolOutcome>,
156    /// Error on failure.
157    pub error: Option<ToolErrorInfo>,
158    /// Execution time.
159    pub duration: Duration,
160}
161
162/// The successful outcome of a tool execution.
163#[derive(Debug, Clone, PartialEq)]
164pub struct ToolOutcome {
165    /// The final output value.
166    pub output: JsonValue,
167}
168
169/// A step finished.
170#[derive(Debug, Clone)]
171pub struct StepEndEvent {
172    /// Call id.
173    pub call_id: String,
174    /// The step.
175    pub step: Arc<StepResult>,
176}
177
178/// A call finished.
179#[derive(Debug, Clone)]
180pub struct EndEvent {
181    /// Application runtime state of the final step (telemetry requires `include_runtime_context`).
182    pub runtime_context: Option<JsonValue>,
183    /// Call id.
184    pub call_id: String,
185    /// All steps.
186    pub steps: Arc<[StepResult]>,
187    /// Usage summed over all steps.
188    pub total_usage: Usage,
189    /// Structured output as JSON (only when `record_outputs` and configured).
190    pub output_recorded: Option<JsonValue>,
191}
192
193/// A streaming call was aborted by cancellation.
194#[derive(Debug, Clone)]
195pub struct AbortEvent {
196    /// Call id.
197    pub call_id: String,
198    /// Steps completed before the abort.
199    pub steps_completed: u32,
200}
201
202/// Where an error occurred.
203#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
204#[serde(rename_all = "kebab-case")]
205#[non_exhaustive]
206pub enum ErrorPhase {
207    /// Prompt standardization or conversion.
208    Prompt,
209    /// The model call.
210    ModelCall,
211    /// Tool execution.
212    ToolExecution,
213    /// Structured output parsing.
214    Output,
215    /// The stream pipeline.
216    Stream,
217}
218
219/// An error occurred.
220#[derive(Debug)]
221pub struct ErrorEvent<'a> {
222    /// Call id.
223    pub call_id: &'a str,
224    /// The error.
225    pub error: &'a Error,
226    /// Where it occurred.
227    pub phase: ErrorPhase,
228}
229
230/// An embedding call started.
231#[derive(Debug, Clone)]
232pub struct EmbedStartEvent {
233    /// Call id.
234    pub call_id: String,
235    /// The model.
236    pub model: ModelIdentity,
237    /// Number of values.
238    pub value_count: usize,
239    /// The values (only when `record_inputs`).
240    pub values: Option<Vec<String>>,
241}
242
243/// An embedding call finished.
244#[derive(Debug, Clone)]
245pub struct EmbedEndEvent {
246    /// Call id.
247    pub call_id: String,
248    /// Number of embeddings.
249    pub embedding_count: usize,
250    /// Tokens used, if reported.
251    pub tokens: Option<u64>,
252    /// Wall time.
253    pub duration: Duration,
254}
255
256/// A rerank call started.
257#[derive(Debug, Clone)]
258pub struct RerankStartEvent {
259    /// Call id.
260    pub call_id: String,
261    /// The model.
262    pub model: ModelIdentity,
263    /// Number of documents.
264    pub document_count: usize,
265    /// The query (only when `record_inputs`).
266    pub query: Option<String>,
267}
268
269/// A rerank call finished.
270#[derive(Debug, Clone)]
271pub struct RerankEndEvent {
272    /// Call id.
273    pub call_id: String,
274    /// Number of ranked documents.
275    pub ranked_count: usize,
276    /// Wall time.
277    pub duration: Duration,
278}