How the Transcribe Command in Agent Reach Uses Whisper via Groq with OpenAI Fallback
The transcribe command in Agent Reach automatically routes audio through Groq's free Whisper API first, then transparently falls back to OpenAI's Whisper endpoint on any HTTP error, while handling audio download, compression, and chunking automatically.
The agent_reach.transcribe module serves as the core orchestrator for converting audio URLs or local files into text. As implemented in the Panniantong/Agent-Reach repository, this command leverages a layered provider architecture that prioritizes Groq's Whisper implementation before falling back to OpenAI, ensuring robust transcription even when rate limits or network issues occur.
Provider Selection and Configuration
The transcribe command supports both automatic provider selection and explicit provider targeting through the provider parameter.
Auto Mode vs Explicit Selection
In agent_reach/transcribe.py, the helper function _provider_order determines the execution sequence based on user input. When provider="auto" is specified (the default), the function returns ["groq", "openai"], ensuring Groq is attempted first. If a specific provider is requested, it returns a single-item list containing only that provider.
# From transcribe.py lines 99-104
def _provider_order(provider: str) -> List[str]:
if provider == "auto":
return ["groq", "openai"]
return [provider]
Configuration Validation
Before initiating any network requests, the code validates that at least one requested provider has an API key configured in ~/.agent-reach/config.yaml. The configuration must contain either groq_api_key or openai_api_key. If neither is present, the function raises a NoProviderConfigured error immediately.
# From transcribe.py lines 22-26
if not any(cfg.get(f"{p}_api_key") for p in providers):
raise NoProviderConfigured(
f"No API key configured for providers: {providers}"
)
Audio Preparation Pipeline
The transcribe command handles the entire preprocessing workflow automatically, from downloading remote media to splitting oversized files.
Downloading with yt-dlp
When the source argument is a URL rather than a local file path, the download_audio function (lines 77-95) invokes yt-dlp to fetch the media stream. The function extracts only the audio component to minimize bandwidth and processing time.
Compression and Formatting
Raw audio is re-encoded to a mono 16 kHz m4a file to meet Whisper's requirements. This compression step ensures the file stays under the 25 MiB upload limit imposed by the Whisper API. The processing occurs in agent_reach/transcribe.py between lines 101-121.
Chunking for Size Limits
If compression still yields a file exceeding 25 MiB, the chunk_audio function (lines 126-154) splits the audio into segments of ≤10 minutes each. Each chunk represents a valid, independent payload for the Whisper API, allowing the system to process long-form content without truncation.
The Fallback Mechanism
The core resilience logic resides in _transcribe_with_fallback, which implements circuit-breaker-style retry logic across providers.
Provider Order Iteration
For each audio chunk, the function iterates over the provider list (typically ["groq", "openai"]). It skips any provider lacking an API key in the configuration, though the prior validation ensures at least one provider is available.
The transcribe_chunk helper executes the actual HTTP POST request:
- Groq: Posts to
https://api.groq.com/openai/v1/audio/transcriptionsusing modelwhisper-large-v3 - OpenAI: Posts to
https://api.openai.com/v1/audio/transcriptionsusing modelwhisper-1
Error Handling and Retry Logic
If Groq returns a non-2xx status code (such as a 429 rate limit), transcribe_chunk raises a TranscribeError. The fallback loop catches this exception, records the error, and proceeds to the next provider. The first successful response returns its transcript immediately; if all providers fail, the last error is re-raised to the caller.
# From transcribe.py lines 58-61 (simplified)
for provider in providers:
try:
return transcribe_chunk(chunk, provider, cfg)
except TranscribeError as e:
errors.append(e)
continue
CLI Usage
The agent_reach.cli module exposes this functionality through the transcribe sub-command (lines 1113-1122). Users can process local files or URLs directly from the terminal.
# Print transcript to stdout
agent-reach transcribe my_audio.mp3
# Save to a file
agent-reach transcribe my_audio.mp3 -o transcript.txt
# Force OpenAI only (bypass Groq)
agent-reach transcribe speech.wav --provider openai
Python API Examples
from agent_reach.transcribe import transcribe
# Auto-select provider (Groq first, OpenAI fallback)
text = transcribe("https://youtu.be/example")
# Force specific provider
text = transcribe("speech.wav", provider="openai")
Fallback in Action
The test suite demonstrates the fallback behavior by simulating a Groq rate limit (429) followed by OpenAI success:
# Test scenario from test_transcribe.py
monkeypatch.setattr(
tr.requests, "post",
lambda url, **kw: FakeResponse(429, "rate limited")
if url == tr.PROVIDERS["groq"]["endpoint"]
else FakeResponse(200, "openai result")
)
text = tr._transcribe_with_fallback(chunk, ["groq", "openai"], cfg)
assert text == "openai result" # OpenAI used after Groq failed
Summary
- The transcribe command uses a provider-agnostic architecture defined in
agent_reach/transcribe.pythat defaults to Groq but automatically falls back to OpenAI. - Audio preprocessing includes yt-dlp downloading, mono 16kHz m4a compression, and automatic chunking to respect the 25 MiB API limit.
- Error handling catches
TranscribeErrorexceptions from failed providers and iterates through the provider list until success or exhaustion. - Configuration requires API keys in
~/.agent-reach/config.yamlfor either Groq (groq_api_key) or OpenAI (openai_api_key). - Chunk assembly concatenates successful segment transcripts with newline characters to produce the final output.
Frequently Asked Questions
What happens if both Groq and OpenAI fail?
If all configured providers return errors (rate limits, authentication failures, or network issues), the _transcribe_with_fallback function re-raises the last TranscribeError encountered. The CLI will display this error and exit with a non-zero status code.
Why does the transcribe command prefer Groq over OpenAI?
The default provider="auto" mode returns ["groq", "openai"] as the execution order because Groq offers a free tier for Whisper transcription with competitive latency. OpenAI serves as the paid fallback for reliability when Groq rate limits are hit.
How does the command handle large audio files like podcasts or lectures?
Files exceeding the 25 MiB limit after compression are automatically split into ≤10-minute chunks by the chunk_audio function. Each chunk is transcribed independently, and the results are concatenated with newline separators before being returned to the user.
Can I use the transcribe command without configuring both API keys?
Yes. You only need to configure one provider's API key in ~/.agent-reach/config.yaml. If you specify provider="groq" or provider="openai" explicitly, only that key is required. The validation logic checks that at least one requested provider has credentials, not all of them.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →