mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-11-05 20:32:15 +00:00
Merge pull request #594 from jcastro/fix/provider-model-availability
fix(ai): refresh Groq ordering and unavailable OpenRouter models
This commit is contained in:
@@ -7,7 +7,9 @@ on:
|
||||
- 'AppImage/scripts/notification_manager.py'
|
||||
- 'AppImage/scripts/notification_templates.py'
|
||||
- 'AppImage/scripts/ai_context_enrichment.py'
|
||||
- 'AppImage/scripts/ai_providers/base.py'
|
||||
- 'AppImage/scripts/ai_providers/**'
|
||||
- 'AppImage/config/verified_ai_models.json'
|
||||
- 'AppImage/scripts/tests/test_groq_model_recommendations.py'
|
||||
- 'AppImage/scripts/tests/test_backup_ai_diagnostics.py'
|
||||
- 'AppImage/scripts/notification_channels.py'
|
||||
- 'AppImage/components/apprise-service-help.tsx'
|
||||
@@ -72,7 +74,9 @@ on:
|
||||
- 'AppImage/scripts/notification_manager.py'
|
||||
- 'AppImage/scripts/notification_templates.py'
|
||||
- 'AppImage/scripts/ai_context_enrichment.py'
|
||||
- 'AppImage/scripts/ai_providers/base.py'
|
||||
- 'AppImage/scripts/ai_providers/**'
|
||||
- 'AppImage/config/verified_ai_models.json'
|
||||
- 'AppImage/scripts/tests/test_groq_model_recommendations.py'
|
||||
- 'AppImage/scripts/tests/test_backup_ai_diagnostics.py'
|
||||
- 'AppImage/scripts/notification_channels.py'
|
||||
- 'AppImage/components/apprise-service-help.tsx'
|
||||
@@ -190,6 +194,19 @@ jobs:
|
||||
bash -n scripts/gpu_tpu/nvidia_installer.sh
|
||||
python3 -B -m unittest discover -s tests -p 'test_nvidia*.py' -v
|
||||
|
||||
ai-model-availability:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 3
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
- name: Test model ordering and curated availability without network or credentials
|
||||
run: python -B -m unittest discover -s AppImage/scripts/tests -p test_groq_model_recommendations.py -v
|
||||
|
||||
installer-and-release:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
|
||||
@@ -110,12 +110,10 @@
|
||||
"openai/gpt-oss-120b",
|
||||
"meta-llama/llama-3.1-8b-instruct",
|
||||
"nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free",
|
||||
"nvidia/nemotron-3-super-120b-a12b:free",
|
||||
"google/gemma-4-26b-a4b-it:free",
|
||||
"poolside/laguna-s-2.1:free"
|
||||
"google/gemma-4-26b-a4b-it:free"
|
||||
],
|
||||
"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": {
|
||||
"_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
|
||||
EXCLUDED_PATTERNS = ['whisper', 'tts', 'guard', 'tool-use']
|
||||
|
||||
# Recommended models (in priority order - versatile/large models first)
|
||||
RECOMMENDED_PREFIXES = ['llama-3.3', 'llama-3.1-70b', 'llama-3.1-8b', 'mixtral', 'gemma']
|
||||
# Prefer the verified default and current GPT-OSS models. Llama remains
|
||||
# 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]:
|
||||
"""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()
|
||||
Reference in New Issue
Block a user