Commit Graph
4 Commits
Author SHA1 Message Date
bruno b69cb9b0f8 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.
2026-09-15 09:26:31 -04:00
bruno f049e208b6 feat(ai): commandes @/ & skills, analyse d'images et capacites des modeles (#81)
CI / lint (push) Successful in 1m10s
CI / security (push) Successful in 43s
CI / test (push) Successful in 2m34s
CI / build (push) Successful in 43s
CI / e2e (push) Successful in 10m59s
2026-09-12 11:38:46 -04:00
bruno d441481930 fix(xiaomi): URL MiMo + header api-key + fallback polling admin SSE
CI / lint (push) Successful in 37s
CI / security (push) Successful in 32s
CI / test (push) Successful in 48s
CI / build (push) Successful in 22s
CI / e2e (push) Successful in 6m1s
Desktop Build / build-windows (push) Canceled after 0s
Desktop Build / build-linux (push) Canceled after 0s
1. **fix(xiaomi): la clé Xiaomi échouait avec 'Name or service not known'**
   - URL précédente api.xiaomi.com n'existe pas (DNS fail)
   - Vraie URL: https://api.xiaomimimo.com/v1/models
   - Xiaomi MiMo utilise un header custom 'api-key:' (PAS 'Authorization: Bearer')
   - Modèles par défaut mis à jour: mimo-v2.5-pro, mimo-v2.5, mimo-v2.5-asr, etc.
   - Le chat dans ai.py supporte maintenant un header custom via auth_header_name

2. **fix(admin): EventSource 503 → fallback polling**
   - Ajout d'un fallback: si EventSource ne reçoit jamais le premier event
     (cookie expiré, réseau bloqué, proxy timeout), on bascule sur du polling
     /api/admin/stats toutes les 5s. Le UI continue de se mettre à jour.
   - Cleanup correct du timer dans disconnectSSE

3. **fix(test_ai_models)**: 2 nouveaux tests de régression
   - test_xiaomi_uses_api_key_header_not_bearer: vérifie URL + header
   - test_xiaomi_test_endpoint_uses_real_url: vérifie /api/config/ai-keys/test
   - Patche backend.ai ET backend.main (import local)
   - Header case-insensitive (urllib normalise à 'Api-key', HTTP est insensible)

Vérifié :
- pytest : 504 passed (502 + 2 nouveaux Xiaomi)
- frontend unit : 7 passed
- validate-imports : 30 modules / 204 exports
- pane-manager JSDOM : 9/9
- ruff check backend/ : All checks passed
2026-09-07 12:47:24 -04:00
bruno 7ff9b854b6 fix(admin,ai): redirect admin.html + modèles fallback + picker provider/modèle par requête
CI / lint (push) Successful in 41s
CI / security (push) Successful in 28s
CI / test (push) Successful in 48s
CI / build (push) Successful in 22s
CI / e2e (push) Successful in 6m5s
Desktop Build / build-windows (push) Canceled after 0s
Desktop Build / build-linux (push) Canceled after 0s
Trois bugs corrigés + une amélioration demandée :

1. **fix(admin): /admin.html redirigeait toujours vers /**
   - admin.js _gateAdmin() lisait /api/auth/status qui ne contient PAS le rôle user
   - Remplacé par /api/auth/me (retourne username, role, vaults)
   - Le code distingue maintenant le cas 'auth désactivé' (admin anonyme) du
     cas 'auth requise non admin' (affiche écran forbidden)

2. **fix(ai): les modèles Nvidia/Xiaomi ne se chargeaient pas dans les dropdowns**
   - Xiaomi : l'endpoint public /v1/models est instable, échec réseau fréquent
   - Toutes les erreurs réseau/d'API renvoyaient models=[] → dropdown vide
   - Ajout d'un fallback curé : _FALLBACK_MODELS dict avec 4-8 modèles populaires
     par provider, TOUJOURS retourné si la clé manque OU si l'API distante échoue
   - Le frontend voit désormais 'fallback' vs 'live' comme hint pour l'utilisateur
   - Gemini parsing : strip du préfixe 'models/' retourné par l'API Gemini
   - 7 nouveaux tests pytest pour _FALLBACK_MODELS + endpoint /api/config/ai-models

3. **feat(ai): picker provider/model dans la toolbar AI + BooksLM**
   - Plusieurs providers peuvent maintenant être activés simultanément
   - Sélection provider+model par section (Forge, BooksLM, etc.) via dropdown
   - État persisté en localStorage (le choix suit l'utilisateur entre sections)
   - Chaque appel AI passe maintenant {provider, model} au backend
   - ai.js : aiAction() lit le picker et l'injecte dans le body
   - bookslm.js : envoie provider+model à /api/ai/bookslm/chat
   - ai_routes.py + bookslm_routes.py : AIRequest et BooksLMChatRequest
     acceptent provider+model, avec save/restore du modèle original
     pour ne pas affecter les autres requêtes concurrentes
   - 7 nouvelles clés i18n (ai.provider, ai.model, ai.model_loading, etc.)
   - 1 nouveau test bookslm vérifie que le schema accepte provider+model
   - validate-imports.mjs : fix faux positif sur 'export { X as Y }'

Vérifié :
- pytest : 502 passed, 5 skipped (494 baseline + 7 AI models + 1 BooksLM)
- frontend unit : 7 passed
- validate-imports : 30 modules / 204 exports / 0 erreur
- pane-manager JSDOM : 9/9
- ruff check backend/ : All checks passed
2026-09-07 12:00:05 -04:00