Skip to main content

codetether_agent/tool/voice_input/
mod.rs

1//! Voice Input Tool — record microphone audio, transcribe via Whisper API.
2//!
3//! Provides a single `record_then_transcribe` action that captures audio
4//! from the default microphone, encodes to WAV, and sends it to the
5//! Voice API `/transcribe` endpoint for speech-to-text.
6
7mod actions;
8pub(crate) mod client;
9pub mod encoder;
10mod input_config;
11mod input_stream;
12mod params;
13pub mod recorder;
14mod schema;
15pub(crate) mod stderr_guard;
16
17use super::{Tool, ToolResult};
18use anyhow::{Context, Result};
19use async_trait::async_trait;
20use serde_json::Value;
21
22/// Voice Input tool — records from mic and transcribes to text.
23pub struct VoiceInputTool {
24    client: reqwest::Client,
25}
26
27impl Default for VoiceInputTool {
28    fn default() -> Self {
29        Self::new()
30    }
31}
32
33impl VoiceInputTool {
34    /// Create a new voice input tool with a configured HTTP client.
35    pub fn new() -> Self {
36        Self {
37            client: client::build_client(),
38        }
39    }
40}
41
42#[async_trait]
43impl Tool for VoiceInputTool {
44    fn id(&self) -> &str {
45        "voice_input"
46    }
47    fn name(&self) -> &str {
48        "VoiceInput"
49    }
50    fn description(&self) -> &str {
51        "Record audio from microphone and transcribe to text. \
52        Action: record_then_transcribe. Uses 16kHz mono WAV. \
53        Set CODETETHER_VOICE_API_URL to override the API endpoint."
54    }
55    fn parameters(&self) -> Value {
56        schema::json_schema()
57    }
58    async fn execute(&self, params: Value) -> Result<ToolResult> {
59        let p: params::Params =
60            serde_json::from_value(params).context("Invalid voice_input params")?;
61        actions::dispatch(&self.client, &p).await
62    }
63}