diff --git a/hermes-nyora/mimo-400-param-incorrect-vision-tool-messages.md b/hermes-nyora/mimo-400-param-incorrect-vision-tool-messages.md new file mode 100644 index 0000000..c0aed63 --- /dev/null +++ b/hermes-nyora/mimo-400-param-incorrect-vision-tool-messages.md @@ -0,0 +1,70 @@ +# 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) +1. **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 de `thinking`. +2. **Xiaomi rejette le contenu de type liste dans les messages `role: tool`** + (multipart `[{type:text},{type:image_url}]`, ce que produit `browser_vision` + pour ses screenshots) → 400 « Param Incorrect », param `` `text` is not set ``. +3. hermes-agent connaît ce bug (issue upstream #27344) et a un recovery dédié + (`_try_strip_image_parts_from_tool_messages` + classifier + `multimodal_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` +```python +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 appels `model=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_*.json` ne sont écrits que sur `max_retries_exhausted` — + un 400 récupéré par fallback ne laisse PAS de dump. Chercher dans + `data/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.