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:
@ -22,6 +22,7 @@
|
||||
//! Each port is **fine-grained** (Interface Segregation): `FileSystem`,
|
||||
//! `PtyPort`, `ProcessSpawner` are separate, never a `System` god-trait.
|
||||
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::Arc;
|
||||
|
||||
use async_trait::async_trait;
|
||||
@ -42,7 +43,9 @@ use crate::issue::{
|
||||
};
|
||||
use crate::markdown::MarkdownDoc;
|
||||
use crate::memory::{Memory, MemoryIndexEntry, MemoryLink, MemorySlug};
|
||||
use crate::model_server::{LocalModelServerConfig, ModelServerEndpoint, ModelServerStatus};
|
||||
use crate::model_server::{
|
||||
HfModelRef, LocalModelServerConfig, ModelPath, ModelServerEndpoint, ModelServerStatus,
|
||||
};
|
||||
use crate::permission::ProjectPermissions;
|
||||
use crate::profile::{AgentProfile, EmbedderProfile};
|
||||
use crate::project::{Project, ProjectPath};
|
||||
@ -582,6 +585,9 @@ pub enum ModelServerError {
|
||||
/// Store operation failed.
|
||||
#[error("store failed: {0}")]
|
||||
Store(String),
|
||||
/// Operation was cancelled by the caller.
|
||||
#[error("cancelled")]
|
||||
Cancelled,
|
||||
/// Readiness timed out.
|
||||
#[error("readiness timed out")]
|
||||
Timeout,
|
||||
@ -1013,6 +1019,66 @@ pub trait ModelServerProbe: Send + Sync {
|
||||
) -> Result<ModelServerStatus, ModelServerError>;
|
||||
}
|
||||
|
||||
/// Progress observed while resolving/downloading a model artifact.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct ModelArtifactProgress {
|
||||
/// Downloaded bytes when known.
|
||||
pub downloaded_bytes: Option<u64>,
|
||||
/// Total bytes when known.
|
||||
pub total_bytes: Option<u64>,
|
||||
/// Source being resolved, usually the Hugging Face repo reference.
|
||||
pub source: Option<String>,
|
||||
}
|
||||
|
||||
/// Resolved local model artifact.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct ModelArtifactResolution {
|
||||
/// Absolute local path to the resolved `.gguf` file.
|
||||
pub path: ModelPath,
|
||||
/// `true` when the artifact was already available in cache.
|
||||
pub cache_hit: bool,
|
||||
}
|
||||
|
||||
/// Cooperative cancellation token for model artifact resolution.
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct ModelArtifactCancel {
|
||||
cancelled: Arc<AtomicBool>,
|
||||
}
|
||||
|
||||
impl ModelArtifactCancel {
|
||||
/// Creates a non-cancelled token.
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Requests cancellation.
|
||||
pub fn cancel(&self) {
|
||||
self.cancelled.store(true, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
/// Returns whether cancellation was requested.
|
||||
#[must_use]
|
||||
pub fn is_cancelled(&self) -> bool {
|
||||
self.cancelled.load(Ordering::SeqCst)
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolves or downloads a model artifact before starting a model server.
|
||||
#[async_trait]
|
||||
pub trait ModelArtifactDownloader: Send + Sync {
|
||||
/// Resolves a Hugging Face model to a local artifact path.
|
||||
///
|
||||
/// # Errors
|
||||
/// [`ModelServerError`] when resolution/download fails or is cancelled.
|
||||
async fn resolve_hf_model(
|
||||
&self,
|
||||
repo: &HfModelRef,
|
||||
progress: Arc<dyn Fn(ModelArtifactProgress) + Send + Sync>,
|
||||
cancel: ModelArtifactCancel,
|
||||
) -> Result<ModelArtifactResolution, ModelServerError>;
|
||||
}
|
||||
|
||||
/// Manages local long-lived child processes.
|
||||
#[async_trait]
|
||||
pub trait ManagedProcess: Send + Sync {
|
||||
|
||||
Reference in New Issue
Block a user