Skip to main content

sim_lib_openai_server/
content_id.rs

1use sim_codec_binary::encode_frame;
2use sim_kernel::{ContentId, Datum, Expr, Result};
3
4use crate::objects::GatewayRequest;
5
6/// Field names stripped from a request before computing its content id.
7///
8/// These carry per-receipt metadata (ids and timestamps) that must not affect
9/// whether two requests are considered content-identical.
10pub const VOLATILE_REQUEST_FIELDS: &[&str] = &[
11    "id",
12    "timestamp",
13    "timestamp-ms",
14    "created-at-ms",
15    "updated-at-ms",
16];
17
18/// Computes the content id of a [`GatewayRequest`], ignoring volatile fields.
19pub fn request_content_id(request: &GatewayRequest) -> Result<ContentId> {
20    request_expr_content_id(&request.to_expr())
21}
22
23/// Computes the content id of a request expression after normalizing away its
24/// volatile fields.
25pub fn request_expr_content_id(expr: &Expr) -> Result<ContentId> {
26    content_id_for_expr(&normalize_request_expr(expr))
27}
28
29/// Computes the content id of an arbitrary expression by encoding it to a
30/// binary frame and hashing the resulting bytes.
31pub fn content_id_for_expr(expr: &Expr) -> Result<ContentId> {
32    let frame = encode_frame(expr)?;
33    Datum::Bytes(frame.0).content_id()
34}
35
36/// Returns a copy of a request map with [`VOLATILE_REQUEST_FIELDS`] removed.
37///
38/// Non-map expressions are returned unchanged.
39pub fn normalize_request_expr(expr: &Expr) -> Expr {
40    let Expr::Map(entries) = expr else {
41        return expr.clone();
42    };
43    Expr::Map(
44        entries
45            .iter()
46            .filter(|(key, _)| !is_volatile_request_key(key))
47            .cloned()
48            .collect(),
49    )
50}
51
52fn is_volatile_request_key(key: &Expr) -> bool {
53    let name = match key {
54        Expr::String(name) => name.as_str(),
55        Expr::Symbol(symbol) if symbol.namespace.is_none() => symbol.name.as_ref(),
56        _ => return false,
57    };
58    VOLATILE_REQUEST_FIELDS.contains(&name)
59}