1 package fr.tiogars.chat.domains.lmstudio.models; 2 3 import java.net.URI; 4 5 import com.fasterxml.jackson.annotation.JsonIgnore; 6 import com.fasterxml.jackson.annotation.JsonProperty; 7 import io.swagger.v3.oas.annotations.media.Schema; 8 import jakarta.validation.constraints.AssertTrue; 9 import jakarta.validation.constraints.NotBlank; 10 import jakarta.validation.constraints.Positive; 11 import jakarta.validation.constraints.Pattern; 12 import jakarta.validation.constraints.Size; 13 14 @Schema(description = "Global LM Studio connection settings") 15 public record LmStudioSettings( 16 @NotBlank @Size(max = 2048) 17 @Schema(example = "http://host.docker.internal:1234") 18 String baseUrl, 19 @NotBlank @Size(max = 255) 20 @Schema(example = "llama3.2") 21 String model, 22 @Positive 23 @Schema(description = "Connection and request timeout in seconds", example = "30") 24 int timeoutSeconds, 25 @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) 26 @Schema(description = "Bearer token. Omit or use null to keep it; empty string removes it.", 27 accessMode = Schema.AccessMode.WRITE_ONLY) 28 @Size(max = 4096) 29 @Pattern(regexp = "(?:[A-Za-z0-9._~+/:\\-]+=*)?", message = "token must be a valid LM Studio API token") 30 String token) { 31 32 public LmStudioSettings(String baseUrl, String model, int timeoutSeconds) { 33 this(baseUrl, model, timeoutSeconds, null); 34 } 35 36 @JsonProperty(access = JsonProperty.Access.READ_ONLY) 37 @Schema(accessMode = Schema.AccessMode.READ_ONLY) 38 public boolean isTokenConfigured() { 39 return token != null && !token.isEmpty(); 40 } 41 42 @Override 43 public String toString() { 44 return "LmStudioSettings[baseUrl=" + baseUrl + ", model=" + model 45 + ", timeoutSeconds=" + timeoutSeconds + ", tokenConfigured=" + isTokenConfigured() + "]"; 46 } 47 48 @JsonIgnore 49 @AssertTrue(message = "baseUrl must be an absolute HTTP(S) URL without credentials, query or fragment") 50 public boolean isBaseUrlValid() { 51 if (baseUrl == null || baseUrl.isBlank()) { 52 return false; 53 } 54 try { 55 URI uri = URI.create(baseUrl); 56 return ("http".equalsIgnoreCase(uri.getScheme()) || "https".equalsIgnoreCase(uri.getScheme())) 57 && uri.getHost() != null 58 && uri.getRawUserInfo() == null 59 && uri.getRawQuery() == null 60 && uri.getRawFragment() == null 61 && uri.getPort() >= -1 && uri.getPort() <= 65535; 62 } catch (IllegalArgumentException exception) { 63 return false; 64 } 65 } 66 }