rusty_openai/openai_api/
completion.rs1use crate::{error_handling::OpenAIResult, openai::OpenAI, setters};
2use serde::Serialize;
3use serde_json::Value;
4
5#[derive(Debug, Serialize)]
7#[serde(untagged)]
8pub enum ResponseFormat {
9 Json {
11 #[serde(rename = "type")]
12 format_type: String,
13 },
14 JsonSchema {
16 #[serde(rename = "type")]
17 format_type: String,
18 json_schema: JsonSchema,
19 strict: bool,
20 },
21}
22
23#[derive(Debug, Serialize)]
25pub struct JsonSchema {
26 pub name: String,
28 pub schema: Value,
30}
31
32pub struct CompletionsApi<'a>(pub(crate) &'a OpenAI<'a>);
34
35#[derive(Default, Serialize)]
37pub struct ChatCompletionRequest {
38 model: String,
40
41 messages: Vec<Value>,
43
44 #[serde(skip_serializing_if = "Option::is_none")]
46 max_tokens: Option<u64>,
47
48 #[serde(skip_serializing_if = "Option::is_none")]
50 temperature: Option<f64>,
51
52 #[serde(skip_serializing_if = "Option::is_none")]
54 top_p: Option<f64>,
55
56 #[serde(skip_serializing_if = "Option::is_none")]
58 n: Option<u64>,
59
60 #[serde(skip_serializing_if = "Option::is_none")]
62 stream: Option<bool>,
63
64 #[serde(skip_serializing_if = "Option::is_none")]
66 stop: Option<Vec<String>>,
67
68 #[serde(skip_serializing_if = "Option::is_none")]
70 presence_penalty: Option<f64>,
71
72 #[serde(skip_serializing_if = "Option::is_none")]
74 frequency_penalty: Option<f64>,
75
76 #[serde(skip_serializing_if = "Option::is_none")]
78 logit_bias: Option<Value>,
79
80 #[serde(skip_serializing_if = "Option::is_none")]
82 user: Option<String>,
83
84 #[serde(skip_serializing_if = "Option::is_none")]
86 response_format: Option<ResponseFormat>,
87}
88
89impl ChatCompletionRequest {
90 #[inline(always)]
92 pub fn new(model: String, messages: Vec<Value>) -> Self {
93 Self {
94 model,
95 messages,
96 ..Default::default()
97 }
98 }
99
100 pub fn new_json(model: String, messages: Vec<Value>) -> Self {
102 Self {
103 model,
104 messages,
105 response_format: Some(ResponseFormat::Json {
106 format_type: "json".to_string(),
107 }),
108 ..Default::default()
109 }
110 }
111
112 pub fn new_json_schema(model: String, messages: Vec<Value>, schema_name: String, schema: Value) -> Self {
114 Self {
115 model,
116 messages,
117 response_format: Some(ResponseFormat::JsonSchema {
118 format_type: "json_schema".to_string(),
119 json_schema: JsonSchema {
120 name: schema_name,
121 schema,
122 },
123 strict: true,
124 }),
125 ..Default::default()
126 }
127 }
128
129 setters! {
132 max_tokens: u64,
133 temperature: f64,
134 top_p: f64,
135 n: u64,
136 stream: bool,
137 stop: Vec<String>,
138 presence_penalty: f64,
139 frequency_penalty: f64,
140 logit_bias: Value,
141 user: String,
142 response_format: ResponseFormat,
143 }
144}
145
146impl<'a> CompletionsApi<'a> {
147 pub async fn create(&self, request: ChatCompletionRequest) -> OpenAIResult<Value> {
157 self.0.post_json("/chat/completions", &request).await
159 }
160}