fix(ai): refresh Groq recommendations and remove unavailable OpenRouter models

This commit is contained in:
Jonatan Castro
2026-11-04 02:41:58 +01:00
parent a026ab5926
commit 344346ff9d
3 changed files with 61 additions and 6 deletions
+2 -4
View File
@@ -110,12 +110,10 @@
"openai/gpt-oss-120b", "openai/gpt-oss-120b",
"meta-llama/llama-3.1-8b-instruct", "meta-llama/llama-3.1-8b-instruct",
"nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free", "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free",
"nvidia/nemotron-3-super-120b-a12b:free", "google/gemma-4-26b-a4b-it:free"
"google/gemma-4-26b-a4b-it:free",
"poolside/laguna-s-2.1:free"
], ],
"recommended": "meta-llama/llama-3.3-70b-instruct", "recommended": "meta-llama/llama-3.3-70b-instruct",
"_note": "Curated manually from the 249+ models OpenRouter serves — the auto-verifier passes ~200 today but only a subset are practical for notification translation. Includes the 11 previously-curated paid models plus 22 new mainstream additions (gpt-5.1, claude-opus-4.8, sonnet-5, grok-4.3/4.20, kimi-k2, deepseek-v3.2, nova, cohere-a, sonar, ...) and 6 `:free` variants re-added manually — the free tier is intentionally supported per user request even though today's rate limits blocked some of them from passing the test. Reviewed 2026-10-26: three `:free` variants no longer served by OpenRouter were dropped." "_note": "Curated manually from the 249+ models OpenRouter serves — the auto-verifier passes ~200 today but only a subset are practical for notification translation. Includes the 11 previously-curated paid models plus 22 new mainstream additions (gpt-5.1, claude-opus-4.8, sonnet-5, grok-4.3/4.20, kimi-k2, deepseek-v3.2, nova, cohere-a, sonar, ...) and 6 `:free` variants re-added manually — the free tier is intentionally supported per user request even though today's rate limits blocked some of them from passing the test. Reviewed 2026-10-26: three `:free` variants no longer served by OpenRouter were dropped. Availability reviewed 2026-11-04 against the public models endpoint: expired poolside/laguna-s-2.1:free and unlisted nvidia/nemotron-3-super-120b-a12b:free removed. This availability check is not a new inference verification; no untested models were added."
}, },
"ollama": { "ollama": {
"_note": "Ollama models are local, we don't filter them. User manages their own models.", "_note": "Ollama models are local, we don't filter them. User manages their own models.",
@@ -21,8 +21,13 @@ class GroqProvider(AIProvider):
# Exclude non-chat models # Exclude non-chat models
EXCLUDED_PATTERNS = ['whisper', 'tts', 'guard', 'tool-use'] EXCLUDED_PATTERNS = ['whisper', 'tts', 'guard', 'tool-use']
# Recommended models (in priority order - versatile/large models first) # Prefer the verified default and current GPT-OSS models. Llama remains
RECOMMENDED_PREFIXES = ['llama-3.3', 'llama-3.1-70b', 'llama-3.1-8b', 'mixtral', 'gemma'] # available for accounts with access; retired Mixtral/Gemma families have
# no recommendation priority. Sorting never adds IDs to the API response.
RECOMMENDED_PREFIXES = [
'openai/gpt-oss-20b', 'openai/gpt-oss-120b', 'qwen/qwen3.8-27b',
'llama-3.3', 'llama-3.1-8b',
]
def list_models(self) -> List[str]: def list_models(self) -> List[str]:
"""List available Groq models for chat completions. """List available Groq models for chat completions.
@@ -0,0 +1,52 @@
"""Provider model ordering and curated availability, without credentials/network."""
import io
import json
from pathlib import Path
import sys
import unittest
from unittest.mock import patch
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from ai_providers.groq_provider import GroqProvider
class GroqModelRecommendationsTests(unittest.TestCase):
def fetch(self, ids):
response = io.BytesIO(json.dumps({'data': [{'id': model} for model in ids]}).encode())
with patch('ai_providers.groq_provider.urllib.request.urlopen', return_value=response) as request:
models = GroqProvider(api_key='fixture-only').list_models()
self.assertEqual(request.call_args.kwargs['timeout'], 10)
return models
def test_current_verified_models_precede_legacy_and_unknown_families(self):
listed = ['mixtral-fixture', 'allam-2-7b', 'llama-3.3-70b-versatile',
'openai/gpt-oss-120b', 'qwen/qwen3.8-27b', 'openai/gpt-oss-20b']
self.assertEqual(self.fetch(listed)[:3],
['openai/gpt-oss-20b', 'openai/gpt-oss-120b', 'qwen/qwen3.8-27b'])
self.assertCountEqual(self.fetch(listed), listed)
def test_recommendations_never_invent_models_or_remove_arabic_model(self):
self.assertEqual(self.fetch(['allam-2-7b']), ['allam-2-7b'])
self.assertEqual(self.fetch([]), [])
def test_non_chat_models_still_excluded(self):
self.assertEqual(self.fetch(['whisper-large-v3', 'llama-prompt-guard-2-22m',
'openai/gpt-oss-20b']), ['openai/gpt-oss-20b'])
def test_missing_credentials_do_not_fetch_models(self):
with patch('ai_providers.groq_provider.urllib.request.urlopen') as request:
self.assertEqual(GroqProvider().list_models(), [])
request.assert_not_called()
def test_curated_catalog_keeps_verified_default_and_removes_unavailable_free_ids(self):
catalog = json.loads((Path(__file__).resolve().parents[2] / 'config/verified_ai_models.json').read_text())
self.assertEqual(GroqProvider.RECOMMENDED_PREFIXES[0], catalog['groq']['recommended'])
for provider in ('groq', 'openrouter'):
self.assertIn(catalog[provider]['recommended'], catalog[provider]['models'])
self.assertNotIn('poolside/laguna-s-2.1:free', catalog['openrouter']['models'])
self.assertNotIn('nvidia/nemotron-3-super-120b-a12b:free', catalog['openrouter']['models'])
self.assertIn('allam-2-7b', catalog['groq']['models'])
if __name__ == '__main__':
unittest.main()