use ferrin_spec::Warning;
use tracing::Span;
use super::ModelIdentity;
pub const WARNINGS_TARGET: &str = "ferrin::warnings";
pub(crate) fn call_span(
operation: &'static str,
function_id: Option<&str>,
model: &ModelIdentity,
) -> Span {
tracing::info_span!(
"ferrin.call",
"gen_ai.operation.name" = operation,
"ferrin.function_id" = function_id.unwrap_or(""),
"gen_ai.request.model" = %model.model_id,
"gen_ai.provider.name" = %model.provider,
)
}
pub(crate) fn step_span(step_number: u32) -> Span {
tracing::info_span!("ferrin.step", "ferrin.step_number" = step_number)
}
pub(crate) fn model_call_span(model: &ModelIdentity) -> Span {
tracing::info_span!(
"ferrin.model_call",
"gen_ai.request.model" = %model.model_id,
"gen_ai.provider.name" = %model.provider,
"gen_ai.response.id" = tracing::field::Empty,
"gen_ai.response.finish_reasons" = tracing::field::Empty,
"gen_ai.usage.input_tokens" = tracing::field::Empty,
"gen_ai.usage.output_tokens" = tracing::field::Empty,
"ferrin.time_to_first_output_ms" = tracing::field::Empty,
)
}
pub(crate) fn tool_span(tool_name: &str, tool_call_id: &str) -> Span {
tracing::info_span!(
"ferrin.tool",
"gen_ai.tool.name" = tool_name,
"gen_ai.tool.call.id" = tool_call_id,
"ferrin.tool.duration_ms" = tracing::field::Empty,
)
}
pub(crate) fn modality_span(operation: &'static str, model: &ModelIdentity) -> Span {
tracing::info_span!(
"ferrin.modality",
"gen_ai.operation.name" = operation,
"gen_ai.request.model" = %model.model_id,
"gen_ai.provider.name" = %model.provider,
)
}
pub(crate) fn log_warnings(warnings: &[Warning], model: &ModelIdentity) {
for warning in warnings {
let (kind, feature) = match warning {
Warning::Unsupported { feature, .. } => ("unsupported", feature.as_str()),
Warning::Compatibility { feature, .. } => ("compatibility", feature.as_str()),
Warning::Deprecated { setting, .. } => ("deprecated", setting.as_str()),
_ => ("other", ""),
};
tracing::warn!(
target: WARNINGS_TARGET,
category = kind,
feature = feature,
provider = %model.provider,
model_id = %model.model_id,
"provider warning"
);
}
}