From 1a9666d73187bede0ee13d756d9be629dd4df670 Mon Sep 17 00:00:00 2001 From: NguyenND Date: Wed, 19 Aug 2026 11:29:12 -0400 Subject: [PATCH] Aug 19 - Update: AI model since the old one no longer exist --- CLAUDE.md | 2 +- app/routes/support.py | 25 +++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 07c3374..3a9326f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -163,7 +163,7 @@ part of the tree — see §7. Device registration on the API side lives in | `DIGEST_SECRET` | Authenticates all cron endpoints | | `REDIS_URL` | Optional. When set, Flask-Limiter uses Redis for shared rate-limit counters across Gunicorn workers. | | `GROQ_API_KEY` | Optional. When set, enables the AI chatbot at `/support/chat`. Absent → chat input disabled; customers see a "Submit to Support" fallback only. | -| `GROQ_MODEL` | Optional. Groq model ID. Defaults to `llama-3.3-70b-versatile`. | +| `GROQ_MODEL` | Optional. Groq model ID. Defaults to `_DEFAULT_GROQ_MODEL` in `routes/support.py` (`openai/gpt-oss-120b`, verified Aug 2026). **Groq retires models without notice** — when the configured one disappears the API 404s and EVERY question returns the generic "problem reaching the AI assistant" reply, with nothing else broken, so it stays invisible until a customer complains. That is how `llama-3.3-70b-versatile` took the chat down. The error handler in `chat_message()` logs the model name and an explicit "set GROQ_MODEL" hint for exactly this case; fixing it needs no deploy, just the env var. | | `ENROLLMENT_NOTIFY_EMAILS` | Optional. Comma-separated extra addresses alerted on a new enrollment, **in addition to** every active `admin` account. For people who should be told but hold no JQC login. | | `ENROLLMENT_DIR` | Optional. Directory for enrollment-form JSON submissions. Defaults to `/enrollments` (git-ignored). Created at boot. | | `DEFAULT_UI_THEME` | Optional, default `modern` (phase50). The design shown when a user has no stored preference — i.e. new accounts and unauthenticated pages. A stored `users.ui_theme` always wins. Set `classic` to revert the default **without** touching anyone's saved choice. | diff --git a/app/routes/support.py b/app/routes/support.py index c5e1b94..524ad7c 100644 --- a/app/routes/support.py +++ b/app/routes/support.py @@ -161,6 +161,10 @@ INSPECTOR_FAQS = [ ] +#: Groq model used when GROQ_MODEL is unset. Verified available Aug 2026. +#: Groq retires models periodically — see the error handler in chat_message(). +_DEFAULT_GROQ_MODEL = 'openai/gpt-oss-120b' + # Soft cap on injected knowledge to keep prompt size (and token cost) reasonable. _KB_MAX_CHARS = 6000 @@ -397,7 +401,14 @@ def chat_message(): messages.append({'role': m['role'], 'content': _redact_pii(m['content'])}) messages.append({'role': 'user', 'content': _redact_pii(user_message)}) - model = os.environ.get('GROQ_MODEL', 'llama-3.3-70b-versatile') + # Default model. Groq RETIRES models without notice, and when the + # configured one disappears every question fails with the generic + # "problem reaching the AI assistant" reply — invisible until a + # customer complains. That is exactly how llama-3.3-70b-versatile + # took the chat down (404 model_not_found, Aug 2026). If this + # happens again, check the log line below and set GROQ_MODEL to a + # current model — no deploy needed. + model = os.environ.get('GROQ_MODEL', _DEFAULT_GROQ_MODEL) completion = client.chat.completions.create( model=model, messages=messages, @@ -406,7 +417,17 @@ def chat_message(): ) reply = completion.choices[0].message.content.strip() except Exception as exc: - logger.error('SUPPORT | Groq error: %s', exc) + # Always name the model — a bare "Groq error" gives whoever reads + # the log nothing to act on, and a retired model is the most likely + # cause of a total outage here. + if 'model_not_found' in str(exc) or 'does not exist' in str(exc): + logger.error( + 'SUPPORT | Groq model %r is not available on this account — ' + 'the assistant is DOWN for every user. Set GROQ_MODEL to a ' + 'current model (see https://console.groq.com/docs/models). ' + 'Underlying error: %s', model, exc) + else: + logger.error('SUPPORT | Groq error (model=%r): %s', model, exc) reply = ("I ran into a problem reaching the AI assistant. " "Please try again, or use **Submit to Support** to contact our team.")