From f17d8411ace0bf534c6f985ac1c84ebbe1e955f2 Mon Sep 17 00:00:00 2001 From: aihai <1072827+aihai@users.noreply.github.com> Date: Sat, 14 Feb 2026 11:02:29 +0800 Subject: [PATCH 1/4] fix(model): Fix NPE when OpenAIClient stream call handle error --- .../core/model/exception/OpenAIException.java | 5 +- .../core/model/OpenAIClientTest.java | 52 +++++++++++++++---- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/agentscope-core/src/main/java/io/agentscope/core/model/exception/OpenAIException.java b/agentscope-core/src/main/java/io/agentscope/core/model/exception/OpenAIException.java index bbf4c3608..3df731920 100644 --- a/agentscope-core/src/main/java/io/agentscope/core/model/exception/OpenAIException.java +++ b/agentscope-core/src/main/java/io/agentscope/core/model/exception/OpenAIException.java @@ -64,7 +64,10 @@ public OpenAIException(String message, int statusCode, String errorCode, String * @return Appropriate exception subclass */ public static OpenAIException create( - int statusCode, String message, String errorCode, String responseBody) { + Integer statusCode, String message, String errorCode, String responseBody) { + if (null == statusCode) { + statusCode = 418; + } return switch (statusCode) { case 400 -> new BadRequestException(message, errorCode, responseBody); case 401 -> new AuthenticationException(message, errorCode, responseBody); diff --git a/agentscope-core/src/test/java/io/agentscope/core/model/OpenAIClientTest.java b/agentscope-core/src/test/java/io/agentscope/core/model/OpenAIClientTest.java index 123db2566..fe6cca90b 100644 --- a/agentscope-core/src/test/java/io/agentscope/core/model/OpenAIClientTest.java +++ b/agentscope-core/src/test/java/io/agentscope/core/model/OpenAIClientTest.java @@ -15,20 +15,10 @@ */ package io.agentscope.core.model; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - import io.agentscope.core.formatter.openai.dto.OpenAIMessage; import io.agentscope.core.formatter.openai.dto.OpenAIRequest; import io.agentscope.core.formatter.openai.dto.OpenAIResponse; import io.agentscope.core.model.exception.OpenAIException; -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; @@ -38,6 +28,17 @@ import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + /** * Unit tests for OpenAIClient. * @@ -882,4 +883,35 @@ void testCustomEndpointPathInStreamCall() throws Exception { recordedRequest.getPath().contains("/v4/chat/completions"), "Stream path should contain custom endpoint path: " + recordedRequest.getPath()); } + + @Test + @DisplayName("Should throw OpenAIException when handle custom endpoint path in stream call") + void testThrowOpenAIExceptionWhenCustomEndpointPathInStreamCall() { + String sseResponse = ""; + + mockServer.enqueue( + new MockResponse() + .setBody(sseResponse) + .setResponseCode(301) + .setHeader("Content-Type", "text/event-stream")); + + OpenAIRequest request = + OpenAIRequest.builder() + .model("gpt-4") + .messages( + List.of( + OpenAIMessage.builder() + .role("user") + .content("Hello") + .build())) + .build(); + + // Use custom endpoint path for stream call + GenerateOptions options = + GenerateOptions.builder().endpointPath("/v4/chat/completions").build(); + + assertThrows( + OpenAIException.class, + () -> client.stream(TEST_API_KEY, baseUrl, request, options).collectList().block()); + } } From 0b4e1609af4e9973260228e9fcebc4bdf5895a53 Mon Sep 17 00:00:00 2001 From: aihai <1072827+aihai@users.noreply.github.com> Date: Sat, 14 Feb 2026 11:17:41 +0800 Subject: [PATCH 2/4] fix(model): Fix NPE when OpenAIClient stream call handle error --- .../java/io/agentscope/core/tool/mcp/McpClientBuilder.java | 7 +++++-- .../src/test/java/io/agentscope/core/VersionTest.java | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/agentscope-core/src/main/java/io/agentscope/core/tool/mcp/McpClientBuilder.java b/agentscope-core/src/main/java/io/agentscope/core/tool/mcp/McpClientBuilder.java index 47dd7dcb1..0338e56d7 100644 --- a/agentscope-core/src/main/java/io/agentscope/core/tool/mcp/McpClientBuilder.java +++ b/agentscope-core/src/main/java/io/agentscope/core/tool/mcp/McpClientBuilder.java @@ -25,6 +25,8 @@ import io.modelcontextprotocol.json.McpJsonMapper; import io.modelcontextprotocol.spec.McpClientTransport; import io.modelcontextprotocol.spec.McpSchema; +import reactor.core.publisher.Mono; + import java.net.URI; import java.net.URLDecoder; import java.net.URLEncoder; @@ -38,7 +40,6 @@ import java.util.Map; import java.util.function.Consumer; import java.util.stream.Collectors; -import reactor.core.publisher.Mono; /** * Builder for creating MCP client wrappers with fluent configuration. @@ -296,7 +297,9 @@ public Mono buildAsync() { McpSchema.Implementation clientInfo = new McpSchema.Implementation( - "agentscope-java", "AgentScope Java Framework", "1.0.10-SNAPSHOT"); + "agentscope-java", + "AgentScope Java Framework", + "1.0.10-SNAPSHOT"); McpSchema.ClientCapabilities clientCapabilities = McpSchema.ClientCapabilities.builder().build(); diff --git a/agentscope-core/src/test/java/io/agentscope/core/VersionTest.java b/agentscope-core/src/test/java/io/agentscope/core/VersionTest.java index a2a4921dd..67cb43be3 100644 --- a/agentscope-core/src/test/java/io/agentscope/core/VersionTest.java +++ b/agentscope-core/src/test/java/io/agentscope/core/VersionTest.java @@ -30,7 +30,8 @@ void testVersionConstant() { // Verify version constant is set Assertions.assertNotNull(Version.VERSION, "VERSION constant should not be null"); Assertions.assertFalse(Version.VERSION.isEmpty(), "VERSION constant should not be empty"); - Assertions.assertEquals("1.0.10-SNAPSHOT", Version.VERSION, "VERSION should match current version"); + Assertions.assertEquals( + "1.0.10-SNAPSHOT", Version.VERSION, "VERSION should match current version"); } @Test From e2b2d44c13fa084a99558001b5faa33eb44a6699 Mon Sep 17 00:00:00 2001 From: aihai <1072827+aihai@users.noreply.github.com> Date: Sat, 14 Feb 2026 11:30:13 +0800 Subject: [PATCH 3/4] fix(model): Fix NPE when OpenAIClient stream call handle error --- .../java/io/agentscope/core/model/exception/OpenAIException.java | 1 + 1 file changed, 1 insertion(+) diff --git a/agentscope-core/src/main/java/io/agentscope/core/model/exception/OpenAIException.java b/agentscope-core/src/main/java/io/agentscope/core/model/exception/OpenAIException.java index 3df731920..fa343864d 100644 --- a/agentscope-core/src/main/java/io/agentscope/core/model/exception/OpenAIException.java +++ b/agentscope-core/src/main/java/io/agentscope/core/model/exception/OpenAIException.java @@ -66,6 +66,7 @@ public OpenAIException(String message, int statusCode, String errorCode, String public static OpenAIException create( Integer statusCode, String message, String errorCode, String responseBody) { if (null == statusCode) { + //When no status code is available, the default is 418 statusCode = 418; } return switch (statusCode) { From ecbdfbc8426e8b93367fdb0fae99a8fcb31fcce2 Mon Sep 17 00:00:00 2001 From: aihai <1072827+aihai@users.noreply.github.com> Date: Sat, 14 Feb 2026 11:38:59 +0800 Subject: [PATCH 4/4] fix(model): Fix NPE when OpenAIClient stream call handle error --- .../core/model/exception/OpenAIException.java | 2 +- .../core/tool/mcp/McpClientBuilder.java | 3 +-- .../core/model/OpenAIClientTest.java | 21 +++++++++---------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/agentscope-core/src/main/java/io/agentscope/core/model/exception/OpenAIException.java b/agentscope-core/src/main/java/io/agentscope/core/model/exception/OpenAIException.java index fa343864d..31f331678 100644 --- a/agentscope-core/src/main/java/io/agentscope/core/model/exception/OpenAIException.java +++ b/agentscope-core/src/main/java/io/agentscope/core/model/exception/OpenAIException.java @@ -66,7 +66,7 @@ public OpenAIException(String message, int statusCode, String errorCode, String public static OpenAIException create( Integer statusCode, String message, String errorCode, String responseBody) { if (null == statusCode) { - //When no status code is available, the default is 418 + // When no status code is available, the default is 418 statusCode = 418; } return switch (statusCode) { diff --git a/agentscope-core/src/main/java/io/agentscope/core/tool/mcp/McpClientBuilder.java b/agentscope-core/src/main/java/io/agentscope/core/tool/mcp/McpClientBuilder.java index 0338e56d7..2798721ba 100644 --- a/agentscope-core/src/main/java/io/agentscope/core/tool/mcp/McpClientBuilder.java +++ b/agentscope-core/src/main/java/io/agentscope/core/tool/mcp/McpClientBuilder.java @@ -25,8 +25,6 @@ import io.modelcontextprotocol.json.McpJsonMapper; import io.modelcontextprotocol.spec.McpClientTransport; import io.modelcontextprotocol.spec.McpSchema; -import reactor.core.publisher.Mono; - import java.net.URI; import java.net.URLDecoder; import java.net.URLEncoder; @@ -40,6 +38,7 @@ import java.util.Map; import java.util.function.Consumer; import java.util.stream.Collectors; +import reactor.core.publisher.Mono; /** * Builder for creating MCP client wrappers with fluent configuration. diff --git a/agentscope-core/src/test/java/io/agentscope/core/model/OpenAIClientTest.java b/agentscope-core/src/test/java/io/agentscope/core/model/OpenAIClientTest.java index fe6cca90b..97b2110d1 100644 --- a/agentscope-core/src/test/java/io/agentscope/core/model/OpenAIClientTest.java +++ b/agentscope-core/src/test/java/io/agentscope/core/model/OpenAIClientTest.java @@ -15,10 +15,20 @@ */ package io.agentscope.core.model; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + import io.agentscope.core.formatter.openai.dto.OpenAIMessage; import io.agentscope.core.formatter.openai.dto.OpenAIRequest; import io.agentscope.core.formatter.openai.dto.OpenAIResponse; import io.agentscope.core.model.exception.OpenAIException; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; @@ -28,17 +38,6 @@ import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - /** * Unit tests for OpenAIClient. *