Skip to main content

ailoop_core/
ids.rs

1//! Run and step identifiers used by the engine to correlate
2//! [`crate::StreamChunk`]s and [`crate::ChatMiddleware`] hooks.
3
4use std::fmt;
5
6use uuid::Uuid;
7
8/// Unique identifier for a single run of the engine.
9///
10/// Carried on every [`crate::StreamChunk`] variant the engine emits and on
11/// every [`crate::ChatMiddleware`] hook so observability code can correlate
12/// events across concurrent runs. The engine mints a fresh
13/// [`Uuid::new_v4`] when [`crate::RunConfig::run_id`] is `None`; callers
14/// pass an existing `RunId` when an outer system already has its own
15/// trace identifier to bind to.
16#[derive(Debug, Clone, PartialEq, Eq, Hash)]
17pub struct RunId(pub Uuid);
18
19impl RunId {
20    /// Create a fresh `RunId` backed by a new v4 UUID.
21    pub fn new() -> Self {
22        Self(Uuid::new_v4())
23    }
24}
25
26impl Default for RunId {
27    fn default() -> Self {
28        Self::new()
29    }
30}
31
32impl fmt::Display for RunId {
33    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34        self.0.fmt(f)
35    }
36}
37
38/// Unique identifier for one provider turn (one model call) within a
39/// run.
40///
41/// A run is composed of one or more steps: each step is a
42/// `chat_stream` call plus any tool execution that follows. The engine
43/// mints a fresh `StepId` at the start of every step and surfaces it on
44/// [`crate::StreamChunk::StepStarted`] / [`crate::StreamChunk::StepFinished`]
45/// so middlewares can scope per-step state (e.g. token counts, retries)
46/// without tracking iteration numbers themselves.
47#[derive(Debug, Clone, PartialEq, Eq, Hash)]
48pub struct StepId(pub Uuid);
49
50impl StepId {
51    /// Create a fresh `StepId` backed by a new v4 UUID.
52    pub fn new() -> Self {
53        Self(Uuid::new_v4())
54    }
55}
56
57impl Default for StepId {
58    fn default() -> Self {
59        Self::new()
60    }
61}
62
63impl fmt::Display for StepId {
64    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65        self.0.fmt(f)
66    }
67}