use serde::{Deserialize, 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 CopilotExt;
impl ProviderExtension for CopilotExt {
const PROVIDER: &'static str = super::PROVIDER_NAME;
type Options = CopilotOptions;
type Extras = CopilotExtras;
}
#[non_exhaustive]
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
pub struct CopilotOptions {}
impl CopilotOptions {
pub fn new() -> Self {
Self::default()
}
}
impl ExtensionOptions for CopilotOptions {
type Ext = CopilotExt;
}
#[non_exhaustive]
#[derive(Clone, Debug, Default, PartialEq)]
pub struct CopilotExtras {
pub copilot_usage: Option<CopilotUsage>,
pub prompt_filter_results: Option<Vec<Value>>,
}
#[non_exhaustive]
#[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize)]
pub struct CopilotUsage {
#[serde(default)]
pub token_details: Option<Vec<TokenDetail>>,
#[serde(default)]
pub total_nano_aiu: Option<u64>,
}
#[non_exhaustive]
#[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize)]
pub struct TokenDetail {
#[serde(default)]
pub token_type: Option<String>,
#[serde(default)]
pub token_count: Option<u64>,
#[serde(default)]
pub batch_size: Option<u64>,
#[serde(default)]
pub cost_per_batch: Option<u64>,
}
impl ReplyExtras for CopilotExtras {
fn from_reply(_api: &Api, raw: &Value) -> Result<Self, serde_json::Error> {
Ok(Self {
copilot_usage: reply_field(raw, "/copilot_usage")?,
prompt_filter_results: reply_field(raw, "/prompt_filter_results")?,
})
}
}
#[cfg(test)]
mod tests;