Author SHA1 Message Date
billisdead 4e9f9c831c Merge pull request 'Fetch GitHub Models catalog with httpx and documented headers' (#5) from fix/github-catalog-httpx into main 2026-10-12 14:52:41 +02:00
billisdeadandClaude Sonnet 5.5 5679940fa7 Fetch GitHub Models catalog with httpx and documented headers
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 14:52:25 +02:00
billisdead 51d91b91c4 Merge pull request 'Parse GitHub Models catalog response defensively' (#4) from fix/github-catalog-parsing into main 2026-10-12 14:50:55 +02:00
billisdeadandClaude Sonnet 5.5 9368f64a9b Parse GitHub Models catalog response defensively
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 14:50:17 +02:00
billisdead c53330c3bd Merge pull request 'Fix model list for GitHub Models via its catalog endpoint' (#3) from fix/github-models-catalog into main 2026-10-12 14:48:28 +02:00
billisdead 80ee96444e Merge pull request 'Ignore local GitHub token file' (#2) from chore/ignore-github-token into main 2026-10-12 14:48:25 +02:00
billisdeadandClaude Sonnet 5.5 5721a0a36f Fix model list for GitHub Models via its catalog endpoint
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 14:47:08 +02:00
billisdeadandClaude Sonnet 5.5 f749cba306 Ignore local GitHub token file
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 14:46:30 +02:00
billisdead bdd7a9f7bf Merge pull request 'Add admin AI models panel' (#1) from feat/admin-ai-models into main 2026-10-12 09:56:03 +02:00
3 changed files with 31 additions and 2 deletions

No files matched your search

+3
View File
@@ -56,3 +56,6 @@ SECURITY_REVIEW.md
Thumbs.db Thumbs.db
*.sass-cache *.sass-cache
coverage/ coverage/
# Secrets locaux
.github-token.txt
+26
View File
@@ -8,6 +8,7 @@ Supporte Mistral AI (par défaut) et tout fournisseur compatible OpenAI.
import json import json
import os import os
import logging import logging
import httpx
from openai import OpenAI, BadRequestError from openai import OpenAI, BadRequestError
from legal_framework import LEGAL_FILTER_PROMPT, SYNTHESIS_PROMPT, LAW_CHECK_PROMPT, build_filter_prompt from legal_framework import LEGAL_FILTER_PROMPT, SYNTHESIS_PROMPT, LAW_CHECK_PROMPT, build_filter_prompt
from legifrance_client import get_legifrance_client from legifrance_client import get_legifrance_client
@@ -77,6 +78,31 @@ def get_client() -> OpenAI:
return _client return _client
GITHUB_CATALOG_URL = "https://models.github.ai/catalog/models"
def list_model_ids() -> list[str]:
"""Modèles accessibles avec la clé en place (GitHub Models : catalogue dédié, /models n'est pas OpenAI-compatible)."""
client = get_client()
if "models.github.ai" in str(client.base_url):
r = httpx.get(
GITHUB_CATALOG_URL,
headers={
"Authorization": f"Bearer {client.api_key}",
"Accept": "application/vnd.github+json",
"X-GitHub-Api-Version": "2022-11-28",
},
timeout=10,
)
if r.status_code != 200 or not r.content:
raise RuntimeError(f"catalogue GitHub HTTP {r.status_code} : {r.text[:120]!r}")
raw = r.json()
if isinstance(raw, dict):
raw = next((v for v in raw.values() if isinstance(v, list)), [])
return sorted(m["id"] if isinstance(m, dict) else str(m) for m in raw)
return sorted(m.id for m in client.models.list().data)
def filter_idea(content: str) -> dict: def filter_idea(content: str) -> dict:
""" """
Filtre une idée selon le cadre légal international des droits humains Filtre une idée selon le cadre légal international des droits humains
+2 -2
View File
@@ -60,7 +60,7 @@ from database import (
check_ip_blacklist, record_ip_rejection, get_ip_blacklist, remove_ip_blacklist, check_ip_blacklist, record_ip_rejection, get_ip_blacklist, remove_ip_blacklist,
set_setting, set_setting,
) )
from ai_agent import filter_idea, synthesize_ideas, check_existing_law, get_client, get_model from ai_agent import filter_idea, synthesize_ideas, check_existing_law, get_client, get_model, list_model_ids
# ─── Logging ──────────────────────────────────────────────────────────────── # ─── Logging ────────────────────────────────────────────────────────────────
@@ -1297,7 +1297,7 @@ def admin_ai_models():
"""Modèles actuellement actifs + liste de ceux accessibles avec la clé en place.""" """Modèles actuellement actifs + liste de ceux accessibles avec la clé en place."""
out = {"filter": get_model("filter"), "synthesis": get_model("synthesis"), "available": [], "error": None} out = {"filter": get_model("filter"), "synthesis": get_model("synthesis"), "available": [], "error": None}
try: try:
out["available"] = sorted(m.id for m in get_client().models.list().data) out["available"] = list_model_ids()
except Exception as e: except Exception as e:
logger.warning("Admin — liste des modèles IA impossible : %s", type(e).__name__) logger.warning("Admin — liste des modèles IA impossible : %s", type(e).__name__)
out["error"] = f"{type(e).__name__}: {str(e)[:200]}" out["error"] = f"{type(e).__name__}: {str(e)[:200]}"