switchAILocal v0.2.0 — failover + MiniMax speech/music/lyrics
[0.2.0] - 2026-04-18
Intelligent failover + MiniMax speech/music/lyrics + built-in web search.
Added
- Failover recovery system
- 10-class error taxonomy in
internal/failover/classify.go:transient,rate_limit,auth,out_of_credits,context_length,permanent,empty_content,stall_pre_first_byte,stall_mid_stream,client_disconnect. - Typed
*failover.FailoverErrorwrapper preservingerrors.Aschains andStatusCode()interface contract. - Conductor-level advance/abort loop in
executeProvidersOncewith structuredevent=failover,event=failover_recovered,event=failover_abortlog lines (fields:request_id,attempt,primary_provider,next_provider,error_class,http_status,latency_ms,error_snippet). StallPhaserinterface so executors can signal watchdog stalls without import cycles.
- 10-class error taxonomy in
- Exponential backoff with jitter (
internal/autoroute/health.go) replaces the hardcoded 5-minute cooldown. Sequence 5s → 10s → 20s → … → 300s cap with ±10% jitter,CooldownAttemptsresets after a successful request following recovery. - Per-provider timeout config (
performance.provider-timeouts.{default, per-provider}) applied to non-streaming requests across all executors. - Streaming stall watchdog (
internal/runtime/executor/stream_watchdog.go) — pre-first-byte timeout and mid-stream stall detection viatime.AfterFunc+ context cancel. - MiniMax TTS adapter —
POST /v1/audio/speechwhen the upstream provider is MiniMax now transparently routes to the provider's native/v1/t2a_proendpoint. Adapter translates OpenAI-shape{model, input, voice, response_format}→ MiniMax{model, text, voice_id, format, …}, posts, parsesbase_resp, fetches the returnedaudio_fileURL (signed aliyun OSS), and streams raw audio bytes back with the correctContent-Type. Source:internal/runtime/executor/minimax_tts.go. - MiniMax music adapter — new endpoint
POST /v1/music/generationshandles both text-to-music (model: minimax:music-2.6) and reference-audio style transfer (model: minimax:music-cover+audio_urloraudio_base64). Hex-encoded upstream audio is decoded server-side and returned as base64 with metadata:{data: {audio, format, size_bytes, duration_ms, sample_rate, channels, bitrate}, model, trace_id, extra_info}. Source:internal/runtime/executor/minimax_music.go. - MiniMax lyrics adapter — new endpoint
POST /v1/music/lyricswith modeswrite_full_song(default) oredit, returns{song_title, style_tags, lyrics}with structure tags ([Verse],[Chorus],[Bridge], etc.). - MiniMax error-code → HTTP-status mapping so the failover taxonomy can classify application-level errors correctly:
1002(RPM rate limit) → 429 (ClassRateLimit, advances),1004/1008(auth/balance) → 401 (ClassAuth, advances),2013(invalid params) → 400 (ClassPermanent, aborts),2061(plan not support) → 402 (ClassOutOfCredits, advances). Previously these came back as HTTP 200 with application-level error bodies and the failover system couldn't see them. - Built-in web search documentation —
minimax:MiniMax-M2.7supports MiniMax-native web search viatools: [{"type": "web_search"}]on/v1/chat/completions. Requiredmax_tokens >= 2000documented (search inflates context to 6k–13k tokens). - New
intelligence.matrixslots:web_search,music_generation,music_cover,lyrics_generation. - Reproducible failover demo (
scripts/demo-failover.sh) — exercises the full pipeline (classification, backoff, advance/abort, structured logs) without live providers.--quickruns the headline kill-provider-mid-request demo; default runs the full matrix (31 tests). - Sprint doc at
docs/sprints/failover-recovery.mdcapturing the design rationale and validator-in-the-loop negotiation history.
Changed
intelligence.matrixdefaults updated to reachable models:vision/audio:xiaomi-tp:mimo-v2-omni(exhausted) →minimax:MiniMax-M2.7(multimodal).transcription:whisper-1(non-existent alias) →whisper-large-v3(groq-hosted).speech:xiaomi-tp:mimo-v2-tts(404) →minimax:speech-02-hd(served by new adapter).
- Documentation updated across six surfaces:
README.md,SKILL.md,docs/user/api-reference.md,skills/ail-provider/README.md,docs-site/concepts/providers.mdx,docs-site/guides/auto-routing-setup.mdx,config.example.yaml— all carry the new endpoint recipes, error-code mapping tables, and MiniMax voice-ID guidance.
Fixed
- Pre-first-byte stream stalls now classify as
ClassStallPreFirstByte(advance-eligible) instead of hanging indefinitely. Previously a frozen provider would block the request for the full upstream timeout. CooldownAttemptsstale after recovery — now resets to 0 on the first success following a cooldown, so the next outage starts from the base tier instead of compounding.
Known issues
internal/intelligence/embedding/TestIntegrationcan fail when run as part ofgo test ./...due to ONNX runtime CGO global-state leakage between tests ("onnxruntime has already been initialized"). The package works correctly in production and the test passes when run in isolation (go test -run TestIntegration). Pre-existing onmain— not introduced in this release.- MiniMax Plus-plan quotas are tight: TTS ~1–5 RPM (9000 chars/day), music-2.6/music-cover/lyrics 100/day each. When the RPM is exceeded the adapter translates
1002to HTTP 429 soClassRateLimitfires and failover advances if a fallback chain is configured.