use super::message::ToolCall;
#[derive(Debug, Clone, PartialEq)]
pub struct ChatResponse {
pub id: String,
pub model: String,
pub created: u64,
pub choices: Vec<Choice>,
pub usage: Usage,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Choice {
pub index: usize,
pub content: Option<String>,
pub reasoning: Option<String>,
pub tool_calls: Vec<ToolCall>,
pub refusal: Option<String>,
pub finish_reason: FinishReason,
pub matched_stop: Option<String>,
pub logprobs: Option<ChoiceLogprobs>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct ChoiceLogprobs {
pub content: Vec<TokenLogprob>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct TokenLogprob {
pub token: String,
pub logprob: f32,
pub top: Vec<(String, f32)>,
}
#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub struct Usage {
pub prompt_tokens: usize,
pub completion_tokens: usize,
pub cached_prompt_tokens: usize,
pub reasoning_tokens: usize,
pub accepted_prediction_tokens: usize,
pub time_to_first_token_ms: f64,
pub decode_time_ms: f64,
pub response_tokens_per_second: f64,
}
impl Usage {
pub fn total_time_ms(&self) -> f64 {
self.time_to_first_token_ms + self.decode_time_ms
}
pub fn decode_rate_tok_s(completion_tokens: usize, decode_time_ms: f64) -> f64 {
if decode_time_ms > 0.0 && completion_tokens > 0 {
completion_tokens.saturating_sub(1) as f64 / (decode_time_ms / 1000.0)
} else {
0.0
}
}
}
pub const FINISH_REASON_TIMEOUT: &str = "timeout";
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum FinishReason {
Stop,
Length,
ToolCalls,
ContentFilter,
Other(String),
}
impl From<&str> for FinishReason {
fn from(s: &str) -> Self {
match s {
"stop" => FinishReason::Stop,
"length" => FinishReason::Length,
"tool_calls" => FinishReason::ToolCalls,
"content_filter" => FinishReason::ContentFilter,
other => FinishReason::Other(other.to_string()),
}
}
}
impl FinishReason {
pub fn as_wire(&self) -> &str {
match self {
FinishReason::Stop => "stop",
FinishReason::Length => "length",
FinishReason::ToolCalls => "tool_calls",
FinishReason::ContentFilter => "content_filter",
FinishReason::Other(s) => s,
}
}
}