Plugin opencode / OpenChamber : donne la vision aux modèles sans capacité image (ex: deepseek-v4-flash).
Quand on colle une image dans OpenChamber, opencode la stocke en base64 dans sa base SQLite (~/.local/share/opencode/opencode.db, table part) — aucun fichier sur disque. Un modèle sans vision comme DS Flash reçoit la part image mais n'a pas de chemin à passer à un outil vision → il répond « donne-moi le chemin du fichier ».
Le plugin intercepte le message (hook chat.message), écrit l'image dans /tmp/opencode-vision/, retire la part image et injecte une part texte :
[Image collée "image-1.png" sauvegardée sur disque : /tmp/opencode-vision/ses_xxx-1.png.
Pour voir cette image, utilise l'outil analyze_image du MCP opencode-vision avec path="...".]
L'agent DS Flash appelle alors automatiquement analyze_image → le MCP opencode-vision route l'image vers un backend vision externe (Gemini 2.5 Flash free tier par défaut) → renvoie une description texte → le modèle principal peut « voir » sans changer de modèle.
# 1. Copier le plugin (auto-chargé par opencode)
cp vision-attachments.plugin.js /root/.config/opencode/plugins/
# 2. Installer le MCP vision (voir MCP section)
# 3. Restart OpenChamber + nouvelle session
systemctl restart openchambersystemctl restart openchamber + nouvelle session.
- Muter, pas réassigner : opencode passe
output.partspar référence et continue d'utiliser sa variable localefeAPRÈS le hook.output.parts = newArray= l'ancien tableau part au LLM (la note n'arrive jamais, le log du plugin ment). Fix :output.parts.splice(0, output.parts.length, ...newParts). - Hériter de l'identité de la part remplacée : une note sans
id/messageID/sessionIDest rejetée par la validation opencode (« Unexpected server error »). Copier les champs de la part image d'origine. - Ne jamais throw dans le hook : try/catch + log dans
/tmp/opencode-vision-plugin.log. - Le SDK ne valide pas le hook :
session.promptavec part image retourneBadRequestmême quand le hook fonctionne (validation des capacités du modèle AVANT le hook). Valider dans l'UI (coller une image en nouvelle session), pas par SDK.
Le plugin seul ne suffit pas — il faut le MCP opencode-vision (backend vision externe) :
- Projet : vision-for-opencode (ou équivalent)
- Installé dans :
/opt/vision-for-opencode/, MCP déclaré dans/root/.config/opencode/opencode.json:{ "mcp": { "opencode-vision": { "type": "local", "command": ["python3", "-u", "/opt/vision-for-opencode/vision_mcp_server.py"], "enabled": true } } } - Clé API :
GEMINI_API_KEY(env >config.json) — Google AI Studio, free tier - Timeouts à ajuster :
PER_CALL_TIMEOUT=30,TOTAL_TIMEOUT=90,FAST_TIMEOUT=20dansvision_proxy.py(le défaut 4s tue Gemini sur les grosses images → faux « HTTP 404 »)
| Fichier | Rôle |
|---|---|
vision-attachments.plugin.js |
Le plugin (version production, logs activés) |
README.md |
Ce fichier |
MIT