Skip to main content

quantum_sdk/
batch.rs

1//! Batch processing — submit multiple prompts in a single request.
2//!
3//! # Example
4//!
5//! ```no_run
6//! # async fn example() -> quantum_sdk::Result<()> {
7//! let client = quantum_sdk::Client::new("qai_key_xxx");
8//!
9//! let resp = client.batch_submit(&[quantum_sdk::BatchJob {
10//!     model: "claude-sonnet-4-6".into(),
11//!     prompt: "Summarize quantum computing".into(),
12//!     ..Default::default()
13//! }]).await?;
14//!
15//! for id in &resp.job_ids {
16//!     println!("Submitted: {id}");
17//! }
18//! # Ok(())
19//! # }
20//! ```
21
22use serde::{Deserialize, Serialize};
23
24use crate::client::Client;
25use crate::error::Result;
26
27/// A single job in a batch submission.
28#[derive(Debug, Clone, Serialize, Default)]
29pub struct BatchJob {
30    /// Model to use for this job.
31    pub model: String,
32
33    /// The prompt text.
34    pub prompt: String,
35
36    /// Optional title for this job.
37    #[serde(skip_serializing_if = "Option::is_none")]
38    pub title: Option<String>,
39
40    /// Optional system prompt.
41    #[serde(skip_serializing_if = "Option::is_none")]
42    pub system_prompt: Option<String>,
43
44    /// Optional maximum tokens to generate.
45    #[serde(skip_serializing_if = "Option::is_none")]
46    pub max_tokens: Option<i64>,
47}
48
49/// Response from batch submission.
50#[derive(Debug, Clone, Deserialize)]
51pub struct BatchSubmitResponse {
52    /// The IDs of the created jobs.
53    pub job_ids: Vec<String>,
54
55    /// Status of the batch submission.
56    #[serde(default)]
57    pub status: String,
58}
59
60/// Response from JSONL batch submission.
61#[derive(Debug, Clone, Deserialize)]
62pub struct BatchJsonlResponse {
63    /// The IDs of the created jobs.
64    pub job_ids: Vec<String>,
65}
66
67/// A single job in the batch jobs list.
68#[derive(Debug, Clone, Deserialize)]
69pub struct BatchJobInfo {
70    /// Job identifier.
71    pub job_id: String,
72
73    /// Current status (e.g. "pending", "running", "completed", "failed").
74    pub status: String,
75
76    /// Model used for this job.
77    #[serde(default)]
78    pub model: Option<String>,
79
80    /// Job title.
81    #[serde(default)]
82    pub title: Option<String>,
83
84    /// When the job was created.
85    #[serde(default)]
86    pub created_at: Option<String>,
87
88    /// When the job completed.
89    #[serde(default)]
90    pub completed_at: Option<String>,
91
92    /// Result data (present when completed).
93    #[serde(default)]
94    pub result: Option<serde_json::Value>,
95
96    /// Error message (present when failed).
97    #[serde(default)]
98    pub error: Option<String>,
99
100    /// Cost in ticks.
101    #[serde(default)]
102    pub cost_ticks: i64,
103}
104
105/// Response from listing batch jobs.
106#[derive(Debug, Clone, Deserialize)]
107pub struct BatchJobsResponse {
108    /// The list of batch jobs.
109    #[serde(default)]
110    pub jobs: Vec<BatchJobInfo>,
111}
112
113impl Client {
114    /// Submit a batch of jobs for processing.
115    ///
116    /// Each job runs independently and can be polled via the Jobs API.
117    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    /// Submit a batch of jobs using JSONL format.
126    ///
127    /// Each line in the JSONL string is a JSON object with model, prompt, etc.
128    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    /// List all batch jobs for the account.
137    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    /// Get the status and result of a single batch job.
145    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}