1
This commit is contained in:
@@ -180,8 +180,37 @@ public class SocialMediaLlmClient {
|
||||
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)
|
||||
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<>();
|
||||
requestBody.put("model", model);
|
||||
requestBody.put("messages", new Map[]{
|
||||
@@ -191,7 +220,7 @@ public class SocialMediaLlmClient {
|
||||
|
||||
String jsonBody = objectMapper.writeValueAsString(requestBody);
|
||||
|
||||
HttpRequest request = HttpRequest.of(chatCompletionsUrl.trim())
|
||||
HttpRequest request = HttpRequest.of(endpoint)
|
||||
.method(Method.POST)
|
||||
.header("Content-Type", "application/json")
|
||||
.header("Accept", "application/json")
|
||||
@@ -202,12 +231,21 @@ public class SocialMediaLlmClient {
|
||||
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();
|
||||
if (response.getStatus() != 200) {
|
||||
log.error("OpenAI 兼容 API 失败: status={}, body={}", response.getStatus(), response.body());
|
||||
throw new IOException("API 调用失败,HTTP 状态码: " + response.getStatus());
|
||||
String body = response.body();
|
||||
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());
|
||||
|
||||
Reference in New Issue
Block a user