feat: catalogue dynamique modèles Codex/Claude avec compatibilité CLI locale

Ajout du catalogue enrichi pour les modèles Codex et Claude avec:
- Compatibilité estimée avec la version CLI locale détectée
- Source d'origine (catalogue/Provider) pour chaque entrée
- Support du catalogue Provider API externe
- Matrice de compatibilité embarquée dans l'application

Frontend:
- UI de configuration des modèles avec affichage des états de compatibilité
- Suggestions dynamiques avec badges de compatibilité
- Messages d'aide contextuels (compatible/unknown/likelyTooRecent)
- Alertes non-bloquantes pour les modèles trop récents
- Gestion des échecs de catalogue avec saisie manuelle conservée

Backend:
- Ports CliVersionReader, ProviderModelCatalogue, CompatibilityMatrixSource
- Implémentations: ProcessCliVersionReader, HttpProviderModelCatalogue, EmbeddedCompatibilityMatrix
- Enrichissement des DTOs avec compatibility, cli_version, warnings
- Tests unitaires complets pour le resolver de catalogue
This commit is contained in:
2026-07-26 16:09:10 +02:00
parent e7bf1d3666
commit ca70ec75f4
25 changed files with 1582 additions and 167 deletions

View File

@ -45,6 +45,7 @@ use crate::issue::{
use crate::markdown::MarkdownDoc;
use crate::mcp_tool_permissions::ProjectMcpToolPermissions;
use crate::memory::{Memory, MemoryIndexEntry, MemoryLink, MemorySlug};
use crate::model_catalogue::{CliVersion, CompatibilityMatrix};
use crate::model_server::{
HfModelRef, LocalModelServerConfig, ModelPath, ModelServerEndpoint, ModelServerStatus,
};
@ -54,7 +55,7 @@ use crate::plugin::{
PluginMcpStatusSet, PluginPackageRef, PluginRegistry, RelativePath, RemovalOutcome,
StagedPluginPackage,
};
use crate::profile::{AgentProfile, EmbedderProfile};
use crate::profile::{AgentProfile, EmbedderProfile, StructuredAdapter};
use crate::project::{Project, ProjectPath};
use crate::remote::RemoteKind;
use crate::skill::{Skill, SkillScope};
@ -1245,6 +1246,37 @@ pub trait ProcessSpawner: Send + Sync {
async fn run(&self, spec: SpawnSpec) -> Result<Output, ProcessError>;
}
/// Read a local structured CLI version using only the allowed `--version` probe.
#[async_trait]
pub trait CliVersionReader: Send + Sync {
/// Best-effort local CLI version lookup.
///
/// # Errors
/// Returns a string suitable for non-blocking catalogue warnings.
async fn read_cli_version(
&self,
adapter: StructuredAdapter,
) -> Result<Option<CliVersion>, String>;
}
/// Best-effort provider API model catalogue.
#[async_trait]
pub trait ProviderModelCatalogue: Send + Sync {
/// Lists provider model ids for an adapter. `Ok(Vec::new())` means no key or
/// unsupported provider and is not a warning-worthy failure.
///
/// # Errors
/// Returns a string suitable for non-blocking catalogue warnings.
async fn list_provider_models(&self, adapter: StructuredAdapter)
-> Result<Vec<String>, String>;
}
/// Source of the versioned compatibility matrix.
pub trait CompatibilityMatrixSource: Send + Sync {
/// Returns matrix data and any fallback warnings.
fn compatibility_matrix(&self) -> (CompatibilityMatrix, Vec<String>);
}
/// Probe readiness of an OpenAI-compatible model server.
#[async_trait]
pub trait ModelServerProbe: Send + Sync {