use crate::kernel::{ExecutionId, StepId, StepType};
use crate::runner::TraceContext;
pub struct ExecutionSpanAttributes {
pub execution_id: String,
pub parent_id: Option<String>,
pub parent_type: Option<String>,
pub tenant_id: Option<String>,
pub user_id: Option<String>,
}
impl ExecutionSpanAttributes {
pub fn new(execution_id: &ExecutionId) -> Self {
Self {
execution_id: execution_id.as_str().to_string(),
parent_id: None,
parent_type: None,
tenant_id: None,
user_id: None,
}
}
pub fn with_parent(
mut self,
parent_id: impl Into<String>,
parent_type: impl Into<String>,
) -> Self {
self.parent_id = Some(parent_id.into());
self.parent_type = Some(parent_type.into());
self
}
pub fn with_tenant(mut self, tenant_id: impl Into<String>) -> Self {
self.tenant_id = Some(tenant_id.into());
self
}
pub fn with_user(mut self, user_id: impl Into<String>) -> Self {
self.user_id = Some(user_id.into());
self
}
pub fn to_attributes(&self) -> Vec<(&'static str, String)> {
let mut attrs = vec![("enact.execution_id", self.execution_id.clone())];
if let Some(ref parent_id) = self.parent_id {
attrs.push(("enact.parent_id", parent_id.clone()));
}
if let Some(ref parent_type) = self.parent_type {
attrs.push(("enact.parent_type", parent_type.clone()));
}
if let Some(ref tenant_id) = self.tenant_id {
attrs.push(("enact.tenant_id", tenant_id.clone()));
}
if let Some(ref user_id) = self.user_id {
attrs.push(("enact.user_id", user_id.clone()));
}
attrs
}
}
pub struct StepSpanAttributes {
pub execution_id: String,
pub step_id: String,
pub step_type: String,
pub name: String,
}
impl StepSpanAttributes {
pub fn new(
execution_id: &ExecutionId,
step_id: &StepId,
step_type: StepType,
name: impl Into<String>,
) -> Self {
Self {
execution_id: execution_id.as_str().to_string(),
step_id: step_id.as_str().to_string(),
step_type: step_type.to_string(),
name: name.into(),
}
}
pub fn to_attributes(&self) -> Vec<(&'static str, String)> {
vec![
("enact.execution_id", self.execution_id.clone()),
("enact.step_id", self.step_id.clone()),
("enact.step_type", self.step_type.clone()),
("enact.step_name", self.name.clone()),
]
}
}
pub struct ToolSpanAttributes {
pub execution_id: String,
pub step_id: String,
pub tool_name: String,
}
impl ToolSpanAttributes {
pub fn new(execution_id: &ExecutionId, step_id: &StepId, tool_name: impl Into<String>) -> Self {
Self {
execution_id: execution_id.as_str().to_string(),
step_id: step_id.as_str().to_string(),
tool_name: tool_name.into(),
}
}
pub fn to_attributes(&self) -> Vec<(&'static str, String)> {
vec![
("enact.execution_id", self.execution_id.clone()),
("enact.step_id", self.step_id.clone()),
("enact.tool_name", self.tool_name.clone()),
]
}
}
pub struct LlmSpanAttributes {
pub execution_id: String,
pub step_id: String,
pub provider: String,
pub model: String,
pub input_tokens: Option<u32>,
pub output_tokens: Option<u32>,
}
impl LlmSpanAttributes {
pub fn new(
execution_id: &ExecutionId,
step_id: &StepId,
provider: impl Into<String>,
model: impl Into<String>,
) -> Self {
Self {
execution_id: execution_id.as_str().to_string(),
step_id: step_id.as_str().to_string(),
provider: provider.into(),
model: model.into(),
input_tokens: None,
output_tokens: None,
}
}
pub fn with_tokens(mut self, input: u32, output: u32) -> Self {
self.input_tokens = Some(input);
self.output_tokens = Some(output);
self
}
pub fn to_attributes(&self) -> Vec<(&'static str, String)> {
let mut attrs = vec![
("enact.execution_id", self.execution_id.clone()),
("enact.step_id", self.step_id.clone()),
("gen_ai.system", self.provider.clone()),
("gen_ai.request.model", self.model.clone()),
];
if let Some(tokens) = self.input_tokens {
attrs.push(("gen_ai.usage.input_tokens", tokens.to_string()));
}
if let Some(tokens) = self.output_tokens {
attrs.push(("gen_ai.usage.output_tokens", tokens.to_string()));
}
attrs
}
}
pub fn execution_span_name(execution_id: &ExecutionId) -> String {
format!("execution:{}", execution_id.as_str())
}
pub fn step_span_name(step_type: &StepType, name: &str) -> String {
format!("step:{}:{}", step_type, name)
}
pub fn tool_span_name(tool_name: &str) -> String {
format!("tool:{}", tool_name)
}
pub fn llm_span_name(provider: &str, model: &str) -> String {
format!("llm:{}:{}", provider, model)
}
pub fn extract_trace_context(trace: &TraceContext) -> (String, String) {
(trace.trace_id.clone(), trace.span_id.clone())
}