Skip to content

fix(scout): stop retiring realtime models on a wrong-endpoint 404 - #15

Merged
aliihsaad merged 2 commits into
mainfrom
fix/scout-realtime-false-positive
Aug 30, 2026
Merged

aliihsaad merged 2 commits into
mainfrom
fix/scout-realtime-false-positive

Conversation

@aliihsaad

Copy link
Copy Markdown
Owner

Regression from #14, caught by the maintainer within hours of deploy. The auto-retirement disabled gemini-2.5-flash-native-audio-preview-12-2025 and gemini-3.1-flash-live-preview — both working perfectly.

What went wrong

The scout probes Google with generateContent. Realtime models answer only over bidiGenerateContent, so Google replies:

models/gemini-3.1-flash-live-preview is not found for API version v1beta, **or is not supported for generateContent**. Call ModelService.ListModels to see the list of available models and their supported methods.

That 404 describes the endpoint, not the model. isGoneMessage matched on 404/not found, and three cycles later both rows were switched off at gone_streak=3.

The misclassification predates #14model_availability.status was already recording these as deprecated. Nothing acted on it until retirement shipped, which is exactly what turned a cosmetic wrong label into disabled models. Retirement didn't create the bug; it made an existing one consequential.

Fixed at both layers

1. isGoneMessage rejects wrong-method 404sis not supported for, supported methods, not supported by. A wrong-endpoint 404 is never removal, whatever the provider, so this generalises past Google.

2. selectSweepCandidateIds stops feeding non-chat models to a chat probe. A model is swept when it advertises chat or vision, or advertises no capability at all (which the router already treats as unrestricted). Realtime, speech and embedding-only rows are excluded — the probe shouldn't render a verdict it isn't equipped to make.

Layer 2 is the real fix; layer 1 is the net that catches the same shape from any other provider.

Migration V23

Re-enables what the bug retired, scoped to rows whose only capabilities are realtime/audio — so it restores exactly the class the probe cannot judge and never resurrects a genuinely dead chat model. It also clears gone_streak, so a stale counter can't re-retire them before the new candidate query takes effect.

Verification

  • 340/340 server tests pass, tsc clean
  • The exact production error strings are now negative cases
  • A genuine Google removal (no longer available to new users) still retires — the guard is narrow, not a blanket 404 exemption
  • New tests assert realtime-only models stay enabled, are excluded from the sweep, and that ordinary chat models are still swept

Note on the deployed state

The two models are currently disabled on the VPS. V23 restores them on the next restart.

🤖 Generated with Claude Code

Regression from the auto-retirement in #14. It disabled
gemini-2.5-flash-native-audio-preview-12-2025 and
gemini-3.1-flash-live-preview, both of which were working perfectly.

The scout probes Google with generateContent. Realtime models answer only
over bidiGenerateContent, so Google replies:

  "models/gemini-3.1-flash-live-preview is not found for API version v1beta,
   or is not supported for generateContent. Call ModelService.ListModels to
   see the list of available models and their supported methods."

That 404 describes the ENDPOINT, not the model. isGoneMessage matched on
'404'/'not found' and three cycles later both rows were switched off. The
misclassification predates #14 — status was already recorded as 'deprecated'
— but nothing acted on it until retirement shipped, which is what turned a
cosmetic wrong label into disabled models.

Fixed at both layers:

  - isGoneMessage now rejects "is not supported for", "supported methods" and
    "not supported by". A wrong-method 404 is never removal, whatever the
    provider. This generalises past Google.
  - selectSweepCandidateIds no longer feeds realtime/speech/embedding-only
    rows to a chat probe at all. A model is swept when it advertises chat or
    vision, or advertises no capability (which the router already treats as
    unrestricted). The probe should not render a verdict it is not equipped
    to make.

Migration V23 re-enables what the bug retired, scoped to rows whose only
capabilities are realtime/audio so it restores exactly the class the probe
cannot judge and never resurrects a genuinely dead chat model. It also clears
gone_streak so a stale counter cannot re-retire them.

Verified: the exact production error strings are now negative cases, while a
genuine Google removal ("no longer available to new users") still retires.
@coderabbitai

coderabbitai Bot commented Aug 30, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1595cb85-428e-4742-8ca5-887bbf38166a


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@aliihsaad
aliihsaad merged commit 7983de4 into main Aug 30, 2026
2 checks passed
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.

1 participant