| | |
| | | package com.zy.ai.service; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.zy.ai.entity.ChatCompletionRequest; |
| | | import com.zy.ai.entity.LlmRouteConfig; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.http.HttpHeaders; |
| | | import org.springframework.http.MediaType; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.web.reactive.function.client.WebClient; |
| | | import reactor.core.publisher.Mono; |
| | | |
| | | import java.time.Duration; |
| | | import java.util.ArrayList; |
| | | import java.util.Comparator; |
| | | import java.util.Collections; |
| | |
| | | private static final long CACHE_TTL_MS = 3000L; |
| | | |
| | | private final LlmRouteConfigService llmRouteConfigService; |
| | | private final LlmSpringAiClientService llmSpringAiClientService; |
| | | |
| | | private volatile List<LlmRouteConfig> allRouteCache = Collections.emptyList(); |
| | | private volatile long cacheExpireAt = 0L; |
| | |
| | | } |
| | | |
| | | private TestHttpResult testJavaRoute(LlmRouteConfig cfg) { |
| | | HashMap<String, Object> req = new HashMap<>(); |
| | | req.put("model", cfg.getModel()); |
| | | List<Map<String, String>> messages = new ArrayList<>(); |
| | | HashMap<String, String> msg = new HashMap<>(); |
| | | msg.put("role", "user"); |
| | | msg.put("content", "ping"); |
| | | ChatCompletionRequest req = new ChatCompletionRequest(); |
| | | req.setModel(cfg.getModel()); |
| | | List<ChatCompletionRequest.Message> messages = new ArrayList<>(); |
| | | ChatCompletionRequest.Message msg = new ChatCompletionRequest.Message(); |
| | | msg.setRole("user"); |
| | | msg.setContent("ping"); |
| | | messages.add(msg); |
| | | req.put("messages", messages); |
| | | req.put("stream", false); |
| | | req.put("max_tokens", 8); |
| | | req.put("temperature", 0); |
| | | |
| | | WebClient client = WebClient.builder().baseUrl(cfg.getBaseUrl()).build(); |
| | | return client.post() |
| | | .uri("/chat/completions") |
| | | .header(HttpHeaders.AUTHORIZATION, "Bearer " + cfg.getApiKey()) |
| | | .contentType(MediaType.APPLICATION_JSON) |
| | | .accept(MediaType.APPLICATION_JSON, MediaType.TEXT_EVENT_STREAM) |
| | | .bodyValue(req) |
| | | .exchangeToMono(resp -> resp.bodyToMono(String.class) |
| | | .defaultIfEmpty("") |
| | | .map(body -> new TestHttpResult(resp.rawStatusCode(), body))) |
| | | .timeout(Duration.ofSeconds(12)) |
| | | .onErrorResume(ex -> Mono.just(new TestHttpResult(-1, safe(ex.getMessage())))) |
| | | .block(); |
| | | req.setMessages(messages); |
| | | req.setStream(false); |
| | | req.setMax_tokens(8); |
| | | req.setTemperature(0D); |
| | | if (cfg.getThinking() != null && cfg.getThinking() == 1) { |
| | | ChatCompletionRequest.Thinking thinking = new ChatCompletionRequest.Thinking(); |
| | | thinking.setType("enable"); |
| | | req.setThinking(thinking); |
| | | } |
| | | try { |
| | | LlmSpringAiClientService.CompletionCallResult result = |
| | | llmSpringAiClientService.callCompletion(cfg.getBaseUrl(), cfg.getApiKey(), req); |
| | | return new TestHttpResult(result.getStatusCode(), result.getPayload()); |
| | | } catch (Throwable ex) { |
| | | Integer statusCode = llmSpringAiClientService.statusCodeOf(ex); |
| | | String body = llmSpringAiClientService.responseBodyOf(ex, 300); |
| | | return new TestHttpResult(statusCode == null ? -1 : statusCode, safe(body != null ? body : ex.getMessage())); |
| | | } |
| | | } |
| | | |
| | | private String trimBody(String body) { |