Skip to main content

aether_telemetry/
content_capture.rs

1/// Content-capture settings. Each field maps 1:1 to a
2/// `gen_ai.*` OTEL content attribute; all default to off.
3#[allow(clippy::struct_excessive_bools)] // independent opt-ins, not a state machine
4#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
5pub struct ContentCaptureSettings {
6    pub system_instructions: bool,
7    pub input_messages: bool,
8    pub output_messages: bool,
9    pub tool_definitions: bool,
10    pub tool_calls: bool,
11}
12
13/// Accumulates span content under a capture policy.
14pub(crate) enum ContentBuffer {
15    Redacted,
16    Recording(String),
17}
18
19impl ContentBuffer {
20    pub(crate) fn new(capture: bool) -> Self {
21        if capture { Self::Recording(String::new()) } else { Self::Redacted }
22    }
23
24    pub(crate) fn push(&mut self, chunk: &str) {
25        if let Self::Recording(text) = self {
26            text.push_str(chunk);
27        }
28    }
29
30    pub(crate) fn set(&mut self, content: &str) {
31        if let Self::Recording(text) = self {
32            content.clone_into(text);
33        }
34    }
35
36    /// The recorded content; `None` when redacted or nothing was recorded.
37    pub(crate) fn get(&self) -> Option<&str> {
38        match self {
39            Self::Recording(text) if !text.is_empty() => Some(text),
40            _ => None,
41        }
42    }
43}