fix(ai): BUG-044 capacités des modèles lues chez le fournisseur (Mistral vision)
CI / lint (push) Successful in 1m20s
CI / security (push) Successful in 53s
CI / test (push) Successful in 2m27s
CI / build (push) Successful in 50s
CI / e2e (push) Successful in 10m48s

Le panneau de modèle par défaut et la bulle ⓘ n'affichaient aucun modèle Mistral
« Vision capable » alors que GET api.mistral.ai/v1/models en déclare 28 : la table
de capacités était entièrement statique et aucun de ses motifs ne correspondait aux
familles Mistral actuelles (seul `pixtral`, retiré de l'API, les matchait).

- backend/provider_capabilities.py (nouveau) : capacités déclarées par le
  fournisseur (Mistral `capabilities`, OpenRouter `architecture`), détectées par
  la forme du payload, snapshot en cache process-wide (TTL 30 min, surchargeable
  par AI_CAPABILITIES_TTL_SECONDS) rempli par GET /api/config/ai-models.
- backend/model_capabilities.py : une déclaration prime sur la table statique
  pour chaque drapeau mentionné ; la table ne comble que le reste (Mistral ne
  déclare jamais `embedding`). Table corrigée pour le repli hors ligne : familles
  vision Mistral (ministral, magistral, mistral-small, mistral-medium,
  mistral-vibe-cli, labs-leanstral), mistral-ocr = vision sans chat, et défaut du
  fournisseur Mistral sans `embeddings` (mistral-large / codestral n'étaient plus
  des « embedders »).
- backend/ai_routes.py : GET /api/ai/model-capabilities reste sans appel réseau
  (cache froid → table statique).
- Tests : tests/test_provider_capabilities.py (nouveau), TestMistralFamilies et
  TestDeclaredCapabilities (bout en bout via l'API).
- Docs : CHANGELOG [Unreleased], registre + journal ISSUES_TODOLIST,
  fiche docs/features/ai-provider-picker.md (§L).

Vérifié : 28/28 modèles vision déclarés par Mistral détectés (0 avant), 0 écart
dans les deux sens ; pytest 1007 passed / 6 skipped ; ruff 0 (backend) ; mypy 0 ;
tests frontend unit 9/9 + IA 66/66 + validate-imports 37 modules ; instance de test
reconstruite et vérifiée sur http://localhost:2020.
This commit is contained in:
2026-09-15 09:26:31 -04:00
parent 140a8f6efe
commit b69cb9b0f8
10 changed files with 723 additions and 23 deletions
+18
View File
@@ -77,6 +77,24 @@ et [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
configuré, donc le **premier** fournisseur ajouté s'y monte aussi. Une
sélection dont le fournisseur n'est plus configuré est purgée de
`obsigate_ai_picker` (retour au défaut au lieu d'un modèle fantôme).
- **BUG-044 — Capacités des modèles erronées (aucun modèle Mistral vision)** : la
bulle ⓘ et le sélecteur de modèle par défaut n'affichaient **aucun** modèle Mistral
« Vision capable », alors que `GET https://api.mistral.ai/v1/models` en déclare 28
(`mistral-medium`, `mistral-small`, `ministral-*`, `magistral-*`, `mistral-ocr-*`,
`mistral-vibe-cli-*`). Cause : la table de capacités était **entièrement statique** et
aucun de ses motifs ne correspondait aux familles Mistral actuelles (seul `pixtral`,
retiré de l'API, les matchait). ObsiGate lit désormais les capacités **déclarées par le
fournisseur** (nouveau `backend/provider_capabilities.py`, snapshot mis en cache par
`GET /api/config/ai-models`) : Mistral (`capabilities.completion_chat` / `vision` /
`audio_transcription` / `audio_speech`) et OpenRouter (`architecture.input_modalities` /
`output_modalities`) sont pris en charge ; la table statique ne sert plus qu'à combler
les drapeaux non déclarés et de repli hors ligne. La table est également corrigée
(familles vision Mistral, `mistral-ocr` = vision sans chat) et le défaut du fournisseur
Mistral ne prétend plus qu'un modèle non reconnu sait produire des embeddings
(BUG-044bis : `mistral-large-latest` / `codestral-latest` étaient annoncés
« Embeddings »). Conséquence : la porte vision de l'assistant
(`frontend/js/bookslm.js`, `backend/bookslm_routes.py`) accepte enfin les images avec un
modèle Mistral vision.
### Sécurité