diff --git a/core/pom.xml b/core/pom.xml index f1dd913..dbcc5b6 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -14,7 +14,7 @@ com.loremind loremind-core - 0.6.11 + 0.6.12 LoreMind Core Backend Core - Architecture Hexagonale diff --git a/core/src/main/resources/application.properties b/core/src/main/resources/application.properties index 951a7fe..357eeae 100644 --- a/core/src/main/resources/application.properties +++ b/core/src/main/resources/application.properties @@ -5,6 +5,12 @@ server.port=8080 # de WebFlux (utilisé uniquement pour WebClient côté adapter SSE vers le Brain). spring.main.web-application-type=servlet +# Pas de timeout sur les requetes async (StreamingResponseBody, SSE). +# Le defaut Tomcat coupe a 30s, ce qui interrompt le streaming d'un pull +# de modele Ollama (peut durer des dizaines de minutes pour un GGUF de 10+ Go). +# -1 = pas de timeout, on s'appuie sur la fermeture cote client ou cote upstream. +spring.mvc.async.request-timeout=-1 + # Configuration de la base de donnees PostgreSQL # Valeurs surchargeables via variables d'env (cf. docker-compose.yml). # En dev local, creez un fichier .env a la racine de core/ OU definissez les diff --git a/installers/install.ps1 b/installers/install.ps1 index 45e5df3..dd19366 100644 --- a/installers/install.ps1 +++ b/installers/install.ps1 @@ -40,7 +40,7 @@ Auteur : ietm64 Licence : AGPL-3.0 Projet : LoreMindMJ - assistant pour Maitres de Jeu de JDR - Version : 0.6.11 + Version : 0.6.12 .LINK https://git.igmlcreation.fr/ietm64/loremind diff --git a/web/package-lock.json b/web/package-lock.json index 39cdfc3..cb6e246 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -1,12 +1,12 @@ { "name": "loremind-web", - "version": "0.6.11", + "version": "0.6.12", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "loremind-web", - "version": "0.6.11", + "version": "0.6.12", "dependencies": { "@angular/animations": "^17.0.0", "@angular/common": "^17.0.0", diff --git a/web/package.json b/web/package.json index 01f18fd..79d0687 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "loremind-web", - "version": "0.6.11", + "version": "0.6.12", "description": "LoreMind Frontend - Angular", "scripts": { "ng": "ng", diff --git a/web/src/app/settings/settings.component.ts b/web/src/app/settings/settings.component.ts index fd5384c..df1635c 100644 --- a/web/src/app/settings/settings.component.ts +++ b/web/src/app/settings/settings.component.ts @@ -59,6 +59,10 @@ export class SettingsComponent implements OnInit { pullTotal = 0; /** Souscription au flux de pull pour pouvoir l'annuler. */ private pullSubscription: Subscription | null = null; + /** True si on a recu un evenement {status:"success"} d'Ollama. Sans ca, + * une fermeture de stream (timeout proxy, perte reseau) ne doit PAS etre + * interpretee comme une reussite. */ + private pullSucceeded = false; /** Modele en cours de suppression (nom) pour disabler son bouton. */ deletingModel: string | null = null; @@ -293,6 +297,9 @@ export class SettingsComponent implements OnInit { if (event.status) this.pullStatus = event.status; if (event.completed != null) this.pullCompleted = event.completed; if (event.total != null) this.pullTotal = event.total; + // Marqueur explicite : Ollama emet "success" en derniere ligne quand + // le pull est reellement complet (manifest + layers + verify). + if (event.status === 'success') this.pullSucceeded = true; }, error: (err) => { this.errorMessage = this.extractError(err, `Echec du telechargement de ${name}.`); @@ -300,6 +307,14 @@ export class SettingsComponent implements OnInit { }, complete: () => { this.pullInProgress = false; + if (!this.pullSucceeded) { + // Stream ferme sans 'success' final = connexion coupee + // (timeout proxy, perte reseau, ...). Le modele est probablement + // partiellement telecharge ; Ollama gardera les couches deja DL. + this.errorMessage = `Telechargement de ${name} interrompu avant la fin. Relancez pour reprendre.`; + this.refreshModels(); + return; + } this.successMessage = `Modele ${name} telecharge.`; this.refreshModels(); // Si l'utilisateur n'avait aucun modele, on selectionne celui-ci. @@ -326,6 +341,7 @@ export class SettingsComponent implements OnInit { this.pullStatus = ''; this.pullCompleted = 0; this.pullTotal = 0; + this.pullSucceeded = false; if (this.pullSubscription) { this.pullSubscription.unsubscribe(); this.pullSubscription = null;