use serde::Serialize;
use serde_json::Value;
use crate::completion::provider_options::reply_field;
use crate::completion::{ExtensionOptions, ProviderExtension, ReplyExtras};
use crate::message::Api;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct XaiExt;
impl ProviderExtension for XaiExt {
const PROVIDER: &'static str = super::PROVIDER_NAME;
type Options = XaiOptions;
type Extras = XaiExtras;
}
#[non_exhaustive]
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
pub struct XaiOptions {
#[serde(rename = "*")]
pub shared: XaiShared,
}
#[non_exhaustive]
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
pub struct XaiShared {
#[serde(skip_serializing_if = "Option::is_none")]
pub prompt_cache_key: Option<String>,
}
impl XaiOptions {
pub fn new() -> Self {
Self::default()
}
pub fn prompt_cache_key(mut self, key: impl Into<String>) -> Self {
self.shared.prompt_cache_key = Some(key.into());
self
}
}
impl ExtensionOptions for XaiOptions {
type Ext = XaiExt;
}
#[non_exhaustive]
#[derive(Clone, Debug, Default, PartialEq)]
pub struct XaiExtras {
pub cost_in_usd_ticks: Option<u64>,
pub num_sources_used: Option<u64>,
pub num_server_side_tools_used: Option<u64>,
pub server_side_tool_usage_details: Option<Value>,
}
impl ReplyExtras for XaiExtras {
fn from_reply(_api: &Api, raw: &Value) -> Result<Self, serde_json::Error> {
Ok(Self {
cost_in_usd_ticks: reply_field(raw, "/usage/cost_in_usd_ticks")?,
num_sources_used: reply_field(raw, "/usage/num_sources_used")?,
num_server_side_tools_used: reply_field(raw, "/usage/num_server_side_tools_used")?,
server_side_tool_usage_details: reply_field(
raw,
"/usage/server_side_tool_usage_details",
)?,
})
}
}
#[cfg(test)]
mod tests;