use serde::{Deserialize, Serialize};
use super::Logprob;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
pub struct GenerateResponse {
#[serde(default)]
pub model: Option<String>,
#[serde(default)]
pub created_at: Option<String>,
#[serde(default)]
pub response: Option<String>,
#[serde(default)]
pub thinking: Option<String>,
#[serde(default)]
pub done: Option<bool>,
#[serde(default)]
pub done_reason: Option<String>,
#[serde(default)]
pub total_duration: Option<i64>,
#[serde(default)]
pub load_duration: Option<i64>,
#[serde(default)]
pub prompt_eval_count: Option<i32>,
#[serde(default)]
pub prompt_eval_duration: Option<i64>,
#[serde(default)]
pub eval_count: Option<i32>,
#[serde(default)]
pub eval_duration: Option<i64>,
#[serde(default)]
pub logprobs: Option<Vec<Logprob>>,
}
impl GenerateResponse {
pub fn text(&self) -> Option<&str> {
self.response.as_deref()
}
pub fn thinking_text(&self) -> Option<&str> {
self.thinking.as_deref()
}
pub fn is_done(&self) -> bool {
self.done.unwrap_or(false)
}
pub fn total_duration_ms(&self) -> Option<f64> {
self.total_duration.map(|ns| ns as f64 / 1_000_000.0)
}
pub fn load_duration_ms(&self) -> Option<f64> {
self.load_duration.map(|ns| ns as f64 / 1_000_000.0)
}
pub fn prompt_eval_duration_ms(&self) -> Option<f64> {
self.prompt_eval_duration.map(|ns| ns as f64 / 1_000_000.0)
}
pub fn eval_duration_ms(&self) -> Option<f64> {
self.eval_duration.map(|ns| ns as f64 / 1_000_000.0)
}
pub fn tokens_per_second(&self) -> Option<f64> {
match (self.eval_count, self.eval_duration) {
(Some(count), Some(duration)) if duration > 0 => {
Some(count as f64 / (duration as f64 / 1_000_000_000.0))
}
_ => None,
}
}
}