use serde::Serialize;
use sha2::{Digest, Sha256};
pub fn fingerprint<M, S, T>(messages: &[M], system: &S, tools: &T, model: Option<&str>) -> String
where
M: Serialize,
S: Serialize,
T: Serialize,
{
let prefix = if messages.is_empty() {
&messages[..]
} else {
&messages[..messages.len() - 1]
};
#[derive(Serialize)]
struct Payload<'a, M, S, T>
where
M: Serialize,
S: Serialize,
T: Serialize,
{
system: &'a S,
tools: &'a T,
model: Option<&'a str>,
prefix_messages: &'a [M],
}
let payload = Payload {
system,
tools,
model,
prefix_messages: prefix,
};
let blob = serde_json::to_vec(&payload).unwrap_or_default();
let mut hasher = Sha256::new();
hasher.update(&blob);
let digest = hasher.finalize();
format!(
"{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}",
digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], digest[6], digest[7]
)
}