1use std::time::Duration;
5
6use http::header::{HeaderName, HeaderValue};
7use serde::Serialize;
8use serde_json::Value;
9
10use crate::error::{Error, Result};
11use crate::question::Questions;
12use crate::response::{ListModelsResponse, SystemOneResponse};
13use crate::retry::RetryPolicy;
14use crate::rubric::Rubric;
15
16#[derive(Debug)]
18pub struct Client {
19 inner: crate::Client,
20 rt: tokio::runtime::Runtime,
21}
22
23impl Client {
24 pub fn new(inner: crate::Client) -> Result<Self> {
26 let rt = tokio::runtime::Builder::new_current_thread()
27 .enable_all()
28 .build()
29 .map_err(|e| Error::Config(format!("could not start runtime: {e}")))?;
30 Ok(Self { inner, rt })
31 }
32
33 pub fn from_env() -> Result<Self> {
35 Self::new(crate::Client::from_env()?)
36 }
37
38 pub fn system_one<S: Serialize>(
40 &self,
41 state: S,
42 questions: impl Into<Questions>,
43 ) -> SystemOneRequest<'_> {
44 SystemOneRequest {
45 rt: &self.rt,
46 req: self.inner.system_one(state, questions),
47 }
48 }
49
50 pub fn ask<R: Rubric>(&self, state: impl Serialize) -> AskRequest<'_, R> {
52 AskRequest {
53 rt: &self.rt,
54 req: self.inner.ask(state),
55 }
56 }
57
58 pub fn list_models(&self) -> ListModelsRequest<'_> {
60 ListModelsRequest {
61 rt: &self.rt,
62 req: self.inner.models().list(),
63 }
64 }
65}
66
67macro_rules! forward {
68 ($($name:ident($($arg:ident: $ty:ty),*)),* $(,)?) => {$(
69 #[doc = concat!("See the async request's `", stringify!($name), "`.")]
70 pub fn $name(mut self, $($arg: $ty),*) -> Self {
71 self.req = self.req.$name($($arg),*);
72 self
73 }
74 )*};
75}
76
77#[must_use = "call .send()"]
79#[derive(Debug)]
80pub struct SystemOneRequest<'a> {
81 rt: &'a tokio::runtime::Runtime,
82 req: crate::SystemOneRequest,
83}
84
85impl SystemOneRequest<'_> {
86 forward!(
87 retry(policy: RetryPolicy),
88 timeout(timeout: Duration),
89 header(name: HeaderName, value: HeaderValue),
90 );
91
92 pub fn model(mut self, model: impl Into<String>) -> Self {
94 self.req = self.req.model(model);
95 self
96 }
97
98 pub fn extra_body(mut self, key: impl Into<String>, value: impl Into<Value>) -> Self {
100 self.req = self.req.extra_body(key, value);
101 self
102 }
103
104 pub fn send(self) -> Result<SystemOneResponse> {
106 self.rt.block_on(self.req.send())
107 }
108}
109
110#[must_use = "call .send()"]
112#[derive(Debug)]
113pub struct AskRequest<'a, R> {
114 rt: &'a tokio::runtime::Runtime,
115 req: crate::AskRequest<R>,
116}
117
118impl<R: Rubric> AskRequest<'_, R> {
119 forward!(
120 retry(policy: RetryPolicy),
121 timeout(timeout: Duration),
122 header(name: HeaderName, value: HeaderValue),
123 );
124
125 pub fn model(mut self, model: impl Into<String>) -> Self {
127 self.req = self.req.model(model);
128 self
129 }
130
131 pub fn extra_body(mut self, key: impl Into<String>, value: impl Into<Value>) -> Self {
133 self.req = self.req.extra_body(key, value);
134 self
135 }
136
137 pub fn send(self) -> Result<R> {
139 self.rt.block_on(self.req.send())
140 }
141}
142
143#[must_use = "call .send()"]
145#[derive(Debug)]
146pub struct ListModelsRequest<'a> {
147 rt: &'a tokio::runtime::Runtime,
148 req: crate::ListModelsRequest,
149}
150
151impl ListModelsRequest<'_> {
152 forward!(
153 retry(policy: RetryPolicy),
154 timeout(timeout: Duration),
155 header(name: HeaderName, value: HeaderValue),
156 );
157
158 pub fn send(self) -> Result<ListModelsResponse> {
160 self.rt.block_on(self.req.send())
161 }
162}