@page "/models" @attribute [Authorize] @inject IOllamaService OllamaService @inject NavigationManager Navigation @inject ILocalizationService Loc @Loc["page.title.models"]

@Loc["models.heading"]

@if (isLoading) {

@Loc["models.status.loading"]

} else if (!string.IsNullOrEmpty(errorMessage)) {
@errorMessage
} else {
@foreach (var model in localModels) {
@model.Name
@Loc["models.label.size"] @FormatSize(model.Size) | @Loc["models.label.modified"] @model.ModifiedAt?.ToString("g")
}
}

@Loc["models.pull.heading"]

@if (isPulling) {
@pullStatus (@pullPercentDisplay)
}
@if (pullResult != null) {
@pullResult
} @code { private List localModels = new(); private bool isLoading; private string? errorMessage; private string modelToPull = string.Empty; private bool isPulling; private double pullProgress; private string pullStatus = string.Empty; private string? pullResult; private string pullPercentDisplay => $"{pullProgress:F0}%"; protected override async Task OnInitializedAsync() { await RefreshModels(); } private async Task RefreshModels() { isLoading = true; errorMessage = null; try { var models = await OllamaService.GetLocalModelsAsync(); localModels = models.ToList(); } catch (Exception ex) { errorMessage = $"{Loc["models.error.loading"]} {ex.Message}"; localModels = new(); } finally { isLoading = false; } } private async Task PullModel() { if (string.IsNullOrWhiteSpace(modelToPull)) return; isPulling = true; pullProgress = 0; pullStatus = Loc["models.pull.status.starting"]; pullResult = null; try { var progress = new Progress(status => { pullStatus = status; InvokeAsync(StateHasChanged); }); await OllamaService.PullModelAsync(modelToPull, progress); pullResult = $"{Loc["models.pull.status.model"]} '{modelToPull}' {Loc["models.pull.status.success"]}"; modelToPull = string.Empty; await RefreshModels(); } catch (Exception ex) { pullResult = $"{Loc["common.error"]} {ex.Message}"; } finally { isPulling = false; } } private static string FormatSize(long? bytes) { if (!bytes.HasValue) return "---"; if (bytes < 1024 * 1024) return $"{bytes / 1024.0:F1} KB"; if (bytes < 1024 * 1024 * 1024) return $"{bytes / (1024.0 * 1024):F1} MB"; return $"{bytes / (1024.0 * 1024 * 1024):F1} GB"; } }