The openai SDK's SyncAPIClient.is_closed is a method, not a property.
getattr(client, 'is_closed', False) returned the bound method object,
which is always truthy — causing _is_openai_client_closed() to report
all clients as closed and triggering unnecessary client recreation
(~100-200ms TCP+TLS overhead per API call).
Fix: check if is_closed is callable and call it, otherwise treat as bool.
Fixes#4377
Co-authored-by: Bartok9 <Bartok9@users.noreply.github.com>
MiniMax APIs (global and China) don't support /v1/models, causing
hermes doctor to always show HTTP 404 even with valid API keys.
Skip the HTTP check for these providers and show '(key configured)'
when the API key is present.
Cherry-picked from PR #822 by Bartok9, rebased onto current main.
Fixes#811
Co-authored-by: Bartok9 <259807879+Bartok9@users.noreply.github.com>
Fixes#160
The issue was that MEDIA tags were being extracted from ALL messages
in the conversation history, not just messages from the current turn.
This caused TTS voice messages generated in earlier turns to be
re-attached to every subsequent reply.
The fix:
- Track history_len before calling run_conversation
- Only scan messages AFTER history_len for MEDIA tags
- Add comprehensive tests to prevent regression
This ensures each voice message is sent exactly once, when it's
generated, not on every subsequent message in the session.