Skip to content
CodexfeatureBackend5 files · +379 −37

Build Modal ASR/TTS backend for a Gradio read-along app

Session from read-along-ai-agent-traces on Hugging Face by kingkw1 · MIT · condensed by Coders Talk

1h 01msession
0interventions
GOAL

Stand up serverless Modal endpoints for Cohere ASR and VoxCPM TTS, wire them into a Gradio reading-practice app with level-aware evaluation logic, and cover the endpoints with contract tests.

  1. Prompt · +0
    Write modal_inference.py with two Modal endpoints: run_cohere_asr and run_voxcpm_tts, using a cached Modal Volume for model weights.
  2. Agent did · +0m
    Inspected repo/spec docs, wrote modal_inference.py with Modal app, image, volume, secret wiring, and the two endpoint functions; also tightened .gitignore for cache/wav/env files.
  3. Prompt · +16m
    Wire app.py's mock ASR/TTS to the real Modal endpoints and implement level-based reading evaluation (phonics, CVC, sentence matching via Levenshtein) without touching Gradio UI/CSS.
  4. Agent did · +17m
    Added Modal.Function lookup/from_name compatibility helper, replaced mock wrappers with remote calls, built phonetic alias + filler-stripping matcher, added python-Levenshtein to requirements, and verified with a local smoke test.
  5. Prompt · +22m
    Write pytest contract tests (test_backend.py) for the deployed Modal endpoints: silent WAV in for ASR, 'Hello' in for TTS, checking response shape only.
  6. Break · 1h 05m away, not counted
  7. Prompt · +23m
    The tests failed — get this working.
  8. Fail · +23m
    test_cohere_asr failed remotely: the ASR endpoint tried to load the gated Cohere model on the silent test WAV instead of handling the contract-test fixture.
  9. Break · 1h 05m away, not counted
  10. Agent did · +23m
    Added a silent-WAV short-circuit in modal_inference.py, redeployed, and used 'modal app rollover --strategy recreate' to kill stale warm containers so both contract tests passed (2 passed in ~112s).
  11. Prompt · +43m
    Running the app and reading 'the dog ran fast' failed with 'Nice try!' after a 17s wait; also saw an old AttributeError traceback in Modal logs.
  12. Fail · +43m
    Prior AttributeError ('list' object has no attribute 'strip') from processor.decode returning a list surfaced again in production logs, and the app's first target sentence didn't match what the developer actually read.
  13. Agent did · +43m
    Fixed the decode normalization for list-vs-string output, reordered TARGET_SENTENCES so the app starts on the sentence being tested, added debug logging of target/transcript, set min_containers=1 to keep ASR warm, redeployed and rolled over containers, then reran contract tests (2 passed in ~105s).
  14. Outcome · +1h 1m
    Feature branch complete: Modal ASR/TTS backend deployed with warm containers, app.py wired to remote endpoints with level-aware matching, test_backend.py passing 2/2 contract tests, and a PR description drafted for review.
VERDICT

Next time I'd give the exact test fixture (silent WAV) up front so the agent designs the endpoint to handle it from the start instead of hitting a gated-model load in production. The fix that actually mattered was forcing a container rollover after each redeploy — without that, Modal kept serving stale code and the tests kept failing against the old container. I also should have specified the intended first-level target sentence earlier, since the mismatch between what I read and what the app expected wasted a debugging cycle that looked like a model bug.

I tried this · 0

Discussion · 0

How Builds work