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:
@ -7,9 +7,14 @@ use domain::model_server::{
|
||||
ExecutablePath, HfModelRef, LlamaCppOptions, LocalModelRef, LocalModelServerConfig,
|
||||
LocalModelServerKind, ModelPath, ModelServerEndpoint, ModelSource, StopPolicy,
|
||||
};
|
||||
use domain::ports::{FileSystem, ModelServerRegistry, ModelServerRuntime, RemotePath};
|
||||
use domain::ports::{
|
||||
FileSystem, ModelArtifactCancel, ModelArtifactDownloader, ModelServerRegistry,
|
||||
ModelServerRuntime, RemotePath,
|
||||
};
|
||||
use domain::LocalModelServerId;
|
||||
use infrastructure::{FsModelServerRegistry, LlamaCppRuntime, LocalFileSystem};
|
||||
use infrastructure::{
|
||||
FsModelServerRegistry, HfModelArtifactDownloader, LlamaCppRuntime, LocalFileSystem,
|
||||
};
|
||||
use uuid::Uuid;
|
||||
|
||||
struct TempDir(PathBuf);
|
||||
@ -28,6 +33,10 @@ impl TempDir {
|
||||
fn child(&self, name: &str) -> RemotePath {
|
||||
RemotePath::new(self.0.join(name).to_string_lossy().into_owned())
|
||||
}
|
||||
|
||||
fn path(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TempDir {
|
||||
@ -189,3 +198,29 @@ async fn fs_model_server_registry_migrates_v1_json_to_v2() {
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn hf_model_artifact_downloader_resolves_deterministic_local_cache_hit_without_network() {
|
||||
let tmp = TempDir::new();
|
||||
let downloader = HfModelArtifactDownloader::new(tmp.path());
|
||||
let repo = HfModelRef::new("Qwen/Qwen3-Coder:Q4_K_M").unwrap();
|
||||
let path = downloader.cache_path_for(&repo);
|
||||
std::fs::create_dir_all(path.parent().unwrap()).unwrap();
|
||||
std::fs::write(&path, b"gguf").unwrap();
|
||||
|
||||
let resolution = downloader
|
||||
.resolve_hf_model(
|
||||
&repo,
|
||||
Arc::new(|_| panic!("cache hit must not report progress")),
|
||||
ModelArtifactCancel::new(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert!(resolution.cache_hit);
|
||||
assert_eq!(resolution.path.as_str(), path.to_string_lossy());
|
||||
assert_eq!(
|
||||
path.strip_prefix(tmp.path()).unwrap(),
|
||||
std::path::Path::new("Qwen--Qwen3-Coder").join("Q4_K_M.gguf")
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user