use super::util;
use serde::{Deserialize, Serialize};
use schemars::JsonSchema;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, JsonSchema, arbitrary::Arbitrary)]
#[schemars(rename = "agent.completions.response.CompletionTokensDetails")]
pub struct CompletionTokensDetails {
#[serde(skip_serializing_if = "Option::is_none")]
#[schemars(extend("omitempty" = true))]
#[arbitrary(with = crate::arbitrary_util::arbitrary_option_u64)]
pub accepted_prediction_tokens: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
#[schemars(extend("omitempty" = true))]
#[arbitrary(with = crate::arbitrary_util::arbitrary_option_u64)]
pub audio_tokens: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
#[schemars(extend("omitempty" = true))]
#[arbitrary(with = crate::arbitrary_util::arbitrary_option_u64)]
pub reasoning_tokens: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
#[schemars(extend("omitempty" = true))]
#[arbitrary(with = crate::arbitrary_util::arbitrary_option_u64)]
pub rejected_prediction_tokens: Option<u64>,
}
impl CompletionTokensDetails {
pub fn any_usage(&self) -> bool {
self.accepted_prediction_tokens.is_some_and(|v| v > 0)
|| self.audio_tokens.is_some_and(|v| v > 0)
|| self.reasoning_tokens.is_some_and(|v| v > 0)
|| self.rejected_prediction_tokens.is_some_and(|v| v > 0)
}
pub fn push(&mut self, other: &CompletionTokensDetails) {
util::push_option_u64(
&mut self.accepted_prediction_tokens,
&other.accepted_prediction_tokens,
);
util::push_option_u64(&mut self.audio_tokens, &other.audio_tokens);
util::push_option_u64(
&mut self.reasoning_tokens,
&other.reasoning_tokens,
);
util::push_option_u64(
&mut self.rejected_prediction_tokens,
&other.rejected_prediction_tokens,
);
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, JsonSchema, arbitrary::Arbitrary)]
#[schemars(rename = "agent.completions.response.PromptTokensDetails")]
pub struct PromptTokensDetails {
#[serde(skip_serializing_if = "Option::is_none")]
#[schemars(extend("omitempty" = true))]
#[arbitrary(with = crate::arbitrary_util::arbitrary_option_u64)]
pub audio_tokens: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
#[schemars(extend("omitempty" = true))]
#[arbitrary(with = crate::arbitrary_util::arbitrary_option_u64)]
pub cached_tokens: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
#[schemars(extend("omitempty" = true))]
#[arbitrary(with = crate::arbitrary_util::arbitrary_option_u64)]
pub cache_write_tokens: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
#[schemars(extend("omitempty" = true))]
#[arbitrary(with = crate::arbitrary_util::arbitrary_option_u64)]
pub video_tokens: Option<u64>,
}
impl PromptTokensDetails {
pub fn any_usage(&self) -> bool {
self.audio_tokens.is_some_and(|v| v > 0)
|| self.cached_tokens.is_some_and(|v| v > 0)
|| self.cache_write_tokens.is_some_and(|v| v > 0)
|| self.video_tokens.is_some_and(|v| v > 0)
}
pub fn push(&mut self, other: &PromptTokensDetails) {
util::push_option_u64(&mut self.audio_tokens, &other.audio_tokens);
util::push_option_u64(&mut self.cached_tokens, &other.cached_tokens);
util::push_option_u64(
&mut self.cache_write_tokens,
&other.cache_write_tokens,
);
util::push_option_u64(&mut self.video_tokens, &other.video_tokens);
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, arbitrary::Arbitrary)]
#[schemars(rename = "agent.completions.response.CostDetails")]
pub struct CostDetails {
#[serde(deserialize_with = "crate::serde_util::decimal")]
#[schemars(with = "f64")]
#[arbitrary(with = crate::arbitrary_util::arbitrary_rust_decimal)]
pub upstream_inference_cost: rust_decimal::Decimal,
#[serde(deserialize_with = "crate::serde_util::decimal")]
#[schemars(with = "f64")]
#[arbitrary(with = crate::arbitrary_util::arbitrary_rust_decimal)]
pub upstream_upstream_inference_cost: rust_decimal::Decimal,
}
impl CostDetails {
pub fn any_usage(&self) -> bool {
self.upstream_inference_cost > rust_decimal::Decimal::ZERO
|| self.upstream_upstream_inference_cost
> rust_decimal::Decimal::ZERO
}
pub fn push(&mut self, other: &CostDetails) {
self.upstream_inference_cost += other.upstream_inference_cost;
self.upstream_upstream_inference_cost +=
other.upstream_upstream_inference_cost;
}
}