Skip to content

Commit 5530d36

Browse files
committed
feat: unify blocking and streaming HTTP modes
1 parent 7286ad8 commit 5530d36

5 files changed

Lines changed: 56 additions & 6 deletions

File tree

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package io.github.easy4j.opencode;
2+
3+
/**
4+
* HTTP 对话响应模式。
5+
*/
6+
public enum HttpResponseMode {
7+
8+
/** 等待完整响应后一次性返回。 */
9+
BLOCKING,
10+
11+
/** 消费 Provider SSE 并逐段回调。 */
12+
STREAM,
13+
14+
/** 由调用方根据结构化输出等请求特征选择。 */
15+
AUTO
16+
}

src/main/java/io/github/easy4j/opencode/OpenCodeClient.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.concurrent.ThreadPoolExecutor;
2222
import java.util.concurrent.TimeUnit;
2323
import java.util.concurrent.atomic.AtomicInteger;
24+
import java.util.function.Consumer;
2425

2526
/**
2627
* Facade client for OpenCode: HTTP Server + SSE event stream + local CLI.
@@ -233,6 +234,7 @@ public boolean isCliEnabled() {
233234
// ============================================================
234235

235236
private void copyHttpConfig(OpenCodeHttpClientConfig src) {
237+
this.config.getHttp().setMode(src.getMode());
236238
this.config.getHttp().setEnabled(src.isEnabled());
237239
this.config.getHttp().setStartupCheckEnabled(src.isStartupCheckEnabled());
238240
this.config.getHttp().setFailFastOnUnavailable(src.isFailFastOnUnavailable());
@@ -251,7 +253,7 @@ private void copyHttpConfig(OpenCodeHttpClientConfig src) {
251253
this.config.getHttp().setStreamMaxPoolSize(src.getStreamMaxPoolSize());
252254
this.config.getHttp().setStreamQueueCapacity(src.getStreamQueueCapacity());
253255
this.config.getHttp().setStreamKeepAliveMillis(src.getStreamKeepAliveMillis());
254-
this.config.getHttp().setSseEventQueueCapacity(src.getSseEventQueueCapacity());
256+
this.config.getHttp().setStreamEventQueueCapacity(src.getStreamEventQueueCapacity());
255257
this.config.getHttp().setRetryOnConnectionFailure(src.isRetryOnConnectionFailure());
256258
this.config.getHttp().setVerifySsl(src.isVerifySsl());
257259
this.config.getHttp().setDefaultModel(src.getDefaultModel());
@@ -367,10 +369,19 @@ public ChatStreamingResponse chatCompletionStream(ChatRequest request, String se
367369

368370
public ChatStreamingResponse chatCompletionStream(ChatRequest request, String sessionKey,
369371
OpenCodeRequestContext context) {
372+
return chatCompletionStream(request, sessionKey, context, null);
373+
}
374+
375+
/**
376+
* 流式对话,并在订阅启动前绑定增量回调,避免丢失首批分片。
377+
*/
378+
public ChatStreamingResponse chatCompletionStream(ChatRequest request, String sessionKey,
379+
OpenCodeRequestContext context,
380+
Consumer<String> deltaConsumer) {
370381
String sessionId = httpClient.ensureSession(sessionKey, context);
371382
PromptRequest promptRequest = ChatMessageMapper.toPromptRequest(request);
372383

373-
ChatStreamingResponse stream = new ChatStreamingResponse();
384+
ChatStreamingResponse stream = new ChatStreamingResponse().onDelta(deltaConsumer);
374385

375386
OpenCodeSseClient.QueueSubscription subscription =
376387
sseClient.subscribeQueueSubscription(context);

src/main/java/io/github/easy4j/opencode/OpenCodeHttpClientConfig.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
@Data
1717
public class OpenCodeHttpClientConfig {
1818

19+
/** 对话响应模式,默认保持兼容的完整响应模式。 */
20+
private HttpResponseMode mode = HttpResponseMode.BLOCKING;
21+
1922
/**
2023
* 是否启用 HTTP 子系统。
2124
* <p>为 false 时跳过 HTTP 客户端初始化和检查。</p>
@@ -102,14 +105,26 @@ public class OpenCodeHttpClientConfig {
102105
/** 流式事件处理线程空闲保活时间(毫秒)。 */
103106
private long streamKeepAliveMillis = 60_000L;
104107

105-
/** 单个 SSE 订阅的事件缓存上限。 */
106-
private int sseEventQueueCapacity = 1_024;
108+
/** 单个流式订阅的事件缓存上限。 */
109+
private int streamEventQueueCapacity = 1_024;
107110

108111
/**
109112
* 遇到失效连接等传输故障时是否允许 OkHttp 自动恢复。
110113
*/
111114
private boolean retryOnConnectionFailure = true;
112115

116+
/** @deprecated 使用 {@link #getStreamEventQueueCapacity()}。 */
117+
@Deprecated
118+
public int getSseEventQueueCapacity() {
119+
return streamEventQueueCapacity;
120+
}
121+
122+
/** @deprecated 使用 {@link #setStreamEventQueueCapacity(int)}。 */
123+
@Deprecated
124+
public void setSseEventQueueCapacity(int value) {
125+
this.streamEventQueueCapacity = value;
126+
}
127+
113128
/**
114129
* 是否校验 HTTPS 证书;为 false 时关闭校验(仅建议开发环境)。
115130
*/

src/main/java/io/github/easy4j/opencode/api/OpenCodeSseClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ public BlockingQueue<Event> subscribeQueue(OpenCodeRequestContext context) {
126126

127127
public QueueSubscription subscribeQueueSubscription(OpenCodeRequestContext context) {
128128
BlockingQueue<Event> queue = new ArrayBlockingQueue<>(
129-
Math.max(1, config.getSseEventQueueCapacity()));
129+
Math.max(1, config.getStreamEventQueueCapacity()));
130130
EventSource source = subscribe(event -> offerLatest(queue, event), context);
131131
return new QueueSubscription(queue, source);
132132
}

src/test/java/io/github/easy4j/opencode/OpenCodeHttpClientConfigTest.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class OpenCodeHttpClientConfigTest {
1212
@Test
1313
void shouldHaveCorrectDefaults() {
1414
OpenCodeHttpClientConfig config = new OpenCodeHttpClientConfig();
15+
assertEquals(HttpResponseMode.BLOCKING, config.getMode());
1516
assertTrue(config.isEnabled());
1617
assertFalse(config.isStartupCheckEnabled());
1718
assertFalse(config.isFailFastOnUnavailable());
@@ -30,7 +31,7 @@ void shouldHaveCorrectDefaults() {
3031
assertEquals(32, config.getStreamMaxPoolSize());
3132
assertEquals(128, config.getStreamQueueCapacity());
3233
assertEquals(60_000L, config.getStreamKeepAliveMillis());
33-
assertEquals(1_024, config.getSseEventQueueCapacity());
34+
assertEquals(1_024, config.getStreamEventQueueCapacity());
3435
assertTrue(config.isRetryOnConnectionFailure());
3536
assertTrue(config.isVerifySsl());
3637
assertNull(config.getDefaultModel());
@@ -50,4 +51,11 @@ void shouldResolveEmptyPasswordWhenNull() {
5051
assertNull(config.getPassword());
5152
assertEquals("", config.resolvePassword());
5253
}
54+
55+
@Test
56+
void shouldKeepLegacySseEventQueueAlias() {
57+
OpenCodeHttpClientConfig config = new OpenCodeHttpClientConfig();
58+
config.setSseEventQueueCapacity(17);
59+
assertEquals(17, config.getStreamEventQueueCapacity());
60+
}
5361
}

0 commit comments

Comments
 (0)