152 lines
4.5 KiB
Java
152 lines
4.5 KiB
Java
package com.homme.demo.service;
|
|
|
|
import java.time.Duration;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
import org.springframework.http.MediaType;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.web.reactive.function.client.WebClient;
|
|
import org.springframework.web.reactive.function.client.WebClientResponseException;
|
|
|
|
import com.fasterxml.jackson.databind.JsonNode;
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
|
import reactor.util.retry.Retry;
|
|
|
|
|
|
|
|
@Service
|
|
public class AzureMistralService {
|
|
|
|
@Value("${azure.mistral.endpoint}")
|
|
private String endPoint;
|
|
|
|
@Value("${azure.mistral.api-key}")
|
|
private String apiKey;
|
|
|
|
@Value("${azure.mistral.deployment}")
|
|
private String deployment;
|
|
|
|
@Value("${azure.mistral.api-version}")
|
|
private String apiVersion;
|
|
|
|
@Autowired
|
|
private WebClient webClient;
|
|
|
|
@Autowired
|
|
private ObjectMapper objectMapper;
|
|
|
|
public String askMistral(String systemPrompt, String userPrompt) {
|
|
|
|
int estimatedTokens = Math.min(8000, Math.max(512, userPrompt.length() / 2));
|
|
return askMistral(systemPrompt, userPrompt, estimatedTokens);
|
|
}
|
|
public String askMistral(String systemPrompt, String userPrompt, int maxTokens) {
|
|
|
|
try {
|
|
String url = endPoint + "/openai/v1/chat/completions";
|
|
|
|
|
|
System.out.println(">>> MODELL = " + deployment + " | URL = " + url);
|
|
|
|
Map<String, Object> requstBody = Map.of(
|
|
"model", "gpt-5-mini-datazone",
|
|
"messages", List.of(
|
|
Map.of("role", "system","content",systemPrompt),
|
|
Map.of("role", "user","content", userPrompt)
|
|
),
|
|
"reasoning_effort", "minimal",
|
|
"max_completion_tokens", maxTokens
|
|
);
|
|
long c0 = System.currentTimeMillis();
|
|
String response = webClient.post()
|
|
.uri(url)
|
|
.header("api-key", apiKey)
|
|
.contentType(MediaType.APPLICATION_JSON)
|
|
.bodyValue(requstBody)
|
|
.retrieve()
|
|
.bodyToMono(String.class)
|
|
.retryWhen(
|
|
Retry.backoff(2, Duration.ofSeconds(5))
|
|
.filter(ex -> ex instanceof WebClientResponseException.TooManyRequests)
|
|
.onRetryExhaustedThrow((spec, sig) -> sig.failure())
|
|
)
|
|
|
|
.block();
|
|
System.out.println(" askMistral daurte = "+ (System.currentTimeMillis()- c0) + "ms");
|
|
|
|
if(response == null || response.isBlank()) {
|
|
throw new RuntimeException("Leere Antwort von Azure Mistral");
|
|
}
|
|
|
|
JsonNode root = objectMapper.readTree(response);
|
|
|
|
return root
|
|
.path("choices")
|
|
.get(0)
|
|
.get("message")
|
|
.path("content")
|
|
.asText();
|
|
|
|
}catch(WebClientResponseException e) {
|
|
throw new RuntimeException("Azure Mistral request failed: "+e.getStatusCode()
|
|
+ " Retry-After = "+ e.getHeaders().getFirst("Retry-After")
|
|
+ " Body = "+ e.getResponseBodyAsString());
|
|
}catch (Exception e) {
|
|
|
|
throw new RuntimeException("Azure Mistral request failed: "+ e.getMessage());
|
|
}
|
|
}
|
|
|
|
public String askMistral(List<Map<String, Object>> messages, int maxTokens) {
|
|
|
|
try {
|
|
String url = endPoint + "/openai/v1/chat/completions";
|
|
|
|
System.out.println(">>> MODELL = " + deployment + " | URL = " + url);
|
|
|
|
Map<String, Object> requstBody = Map.of(
|
|
"model", "gpt-5-mini-datazone",
|
|
"messages", messages,
|
|
"reasoning_effort", "minimal",
|
|
"max_completion_tokens", maxTokens
|
|
);
|
|
|
|
long c0 = System.currentTimeMillis();
|
|
String response = webClient.post()
|
|
.uri(url)
|
|
.header("api-key", apiKey)
|
|
.contentType(MediaType.APPLICATION_JSON)
|
|
.bodyValue(requstBody)
|
|
.retrieve()
|
|
.bodyToMono(String.class)
|
|
.retryWhen(
|
|
Retry.backoff(2, Duration.ofSeconds(5))
|
|
.filter(ex -> ex instanceof WebClientResponseException.TooManyRequests)
|
|
.onRetryExhaustedThrow((spec, sig) -> sig.failure())
|
|
)
|
|
.block();
|
|
System.out.println(" askMistral daurte = " + (System.currentTimeMillis() - c0) + "ms");
|
|
|
|
if (response == null || response.isBlank()) {
|
|
throw new RuntimeException("Leere Antwort von Azure Mistral");
|
|
}
|
|
|
|
JsonNode root = objectMapper.readTree(response);
|
|
return root.path("choices").get(0).get("message").path("content").asText();
|
|
|
|
} catch (WebClientResponseException e) {
|
|
throw new RuntimeException("Azure Mistral request failed: " + e.getStatusCode()
|
|
+ " Retry-After = " + e.getHeaders().getFirst("Retry-After")
|
|
+ " Body = " + e.getResponseBodyAsString());
|
|
} catch (Exception e) {
|
|
throw new RuntimeException("Azure Mistral request failed: " + e.getMessage());
|
|
}
|
|
}
|
|
|
|
|
|
}
|