use std::borrow::Cow;
pub use nemo_relay_types::api::event::*;
use nemo_relay_types::api::llm::LlmRequest;
use nemo_relay_types::codec::request::AnnotatedLlmRequest;
use nemo_relay_types::codec::response::AnnotatedLlmResponse;
use crate::codec::resolve;
pub(crate) fn is_valid_event_metadata_attribute_key(key: &str) -> bool {
key.split('.').all(|segment| {
!segment.is_empty()
&& segment.chars().all(|character| {
character.is_ascii_alphanumeric() || matches!(character, '_' | '-')
})
})
}
pub trait EventNormalizationExt {
#[must_use]
fn normalized_llm_request(&self) -> Option<Cow<'_, AnnotatedLlmRequest>>;
#[must_use]
fn normalized_llm_response(&self) -> Option<Cow<'_, AnnotatedLlmResponse>>;
}
impl EventNormalizationExt for Event {
fn normalized_llm_request(&self) -> Option<Cow<'_, AnnotatedLlmRequest>> {
if let Some(annotated) = self.annotated_request() {
return Some(Cow::Borrowed(annotated.as_ref()));
}
let request: LlmRequest = serde_json::from_value(self.input()?.clone()).ok()?;
resolve::normalize_request_with_hint(&request, Some(self.name())).map(Cow::Owned)
}
fn normalized_llm_response(&self) -> Option<Cow<'_, AnnotatedLlmResponse>> {
if let Some(annotated) = self.annotated_response() {
return Some(Cow::Borrowed(annotated.as_ref()));
}
resolve::normalize_response(self.output()?).map(Cow::Owned)
}
}