use super::types::{ExecutionStatus, StepResult};
use crate::t;
use once_cell::sync::Lazy;
use regex::Regex;
pub static VARIABLE_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"\{\{([^}]+)\}\}").unwrap());
pub const OUTPUT_SUMMARY_MAX_LEN: usize = 200;
pub fn get_output_summary(output: &str) -> String {
if output.len() <= OUTPUT_SUMMARY_MAX_LEN {
output.to_string()
} else {
format!("{}...", &output[..OUTPUT_SUMMARY_MAX_LEN])
}
}
pub fn format_step_results(results: &[StepResult]) -> String {
if results.is_empty() {
return t!("skill.no_steps_executed").to_string();
}
if results.len() == 1 {
return results[0].output.clone();
}
let success_count = results
.iter()
.filter(|r| r.status == ExecutionStatus::Success)
.count();
let failure_count = results.len() - success_count;
let mut output = format!(
"{} (SUCCESS {} / FAILURE {}):\n\n",
t!("skill.executed_steps", results.len()),
success_count,
failure_count
);
for (i, result) in results.iter().enumerate() {
let marker = match result.status {
ExecutionStatus::Success => "SUCCESS",
ExecutionStatus::Failure => "FAILURE",
};
output.push_str(&format!("{} {}: {}\n", marker, i + 1, result.output));
}
output
}
pub fn format_duration(ms: u64) -> String {
if ms >= 1000 {
format!("{:.2}s", ms as f64 / 1000.0)
} else if ms > 0 {
format!("{}ms", ms)
} else {
"<1ms".to_string()
}
}
pub fn format_parameters(
params: Option<&std::collections::HashMap<String, serde_json::Value>>,
) -> String {
match params {
Some(p) if !p.is_empty() => {
let json_str = serde_json::to_string(p).unwrap_or_else(|_| "{}".to_string());
if json_str.len() > 100 {
format!("{}...", &json_str[..100])
} else {
json_str
}
}
_ => "{}".to_string(),
}
}