mod client;
use std::collections::BTreeMap;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
pub use client::{Client, ClientBuilder};
pub use reqwest;
pub const MAX_OPTIONS: usize = 255;
pub const MAX_LEVELS: usize = 10;
use crate::{Confidence, Instructions, Model, Probability, State};
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, JsonSchema)]
#[serde(transparent)]
pub struct QuestionId(String);
impl QuestionId {
pub fn as_str(&self) -> &str {
&self.0
}
}
impl From<String> for QuestionId {
fn from(s: String) -> Self {
Self(s)
}
}
impl From<&str> for QuestionId {
fn from(s: &str) -> Self {
Self(s.to_owned())
}
}
impl std::borrow::Borrow<str> for QuestionId {
fn borrow(&self) -> &str {
&self.0
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct NoulCriteria {
#[serde(rename = "true")]
pub yes: String,
#[serde(rename = "false")]
pub no: String,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "type", rename_all = "lowercase")]
pub enum Question {
Noul {
instructions: Instructions,
#[serde(default, skip_serializing_if = "Option::is_none")]
criteria: Option<NoulCriteria>,
},
Choice {
instructions: Instructions,
criteria: BTreeMap<String, Option<String>>,
},
Score {
instructions: Instructions,
criteria: Vec<String>,
},
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct Request {
pub state: State,
pub model: Model,
pub questions: BTreeMap<QuestionId, Question>,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "type", rename_all = "lowercase")]
pub enum Answer {
Noul {
noul: Probability,
},
Choice {
choice: String,
probabilities: BTreeMap<String, Probability>,
confidence: Confidence,
},
Score {
score: f64,
#[serde(with = "level_keys")]
#[schemars(with = "BTreeMap<String, String>")]
legend: BTreeMap<u8, String>,
#[serde(with = "level_keys")]
#[schemars(with = "BTreeMap<String, Probability>")]
probabilities: BTreeMap<u8, Probability>,
confidence: Confidence,
},
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct Usage {
pub input_tokens: u64,
pub output_tokens: u64,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct Response {
pub model: Model,
pub answers: BTreeMap<QuestionId, Answer>,
pub usage: Usage,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct ModelInfo {
pub name: String,
pub description: String,
pub release_date: String,
}
mod level_keys {
use std::collections::BTreeMap;
use serde::de::Error as _;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
pub(super) fn serialize<S: Serializer, T: Serialize>(
map: &BTreeMap<u8, T>,
s: S,
) -> Result<S::Ok, S::Error> {
s.collect_map(map.iter().map(|(k, v)| (k.to_string(), v)))
}
pub(super) fn deserialize<'de, D: Deserializer<'de>, T: Deserialize<'de>>(
d: D,
) -> Result<BTreeMap<u8, T>, D::Error> {
BTreeMap::<String, T>::deserialize(d)?
.into_iter()
.map(|(k, v)| {
k.parse::<u8>()
.map(|k| (k, v))
.map_err(|e| D::Error::custom(format!("level key {k:?}: {e}")))
})
.collect()
}
}
#[derive(Deserialize)]
pub(crate) struct ModelsResponse {
pub(crate) models: Vec<ModelInfo>,
}