microclaw_engine/internal/app/
transcribe.rs1use reqwest::multipart;
2
3pub async fn transcribe_audio(api_key: &str, audio_bytes: &[u8]) -> Result<String, String> {
4 let client = reqwest::Client::new();
5
6 let part = multipart::Part::bytes(audio_bytes.to_vec())
7 .file_name("audio.ogg")
8 .mime_str("audio/ogg")
9 .map_err(|e| e.to_string())?;
10
11 let form = multipart::Form::new()
12 .text("model", "whisper-1")
13 .part("file", part);
14
15 let resp = client
16 .post("https://api.openai.com/v1/audio/transcriptions")
17 .header("Authorization", format!("Bearer {api_key}"))
18 .multipart(form)
19 .send()
20 .await
21 .map_err(|e| format!("Whisper API request failed: {e}"))?;
22
23 if !resp.status().is_success() {
24 let status = resp.status();
25 let body = resp.text().await.unwrap_or_default();
26 return Err(format!("Whisper API error HTTP {status}: {body}"));
27 }
28
29 let body: serde_json::Value = resp
30 .json()
31 .await
32 .map_err(|e| format!("Failed to parse Whisper response: {e}"))?;
33
34 body.get("text")
35 .and_then(|t| t.as_str())
36 .map(|s| s.to_string())
37 .ok_or_else(|| "Whisper response missing 'text' field".into())
38}
39
40#[cfg(test)]
41mod tests {
42 #[test]
43 fn test_transcribe_module_exists() {
44 }
46}