feat(model-server): progression fine du téléchargement du modèle llamacpp (#54)

Stretch B2/F2 de #54, par-dessus le MVP déjà mergé (B1/F1).

Backend : le port de téléchargement HF publie une progression débouncée
(bytes reçus / total, pourcentage) via le stream de statut du serveur
modèle, avec gestion du total inconnu (pas de faux %), du cache hit,
de l'annulation et du timeout.

Frontend : l'overlay plein-cellule de préparation du serveur affiche la
progression réelle (barre, %, octets, source) en mappant le fil de
statut, avec la règle « pas de faux % » quand le total est inconnu.

Tests : application + infrastructure (téléchargement débouncé, cancel,
timeout, cache hit, total inconnu) et vitest (overlay + formatage pur).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 10:37:14 +02:00
parent bd335c3a1c
commit 2183dfd291
15 changed files with 1368 additions and 87 deletions

View File

@ -74,10 +74,10 @@ use infrastructure::{
FsEmbedderPromptStore, FsHandoffStore, FsIssueNumberAllocator, FsIssueStore, FsLiveStateStore,
FsMemoryStore, FsModelServerRegistry, FsOrchestratorWatcher, FsPermissionStore, FsProfileStore,
FsProjectStore, FsProviderSessionStore, FsSkillStore, FsSprintStore, FsTemplateStore,
FsWindowStateStore, Git2Repository, HeuristicHandoffSummarizer, HttpOpenAiCompatibleProbe,
IdeaiContextStore, InMemoryConversationRegistry, InMemoryMailbox, LlamaCppRuntime,
LocalFileSystem, LocalManagedProcess, LocalProcessSpawner, McpServer, MediatedInbox,
NaiveMemoryRecall, OrchestratorWatchHandle, PortablePtyAdapter, RwFileGuard,
FsWindowStateStore, Git2Repository, HeuristicHandoffSummarizer, HfModelArtifactDownloader,
HttpOpenAiCompatibleProbe, IdeaiContextStore, InMemoryConversationRegistry, InMemoryMailbox,
LlamaCppRuntime, LocalFileSystem, LocalManagedProcess, LocalProcessSpawner, McpServer,
MediatedInbox, NaiveMemoryRecall, OrchestratorWatchHandle, PortablePtyAdapter, RwFileGuard,
StructuredSessionFactory, SystemClock, SystemMillisClock, TicketAssistantEnvironmentPreparer,
TicketToolProvider, TokioBroadcastEventBus, TokioScheduler, ToolPolicyRegistry, UuidGenerator,
VectorMemoryRecall, DEFAULT_OLLAMA_BASE_URL, ONNX_CACHE_SUBDIR, RECOMMENDED_ONNX_MODELS,
@ -1234,15 +1234,23 @@ impl AppState {
Arc::clone(&fs_port),
app_data_dir.to_string_lossy().into_owned(),
));
let ensure_local_model_server = Arc::new(EnsureLocalModelServer::new(
Arc::clone(&model_server_registry) as Arc<dyn domain::ports::ModelServerRegistry>,
Arc::new(HttpOpenAiCompatibleProbe::default())
as Arc<dyn domain::ports::ModelServerProbe>,
Arc::new(LocalManagedProcess::new()) as Arc<dyn domain::ports::ManagedProcess>,
Arc::new(LlamaCppRuntime::new()) as Arc<dyn domain::ports::ModelServerRuntime>,
Arc::clone(&fs_port),
Arc::clone(&events_port),
let model_artifact_downloader = Arc::new(HfModelArtifactDownloader::new(
app_data_dir.join("hf-model-artifacts"),
));
let ensure_local_model_server = Arc::new(
EnsureLocalModelServer::new(
Arc::clone(&model_server_registry) as Arc<dyn domain::ports::ModelServerRegistry>,
Arc::new(HttpOpenAiCompatibleProbe::default())
as Arc<dyn domain::ports::ModelServerProbe>,
Arc::new(LocalManagedProcess::new()) as Arc<dyn domain::ports::ManagedProcess>,
Arc::new(LlamaCppRuntime::new()) as Arc<dyn domain::ports::ModelServerRuntime>,
Arc::clone(&fs_port),
Arc::clone(&events_port),
)
.with_model_artifact_downloader(
model_artifact_downloader as Arc<dyn domain::ports::ModelArtifactDownloader>,
),
);
let model_server_registry_port =
Arc::clone(&model_server_registry) as Arc<dyn domain::ports::ModelServerRegistry>;
let list_model_servers = Arc::new(ListModelServers::new(Arc::clone(