use opentelemetry::Value;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[non_exhaustive]
pub enum SpanKind {
Llm,
Embedding,
Chain,
Tool,
Agent,
Retriever,
Reranker,
Guardrail,
Evaluator,
}
impl SpanKind {
#[inline]
pub const fn as_str(&self) -> &'static str {
match self {
SpanKind::Llm => "LLM",
SpanKind::Embedding => "EMBEDDING",
SpanKind::Chain => "CHAIN",
SpanKind::Tool => "TOOL",
SpanKind::Agent => "AGENT",
SpanKind::Retriever => "RETRIEVER",
SpanKind::Reranker => "RERANKER",
SpanKind::Guardrail => "GUARDRAIL",
SpanKind::Evaluator => "EVALUATOR",
}
}
}
impl std::str::FromStr for SpanKind {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_uppercase().as_str() {
"LLM" => Ok(SpanKind::Llm),
"EMBEDDING" => Ok(SpanKind::Embedding),
"CHAIN" => Ok(SpanKind::Chain),
"TOOL" => Ok(SpanKind::Tool),
"AGENT" => Ok(SpanKind::Agent),
"RETRIEVER" => Ok(SpanKind::Retriever),
"RERANKER" => Ok(SpanKind::Reranker),
"GUARDRAIL" => Ok(SpanKind::Guardrail),
"EVALUATOR" => Ok(SpanKind::Evaluator),
_ => Err(()),
}
}
}
impl std::fmt::Display for SpanKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
impl From<SpanKind> for Value {
fn from(kind: SpanKind) -> Self {
Value::String(kind.as_str().into())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_span_kind_as_str() {
assert_eq!(SpanKind::Llm.as_str(), "LLM");
assert_eq!(SpanKind::Embedding.as_str(), "EMBEDDING");
assert_eq!(SpanKind::Chain.as_str(), "CHAIN");
assert_eq!(SpanKind::Tool.as_str(), "TOOL");
assert_eq!(SpanKind::Agent.as_str(), "AGENT");
assert_eq!(SpanKind::Retriever.as_str(), "RETRIEVER");
assert_eq!(SpanKind::Reranker.as_str(), "RERANKER");
assert_eq!(SpanKind::Guardrail.as_str(), "GUARDRAIL");
assert_eq!(SpanKind::Evaluator.as_str(), "EVALUATOR");
}
#[test]
fn test_span_kind_from_str() {
assert_eq!("LLM".parse(), Ok(SpanKind::Llm));
assert_eq!("llm".parse(), Ok(SpanKind::Llm));
assert_eq!("Llm".parse(), Ok(SpanKind::Llm));
assert_eq!("invalid".parse::<SpanKind>(), Err(()));
}
#[test]
fn test_span_kind_display() {
assert_eq!(format!("{}", SpanKind::Llm), "LLM");
assert_eq!(format!("{}", SpanKind::Agent), "AGENT");
}
}