Skip to content

feat: fall back to OpenCode when Anthropic is unavailable#107

Open
vinicius91carvalho wants to merge 1 commit into
routatic:mainfrom
vinicius91carvalho:106-anthropic-first-fallback
Open

feat: fall back to OpenCode when Anthropic is unavailable#107
vinicius91carvalho wants to merge 1 commit into
routatic:mainfrom
vinicius91carvalho:106-anthropic-first-fallback

Conversation

@vinicius91carvalho

Copy link
Copy Markdown

Closes #106

Summary

  • add opt-in Anthropic-first passthrough with OAuth/capability header preservation
  • fall back on 408, 429, 5xx, and transport failures before response streaming starts
  • honor Retry-After with adaptive single-request recovery probes and no synthetic health calls
  • skip usage-limited OpenCode Go models and continue through working Zen-free fallbacks
  • refresh generated defaults and document Claude subscription configuration

Validation

  • gofmt check
  • go vet ./...
  • go test ./... -race
  • go build ./cmd/routatic-proxy
  • golangci-lint (0 issues)
  • live Claude Code -> Anthropic passthrough
  • forced Anthropic 429 -> real OpenCode fallback
  • resumed Claude Code session retained context across Anthropic -> OpenCode failover
  • live one-token checks for configured Zen-free models

Notes

The free Zen catalog still lists MiniMax M3 Free and Qwen3.6 Plus Free, but both report that their promotions ended. Defaults therefore use the currently working Nemotron 3 Ultra Free, MiMo V2.5 Free, and DeepSeek V4 Flash Free endpoints.

@kilo-code-bot

kilo-code-bot Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Code Review Roast 🔥

Verdict: No Issues Found | Recommendation: Merge

Oh wait, this PR is actually clean. I need to sit down. I had my flamethrower warmed up and everything.

📊 Overall: Like finding a unicorn in production — I didn't think clean PRs existed anymore, but here we are.

The Anthropic-first passthrough implementation is solid:

  • Proper circuit breaker pattern with exponential backoff up to 15 minutes
  • Retry-After header support for HTTP-date format parsing (though now is passed as parameter, not captured internally)
  • Zero-byte stream handling with 32KB buffer
  • Provider-wide usage limit skipping works correctly in both streaming and non-streaming paths
  • Tests cover concurrent probe scenarios, transport failures, and redirect handling without credential leaks

The only thing that made me raise an eyebrow was copyStreamingResponse silently swallowing write errors — but that's expected for streaming where client disconnects are normal.

Files Reviewed (11 files)
  • internal/handlers/anthropic_first.go - 287 lines (new)
  • internal/handlers/anthropic_first_test.go - 228 lines (new)
  • internal/handlers/messages.go - 6 changed lines
  • internal/handlers/messages_test.go - 87 new lines
  • internal/server/server.go - 2 changed lines
  • internal/config/config.go - 5 new lines
  • internal/config/loader.go - 4 new lines
  • internal/config/loader_test.go - 22 new lines
  • internal/router/fallback.go - 9 changed lines
  • internal/router/fallback_test.go - 48 new lines
  • internal/provider/opencode_zen.go - 2 new lines
  • cmd/routatic-proxy/main.go - 20 changed lines

Reviewed by laguna-m.1-20260312:free · Input: 343.2K · Output: 11K · Cached: 1.1M

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: use OpenCode only when Anthropic is unavailable

1 participant