1use serde::{Deserialize, Serialize};
23
24use crate::client::Client;
25use crate::error::Result;
26
27#[derive(Debug, Clone, Serialize, Default)]
29pub struct BatchJob {
30 pub model: String,
32
33 pub prompt: String,
35
36 #[serde(skip_serializing_if = "Option::is_none")]
38 pub title: Option<String>,
39
40 #[serde(skip_serializing_if = "Option::is_none")]
42 pub system_prompt: Option<String>,
43
44 #[serde(skip_serializing_if = "Option::is_none")]
46 pub max_tokens: Option<i64>,
47}
48
49#[derive(Debug, Clone, Deserialize)]
51pub struct BatchSubmitResponse {
52 pub job_ids: Vec<String>,
54
55 #[serde(default)]
57 pub status: String,
58}
59
60#[derive(Debug, Clone, Deserialize)]
62pub struct BatchJsonlResponse {
63 pub job_ids: Vec<String>,
65}
66
67#[derive(Debug, Clone, Deserialize)]
69pub struct BatchJobInfo {
70 pub job_id: String,
72
73 pub status: String,
75
76 #[serde(default)]
78 pub model: Option<String>,
79
80 #[serde(default)]
82 pub title: Option<String>,
83
84 #[serde(default)]
86 pub created_at: Option<String>,
87
88 #[serde(default)]
90 pub completed_at: Option<String>,
91
92 #[serde(default)]
94 pub result: Option<serde_json::Value>,
95
96 #[serde(default)]
98 pub error: Option<String>,
99
100 #[serde(default)]
102 pub cost_ticks: i64,
103}
104
105#[derive(Debug, Clone, Deserialize)]
107pub struct BatchJobsResponse {
108 #[serde(default)]
110 pub jobs: Vec<BatchJobInfo>,
111}
112
113impl Client {
114 pub async fn batch_submit(&self, jobs: &[BatchJob]) -> Result<BatchSubmitResponse> {
118 let body = serde_json::json!({ "jobs": jobs });
119 let (resp, _meta) = self
120 .post_json::<serde_json::Value, BatchSubmitResponse>("/qai/v1/batch", &body)
121 .await?;
122 Ok(resp)
123 }
124
125 pub async fn batch_submit_jsonl(&self, jsonl: &str) -> Result<BatchJsonlResponse> {
129 let body = serde_json::json!({ "jsonl": jsonl });
130 let (resp, _meta) = self
131 .post_json::<serde_json::Value, BatchJsonlResponse>("/qai/v1/batch/jsonl", &body)
132 .await?;
133 Ok(resp)
134 }
135
136 pub async fn batch_jobs(&self) -> Result<BatchJobsResponse> {
138 let (resp, _meta) = self
139 .get_json::<BatchJobsResponse>("/qai/v1/batch/jobs")
140 .await?;
141 Ok(resp)
142 }
143
144 pub async fn batch_job(&self, id: &str) -> Result<BatchJobInfo> {
146 let path = format!("/qai/v1/batch/jobs/{id}");
147 let (resp, _meta) = self.get_json::<BatchJobInfo>(&path).await?;
148 Ok(resp)
149 }
150}