kernel/event/record/
probe.rs1use serde::{Deserialize, Serialize};
10
11use crate::model::Ceiling;
12use crate::reach::Reach;
13
14#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
19#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
20pub struct ModelFacts {
21 pub id: String,
22 pub context_tokens: Option<u64>,
24 pub max_output_tokens: Option<Ceiling>,
26 pub input_modalities: Vec<String>,
29 pub input_price: Option<String>,
32 pub output_price: Option<String>,
34}
35
36#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
43#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
44pub struct EndpointProbed {
45 pub name: String,
46 pub base_url: String,
47 pub reach: Reach,
49 pub models: Vec<String>,
50 pub facts: Vec<ModelFacts>,
51 #[serde(default, skip_serializing_if = "Option::is_none")]
53 pub failed: Option<ProbeFailure>,
54}
55
56#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
58#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
59pub struct ProbeFailure {
60 pub code: String,
61 pub subject: String,
62}
63
64#[cfg(test)]
65#[allow(clippy::unwrap_used, reason = "test code")]
66mod tests {
67 use super::*;
68 use crate::event::Payload;
69
70 #[test]
74 fn a_probed_line_keeps_the_bytes_its_ledger_already_holds() {
75 let line = concat!(
76 r#"{"base_url":"http://127.0.0.1:1","facts":[],"#,
77 r#""failed":{"code":"E_PROVIDER","subject":"m"},"models":[],"name":"local","#,
78 r#""reach":{"answered":{"detail":"no socket","state":"unreachable"},"#,
79 r#""connected":{"state":"refused"},"elapsed_ms":3,"host":"127.0.0.1","#,
80 r#""named":{"detail":1,"state":"resolved"},"through":{"state":"direct"}}}"#,
81 );
82 let read: EndpointProbed = serde_json::from_str::<Payload>(line)
83 .unwrap()
84 .read()
85 .unwrap();
86 assert_eq!(
87 serde_json::to_string(&Payload::of(&read).unwrap()).unwrap(),
88 line
89 );
90 }
91}