1
This commit is contained in:
@@ -180,8 +180,37 @@ public class SocialMediaLlmClient {
|
|||||||
return t.isEmpty() ? null : t;
|
return t.isEmpty() ? null : t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 火山方舟「Coding / OpenClaw」文档里的基址常为 {@code .../api/coding/v3},与 OpenAI 兼容对话接口
|
||||||
|
* {@code .../api/v3/chat/completions} 不同,误填会导致 404。此处自动纠正常见误填。
|
||||||
|
*
|
||||||
|
* @see <a href="https://www.volcengine.com/docs/82379/1174746">方舟对话 API</a>
|
||||||
|
*/
|
||||||
|
private static String normalizeOpenAiCompatibleUrl(String chatCompletionsUrl) {
|
||||||
|
if (StrUtil.isBlank(chatCompletionsUrl)) {
|
||||||
|
return chatCompletionsUrl;
|
||||||
|
}
|
||||||
|
String u = chatCompletionsUrl.trim().replaceAll("/+$", "");
|
||||||
|
if (!u.contains("volces.com") || u.contains("chat/completions")) {
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
if (u.contains("/api/coding/")) {
|
||||||
|
String fixed = u.replace("/api/coding/v3", "/api/v3/chat/completions");
|
||||||
|
if (!fixed.equals(u)) {
|
||||||
|
return fixed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
|
||||||
private String callOpenAiCompatible(String chatCompletionsUrl, String apiKey, String model, String userText)
|
private String callOpenAiCompatible(String chatCompletionsUrl, String apiKey, String model, String userText)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
String endpoint = normalizeOpenAiCompatibleUrl(chatCompletionsUrl);
|
||||||
|
String originalTrim = chatCompletionsUrl == null ? "" : chatCompletionsUrl.trim().replaceAll("/+$", "");
|
||||||
|
if (!endpoint.equals(originalTrim)) {
|
||||||
|
log.info("OpenAI 兼容 URL 已规范化: {} -> {}", originalTrim, endpoint);
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, Object> requestBody = new HashMap<>();
|
Map<String, Object> requestBody = new HashMap<>();
|
||||||
requestBody.put("model", model);
|
requestBody.put("model", model);
|
||||||
requestBody.put("messages", new Map[]{
|
requestBody.put("messages", new Map[]{
|
||||||
@@ -191,7 +220,7 @@ public class SocialMediaLlmClient {
|
|||||||
|
|
||||||
String jsonBody = objectMapper.writeValueAsString(requestBody);
|
String jsonBody = objectMapper.writeValueAsString(requestBody);
|
||||||
|
|
||||||
HttpRequest request = HttpRequest.of(chatCompletionsUrl.trim())
|
HttpRequest request = HttpRequest.of(endpoint)
|
||||||
.method(Method.POST)
|
.method(Method.POST)
|
||||||
.header("Content-Type", "application/json")
|
.header("Content-Type", "application/json")
|
||||||
.header("Accept", "application/json")
|
.header("Accept", "application/json")
|
||||||
@@ -202,12 +231,21 @@ public class SocialMediaLlmClient {
|
|||||||
request.header("Authorization", "Bearer " + apiKey.trim());
|
request.header("Authorization", "Bearer " + apiKey.trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("请求 OpenAI 兼容 API: URL={}, model={}", chatCompletionsUrl, model);
|
log.info("请求 OpenAI 兼容 API: URL={}, model={}", endpoint, model);
|
||||||
|
|
||||||
HttpResponse response = request.execute();
|
HttpResponse response = request.execute();
|
||||||
if (response.getStatus() != 200) {
|
if (response.getStatus() != 200) {
|
||||||
log.error("OpenAI 兼容 API 失败: status={}, body={}", response.getStatus(), response.body());
|
String body = response.body();
|
||||||
throw new IOException("API 调用失败,HTTP 状态码: " + response.getStatus());
|
log.error("OpenAI 兼容 API 失败: status={}, body={}", response.getStatus(), body);
|
||||||
|
String hint = "";
|
||||||
|
if (response.getStatus() == 404) {
|
||||||
|
hint = "(若为火山方舟:请使用 .../api/v3/chat/completions ,不要用 Coding 文档中的 .../api/coding/v3 )";
|
||||||
|
}
|
||||||
|
String snippet = "";
|
||||||
|
if (StrUtil.isNotBlank(body)) {
|
||||||
|
snippet = " — " + (body.length() > 400 ? body.substring(0, 400) + "..." : body);
|
||||||
|
}
|
||||||
|
throw new IOException("API 调用失败,HTTP 状态码: " + response.getStatus() + hint + snippet);
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonNode root = objectMapper.readTree(response.body());
|
JsonNode root = objectMapper.readTree(response.body());
|
||||||
|
|||||||
Reference in New Issue
Block a user