From 9a8018c3fbc94f99d5d184c8cb1ef23d7366cea0 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期三, 29 四月 2026 17:02:38 +0800
Subject: [PATCH] #堆垛机任务执行优先级修改

---
 src/main/java/com/zy/ai/service/LlmRoutingService.java |  113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 113 insertions(+), 0 deletions(-)

diff --git a/src/main/java/com/zy/ai/service/LlmRoutingService.java b/src/main/java/com/zy/ai/service/LlmRoutingService.java
index 2af0825..25502dc 100644
--- a/src/main/java/com/zy/ai/service/LlmRoutingService.java
+++ b/src/main/java/com/zy/ai/service/LlmRoutingService.java
@@ -1,17 +1,24 @@
 package com.zy.ai.service;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.alibaba.fastjson.JSON;
 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.http.ResponseEntity;
 import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestClient;
+import org.springframework.web.client.RestClientResponseException;
 
 import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -21,9 +28,13 @@
 public class LlmRoutingService {
 
     private static final long CACHE_TTL_MS = 3000L;
+    private static final String DEFAULT_PROVIDER_TYPE = "OPENAI_COMPATIBLE";
+    private static final String DEFAULT_PROTOCOL_TYPE = "OPENAI_CHAT_COMPLETIONS";
+    private static final String DEFAULT_AUTH_TYPE = "BEARER";
 
     private final LlmRouteConfigService llmRouteConfigService;
     private final LlmSpringAiClientService llmSpringAiClientService;
+    private final RestClient routeTestClient = RestClient.builder().build();
 
     private volatile List<LlmRouteConfig> allRouteCache = Collections.emptyList();
     private volatile long cacheExpireAt = 0L;
@@ -176,6 +187,8 @@
 
     public LlmRouteConfig fillAndNormalize(LlmRouteConfig cfg, boolean isCreate) {
         Date now = new Date();
+        trimStringFields(cfg);
+        normalizeProtocolFields(cfg);
         if (isBlank(cfg.getName())) {
             cfg.setName("LLM_ROUTE_" + now.getTime());
         }
@@ -217,6 +230,8 @@
         HashMap<String, Object> result = new HashMap<>();
         long start = System.currentTimeMillis();
         try {
+            trimStringFields(cfg);
+            normalizeProtocolFields(cfg);
             TestHttpResult raw = testJavaRoute(cfg);
             fillTestResult(result, raw, start);
         } catch (Exception e) {
@@ -226,7 +241,52 @@
             result.put("message", "娴嬭瘯寮傚父: " + safe(e.getMessage()));
             result.put("responseSnippet", "");
         }
+        fillProtocolResult(result, cfg);
         return result;
+    }
+
+    private void trimStringFields(LlmRouteConfig cfg) {
+        if (cfg == null) return;
+        cfg.setName(trimToNull(cfg.getName()));
+        cfg.setProviderType(trimToNull(cfg.getProviderType()));
+        cfg.setProtocolType(trimToNull(cfg.getProtocolType()));
+        cfg.setBaseUrl(trimToNull(cfg.getBaseUrl()));
+        cfg.setEndpointPath(trimToNull(cfg.getEndpointPath()));
+        cfg.setApiKey(trimToNull(cfg.getApiKey()));
+        cfg.setAuthType(trimToNull(cfg.getAuthType()));
+        cfg.setAuthHeaderName(trimToNull(cfg.getAuthHeaderName()));
+        cfg.setModel(trimToNull(cfg.getModel()));
+        cfg.setCapabilities(trimToNull(cfg.getCapabilities()));
+        cfg.setRequestOptions(trimToNull(cfg.getRequestOptions()));
+        cfg.setMemo(trimToNull(cfg.getMemo()));
+    }
+
+    private void normalizeProtocolFields(LlmRouteConfig cfg) {
+        if (cfg == null) return;
+        if (isBlank(cfg.getProviderType())) {
+            cfg.setProviderType(DEFAULT_PROVIDER_TYPE);
+        }
+        if (isBlank(cfg.getProtocolType())) {
+            cfg.setProtocolType(DEFAULT_PROTOCOL_TYPE);
+        }
+        if (isBlank(cfg.getAuthType())) {
+            cfg.setAuthType(DEFAULT_AUTH_TYPE);
+        }
+    }
+
+    private void fillProtocolResult(HashMap<String, Object> result, LlmRouteConfig cfg) {
+        if (cfg == null) return;
+        result.put("providerType", cfg.getProviderType());
+        result.put("protocolType", cfg.getProtocolType());
+        result.put("endpointPath", cfg.getEndpointPath());
+        result.put("authType", cfg.getAuthType());
+        result.put("authHeaderName", cfg.getAuthHeaderName());
+    }
+
+    private String trimToNull(String s) {
+        if (s == null) return null;
+        String trimmed = s.trim();
+        return trimmed.isEmpty() ? null : trimmed;
     }
 
     private void fillTestResult(HashMap<String, Object> result, TestHttpResult raw, long start) {
@@ -239,6 +299,10 @@
     }
 
     private TestHttpResult testJavaRoute(LlmRouteConfig cfg) {
+        if ("OPENAI_RESPONSES".equalsIgnoreCase(safe(cfg.getProtocolType()))) {
+            return testResponsesRoute(cfg);
+        }
+
         ChatCompletionRequest req = new ChatCompletionRequest();
         req.setModel(cfg.getModel());
         List<ChatCompletionRequest.Message> messages = new ArrayList<>();
@@ -266,6 +330,55 @@
         }
     }
 
+    private TestHttpResult testResponsesRoute(LlmRouteConfig cfg) {
+        LinkedHashMap<String, Object> body = new LinkedHashMap<>();
+        body.put("model", cfg.getModel());
+        body.put("input", "ping");
+        body.put("max_output_tokens", 8);
+        try {
+            ResponseEntity<String> response = routeTestClient.post()
+                    .uri(responsesEndpointUrl(cfg))
+                    .contentType(MediaType.APPLICATION_JSON)
+                    .headers(headers -> applyRouteAuth(headers, cfg))
+                    .body(JSON.toJSONString(body))
+                    .retrieve()
+                    .toEntity(String.class);
+            return new TestHttpResult(response.getStatusCode().value(), response.getBody());
+        } catch (RestClientResponseException ex) {
+            return new TestHttpResult(ex.getStatusCode().value(), trimBody(ex.getResponseBodyAsString()));
+        } catch (Throwable ex) {
+            return new TestHttpResult(-1, safe(ex.getMessage()));
+        }
+    }
+
+    private String responsesEndpointUrl(LlmRouteConfig cfg) {
+        String baseUrl = safe(cfg.getBaseUrl());
+        String endpointPath = safe(cfg.getEndpointPath());
+        if (endpointPath.isEmpty()) {
+            endpointPath = "/responses";
+        }
+        if (baseUrl.endsWith("/") && endpointPath.startsWith("/")) {
+            return baseUrl + endpointPath.substring(1);
+        }
+        if (!baseUrl.endsWith("/") && !endpointPath.startsWith("/")) {
+            return baseUrl + "/" + endpointPath;
+        }
+        return baseUrl + endpointPath;
+    }
+
+    private void applyRouteAuth(HttpHeaders headers, LlmRouteConfig cfg) {
+        String authType = safe(cfg.getAuthType()).toUpperCase();
+        if ("NONE".equals(authType) || isBlank(cfg.getApiKey())) {
+            return;
+        }
+        if ("API_KEY".equals(authType)) {
+            String headerName = safe(cfg.getAuthHeaderName());
+            headers.set(headerName.isEmpty() ? "X-API-Key" : headerName, cfg.getApiKey());
+            return;
+        }
+        headers.setBearerAuth(cfg.getApiKey());
+    }
+
     private String trimBody(String body) {
         String x = safe(body).replace("\r", " ").replace("\n", " ");
         return x.length() > 300 ? x.substring(0, 300) : x;

--
Gitblit v1.9.1