use serde::{Deserialize, Serialize};
pub const LLM_COMPLETE_METHOD: &str = "nexo/admin/llm/complete";
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct LlmChatMessage {
pub role: String,
pub content: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct LlmCompleteInput {
pub provider: String,
pub model: String,
pub messages: Vec<LlmChatMessage>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub max_tokens: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub temperature: Option<f32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub system_prompt: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
pub struct LlmUsage {
#[serde(default)]
pub prompt_tokens: u64,
#[serde(default)]
pub completion_tokens: u64,
#[serde(default)]
pub total_tokens: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct LlmCompleteResponse {
pub content: String,
pub model: String,
#[serde(default)]
pub usage: LlmUsage,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn round_trip_input() {
let i = LlmCompleteInput {
provider: "deepseek-19c7".into(),
model: "deepseek-v4-flash".into(),
messages: vec![
LlmChatMessage {
role: "system".into(),
content: "Eres Ana, asistente comercial.".into(),
},
LlmChatMessage {
role: "user".into(),
content: "¿Tienen plan empresarial?".into(),
},
],
max_tokens: Some(512),
temperature: Some(0.7),
system_prompt: None,
};
let v = serde_json::to_value(&i).unwrap();
let back: LlmCompleteInput = serde_json::from_value(v).unwrap();
assert_eq!(i, back);
}
#[test]
fn round_trip_response() {
let r = LlmCompleteResponse {
content: "Hola, sí — el plan empresarial cubre…".into(),
model: "deepseek-v4-flash".into(),
usage: LlmUsage {
prompt_tokens: 42,
completion_tokens: 18,
total_tokens: 60,
},
};
let v = serde_json::to_value(&r).unwrap();
let back: LlmCompleteResponse = serde_json::from_value(v).unwrap();
assert_eq!(r, back);
}
#[test]
fn method_constant() {
assert_eq!(LLM_COMPLETE_METHOD, "nexo/admin/llm/complete");
}
}