What's new in v0.50.20
Fix: Chat no longer silently swallows agent failures (closes #373)
When the agent fails internally (auth error, missing credentials, model unavailable, network timeout) it returns an empty response without raising. Previously the chat would just sit there with the user's message unanswered and no feedback. Now:
- If
run_conversation()completes but produces no assistant reply and no streaming tokens, the server emits anapperrorevent with typeauth_mismatchorno_response— the same inline error bubble that shows for rate limits. - The
donehandler has a belt-and-suspenders guard too: ifdonearrives with zero assistant messages and no streamed text, an inline "No response received" message appears.
Example: With an invalid API key you now see:
Provider mismatch: Error code: 401 — Missing Authentication header
Runhermes modelin your terminal to update credentials, then restart the WebUI.
Cleanup: Remove stale OpenAI models (closes #374)
gpt-4o and o3 removed from the default OpenAI model list. Both are superseded by gpt-5.4-mini (general) and o4-mini (reasoning). The Copilot provider list keeps gpt-4o since it's still available there.
Feature: Live model fetching from provider API (closes #375)
New GET /api/models/live?provider=openai endpoint fetches the actual model catalog from the provider's /v1/models API. The dropdown loads the static list immediately (no flicker), then appends any additional models from the live fetch in the background. Results are cached per session. Includes scheme validation and SSRF protection.
Providers without a standard /v1/models endpoint (Anthropic, Google) return gracefully with no fetch attempt.
Security (found and fixed during review)
- SSRF hostname bypass in
/api/models/live: substring match"ollama" in hostnameallowedevil-ollama.attacker.comto bypass the private IP guard. Changed to exact set membership check. - Auth detection operator precedence bug in
api/streaming.py: Python ternary was absorbing the entire precedingor-chain, causing auth error detection to always returnFalsewhen_last_errorwas unset. Fixed.
949 tests | Full changelog