Analyze: transcode non-MP3 audio and report failed sections honestly

Merged
SI
2d ago
+413-15

What

  • Model service (modal/serve_music_flamingo.py): downloads outside WAV/MP3/FLAC (M4A/AAC, OGG, WebM, MP4 audio) are transcoded to 16 kHz mono WAV with ffmpeg before inference; the download has a 120 s timeout; unreachable or undecodable audio answers 422 (audio_unreachable / audio_undecodable) instead of a bare 500. Merging redeploys the Modal app (.github/workflows/deploy-modal.yml).
  • API: executeFullReport returns failed: string[] (report keys of failed sections). POST /api/songs/analyze with full_report now answers
    • 200 { status: "success", failed: [] } when every section returned,
    • 200 { status: "partial", failed: [...] } when some failed (those sections still carry { error }),
    • 502 { status: "error", error, failed } when every section failed (nothing is charged, as before).
  • A rejection from the model service answers 502 { status: "error", error, upstream_status, detail } (new FlamingoServiceError), not 500. The analyze_music MCP tool surfaces the same error.

Why

An .m4a URL failed all 13 sections and the API still said success (found 2026-11-04 while comparing the full report against a competitor's analyst report). Callers could not tell a broken file from a working one.

Tests

  • New: FlamingoServiceError, executeFullReport.failed, processAnalyzeMusicRequest.partial, postFlamingoGenerateHandler.upstream, plus an upstream-status case in callFlamingoGenerate.
  • Updated the three full-report mocks for the new failed field.
  • vitest run lib/flamingo lib/mcp/tools/flamingo: 174 passed. ESLint and Prettier clean.
  • transcode_to_wav smoke-tested locally on a real 1:59 M4A → 16 kHz mono WAV, original removed.

Docs

The full_report response gains status: "partial" and failed; the docs entry for /api/songs/analyze should mention both (follow-up).

🤖 Generated with Claude Code


Summary by cubic

Fixes broken audio files being reported as successful full reports, and makes non-MP3 audio actually analyze correctly.

The model service now transcodes downloaded audio outside WAV/MP3/FLAC to 16 kHz mono WAV with ffmpeg before inference, bounds downloads at 120 s, and returns 422 with audio_unreachable or audio_undecodable instead of a bare 500. The API now reports failed report sections honestly: executeFullReport returns a failed key list, single-call upstream rejections answer 502 with upstream_status and detail, and POST /api/songs/analyze with full_report answers 200 status: "partial" when some sections fail and 502 when all fail, in which case nothing is charged. The analyze_music MCP tool surfaces the same errors.

Migration
Merging redeploys the Modal app via .github/workflows/deploy-modal.yml. The docs entry for /api/songs/analyze should mention status: "partial" and the failed field (follow-up).