Skip to main content

yapi_types/
classify.rs

1//! Classifier and image-generation requests and results.
2//!
3//! Mirrors `ClassifierContext`, `ClassifierResult`, `ImagesContext` and
4//! `AssistantImages` in `packages/ai/src/types.ts` in pi `v1.0.0`.
5#![allow(
6    missing_docs,
7    reason = "fields mirror pi's TypeScript types; contracts are noted where they differ from the name"
8)]
9
10use indexmap::IndexMap;
11use serde::{Deserialize, Serialize};
12use serde_json::{Map, Value};
13
14use crate::message::{ImageContent, TextContent, Usage};
15
16/// The meaning of each answer of a `bool` question.
17#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
18pub struct BoolCriteria {
19    #[serde(rename = "true")]
20    pub yes: String,
21    #[serde(rename = "false")]
22    pub no: String,
23}
24
25/// One question about the state, tagged by `type`.
26#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
27#[serde(tag = "type", rename_all = "lowercase")]
28pub enum ClassifierQuestion {
29    /// Pick one key of `criteria`; each value describes its option.
30    Choice {
31        instructions: String,
32        criteria: IndexMap<String, String>,
33    },
34    /// A level index into `criteria`, lowest first.
35    Score {
36        instructions: String,
37        criteria: Vec<String>,
38    },
39    /// Yes or no.
40    Bool {
41        instructions: String,
42        criteria: BoolCriteria,
43    },
44}
45
46impl ClassifierQuestion {
47    /// What the question asks.
48    pub fn instructions(&self) -> &str {
49        match self {
50            ClassifierQuestion::Choice { instructions, .. }
51            | ClassifierQuestion::Score { instructions, .. }
52            | ClassifierQuestion::Bool { instructions, .. } => instructions,
53        }
54    }
55}
56
57/// What a classifier judges, and the questions to answer about it.
58#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
59pub struct ClassifierContext {
60    pub state: Map<String, Value>,
61    pub questions: IndexMap<String, ClassifierQuestion>,
62}
63
64/// One answer, tagged by `type`.
65#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
66#[serde(tag = "type", rename_all = "lowercase")]
67pub enum ClassifierAnswer {
68    Choice {
69        choice: String,
70        probabilities: IndexMap<String, f64>,
71        confidence: f64,
72    },
73    Score {
74        score: f64,
75        confidence: f64,
76    },
77    Bool {
78        probability: f64,
79    },
80}
81
82/// How a classification or image request ended.
83#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
84#[serde(rename_all = "lowercase")]
85pub enum OutcomeReason {
86    Stop,
87    Error,
88    Aborted,
89}
90
91/// A classification's answers, by question id.
92#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
93#[serde(rename_all = "camelCase")]
94pub struct ClassifierResult {
95    pub api: String,
96    pub provider: String,
97    pub model: String,
98    pub answers: IndexMap<String, ClassifierAnswer>,
99    /// Token usage priced from the catalog, when the service reports tokens.
100    #[serde(default, skip_serializing_if = "Option::is_none")]
101    pub usage: Option<Usage>,
102    pub stop_reason: OutcomeReason,
103    #[serde(default, skip_serializing_if = "Option::is_none")]
104    pub error_message: Option<String>,
105    pub timestamp: u64,
106}
107
108/// A text or image block of an image request or result.
109#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
110#[serde(tag = "type", rename_all = "lowercase")]
111pub enum ImagesContent {
112    Text(TextContent),
113    Image(ImageContent),
114}
115
116/// The prompt and reference images of an image request.
117#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
118pub struct ImagesContext {
119    pub input: Vec<ImagesContent>,
120}
121
122/// Images, and any text, an image model returned.
123#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
124#[serde(rename_all = "camelCase")]
125pub struct AssistantImages {
126    pub api: String,
127    pub provider: String,
128    pub model: String,
129    pub output: Vec<ImagesContent>,
130    #[serde(default, skip_serializing_if = "Option::is_none")]
131    pub response_id: Option<String>,
132    #[serde(default, skip_serializing_if = "Option::is_none")]
133    pub usage: Option<Usage>,
134    pub stop_reason: OutcomeReason,
135    #[serde(default, skip_serializing_if = "Option::is_none")]
136    pub error_message: Option<String>,
137    pub timestamp: u64,
138}