Skip to content

Commit 11e3430

Browse files
committed
refactor: decouple from okhttp3-extension (use String for log level) for Maven Central compatibility
- OpenClawDebugConfig.level: HttpLogLevel → String (BASIC/HEADERS/BODY) - 8 files: HttpLogLevel → String constants in debug() methods - Remove io.github.easy4j:okhttp3-extension dependency (compile + test) - Remove okhttp3-extension.version property
1 parent 433fc8f commit 11e3430

10 files changed

Lines changed: 58 additions & 51 deletions

File tree

‎pom.xml‎

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -448,10 +448,10 @@
448448
<artifactId>maven-release-plugin</artifactId>
449449
</plugin>
450450

451-
<!-- https://mvnrepository.com/artifact/org.sonatype.central/central-publishing-maven-plugin -->
451+
<!-- https://mvnrepository.com/artifact/org.sonatype.plugins/nexus-staging-maven-plugin -->
452452
<plugin>
453-
<groupId>org.sonatype.central</groupId>
454-
<artifactId>central-publishing-maven-plugin</artifactId>
453+
<groupId>org.sonatype.plugins</groupId>
454+
<artifactId>nexus-staging-maven-plugin</artifactId>
455455
</plugin>
456456
</plugins>
457457
</build>
@@ -472,7 +472,6 @@
472472
<junit-jupiter.version>6.1.0</junit-jupiter.version>
473473
<lombok.version>1.18.46</lombok.version>
474474
<okhttp3.version>4.12.0</okhttp3.version>
475-
<okhttp3-extension.version>2.0.x.20260630-SNAPSHOT</okhttp3-extension.version>
476475
<slf4j.version>2.0.18</slf4j.version>
477476
<!-- Maven Plugin versions -->
478477
<maven-central-publishing-plugin.version>0.11.0</maven-central-publishing-plugin.version>
@@ -496,11 +495,6 @@
496495
<!-- 依赖版本统一管理(dependencyManagement) -->
497496
<dependencyManagement>
498497
<dependencies>
499-
<dependency>
500-
<groupId>io.github.easy4j</groupId>
501-
<artifactId>okhttp3-extension</artifactId>
502-
<version>${okhttp3-extension.version}</version>
503-
</dependency>
504498
<!-- For OkHttp -->
505499
<dependency>
506500
<groupId>com.squareup.okhttp3</groupId>
@@ -571,10 +565,6 @@
571565

572566
<!-- 项目依赖(dependencies) -->
573567
<dependencies>
574-
<dependency>
575-
<groupId>io.github.easy4j</groupId>
576-
<artifactId>okhttp3-extension</artifactId>
577-
</dependency>
578568
<!-- For OkHttp -->
579569
<dependency>
580570
<groupId>com.squareup.okhttp3</groupId>
Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
package io.github.easy4j.openclaw;
22

33
import lombok.Data;
4-
import okhttp3.extension.logging.HttpLogLevel;
54

65
/**
76
* OpenClaw SDK 统一调试配置,用于控制生命周期、请求头和正文日志。
87
*
98
* <p>调试默认关闭。正文日志始终受长度限制,认证头和敏感令牌仍由客户端脱敏。</p>
109
*
10+
* <p>{@link #level} 字段使用字符串表示日志级别。可选值:
11+
* <ul>
12+
* <li>{@code "NONE"} — 不输出</li>
13+
* <li>{@code "BASIC"} — 仅方法/路径/状态/耗时</li>
14+
* <li>{@code "HEADERS"} — BASIC + 请求/响应头</li>
15+
* <li>{@code "BODY"} — HEADERS + 请求/响应正文(受 {@link #maxContentLength} 限制)</li>
16+
* </ul>
17+
* 当 classpath 上有 {@code io.github.easy4j:okhttp3-extension} 时,{@link #level} 会按相同语义传递给底层日志拦截器;否则仅用于 SDK 自身 DEBUG 输出。</p>
18+
*
1119
* @author <a href="https://github.com/loong10k">Loong Wan</a>
1220
* @since 1.0.0
1321
*/
@@ -17,20 +25,26 @@ public class OpenClawDebugConfig {
1725
/** 是否允许 SDK 输出调试诊断信息。 */
1826
private boolean enabled;
1927

20-
/** 启用调试后的详细程度。 */
21-
private HttpLogLevel level = HttpLogLevel.BASIC;
28+
/**
29+
* 启用调试后的详细程度;字符串常量,对齐 {@code okhttp3.extension.logging.HttpLogLevel}。
30+
*/
31+
private String level = "BASIC";
2232

2333
/** BODY 级别单项正文允许记录的最大字符数。 */
2434
private int maxContentLength = 2_000;
2535

2636
/**
2737
* 判断指定级别的日志是否允许输出。
38+
* <p>简单的字符串排序:{@code NONE &lt; BASIC &lt; HEADERS &lt; BODY}。</p>
2839
*
29-
* @param required 待输出信息要求的最低级别
40+
* @param required 待输出信息要求的最低级别(字符串)
3041
* @return 调试已启用且当前级别满足要求时返回 {@code true}
3142
*/
32-
public boolean allows(HttpLogLevel required) {
33-
return enabled && level != null && level.allows(required);
43+
public boolean allows(String required) {
44+
if (!enabled || level == null || required == null) {
45+
return false;
46+
}
47+
return rank(level) >= rank(required);
3448
}
3549

3650
/**
@@ -41,4 +55,14 @@ public boolean allows(HttpLogLevel required) {
4155
public int resolveMaxContentLength() {
4256
return Math.max(1, maxContentLength);
4357
}
44-
}
58+
59+
private static int rank(String level) {
60+
switch (level.toUpperCase()) {
61+
case "BODY": return 3;
62+
case "HEADERS": return 2;
63+
case "BASIC": return 1;
64+
case "NONE": return 0;
65+
default: return 1;
66+
}
67+
}
68+
}

‎src/main/java/io/github/easy4j/openclaw/api/OpenClawChatClient.java‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import io.github.easy4j.openclaw.api.sse.StreamingChatResponse;
1010
import lombok.extern.slf4j.Slf4j;
1111
import okhttp3.OkHttpClient;
12-
import okhttp3.extension.logging.HttpLogLevel;
1312

1413
import java.net.URLEncoder;
1514
import java.util.HashMap;
@@ -138,7 +137,7 @@ public CompletableFuture<ChatResponse> chatCompletionAsync(ChatRequest request,
138137
String bodyModel = resolveModel(request);
139138

140139
debug("Resolved body model (agent routing): {}", bodyModel);
141-
debug(HttpLogLevel.HEADERS, "Headers to send: {}", headers);
140+
debug("HEADERS", "Headers to send: {}", headers);
142141

143142
ChatRequest normalized = ChatRequest.builder()
144143
.model(bodyModel)

‎src/main/java/io/github/easy4j/openclaw/api/OpenClawEmbeddingsClient.java‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import io.github.easy4j.openclaw.api.model.EmbeddingsResponse;
88
import lombok.extern.slf4j.Slf4j;
99
import okhttp3.OkHttpClient;
10-
import okhttp3.extension.logging.HttpLogLevel;
1110

1211
import java.util.HashMap;
1312
import java.util.Map;
@@ -62,7 +61,7 @@ public CompletableFuture<EmbeddingsResponse> createEmbeddingsAsync(EmbeddingsReq
6261
debug("=== Embeddings Request ===");
6362
debug("agent: {}", request.getAgent());
6463
debug("model: {}", request.getModel());
65-
debug(HttpLogLevel.BODY, "input: {}", request.getInput());
64+
debug("BODY", "input: {}", request.getInput());
6665

6766
// 验证请求
6867
validateRequest(request);

‎src/main/java/io/github/easy4j/openclaw/api/OpenClawHttpClient.java‎

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import lombok.Getter;
1111
import lombok.extern.slf4j.Slf4j;
1212
import okhttp3.*;
13-
import okhttp3.extension.logging.HttpLogLevel;
1413

1514
import java.io.IOException;
1615
import java.util.Map;
@@ -83,7 +82,7 @@ private OpenClawHttpClient(OpenClawHttpClientConfig config, ObjectMapper objectM
8382
this.objectMapper = objectMapper != null ? objectMapper : createObjectMapper();
8483
this.httpClient = Objects.requireNonNull(httpClient, "httpClient");
8584
this.ownsHttpClient = ownsHttpClient;
86-
debug(HttpLogLevel.BASIC, "OpenClaw HTTP client initialized: baseUrl={}, connectTimeoutMs={}, readTimeoutMs={}, "
85+
debug("BASIC", "OpenClaw HTTP client initialized: baseUrl={}, connectTimeoutMs={}, readTimeoutMs={}, "
8786
+ "callTimeoutMs={}, retryOnConnectionFailure={}, debugLevel={}",
8887
config.getBaseUrl(), config.getConnectTimeoutMillis(), config.getReadTimeoutMillis(),
8988
config.getCallTimeoutMillis(), config.isRetryOnConnectionFailure(),
@@ -139,7 +138,7 @@ protected Request.Builder authedBuilder(String url, Map<String, String> headers)
139138
headers.forEach((k, v) -> {
140139
if (k != null && v != null) {
141140
builder.header(k, v);
142-
debug(HttpLogLevel.HEADERS, "Added header: {}={}", k, redactHeader(k, v));
141+
debug("HEADERS", "Added header: {}={}", k, redactHeader(k, v));
143142
}
144143
});
145144
}
@@ -200,7 +199,7 @@ protected CompletableFuture<String> postJsonAsync(String path, Object body, Map<
200199

201200
try {
202201
String json = objectMapper.writeValueAsString(body);
203-
debug(HttpLogLevel.BODY, "Request body: {}", truncate(json));
202+
debug("BODY", "Request body: {}", truncate(json));
204203

205204
Request request = authedBuilder(url, headers)
206205
.post(RequestBody.create(json, JSON))
@@ -281,9 +280,9 @@ protected CompletableFuture<String> executeAsync(Request request, String url,
281280
HttpCallCancellation cancellation) {
282281
long requestId = REQUEST_SEQUENCE.incrementAndGet();
283282
long startedAt = System.nanoTime();
284-
debug(HttpLogLevel.BASIC, "HTTP request started: requestId={}, method={}, url={}",
283+
debug("BASIC", "HTTP request started: requestId={}, method={}, url={}",
285284
requestId, request.method(), request.url());
286-
debug(HttpLogLevel.HEADERS, "HTTP request headers: requestId={}, headers={}",
285+
debug("HEADERS", "HTTP request headers: requestId={}, headers={}",
287286
requestId, redactHeaders(request.headers()));
288287

289288
// 传输层只读取状态码和响应体;此处统一把非 2xx 响应转换为携带诊断信息的 SDK 异常。
@@ -300,9 +299,9 @@ protected CompletableFuture<String> executeAsync(Request request, String url,
300299
requestId, request.method(), request.url(), elapsedMillis(startedAt), unwrap(error).getMessage());
301300
return;
302301
}
303-
debug(HttpLogLevel.BASIC, "HTTP request completed: requestId={}, method={}, url={}, bodyLength={}, elapsedMs={}",
302+
debug("BASIC", "HTTP request completed: requestId={}, method={}, url={}, bodyLength={}, elapsedMs={}",
304303
requestId, request.method(), request.url(), respBody.length(), elapsedMillis(startedAt));
305-
debug(HttpLogLevel.BODY, "HTTP response body: requestId={}, body={}", requestId, truncate(respBody));
304+
debug("BODY", "HTTP response body: requestId={}, body={}", requestId, truncate(respBody));
306305
});
307306
}
308307

@@ -562,7 +561,7 @@ public CompletableFuture<Void> healthAsync() {
562561
* @param args 填充消息模板占位符的参数
563562
*/
564563
protected void debug(String msg, Object... args) {
565-
debug(HttpLogLevel.BASIC, msg, args);
564+
debug("BASIC", msg, args);
566565
}
567566

568567
/**
@@ -572,7 +571,7 @@ protected void debug(String msg, Object... args) {
572571
* @param msg 包含 SLF4J 占位符的日志消息模板
573572
* @param args 填充消息模板占位符的参数
574573
*/
575-
protected void debug(HttpLogLevel level, String msg, Object... args) {
574+
void debug(String level, String msg, Object... args) {
576575
if (config.getDebug().allows(level) && log.isDebugEnabled()) {
577576
log.debug(msg, args);
578577
}

‎src/main/java/io/github/easy4j/openclaw/api/OpenClawSseClient.java‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import okhttp3.Request;
1616
import okhttp3.RequestBody;
1717
import okhttp3.Response;
18-
import okhttp3.extension.logging.HttpLogLevel;
1918

2019
import java.io.IOException;
2120
import java.util.HashMap;
@@ -269,7 +268,7 @@ private static ExecutorService createStreamExecutor(OpenClawHttpClientConfig con
269268
}
270269

271270
private void logInitialization(OpenClawHttpClientConfig config) {
272-
if (config.getDebug().allows(HttpLogLevel.BASIC)) {
271+
if (config.getDebug().allows("BASIC")) {
273272
log.debug("OpenClaw SSE client initialized: baseUrl={}, maxRequests={}, "
274273
+ "maxRequestsPerHost={}, eventQueueCapacity={}, reconnectPolicy=none, debugLevel={}",
275274
config.getBaseUrl(), config.getMaxRequests(), config.getMaxRequestsPerHost(),

‎src/main/java/io/github/easy4j/openclaw/api/OpenClawToolInvokeClient.java‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import io.github.easy4j.openclaw.api.model.ToolInvokeResult;
1010
import lombok.extern.slf4j.Slf4j;
1111
import okhttp3.*;
12-
import okhttp3.extension.logging.HttpLogLevel;
1312

1413
import java.util.Objects;
1514
import java.util.concurrent.CompletableFuture;
@@ -80,7 +79,7 @@ public CompletableFuture<ToolInvokeResult> invokeAsync(ToolInvokeRequest request
8079
debug("=== Tool Invoke Request ===");
8180
debug("tool: {}", request.getTool());
8281
debug("action: {}", request.getAction());
83-
debug(HttpLogLevel.BODY, "args: {}", request.getArgs());
82+
debug("BODY", "args: {}", request.getArgs());
8483

8584
if (OpenClawStrings.isBlank(request.getTool())) {
8685
String msg = "Tool name is required";
@@ -97,7 +96,7 @@ public CompletableFuture<ToolInvokeResult> invokeAsync(ToolInvokeRequest request
9796
int status = response.getStatusCode();
9897
String respBody = response.getBody();
9998
debug("Tool invoke response status: {}", status);
100-
debug(HttpLogLevel.BODY, "Tool invoke response body: {}", truncate(respBody));
99+
debug("BODY", "Tool invoke response body: {}", truncate(respBody));
101100

102101
if (status == 404) {
103102
String msg = "Tool not available: " + request.getTool();

‎src/main/java/io/github/easy4j/openclaw/api/sse/SseStreamReader.java‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import io.github.easy4j.openclaw.exception.OpenClawHttpException;
77
import io.github.easy4j.openclaw.api.model.ChatChunk;
88
import lombok.extern.slf4j.Slf4j;
9-
import okhttp3.extension.logging.HttpLogLevel;
109

1110
import java.io.BufferedReader;
1211
import java.io.InputStream;
@@ -108,7 +107,7 @@ public <T> void readStream(InputStream inputStream, SseEventHandler handler, Cla
108107
T chunk = objectMapper.readValue(data, chunkClass);
109108
sseEvent.setParsed(chunk);
110109
} catch (Exception parseEx) {
111-
if (debug.allows(HttpLogLevel.BASIC)) {
110+
if (debug.allows("BASIC")) {
112111
log.debug("Failed to parse SSE data as {}: {}",
113112
chunkClass.getSimpleName(), parseEx.getMessage());
114113
}

‎src/main/java/io/github/easy4j/openclaw/ws/OpenClawGatewayWsClient.java‎

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import io.github.easy4j.openclaw.ws.protocol.params.*;
1212
import io.github.easy4j.openclaw.ws.protocol.result.*;
1313
import lombok.extern.slf4j.Slf4j;
14-
import okhttp3.extension.logging.HttpLogLevel;
1514
import org.java_websocket.client.WebSocketClient;
1615
import org.java_websocket.handshake.ServerHandshake;
1716

@@ -160,7 +159,7 @@ public void onOpen(ServerHandshake handshake) {
160159
if (!connectFuture.isDone()) {
161160
String nonce = challengeNonce.get();
162161
if (nonce == null) {
163-
debug(HttpLogLevel.BASIC, "connect.challenge not received within {}ms, sending connect without nonce", CHALLENGE_TIMEOUT_MS);
162+
debug("BASIC", "connect.challenge not received within {}ms, sending connect without nonce", CHALLENGE_TIMEOUT_MS);
164163
}
165164
sendConnectHandshake();
166165
}
@@ -190,7 +189,7 @@ public void onMessage(String message) {
190189
handleEvent(root);
191190
break;
192191
case "req":
193-
debug(HttpLogLevel.BODY, "Received unexpected req frame from Gateway: {}", root);
192+
debug("BODY", "Received unexpected req frame from Gateway: {}", root);
194193
break;
195194
default:
196195
log.warn("Unknown frame type: {}", type);
@@ -250,7 +249,7 @@ private void sendConnectHandshake() {
250249
connectLock.lock();
251250
try {
252251
if (connectFuture.isDone()) {
253-
debug(HttpLogLevel.BASIC, "Skipping duplicate connect handshake");
252+
debug("BASIC", "Skipping duplicate connect handshake");
254253
return;
255254
}
256255

@@ -283,7 +282,7 @@ private void sendConnectHandshake() {
283282

284283
try {
285284
String json = objectMapper.writeValueAsString(req);
286-
debug(HttpLogLevel.BODY, "Sending connect handshake: {}", json);
285+
debug("BODY", "Sending connect handshake: {}", json);
287286
sendFrame(json);
288287
} catch (JsonProcessingException e) {
289288
failConnectFuture(e);
@@ -307,7 +306,7 @@ private CompletableFuture<HelloOk> beginConnectAttempt() {
307306
return current;
308307
}
309308
if (isOpen()) {
310-
debug(HttpLogLevel.BASIC, "Closing existing WebSocket before reconnect");
309+
debug("BASIC", "Closing existing WebSocket before reconnect");
311310
super.close();
312311
}
313312
resetConnectStateUnderLock();
@@ -893,7 +892,7 @@ private static String generateId() {
893892
return UUID.randomUUID().toString().replace("-", "").substring(0, 16);
894893
}
895894

896-
private void debug(HttpLogLevel level, String message, Object... arguments) {
895+
void debug(String level, String message, Object... arguments) {
897896
if (config.getDebug().allows(level)) {
898897
log.debug(message, arguments);
899898
}
@@ -915,9 +914,9 @@ private boolean handleConnectChallenge(JsonNode root) {
915914
String nonce = payload.path("nonce").asText(null);
916915
if (nonce != null) {
917916
challengeNonce.set(nonce);
918-
debug(HttpLogLevel.BASIC, "Received connect.challenge with nonce, sending connect handshake");
917+
debug("BASIC", "Received connect.challenge with nonce, sending connect handshake");
919918
} else {
920-
debug(HttpLogLevel.BASIC, "Received connect.challenge without nonce");
919+
debug("BASIC", "Received connect.challenge without nonce");
921920
}
922921
// 收到挑战后立即发送 connect 握手
923922
sendConnectHandshake();

‎src/test/java/io/github/easy4j/openclaw/OpenClawHttpClientConfigTest.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ void debugLoggingIsOptIn() {
1111
OpenClawHttpClientConfig config = new OpenClawHttpClientConfig();
1212
org.junit.jupiter.api.Assertions.assertFalse(config.getDebug().isEnabled());
1313
org.junit.jupiter.api.Assertions.assertEquals(2_000, config.getDebug().getMaxContentLength());
14-
org.junit.jupiter.api.Assertions.assertEquals(okhttp3.extension.logging.HttpLogLevel.BASIC,
14+
org.junit.jupiter.api.Assertions.assertEquals("BASIC",
1515
config.getDebug().getLevel());
1616
}
1717

0 commit comments

Comments
 (0)