1use std::sync::Arc;
5use std::time::Duration;
6
7use http::header::{HeaderName, HeaderValue};
8use serde::Serialize;
9use serde_json::Value;
10
11use crate::error::{Error, Result};
12use crate::question::Questions;
13use crate::response::{ListModelsResponse, SystemOneResponse};
14use crate::retry::RetryPolicy;
15use crate::rubric::Rubric;
16
17#[derive(Debug, Clone)]
19pub struct Client {
20 inner: crate::Client,
21 rt: Arc<tokio::runtime::Runtime>,
22}
23
24impl Client {
25 pub fn new(inner: crate::Client) -> Result<Self> {
33 let rt = tokio::runtime::Builder::new_current_thread()
34 .enable_all()
35 .build()
36 .map_err(|e| Error::config_caused("could not start the async runtime", e))?;
37 Ok(Self {
38 inner,
39 rt: Arc::new(rt),
40 })
41 }
42
43 pub fn from_env() -> Result<Self> {
49 Self::new(crate::Client::from_env()?)
50 }
51
52 pub fn default_model(&self) -> &str {
54 self.inner.default_model()
55 }
56
57 pub fn models(&self) -> Models<'_> {
59 Models { client: self }
60 }
61
62 pub fn system_one<S: Serialize>(
64 &self,
65 state: S,
66 questions: impl Into<Questions>,
67 ) -> SystemOneRequest<'_> {
68 SystemOneRequest {
69 rt: &self.rt,
70 req: self.inner.system_one(state, questions),
71 }
72 }
73
74 pub fn ask<R: Rubric>(&self, state: impl Serialize) -> AskRequest<'_, R> {
76 AskRequest {
77 rt: &self.rt,
78 req: self.inner.ask(state),
79 }
80 }
81}
82
83#[derive(Debug, Clone, Copy)]
85pub struct Models<'a> {
86 client: &'a Client,
87}
88
89impl<'a> Models<'a> {
90 pub fn list(&self) -> ListModelsRequest<'a> {
92 ListModelsRequest {
93 rt: &self.client.rt,
94 req: self.client.inner.models().list(),
95 }
96 }
97}
98
99macro_rules! forward {
100 ($($name:ident($($arg:ident: $ty:ty),*)),* $(,)?) => {$(
101 #[doc = concat!("See the async request's `", stringify!($name), "`.")]
102 pub fn $name(mut self, $($arg: $ty),*) -> Self {
103 self.req = self.req.$name($($arg),*);
104 self
105 }
106 )*};
107}
108
109#[must_use = "call .send()"]
111#[derive(Debug)]
112pub struct SystemOneRequest<'a> {
113 rt: &'a tokio::runtime::Runtime,
114 req: crate::SystemOneRequest,
115}
116
117impl SystemOneRequest<'_> {
118 forward!(
119 retry(policy: RetryPolicy),
120 timeout(timeout: Duration),
121 header(name: HeaderName, value: HeaderValue),
122 );
123
124 pub fn model(mut self, model: impl Into<String>) -> Self {
126 self.req = self.req.model(model);
127 self
128 }
129
130 pub fn extra_body(mut self, key: impl Into<String>, value: impl Into<Value>) -> Self {
132 self.req = self.req.extra_body(key, value);
133 self
134 }
135
136 pub fn send(self) -> Result<SystemOneResponse> {
146 self.rt.block_on(self.req.send())
147 }
148}
149
150#[must_use = "call .send()"]
152#[derive(Debug)]
153pub struct AskRequest<'a, R> {
154 rt: &'a tokio::runtime::Runtime,
155 req: crate::AskRequest<R>,
156}
157
158impl<R: Rubric> AskRequest<'_, R> {
159 forward!(
160 retry(policy: RetryPolicy),
161 timeout(timeout: Duration),
162 header(name: HeaderName, value: HeaderValue),
163 );
164
165 pub fn model(mut self, model: impl Into<String>) -> Self {
167 self.req = self.req.model(model);
168 self
169 }
170
171 pub fn extra_body(mut self, key: impl Into<String>, value: impl Into<Value>) -> Self {
173 self.req = self.req.extra_body(key, value);
174 self
175 }
176
177 pub fn send(self) -> Result<R> {
187 self.rt.block_on(self.req.send())
188 }
189}
190
191#[must_use = "call .send()"]
193#[derive(Debug)]
194pub struct ListModelsRequest<'a> {
195 rt: &'a tokio::runtime::Runtime,
196 req: crate::ListModelsRequest,
197}
198
199impl ListModelsRequest<'_> {
200 forward!(
201 retry(policy: RetryPolicy),
202 timeout(timeout: Duration),
203 header(name: HeaderName, value: HeaderValue),
204 );
205
206 pub fn send(self) -> Result<ListModelsResponse> {
216 self.rt.block_on(self.req.send())
217 }
218}