Skip to main content

synth_ai/
optimization_api.rs

1use std::sync::Arc;
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6use crate::models::{ArtifactsResponse, CursorParams, EventsResponse, JsonMap, ResourceList};
7use crate::openapi_paths;
8use crate::transport::Transport;
9use crate::types::Result;
10
11#[derive(Debug, Clone, Serialize, Deserialize, Default)]
12pub struct PolicyOptimizationSystem {
13    #[serde(default)]
14    pub system_id: Option<String>,
15    #[serde(default)]
16    pub id: Option<String>,
17    #[serde(default)]
18    pub status: Option<String>,
19    #[serde(flatten)]
20    pub extra: JsonMap,
21}
22
23#[derive(Debug, Clone, Serialize, Deserialize, Default)]
24pub struct PolicyOptimizationOfflineJob {
25    #[serde(default)]
26    pub job_id: Option<String>,
27    #[serde(default)]
28    pub id: Option<String>,
29    #[serde(default)]
30    pub status: Option<String>,
31    #[serde(flatten)]
32    pub extra: JsonMap,
33}
34
35#[derive(Debug, Clone, Serialize, Deserialize, Default)]
36pub struct PolicyOptimizationOnlineSession {
37    #[serde(default)]
38    pub session_id: Option<String>,
39    #[serde(default)]
40    pub id: Option<String>,
41    #[serde(default)]
42    pub status: Option<String>,
43    #[serde(flatten)]
44    pub extra: JsonMap,
45}
46
47#[derive(Debug, Clone, Serialize, Deserialize, Default)]
48pub struct SystemCreateRequest {
49    #[serde(flatten)]
50    pub body: JsonMap,
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize, Default)]
54pub struct SystemUpdateRequest {
55    #[serde(flatten)]
56    pub body: JsonMap,
57}
58
59#[derive(Debug, Clone, Serialize, Deserialize, Default)]
60pub struct OfflineJobCreateRequest {
61    #[serde(skip_serializing_if = "Option::is_none")]
62    pub system_id: Option<String>,
63    #[serde(skip_serializing_if = "Option::is_none")]
64    pub algorithm: Option<String>,
65    #[serde(skip_serializing_if = "Option::is_none")]
66    pub config: Option<Value>,
67    #[serde(flatten)]
68    pub extra: JsonMap,
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize, Default)]
72pub struct OfflineJobUpdateRequest {
73    #[serde(skip_serializing_if = "Option::is_none")]
74    pub state: Option<String>,
75    #[serde(skip_serializing_if = "Option::is_none")]
76    pub reason: Option<String>,
77    #[serde(flatten)]
78    pub extra: JsonMap,
79}
80
81#[derive(Debug, Clone, Serialize, Deserialize, Default)]
82pub struct OnlineSessionCreateRequest {
83    #[serde(skip_serializing_if = "Option::is_none")]
84    pub system_id: Option<String>,
85    #[serde(skip_serializing_if = "Option::is_none")]
86    pub algorithm: Option<String>,
87    #[serde(skip_serializing_if = "Option::is_none")]
88    pub config: Option<Value>,
89    #[serde(flatten)]
90    pub extra: JsonMap,
91}
92
93#[derive(Debug, Clone, Serialize, Deserialize, Default)]
94pub struct OnlineSessionUpdateRequest {
95    #[serde(skip_serializing_if = "Option::is_none")]
96    pub state: Option<String>,
97    #[serde(skip_serializing_if = "Option::is_none")]
98    pub reason: Option<String>,
99    #[serde(flatten)]
100    pub extra: JsonMap,
101}
102
103#[derive(Debug, Clone, Serialize, Deserialize, Default)]
104pub struct OnlineRewardRequest {
105    pub trace_correlation_id: String,
106    pub reward_info: RewardInfo,
107    #[serde(flatten)]
108    pub extra: JsonMap,
109}
110
111#[derive(Debug, Clone, Serialize, Deserialize, Default)]
112pub struct RewardInfo {
113    pub outcome_reward: f64,
114    #[serde(skip_serializing_if = "Option::is_none")]
115    pub event_rewards: Option<Vec<f64>>,
116    #[serde(flatten)]
117    pub extra: JsonMap,
118}
119
120#[derive(Clone)]
121pub struct OptimizationClient {
122    transport: Arc<Transport>,
123}
124
125impl OptimizationClient {
126    pub(crate) fn new(transport: Arc<Transport>) -> Self {
127        Self { transport }
128    }
129
130    pub fn systems(&self) -> SystemsClient {
131        SystemsClient {
132            transport: self.transport.clone(),
133        }
134    }
135
136    pub fn offline(&self) -> OfflineJobsClient {
137        OfflineJobsClient {
138            transport: self.transport.clone(),
139        }
140    }
141
142    pub fn online(&self) -> OnlineSessionsClient {
143        OnlineSessionsClient {
144            transport: self.transport.clone(),
145        }
146    }
147}
148
149#[derive(Clone)]
150pub struct SystemsClient {
151    transport: Arc<Transport>,
152}
153
154impl SystemsClient {
155    pub async fn create(&self, request: &SystemCreateRequest) -> Result<PolicyOptimizationSystem> {
156        self.transport
157            .post_json(openapi_paths::V1_POLICY_OPTIMIZATION_SYSTEMS, request)
158            .await
159    }
160
161    pub async fn get(&self, system_id: &str) -> Result<PolicyOptimizationSystem> {
162        self.transport
163            .get_json(&openapi_paths::v1_policy_optimization_system(system_id))
164            .await
165    }
166
167    pub async fn list(&self, params: Option<&CursorParams>) -> Result<ResourceList<PolicyOptimizationSystem>> {
168        match params {
169            Some(query) => {
170                self.transport
171                    .get_json_with_query(openapi_paths::V1_POLICY_OPTIMIZATION_SYSTEMS, query)
172                    .await
173            }
174            None => {
175                self.transport
176                    .get_json(openapi_paths::V1_POLICY_OPTIMIZATION_SYSTEMS)
177                    .await
178            }
179        }
180    }
181
182    pub async fn update(
183        &self,
184        system_id: &str,
185        request: &SystemUpdateRequest,
186    ) -> Result<PolicyOptimizationSystem> {
187        self.transport
188            .patch_json(&openapi_paths::v1_policy_optimization_system(system_id), request)
189            .await
190    }
191
192    pub async fn delete(&self, system_id: &str) -> Result<()> {
193        self.transport
194            .delete_empty(&openapi_paths::v1_policy_optimization_system(system_id))
195            .await
196    }
197}
198
199#[derive(Clone)]
200pub struct OfflineJobsClient {
201    transport: Arc<Transport>,
202}
203
204impl OfflineJobsClient {
205    pub async fn create(&self, request: &OfflineJobCreateRequest) -> Result<PolicyOptimizationOfflineJob> {
206        self.transport
207            .post_json(openapi_paths::V1_OFFLINE_JOBS, request)
208            .await
209    }
210
211    pub async fn get(&self, job_id: &str) -> Result<PolicyOptimizationOfflineJob> {
212        self.transport
213            .get_json(&openapi_paths::v1_offline_job(job_id))
214            .await
215    }
216
217    pub async fn list(&self, params: Option<&CursorParams>) -> Result<ResourceList<PolicyOptimizationOfflineJob>> {
218        match params {
219            Some(query) => self
220                .transport
221                .get_json_with_query(openapi_paths::V1_OFFLINE_JOBS, query)
222                .await,
223            None => self.transport.get_json(openapi_paths::V1_OFFLINE_JOBS).await,
224        }
225    }
226
227    pub async fn update(
228        &self,
229        job_id: &str,
230        request: &OfflineJobUpdateRequest,
231    ) -> Result<PolicyOptimizationOfflineJob> {
232        self.transport
233            .patch_json(&openapi_paths::v1_offline_job(job_id), request)
234            .await
235    }
236
237    pub async fn events(&self, job_id: &str, params: Option<&CursorParams>) -> Result<EventsResponse> {
238        let path = openapi_paths::v1_offline_job_events(job_id);
239        match params {
240            Some(query) => self.transport.get_json_with_query(&path, query).await,
241            None => self.transport.get_json(&path).await,
242        }
243    }
244
245    pub async fn artifacts(&self, job_id: &str) -> Result<ArtifactsResponse> {
246        self.transport
247            .get_json(&openapi_paths::v1_offline_job_artifacts(job_id))
248            .await
249    }
250
251    pub async fn cancel(&self, job_id: &str, reason: Option<String>) -> Result<PolicyOptimizationOfflineJob> {
252        self.update(
253            job_id,
254            &OfflineJobUpdateRequest {
255                state: Some("cancelled".to_string()),
256                reason,
257                extra: JsonMap::new(),
258            },
259        )
260        .await
261    }
262
263    pub async fn pause(&self, job_id: &str, reason: Option<String>) -> Result<PolicyOptimizationOfflineJob> {
264        self.update(
265            job_id,
266            &OfflineJobUpdateRequest {
267                state: Some("paused".to_string()),
268                reason,
269                extra: JsonMap::new(),
270            },
271        )
272        .await
273    }
274
275    pub async fn resume(&self, job_id: &str, reason: Option<String>) -> Result<PolicyOptimizationOfflineJob> {
276        self.update(
277            job_id,
278            &OfflineJobUpdateRequest {
279                state: Some("running".to_string()),
280                reason,
281                extra: JsonMap::new(),
282            },
283        )
284        .await
285    }
286}
287
288#[derive(Clone)]
289pub struct OnlineSessionsClient {
290    transport: Arc<Transport>,
291}
292
293impl OnlineSessionsClient {
294    pub async fn create(
295        &self,
296        request: &OnlineSessionCreateRequest,
297    ) -> Result<PolicyOptimizationOnlineSession> {
298        self.transport
299            .post_json(openapi_paths::V1_ONLINE_SESSIONS, request)
300            .await
301    }
302
303    pub async fn get(&self, session_id: &str) -> Result<PolicyOptimizationOnlineSession> {
304        self.transport
305            .get_json(&openapi_paths::v1_online_session(session_id))
306            .await
307    }
308
309    pub async fn list(
310        &self,
311        params: Option<&CursorParams>,
312    ) -> Result<ResourceList<PolicyOptimizationOnlineSession>> {
313        match params {
314            Some(query) => self
315                .transport
316                .get_json_with_query(openapi_paths::V1_ONLINE_SESSIONS, query)
317                .await,
318            None => self.transport.get_json(openapi_paths::V1_ONLINE_SESSIONS).await,
319        }
320    }
321
322    pub async fn update(
323        &self,
324        session_id: &str,
325        request: &OnlineSessionUpdateRequest,
326    ) -> Result<PolicyOptimizationOnlineSession> {
327        self.transport
328            .patch_json(&openapi_paths::v1_online_session(session_id), request)
329            .await
330    }
331
332    pub async fn reward(
333        &self,
334        session_id: &str,
335        request: &OnlineRewardRequest,
336    ) -> Result<PolicyOptimizationOnlineSession> {
337        self.transport
338            .post_json(&openapi_paths::v1_online_session_reward(session_id), request)
339            .await
340    }
341
342    pub async fn events(
343        &self,
344        session_id: &str,
345        params: Option<&CursorParams>,
346    ) -> Result<EventsResponse> {
347        let path = openapi_paths::v1_online_session_events(session_id);
348        match params {
349            Some(query) => self.transport.get_json_with_query(&path, query).await,
350            None => self.transport.get_json(&path).await,
351        }
352    }
353
354    pub async fn cancel(
355        &self,
356        session_id: &str,
357        reason: Option<String>,
358    ) -> Result<PolicyOptimizationOnlineSession> {
359        self.update(
360            session_id,
361            &OnlineSessionUpdateRequest {
362                state: Some("cancelled".to_string()),
363                reason,
364                extra: JsonMap::new(),
365            },
366        )
367        .await
368    }
369
370    pub async fn pause(
371        &self,
372        session_id: &str,
373        reason: Option<String>,
374    ) -> Result<PolicyOptimizationOnlineSession> {
375        self.update(
376            session_id,
377            &OnlineSessionUpdateRequest {
378                state: Some("paused".to_string()),
379                reason,
380                extra: JsonMap::new(),
381            },
382        )
383        .await
384    }
385
386    pub async fn resume(
387        &self,
388        session_id: &str,
389        reason: Option<String>,
390    ) -> Result<PolicyOptimizationOnlineSession> {
391        self.update(
392            session_id,
393            &OnlineSessionUpdateRequest {
394                state: Some("running".to_string()),
395                reason,
396                extra: JsonMap::new(),
397            },
398        )
399        .await
400    }
401}