1use std::fmt;
20
21use bytes::Bytes;
22use http::{HeaderMap, StatusCode};
23use serde::{
24 Serialize, Serializer,
25 ser::{SerializeMap, SerializeStruct},
26};
27
28use crate::{constants::request_id, content::Content, name::Name};
29
30#[derive(Debug, Clone, PartialEq)]
43pub struct SystemOneResponse<A = Answers> {
44 model: Name,
45 usage: Usage,
46 answers: A,
47 meta: ResponseMeta,
48}
49
50impl<A> SystemOneResponse<A> {
51 pub(crate) fn from_parts(model: Name, usage: Usage, answers: A, meta: ResponseMeta) -> Self {
53 Self { model, usage, answers, meta }
54 }
55
56 #[must_use]
59 pub fn model(&self) -> &str {
60 self.model.as_str()
61 }
62
63 #[must_use]
65 pub fn usage(&self) -> &Usage {
66 &self.usage
67 }
68
69 #[must_use]
71 pub fn answers(&self) -> &A {
72 &self.answers
73 }
74
75 #[must_use]
77 pub fn meta(&self) -> &ResponseMeta {
78 &self.meta
79 }
80
81 #[must_use]
83 pub fn into_answers(self) -> A {
84 self.answers
85 }
86}
87
88impl<A> Serialize for SystemOneResponse<A>
89where
90 A: Serialize,
91{
92 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
93 where
94 S: Serializer,
95 {
96 let mut out = serializer.serialize_struct("SystemOneResponse", 3)?;
97 out.serialize_field("model", &self.model)?;
98 out.serialize_field("usage", &self.usage)?;
99 out.serialize_field("answers", &self.answers)?;
100 out.end()
101 }
102}
103
104#[derive(Clone, PartialEq)]
113pub struct ResponseMeta {
114 status: StatusCode,
115 headers: HeaderMap,
116 body: Bytes,
117}
118
119impl ResponseMeta {
120 pub(crate) fn new(status: StatusCode, headers: HeaderMap, body: Bytes) -> Self {
122 Self { status, headers, body }
123 }
124
125 pub(crate) fn into_parts(self) -> (StatusCode, HeaderMap, Bytes) {
127 (self.status, self.headers, self.body)
128 }
129
130 #[must_use]
132 pub fn status(&self) -> StatusCode {
133 self.status
134 }
135
136 #[must_use]
138 pub fn headers(&self) -> &HeaderMap {
139 &self.headers
140 }
141
142 #[must_use]
146 pub fn request_id(&self) -> Option<&str> {
147 request_id(&self.headers)
148 }
149
150 #[must_use]
152 pub fn raw_body(&self) -> &Bytes {
153 &self.body
154 }
155}
156
157impl fmt::Debug for ResponseMeta {
158 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
159 formatter
160 .debug_struct("ResponseMeta")
161 .field("status", &self.status.as_u16())
162 .field("request_id", &self.request_id())
163 .field("headers", &format_args!("<{} headers>", self.headers.len()))
164 .field("body", &format_args!("<{} bytes>", self.body.len()))
165 .finish()
166 }
167}
168
169#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize)]
174pub struct Usage {
175 input_tokens: Option<u64>,
176 output_tokens: Option<u64>,
177}
178
179impl Usage {
180 #[must_use]
183 pub fn new(input_tokens: Option<u64>, output_tokens: Option<u64>) -> Self {
184 Self { input_tokens, output_tokens }
185 }
186
187 #[must_use]
189 pub fn input_tokens(&self) -> Option<u64> {
190 self.input_tokens
191 }
192
193 #[must_use]
195 pub fn output_tokens(&self) -> Option<u64> {
196 self.output_tokens
197 }
198}
199
200#[derive(Debug, Clone, PartialEq, Default)]
213pub struct Answers {
214 entries: Vec<(Name, Answer)>,
215}
216
217impl Answers {
218 pub(crate) fn with_capacity(capacity: usize) -> Self {
220 Self { entries: Vec::with_capacity(capacity) }
221 }
222
223 pub(crate) fn push(&mut self, name: Name, answer: Answer) {
225 self.entries.push((name, answer));
226 }
227
228 #[cfg(test)]
230 pub(crate) fn capacity(&self) -> usize {
231 self.entries.capacity()
232 }
233
234 #[must_use]
236 pub fn len(&self) -> usize {
237 self.entries.len()
238 }
239
240 #[must_use]
242 pub fn is_empty(&self) -> bool {
243 self.entries.is_empty()
244 }
245
246 #[must_use]
248 pub fn get(&self, name: &str) -> Option<&Answer> {
249 self.entries.iter().find(|(key, _)| key.as_str() == name).map(|(_, answer)| answer)
250 }
251
252 #[must_use]
255 pub fn noul(&self, name: &str) -> Option<&NoulAnswer> {
256 self.get(name).and_then(Answer::as_noul)
257 }
258
259 #[must_use]
262 pub fn choice(&self, name: &str) -> Option<&ChoiceAnswer> {
263 self.get(name).and_then(Answer::as_choice)
264 }
265
266 #[must_use]
269 pub fn score(&self, name: &str) -> Option<&ScoreAnswer> {
270 self.get(name).and_then(Answer::as_score)
271 }
272
273 pub fn iter(&self) -> impl ExactSizeIterator<Item = (&str, &Answer)> + DoubleEndedIterator {
275 self.entries.iter().map(|(name, answer)| (name.as_str(), answer))
276 }
277
278 pub fn names(&self) -> impl ExactSizeIterator<Item = &str> + DoubleEndedIterator {
280 self.entries.iter().map(|(name, _)| name.as_str())
281 }
282
283 pub fn nouls(&self) -> impl DoubleEndedIterator<Item = (&str, &NoulAnswer)> {
285 self.iter().filter_map(|(name, answer)| answer.as_noul().map(|noul| (name, noul)))
286 }
287
288 pub fn choices(&self) -> impl DoubleEndedIterator<Item = (&str, &ChoiceAnswer)> {
290 self.iter().filter_map(|(name, answer)| answer.as_choice().map(|choice| (name, choice)))
291 }
292
293 pub fn scores(&self) -> impl DoubleEndedIterator<Item = (&str, &ScoreAnswer)> {
295 self.iter().filter_map(|(name, answer)| answer.as_score().map(|score| (name, score)))
296 }
297}
298
299impl<S> FromIterator<(S, Answer)> for Answers
300where
301 S: Into<String>,
302{
303 fn from_iter<I>(iter: I) -> Self
304 where
305 I: IntoIterator<Item = (S, Answer)>,
306 {
307 Self {
308 entries: iter
309 .into_iter()
310 .map(|(name, answer)| (Name::from(name.into()), answer))
311 .collect(),
312 }
313 }
314}
315
316impl Serialize for Answers {
317 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
318 where
319 S: Serializer,
320 {
321 Pairs(&self.entries).serialize(serializer)
322 }
323}
324
325#[derive(Debug, Clone, PartialEq)]
327#[non_exhaustive]
328pub enum Answer {
329 Noul(NoulAnswer),
331 Choice(ChoiceAnswer),
333 Score(ScoreAnswer),
335}
336
337impl Answer {
338 #[must_use]
340 pub fn as_noul(&self) -> Option<&NoulAnswer> {
341 match self {
342 Self::Noul(answer) => Some(answer),
343 Self::Choice(_) | Self::Score(_) => None,
344 }
345 }
346
347 #[must_use]
349 pub fn as_choice(&self) -> Option<&ChoiceAnswer> {
350 match self {
351 Self::Choice(answer) => Some(answer),
352 Self::Noul(_) | Self::Score(_) => None,
353 }
354 }
355
356 #[must_use]
358 pub fn as_score(&self) -> Option<&ScoreAnswer> {
359 match self {
360 Self::Score(answer) => Some(answer),
361 Self::Noul(_) | Self::Choice(_) => None,
362 }
363 }
364}
365
366impl From<NoulAnswer> for Answer {
367 fn from(answer: NoulAnswer) -> Self {
368 Self::Noul(answer)
369 }
370}
371
372impl From<ChoiceAnswer> for Answer {
373 fn from(answer: ChoiceAnswer) -> Self {
374 Self::Choice(answer)
375 }
376}
377
378impl From<ScoreAnswer> for Answer {
379 fn from(answer: ScoreAnswer) -> Self {
380 Self::Score(answer)
381 }
382}
383
384impl Serialize for Answer {
385 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
386 where
387 S: Serializer,
388 {
389 match self {
390 Self::Noul(answer) => answer.serialize(serializer),
391 Self::Choice(answer) => answer.serialize(serializer),
392 Self::Score(answer) => answer.serialize(serializer),
393 }
394 }
395}
396
397#[derive(Debug, Clone, Copy, PartialEq)]
401pub struct NoulAnswer {
402 noul: f64,
403}
404
405impl NoulAnswer {
406 #[must_use]
409 pub fn new(noul: f64) -> Self {
410 Self { noul }
411 }
412
413 #[must_use]
416 pub fn noul(&self) -> f64 {
417 self.noul
418 }
419}
420
421impl Serialize for NoulAnswer {
422 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
423 where
424 S: Serializer,
425 {
426 let mut out = serializer.serialize_struct("NoulAnswer", 2)?;
427 out.serialize_field("type", "noul")?;
428 out.serialize_field("noul", &self.noul)?;
429 out.end()
430 }
431}
432
433#[derive(Debug, Clone, PartialEq)]
437pub struct ChoiceAnswer {
438 choice: Name,
439 confidence: f64,
440 probabilities: Vec<(Name, f64)>,
441}
442
443impl ChoiceAnswer {
444 #[must_use]
447 pub fn new<C, I, S>(choice: C, confidence: f64, probabilities: I) -> Self
448 where
449 C: Into<String>,
450 I: IntoIterator<Item = (S, f64)>,
451 S: Into<String>,
452 {
453 Self::from_parts(
454 Name::from(choice.into()),
455 confidence,
456 probabilities
457 .into_iter()
458 .map(|(name, probability)| (Name::from(name.into()), probability))
459 .collect(),
460 )
461 }
462
463 pub(crate) fn from_parts(
465 choice: Name,
466 confidence: f64,
467 probabilities: Vec<(Name, f64)>,
468 ) -> Self {
469 Self { choice, confidence, probabilities }
470 }
471
472 #[must_use]
474 pub fn choice(&self) -> &str {
475 self.choice.as_str()
476 }
477
478 #[must_use]
480 pub fn confidence(&self) -> f64 {
481 self.confidence
482 }
483
484 pub fn probabilities(
486 &self,
487 ) -> impl ExactSizeIterator<Item = (&str, f64)> + DoubleEndedIterator {
488 self.probabilities.iter().map(|(name, probability)| (name.as_str(), *probability))
489 }
490
491 #[must_use]
493 pub fn probability(&self, name: &str) -> Option<f64> {
494 self.probabilities
495 .iter()
496 .find(|(key, _)| key.as_str() == name)
497 .map(|(_, probability)| *probability)
498 }
499}
500
501impl Serialize for ChoiceAnswer {
502 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
503 where
504 S: Serializer,
505 {
506 let mut out = serializer.serialize_struct("ChoiceAnswer", 4)?;
507 out.serialize_field("type", "choice")?;
508 out.serialize_field("choice", &self.choice)?;
509 out.serialize_field("confidence", &self.confidence)?;
510 out.serialize_field("probabilities", &Pairs(&self.probabilities))?;
511 out.end()
512 }
513}
514
515#[derive(Debug, Clone, PartialEq)]
528pub struct ScoreAnswer {
529 score: f64,
530 confidence: f64,
531 legend: Vec<(u32, Content<'static>)>,
532 probabilities: Vec<(u32, f64)>,
533}
534
535impl ScoreAnswer {
536 #[must_use]
539 pub fn new<L, P>(score: f64, confidence: f64, legend: L, probabilities: P) -> Self
540 where
541 L: IntoIterator<Item = (u32, Content<'static>)>,
542 P: IntoIterator<Item = (u32, f64)>,
543 {
544 let mut sorted_legend: Vec<_> = legend.into_iter().collect();
545 sort_by_level(&mut sorted_legend);
546 let mut sorted_probabilities: Vec<_> = probabilities.into_iter().collect();
547 sort_by_level(&mut sorted_probabilities);
548 Self::from_sorted(score, confidence, sorted_legend, sorted_probabilities)
549 }
550
551 pub(crate) fn from_sorted(
554 score: f64,
555 confidence: f64,
556 legend: Vec<(u32, Content<'static>)>,
557 probabilities: Vec<(u32, f64)>,
558 ) -> Self {
559 debug_assert!(legend.is_sorted_by_key(|(level, _)| *level), "the legend is sorted");
560 debug_assert!(
561 probabilities.is_sorted_by_key(|(level, _)| *level),
562 "the probabilities are sorted"
563 );
564 Self { score, confidence, legend, probabilities }
565 }
566
567 #[must_use]
570 pub fn score(&self) -> f64 {
571 self.score
572 }
573
574 #[must_use]
576 pub fn confidence(&self) -> f64 {
577 self.confidence
578 }
579
580 pub fn legend(
583 &self,
584 ) -> impl ExactSizeIterator<Item = (u32, &Content<'static>)> + DoubleEndedIterator {
585 self.legend.iter().map(|(level, description)| (*level, description))
586 }
587
588 #[must_use]
590 pub fn description(&self, level: u32) -> Option<&Content<'static>> {
591 self.legend.binary_search_by_key(&level, |(key, _)| *key).ok().map(|at| &self.legend[at].1)
592 }
593
594 pub fn probabilities(&self) -> impl ExactSizeIterator<Item = (u32, f64)> + DoubleEndedIterator {
596 self.probabilities.iter().copied()
597 }
598
599 #[must_use]
601 pub fn probability(&self, level: u32) -> Option<f64> {
602 self.probabilities
603 .binary_search_by_key(&level, |(key, _)| *key)
604 .ok()
605 .map(|at| self.probabilities[at].1)
606 }
607}
608
609impl Serialize for ScoreAnswer {
610 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
611 where
612 S: Serializer,
613 {
614 let mut out = serializer.serialize_struct("ScoreAnswer", 5)?;
615 out.serialize_field("type", "score")?;
616 out.serialize_field("score", &self.score)?;
617 out.serialize_field("confidence", &self.confidence)?;
618 out.serialize_field("legend", &Pairs(&self.legend))?;
619 out.serialize_field("probabilities", &Pairs(&self.probabilities))?;
620 out.end()
621 }
622}
623
624struct Pairs<'a, K, V>(&'a [(K, V)]);
627
628impl<K, V> Serialize for Pairs<'_, K, V>
629where
630 K: Serialize,
631 V: Serialize,
632{
633 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
634 where
635 S: Serializer,
636 {
637 let mut out = serializer.serialize_map(Some(self.0.len()))?;
638 for (key, value) in self.0 {
639 out.serialize_entry(key, value)?;
640 }
641 out.end()
642 }
643}
644
645pub(crate) fn push_by_level<T>(
655 entries: &mut Vec<(u32, T)>,
656 in_order: &mut bool,
657 level: u32,
658 value: T,
659) {
660 *in_order &= entries.last().is_none_or(|(last, _)| *last <= level);
661 entries.push((level, value));
662}
663
664pub(crate) fn sort_by_level<T>(entries: &mut [(u32, T)]) {
667 entries.sort_by_key(|(level, _)| *level);
668}
669
670#[cfg(test)]
671#[path = "response_tests.rs"]
672mod tests;