3.9 KiB
mimo-v2.5 — HTTP 400 « Param Incorrect » (text is not set) sur screenshots browser_vision
Date : 2026-07-09 · Instance : hermes-nyora · Tags : nyora, mimo, opencode, xiaomi, vision, browser_vision, 400
Symptôme
Depuis le 08/07 ~21:30, appels mimo-v2.5 en échec récurrent (3 sessions, 6 appels) :
WARNING agent.conversation_loop: API call failed (attempt 1/3)
error_type=BadRequestError provider=opencode-go model=mimo-v2.5
summary=HTTP 400: Error from provider (Xiaomi): Param Incorrect
Détail complet dans le log : 'param': 'text is not set'. Chaque échec déclenche un
fallback silencieux vers deepseek-v4-flash (la réponse arrive, mais pas par mimo).
deepseek ne présente jamais le problème sur la même stack.
Cause racine (reproduite par appel direct opencode.ai/zen/go/v1)
- mimo-v2.5 est vision-capable : les images dans les messages
user(photos Telegram) passent et sont bien décrites. Ce n'est PAS un problème d'image utilisateur, ni de tools, ni de streaming, ni dethinking. - Xiaomi rejette le contenu de type liste dans les messages
role: tool(multipart[{type:text},{type:image_url}], ce que produitbrowser_visionpour ses screenshots) → 400 « Param Incorrect », param`text` is not set. - hermes-agent connaît ce bug (issue upstream #27344) et a un recovery dédié
(
_try_strip_image_parts_from_tool_messages+ classifiermultimodal_tool_content_unsupported), mais le pattern du classifier est"text is not set"SANS backticks alors que l'API renvoie désormais`text`AVEC backticks → pattern raté → 400 générique → fallback.
Repro minimale (SDK openai, clé OPENCODE_GO_API_KEY du container) : un message
role:tool avec content liste contenant un part image → 400 systématique.
Le même contenu en message user → OK.
Fix appliqué (config-only, aucune modif d'image Docker)
Plugin utilisateur (mécanisme officiel $HERMES_HOME/plugins/model-providers/,
last-writer-wins sur les profils bundled) :
/volume1/docker/hermes-platform/hermes-nyora/data/plugins/model-providers/opencode-go-vision-fix/__init__.py
from providers import get_provider_profile
_profile = get_provider_profile("opencode-go")
if _profile is not None:
_profile.supports_vision_tool_messages = False
Effet : _tool_result_content_for_active_model convertit préemptivement les
résultats d'outils multimodaux en résumé texte (_multimodal_text_summary)
avant l'envoi à Xiaomi. La vision native des images user reste active.
Ownership 1026:100, puis docker restart hermes-agent-nyora.
Vérification (2026-07-09 ~07:00 UTC)
- Process frais :
supports_vision_tool_messages=False, cap max_tokens mimo-v2.5-pro conservé, tool result screenshot → str sans image_url. - E2E via api_server (port 8642, clé
API_SERVER_KEY) : scénario exact en échec la veille (navigation +browser_vision+ description) → réponse correcte, 3 appelsmodel=mimo-v2.5, zéro 400, zéro fallback.
Impact sur le comparatif mimo vs deepseek
Les stats du pilote (05→08/07) ne sont PAS faussées : zéro occurrence dans agent.log.1 (04/07→08/07 20:42) ; les 6 × 400 datent du 08/07 21:35–22:05, après le verdict, déclenchées par un nouveau pattern d'usage (sessions browser avec screenshots). Le « 1 erreur / 591 appels » de mimo tient. Nuance : les tours en 400 ont été servis par deepseek via fallback (3 tours, négligeable).
Pièges / à savoir
- Les
request_dump_*.jsonne sont écrits que surmax_retries_exhausted— un 400 récupéré par fallback ne laisse PAS de dump. Chercher dansdata/logs/agent.log(Param Incorrect,Fallback activated). - curl/urllib directs sur opencode.ai → 403 Cloudflare 1010 (User-Agent) ; utiliser le SDK openai du venv du container.
- À retirer si l'image upstream corrige le pattern du classifier (backticks) ou si Xiaomi accepte le contenu liste dans les messages tool.