gproxy_protocol/protocol/openai/
models.rs1use std::collections::BTreeMap;
2
3use serde::{Deserialize, Serialize};
4
5use super::common::*;
6
7pub type ModelsWireModel = OpenAiWireModel<(), ModelListResponse>;
8pub type ModelRetrieveWireModel = OpenAiWireModel<(), Model>;
9
10#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
11#[non_exhaustive]
12pub struct ModelListResponse {
13 pub data: Vec<Model>,
14 pub object: ListObjectType,
15 #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
16 pub extra: Extra,
17}
18
19#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
20#[non_exhaustive]
21pub struct Model {
22 pub id: OpenAiModelId,
23 #[serde(default, skip_serializing_if = "Option::is_none")]
27 pub created: Option<u64>,
28 #[serde(default, skip_serializing_if = "Option::is_none")]
32 pub display_name: Option<String>,
33 #[serde(default, skip_serializing_if = "Option::is_none")]
37 pub context_window: Option<u64>,
38 #[serde(default, skip_serializing_if = "Option::is_none")]
42 pub max_context_window: Option<u64>,
43 #[serde(default, skip_serializing_if = "Option::is_none")]
44 pub max_output_tokens: Option<u64>,
45 #[serde(default, skip_serializing_if = "Option::is_none")]
46 pub thinking_supported: Option<bool>,
47 pub object: ModelObjectType,
48 pub owned_by: String,
49 #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
50 pub extra: Extra,
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56
57 #[test]
60 fn model_decodes_without_created() {
61 let m: Model = serde_json::from_str(
62 r#"{"id":"deepseek-chat","object":"model","owned_by":"deepseek"}"#,
63 )
64 .expect("decode without created");
65 assert_eq!(m.created, None);
66 let s = serde_json::to_string(&m).unwrap();
68 assert!(!s.contains("created"), "{s}");
69 }
70}