#![allow(dead_code)]
pub(crate) const GEN_AI_PROVIDER_NAME: &str = "gen_ai.provider.name";
pub(crate) const GEN_AI_OPERATION_NAME: &str = "gen_ai.operation.name";
pub(crate) const GEN_AI_REQUEST_MODEL: &str = "gen_ai.request.model";
pub(crate) const GEN_AI_RESPONSE_MODEL: &str = "gen_ai.response.model";
pub(crate) const GEN_AI_USAGE_INPUT_TOKENS: &str = "gen_ai.usage.input_tokens";
pub(crate) const GEN_AI_USAGE_OUTPUT_TOKENS: &str = "gen_ai.usage.output_tokens";
pub(crate) const GEN_AI_RESPONSE_FINISH_REASONS: &str = "gen_ai.response.finish_reasons";
pub(crate) const GEN_AI_REQUEST_MAX_TOKENS: &str = "gen_ai.request.max_tokens";
pub(crate) const GEN_AI_REQUEST_TEMPERATURE: &str = "gen_ai.request.temperature";
pub(crate) const GEN_AI_TOOL_NAME: &str = "gen_ai.tool.name";
pub(crate) const GEN_AI_MESSAGE_CONTENT: &str = "gen_ai.message.content";
pub(crate) const GEN_AI_CHOICE_INDEX: &str = "gen_ai.choice.index";
pub(crate) const ERROR_TYPE: &str = "error.type";
pub(crate) const RUN_ID_ATTR: &str = "langchainrust.run_id";
pub(crate) const TRACE_ID_ATTR: &str = "langchainrust.trace_id";
pub(crate) const GEN_AI_USAGE_CACHE_READ: &str = "gen_ai.usage.cache_read.input_tokens";
pub(crate) const GEN_AI_USAGE_CACHE_CREATION: &str = "gen_ai.usage.cache_creation.input_tokens";
pub(crate) const GEN_AI_USAGE_REASONING: &str = "gen_ai.usage.reasoning.output_tokens";
const MAX_ERROR_TYPE_CHARS: usize = 64;
pub(crate) fn error_type(message: &str) -> String {
let first = message.lines().next().unwrap_or("").trim();
let head = first.split(':').next().unwrap_or(first).trim();
if head.is_empty() {
"error".to_string()
} else {
truncate(head, MAX_ERROR_TYPE_CHARS)
}
}
pub(crate) fn truncate(s: &str, max_chars: usize) -> String {
match s.char_indices().nth(max_chars) {
None => s.to_string(),
Some((idx, _)) => format!("{}…", &s[..idx]),
}
}