chore: update jackson version, add custom headers (#30)
This commit is contained in:
parent
192ea35963
commit
72f21989bb
35 changed files with 670 additions and 143 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -3,6 +3,7 @@ target/
|
||||||
!.mvn/wrapper/maven-wrapper.jar
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
!**/src/main/**
|
!**/src/main/**
|
||||||
!**/src/test/**
|
!**/src/test/**
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
### STS ###
|
### STS ###
|
||||||
.apt_generated
|
.apt_generated
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<slf4j.version>2.0.11</slf4j.version>
|
<slf4j.version>2.0.11</slf4j.version>
|
||||||
<okhttp.version>3.14.9</okhttp.version>
|
<okhttp.version>3.14.9</okhttp.version>
|
||||||
<jackson.version>2.11.3</jackson.version>
|
<jackson.version>2.18.3</jackson.version>
|
||||||
<retrofit2.version>2.9.0</retrofit2.version>
|
<retrofit2.version>2.9.0</retrofit2.version>
|
||||||
<rxjava.version>3.1.8</rxjava.version>
|
<rxjava.version>3.1.8</rxjava.version>
|
||||||
<jwt.version>4.2.2</jwt.version>
|
<jwt.version>4.2.2</jwt.version>
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
|
||||||
import retrofit2.converter.jackson.JacksonConverterFactory;
|
import retrofit2.converter.jackson.JacksonConverterFactory;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -477,6 +478,19 @@ public abstract class AbstractAiClient extends AbstractClientBaseService {
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Config the custom headers
|
||||||
|
* @param customHeaders custom headers
|
||||||
|
* @return this Builder instance for method chaining
|
||||||
|
*/
|
||||||
|
public B customHeaders(Map<String, String> customHeaders) {
|
||||||
|
if (customHeaders == null || customHeaders.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("Custom headers cannot be null or empty");
|
||||||
|
}
|
||||||
|
config.setCustomHeaders(customHeaders);
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disables token caching, forcing the client to use API keys for direct requests.
|
* Disables token caching, forcing the client to use API keys for direct requests.
|
||||||
* This is the default behavior.
|
* This is the default behavior.
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,13 @@ import okhttp3.ResponseBody;
|
||||||
import retrofit2.Call;
|
import retrofit2.Call;
|
||||||
import retrofit2.http.Body;
|
import retrofit2.http.Body;
|
||||||
import retrofit2.http.GET;
|
import retrofit2.http.GET;
|
||||||
|
import retrofit2.http.HeaderMap;
|
||||||
import retrofit2.http.POST;
|
import retrofit2.http.POST;
|
||||||
import retrofit2.http.Path;
|
import retrofit2.http.Path;
|
||||||
import retrofit2.http.Streaming;
|
import retrofit2.http.Streaming;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chat Completions API for advanced GLM-4 series models Provides synchronous,
|
* Chat Completions API for advanced GLM-4 series models Provides synchronous,
|
||||||
* asynchronous, and streaming chat completion capabilities Supports complex reasoning,
|
* asynchronous, and streaming chat completion capabilities Supports complex reasoning,
|
||||||
|
|
@ -36,6 +39,23 @@ public interface ChatApi {
|
||||||
@POST("chat/completions")
|
@POST("chat/completions")
|
||||||
Call<ResponseBody> createChatCompletionStream(@Body ChatCompletionCreateParams request);
|
Call<ResponseBody> createChatCompletionStream(@Body ChatCompletionCreateParams request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a streaming chat completion with custom headers support Returns response
|
||||||
|
* content incrementally through Server-Sent Events (SSE) for immediate user feedback
|
||||||
|
* Optimized for interactive applications requiring low latency and progressive
|
||||||
|
* content delivery Supports all GLM-4 models with configurable streaming parameters
|
||||||
|
* and custom HTTP headers
|
||||||
|
* @param request Chat completion parameters including model selection, messages, and
|
||||||
|
* streaming settings
|
||||||
|
* @param headers Custom HTTP headers to be added to the request
|
||||||
|
* @return Streaming response body with incremental content, usage statistics, and
|
||||||
|
* completion indicators
|
||||||
|
*/
|
||||||
|
@Streaming
|
||||||
|
@POST("chat/completions")
|
||||||
|
Call<ResponseBody> createChatCompletionStream(@Body ChatCompletionCreateParams request,
|
||||||
|
@HeaderMap Map<String, String> headers);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an asynchronous chat completion for long-running tasks Submits the request
|
* Create an asynchronous chat completion for long-running tasks Submits the request
|
||||||
* and returns immediately with a task ID for later result retrieval Ideal for complex
|
* and returns immediately with a task ID for later result retrieval Ideal for complex
|
||||||
|
|
@ -64,6 +84,22 @@ public interface ChatApi {
|
||||||
@POST("chat/completions")
|
@POST("chat/completions")
|
||||||
Single<ModelData> createChatCompletion(@Body ChatCompletionCreateParams request);
|
Single<ModelData> createChatCompletion(@Body ChatCompletionCreateParams request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a synchronous chat completion with custom headers support Waits for the
|
||||||
|
* GLM-4 model to complete execution and returns the final result with custom HTTP
|
||||||
|
* headers Supports complex reasoning, tool calling, function execution, and
|
||||||
|
* multi-modal understanding Features advanced capabilities like web search
|
||||||
|
* integration, code interpretation, and image analysis
|
||||||
|
* @param request Chat completion parameters including model selection, conversation
|
||||||
|
* messages, generation settings, tools configuration, and response format
|
||||||
|
* @param headers Custom HTTP headers to be added to the request
|
||||||
|
* @return Complete chat completion response with generated content, usage statistics,
|
||||||
|
* tool call results, and reasoning traces
|
||||||
|
*/
|
||||||
|
@POST("chat/completions")
|
||||||
|
Single<ModelData> createChatCompletion(@Body ChatCompletionCreateParams request,
|
||||||
|
@HeaderMap Map<String, String> headers);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query the result of an asynchronous chat completion task Retrieves the completion
|
* Query the result of an asynchronous chat completion task Retrieves the completion
|
||||||
* result or current status using the task ID from async request Provides detailed
|
* result or current status using the task ID from async request Provides detailed
|
||||||
|
|
|
||||||
|
|
@ -260,6 +260,11 @@ public final class Constants {
|
||||||
*/
|
*/
|
||||||
public static final String ModelCogVideoX2 = "cogvideox-2";
|
public static final String ModelCogVideoX2 = "cogvideox-2";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CogVideoX-3 model
|
||||||
|
*/
|
||||||
|
public static final String ModelCogVideoX3 = "cogvideox-3";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vidu Q1 Text model - High-performance video generation from text input. Supports
|
* Vidu Q1 Text model - High-performance video generation from text input. Supports
|
||||||
* general and anime styles.
|
* general and anime styles.
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import lombok.Builder;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static ai.z.openapi.core.Constants.Z_AI_BASE_URL;
|
import static ai.z.openapi.core.Constants.Z_AI_BASE_URL;
|
||||||
|
|
@ -63,6 +64,11 @@ public class ZaiConfig {
|
||||||
*/
|
*/
|
||||||
private String apiSecret;
|
private String apiSecret;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom Http Request Headers
|
||||||
|
*/
|
||||||
|
private Map<String, String> customHeaders;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JWT token expiration time in milliseconds (default: 30 minutes).
|
* JWT token expiration time in milliseconds (default: 30 minutes).
|
||||||
*/
|
*/
|
||||||
|
|
@ -408,4 +414,12 @@ public class ZaiConfig {
|
||||||
return source_channel;
|
return source_channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get custom headers
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Map<String, String> getCustomHeaders() {
|
||||||
|
return customHeaders;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,16 +7,17 @@ import okhttp3.Request;
|
||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OkHttp Interceptor that adds an authorization token header
|
* OkHttp Interceptor that adds an authorization token header
|
||||||
*/
|
*/
|
||||||
public class AuthenticationInterceptor implements Interceptor {
|
public class HttpRequestInterceptor implements Interceptor {
|
||||||
|
|
||||||
private final ZaiConfig config;
|
private final ZaiConfig config;
|
||||||
|
|
||||||
public AuthenticationInterceptor(ZaiConfig config) {
|
public HttpRequestInterceptor(ZaiConfig config) {
|
||||||
Objects.requireNonNull(config.getApiKey(), "Z.ai token required");
|
Objects.requireNonNull(config.getApiKey(), "Z.ai token required");
|
||||||
this.config = config;
|
this.config = config;
|
||||||
}
|
}
|
||||||
|
|
@ -31,17 +32,22 @@ public class AuthenticationInterceptor implements Interceptor {
|
||||||
TokenManager tokenManager = GlobalTokenManager.getTokenManagerV4();
|
TokenManager tokenManager = GlobalTokenManager.getTokenManagerV4();
|
||||||
accessToken = tokenManager.getToken(this.config);
|
accessToken = tokenManager.getToken(this.config);
|
||||||
}
|
}
|
||||||
String source_channel = "java-sdk";
|
String source_channel = "z-ai-sdk-java";
|
||||||
if (StringUtils.isNotEmpty(config.getSource_channel())) {
|
if (StringUtils.isNotEmpty(config.getSource_channel())) {
|
||||||
source_channel = config.getSource_channel();
|
source_channel = config.getSource_channel();
|
||||||
}
|
}
|
||||||
Request request = chain.request()
|
Request.Builder request = chain.request()
|
||||||
.newBuilder()
|
.newBuilder()
|
||||||
.header("Authorization", "Bearer " + accessToken)
|
.header("Authorization", "Bearer " + accessToken)
|
||||||
.header("x-source-channel", source_channel)
|
.header("x-source-channel", source_channel)
|
||||||
.header("Accept-Language", "en-US,en")
|
.header("Zai-SDK-Ver", "0.0.2")
|
||||||
.build();
|
.header("Accept-Language", "en-US,en");
|
||||||
return chain.proceed(request);
|
if (Objects.nonNull(config.getCustomHeaders())) {
|
||||||
|
for (Map.Entry<String, String> entry : config.getCustomHeaders().entrySet()) {
|
||||||
|
request.addHeader(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return chain.proceed(request.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -5,6 +5,8 @@ import ai.z.openapi.service.model.ChatCompletionResponse;
|
||||||
import ai.z.openapi.service.model.AsyncResultRetrieveParams;
|
import ai.z.openapi.service.model.AsyncResultRetrieveParams;
|
||||||
import ai.z.openapi.service.model.QueryModelResultResponse;
|
import ai.z.openapi.service.model.QueryModelResultResponse;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chat completion service interface
|
* Chat completion service interface
|
||||||
*/
|
*/
|
||||||
|
|
@ -32,4 +34,13 @@ public interface ChatService {
|
||||||
*/
|
*/
|
||||||
QueryModelResultResponse retrieveAsyncResult(AsyncResultRetrieveParams request);
|
QueryModelResultResponse retrieveAsyncResult(AsyncResultRetrieveParams request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a chat completion with custom headers support. This method allows passing
|
||||||
|
* custom HTTP headers along with the chat completion request.
|
||||||
|
* @param request the chat completion request parameters
|
||||||
|
* @param customHeaders custom HTTP headers to be added to the request
|
||||||
|
* @return ChatCompletionResponse containing the completion result
|
||||||
|
*/
|
||||||
|
ChatCompletionResponse createChatCompletion(ChatCompletionCreateParams request, Map<String, String> customHeaders);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -7,11 +7,12 @@ import ai.z.openapi.service.model.ChatCompletionResponse;
|
||||||
import ai.z.openapi.service.model.AsyncResultRetrieveParams;
|
import ai.z.openapi.service.model.AsyncResultRetrieveParams;
|
||||||
import ai.z.openapi.service.model.QueryModelResultResponse;
|
import ai.z.openapi.service.model.QueryModelResultResponse;
|
||||||
import ai.z.openapi.service.model.ModelData;
|
import ai.z.openapi.service.model.ModelData;
|
||||||
|
import ai.z.openapi.service.model.ChatRequestWithHeaders;
|
||||||
import ai.z.openapi.utils.FlowableRequestSupplier;
|
import ai.z.openapi.utils.FlowableRequestSupplier;
|
||||||
import ai.z.openapi.utils.RequestSupplier;
|
import ai.z.openapi.utils.RequestSupplier;
|
||||||
import ai.z.openapi.utils.StringUtils;
|
|
||||||
import okhttp3.ResponseBody;
|
import okhttp3.ResponseBody;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -64,6 +65,38 @@ public class ChatServiceImpl implements ChatService {
|
||||||
return this.zAiClient.executeRequest(request, supplier, ChatCompletionResponse.class);
|
return this.zAiClient.executeRequest(request, supplier, ChatCompletionResponse.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChatCompletionResponse createChatCompletion(ChatCompletionCreateParams request,
|
||||||
|
Map<String, String> customHeaders) {
|
||||||
|
if (Objects.isNull(customHeaders)) {
|
||||||
|
throw new IllegalArgumentException("customHeaders can not be null");
|
||||||
|
}
|
||||||
|
validateParams(request);
|
||||||
|
if (Objects.nonNull(request.getStream()) && request.getStream()) {
|
||||||
|
return streamChatCompletionWithHeaders(request, customHeaders);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return syncChatCompletionWithHeaders(request, customHeaders);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ChatCompletionResponse streamChatCompletionWithHeaders(ChatCompletionCreateParams request,
|
||||||
|
Map<String, String> customHeaders) {
|
||||||
|
ChatRequestWithHeaders requestWithHeaders = new ChatRequestWithHeaders(request, customHeaders);
|
||||||
|
FlowableRequestSupplier<ChatRequestWithHeaders, retrofit2.Call<ResponseBody>> supplier = (wrapper) -> chatApi
|
||||||
|
.createChatCompletionStream(wrapper.getRequest(), wrapper.getCustomHeaders());
|
||||||
|
return this.zAiClient.streamRequest(requestWithHeaders, supplier, ChatCompletionResponse.class,
|
||||||
|
ModelData.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ChatCompletionResponse syncChatCompletionWithHeaders(ChatCompletionCreateParams request,
|
||||||
|
Map<String, String> customHeaders) {
|
||||||
|
ChatRequestWithHeaders requestWithHeaders = new ChatRequestWithHeaders(request, customHeaders);
|
||||||
|
RequestSupplier<ChatRequestWithHeaders, ModelData> supplier = (wrapper) -> chatApi
|
||||||
|
.createChatCompletion(wrapper.getRequest(), wrapper.getCustomHeaders());
|
||||||
|
return this.zAiClient.executeRequest(requestWithHeaders, supplier, ChatCompletionResponse.class);
|
||||||
|
}
|
||||||
|
|
||||||
private void validateParams(ChatCompletionCreateParams request) {
|
private void validateParams(ChatCompletionCreateParams request) {
|
||||||
if (request == null) {
|
if (request == null) {
|
||||||
throw new IllegalArgumentException("request cannot be null");
|
throw new IllegalArgumentException("request cannot be null");
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
package ai.z.openapi.service.file;
|
||||||
|
|
||||||
|
public enum UploadFilePurpose {
|
||||||
|
|
||||||
|
BATCH("batch"), FILE_EXTRACT("file-extract"), CODE_INTERPRETER("code-interpreter"), AGENT("agent");
|
||||||
|
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
UploadFilePurpose(final String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String value() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
package ai.z.openapi.service.model;
|
||||||
|
|
||||||
|
import ai.z.openapi.core.model.ClientRequest;
|
||||||
|
import ai.z.openapi.service.CommonRequest;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chat request wrapper that includes custom headers support. This class wraps the
|
||||||
|
* original ChatCompletionCreateParams and adds custom headers functionality.
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class ChatRequestWithHeaders extends CommonRequest implements ClientRequest<ChatRequestWithHeaders> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The original chat completion request parameters
|
||||||
|
*/
|
||||||
|
private ChatCompletionCreateParams request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom headers to be added to the HTTP request
|
||||||
|
*/
|
||||||
|
private Map<String, String> customHeaders;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package ai.z.openapi.utils;
|
package ai.z.openapi.utils;
|
||||||
|
|
||||||
import ai.z.openapi.core.config.ZaiConfig;
|
import ai.z.openapi.core.config.ZaiConfig;
|
||||||
import ai.z.openapi.core.token.AuthenticationInterceptor;
|
import ai.z.openapi.core.token.HttpRequestInterceptor;
|
||||||
import okhttp3.ConnectionPool;
|
import okhttp3.ConnectionPool;
|
||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
|
|
||||||
|
|
@ -42,7 +42,7 @@ public final class OkHttps {
|
||||||
throw new IllegalArgumentException("Configuration cannot be null");
|
throw new IllegalArgumentException("Configuration cannot be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
OkHttpClient.Builder builder = new OkHttpClient.Builder().addInterceptor(new AuthenticationInterceptor(config));
|
OkHttpClient.Builder builder = new OkHttpClient.Builder().addInterceptor(new HttpRequestInterceptor(config));
|
||||||
|
|
||||||
// Configure timeouts
|
// Configure timeouts
|
||||||
configureTimeouts(builder, config);
|
configureTimeouts(builder, config);
|
||||||
|
|
|
||||||
|
|
@ -61,44 +61,6 @@ public class AssistantServiceTest {
|
||||||
"AssistantService should be an instance of AssistantServiceImpl");
|
"AssistantService should be an instance of AssistantServiceImpl");
|
||||||
}
|
}
|
||||||
|
|
||||||
// As of 2025-07-23, no models support synchronous completion
|
|
||||||
// @Test
|
|
||||||
// @DisplayName("Test Synchronous Assistant Completion - Basic Functionality")
|
|
||||||
// @EnabledIfEnvironmentVariable(named = "ZAI_API_KEY", matches = "^[^.]+\\.[^.]+$")
|
|
||||||
// void testSyncAssistantCompletion() throws JsonProcessingException {
|
|
||||||
// // Prepare test data
|
|
||||||
// MessageTextContent textContent = MessageTextContent.builder()
|
|
||||||
// .text("Hello, please introduce yourself")
|
|
||||||
// .type("text")
|
|
||||||
// .build();
|
|
||||||
|
|
||||||
// ConversationMessage message = ConversationMessage.builder()
|
|
||||||
// .role("user")
|
|
||||||
// .content(Collections.singletonList(textContent))
|
|
||||||
// .build();
|
|
||||||
|
|
||||||
// String requestId = String.format(REQUEST_ID_TEMPLATE, System.currentTimeMillis());
|
|
||||||
|
|
||||||
// AssistantParameters request = AssistantParameters.builder()
|
|
||||||
// .model(Constants.ModelChatGLM4Assistant)
|
|
||||||
// .assistantId(TEST_ASSISTANT_ID)
|
|
||||||
// .stream(false)
|
|
||||||
// .messages(Collections.singletonList(message))
|
|
||||||
// .requestId(requestId)
|
|
||||||
// .build();
|
|
||||||
|
|
||||||
// // Execute test
|
|
||||||
// AssistantApiResponse response = assistantService.assistantCompletion(request);
|
|
||||||
|
|
||||||
// // Verify results
|
|
||||||
// assertNotNull(response, "Response should not be null");
|
|
||||||
// assertTrue(response.isSuccess(), "Response should be successful");
|
|
||||||
// assertNotNull(response.getData(), "Response data should not be null");
|
|
||||||
// assertNull(response.getError(), "Response error should be null");
|
|
||||||
// logger.info("Synchronous assistant completion response: {}",
|
|
||||||
// mapper.writeValueAsString(response));
|
|
||||||
// }
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Test Stream Assistant Completion")
|
@DisplayName("Test Stream Assistant Completion")
|
||||||
@EnabledIfEnvironmentVariable(named = "ZAI_API_KEY", matches = "^[^.]+\\.[^.]+$")
|
@EnabledIfEnvironmentVariable(named = "ZAI_API_KEY", matches = "^[^.]+\\.[^.]+$")
|
||||||
|
|
@ -188,13 +150,17 @@ public class AssistantServiceTest {
|
||||||
@EnabledIfEnvironmentVariable(named = "ZAI_API_KEY", matches = "^[^.]+\\.[^.]+$")
|
@EnabledIfEnvironmentVariable(named = "ZAI_API_KEY", matches = "^[^.]+\\.[^.]+$")
|
||||||
void testQueryConversationUsage() {
|
void testQueryConversationUsage() {
|
||||||
// Prepare test data
|
// Prepare test data
|
||||||
ConversationParameters request = ConversationParameters.builder().assistantId(TEST_ASSISTANT_ID).build();
|
ConversationParameters request = ConversationParameters.builder()
|
||||||
|
.assistantId(TEST_ASSISTANT_ID)
|
||||||
|
.page(1)
|
||||||
|
.pageSize(5)
|
||||||
|
.build();
|
||||||
|
|
||||||
// Execute test
|
// Execute test
|
||||||
ConversationUsageListResponse response = assistantService.queryConversationUsage(request);
|
ConversationUsageListResponse response = assistantService.queryConversationUsage(request);
|
||||||
|
|
||||||
// Verify results
|
// Verify results
|
||||||
assertNotNull(response, "Response should not be null");
|
assertNotNull(response.getData(), "Response should not be null");
|
||||||
logger.info("Query conversation usage response: {}", response);
|
logger.info("Query conversation usage response: {}", response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -216,7 +182,7 @@ public class AssistantServiceTest {
|
||||||
.messages(Collections.singletonList(message))
|
.messages(Collections.singletonList(message))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
AssistantApiResponse response = assistantService.assistantCompletion(request);
|
AssistantApiResponse response = assistantService.assistantCompletionStream(request);
|
||||||
|
|
||||||
// Should handle error gracefully
|
// Should handle error gracefully
|
||||||
assertNotNull(response, "Response should not be null even for invalid assistant ID");
|
assertNotNull(response, "Response should not be null even for invalid assistant ID");
|
||||||
|
|
@ -258,45 +224,29 @@ public class AssistantServiceTest {
|
||||||
|
|
||||||
AssistantParameters request = AssistantParameters.builder()
|
AssistantParameters request = AssistantParameters.builder()
|
||||||
.assistantId(TEST_ASSISTANT_ID)
|
.assistantId(TEST_ASSISTANT_ID)
|
||||||
.stream(false)
|
.stream(true)
|
||||||
.messages(messages)
|
.messages(messages)
|
||||||
.requestId(requestId)
|
.requestId(requestId)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
AssistantApiResponse response = assistantService.assistantCompletion(request);
|
AssistantApiResponse response = assistantService.assistantCompletionStream(request);
|
||||||
|
response.getFlowable().doOnNext(accumulator -> {
|
||||||
|
if (accumulator.getChoices() != null && !accumulator.getChoices().isEmpty()) {
|
||||||
|
MessageContent delta = accumulator.getChoices().get(0).getDelta();
|
||||||
|
if (delta != null) {
|
||||||
|
try {
|
||||||
|
logger.info("MessageContent: {}", mapper.writeValueAsString(delta));
|
||||||
|
}
|
||||||
|
catch (JsonProcessingException e) {
|
||||||
|
logger.error("Error processing message content", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.doOnComplete(() -> logger.info("Stream response completed, received messages"))
|
||||||
|
.doOnError(throwable -> logger.error("Stream error: {}", throwable.getMessage()))
|
||||||
|
.blockingSubscribe();
|
||||||
assertNotNull(response, "Multi-turn conversation response should not be null");
|
assertNotNull(response, "Multi-turn conversation response should not be null");
|
||||||
logger.info("Multi-turn conversation response: {}", mapper.writeValueAsString(response));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Test Assistant with Translation Parameters")
|
|
||||||
@EnabledIfEnvironmentVariable(named = "ZAI_API_KEY", matches = "^[^.]+\\.[^.]+$")
|
|
||||||
void testAssistantWithTranslation() throws JsonProcessingException {
|
|
||||||
// This test is based on the existing
|
|
||||||
// TestAssistantClientApiService.testTranslateAssistantCompletion
|
|
||||||
MessageTextContent textContent = MessageTextContent.builder().text("Hello there").type("text").build();
|
|
||||||
|
|
||||||
ConversationMessage message = ConversationMessage.builder()
|
|
||||||
.role("user")
|
|
||||||
.content(Collections.singletonList(textContent))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
String requestId = String.format(REQUEST_ID_TEMPLATE, System.currentTimeMillis());
|
|
||||||
|
|
||||||
AssistantParameters request = AssistantParameters.builder()
|
|
||||||
.assistantId("9996ijk789lmn012o345p999") // Translation assistant ID
|
|
||||||
.stream(false)
|
|
||||||
.messages(Collections.singletonList(message))
|
|
||||||
.requestId(requestId)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Execute test
|
|
||||||
AssistantApiResponse response = assistantService.assistantCompletion(request);
|
|
||||||
|
|
||||||
// Verify results
|
|
||||||
assertNotNull(response, "Translation response should not be null");
|
|
||||||
logger.info("Translation assistant response: {}", mapper.writeValueAsString(response));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -303,7 +303,7 @@ public class AudioServiceTest {
|
||||||
@DisplayName("Should transcribe different audio formats successfully")
|
@DisplayName("Should transcribe different audio formats successfully")
|
||||||
@EnabledIfEnvironmentVariable(named = "ZAI_API_KEY", matches = "^[^.]+\\.[^.]+$")
|
@EnabledIfEnvironmentVariable(named = "ZAI_API_KEY", matches = "^[^.]+\\.[^.]+$")
|
||||||
void shouldTranscribeDifferentAudioFormatsSuccessfully() throws JsonProcessingException {
|
void shouldTranscribeDifferentAudioFormatsSuccessfully() throws JsonProcessingException {
|
||||||
String[] audioFiles = { "asr.wav", "asr.webm" };
|
String[] audioFiles = { "asr.wav", "asr.mp3" };
|
||||||
|
|
||||||
for (String audioFile : audioFiles) {
|
for (String audioFile : audioFiles) {
|
||||||
String requestId = String.format(REQUEST_ID_TEMPLATE + "-%s", System.currentTimeMillis(), audioFile);
|
String requestId = String.format(REQUEST_ID_TEMPLATE + "-%s", System.currentTimeMillis(), audioFile);
|
||||||
|
|
|
||||||
|
|
@ -508,4 +508,187 @@ public class ChatServiceTest {
|
||||||
logger.info("CodeGeex code completion test completed");
|
logger.info("CodeGeex code completion test completed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Test Synchronous Chat Completion with Custom Headers")
|
||||||
|
@EnabledIfEnvironmentVariable(named = "ZAI_API_KEY", matches = "^[^.]+\\.[^.]+$")
|
||||||
|
void testSyncChatCompletionWithCustomHeaders() throws JsonProcessingException {
|
||||||
|
// Prepare test data
|
||||||
|
List<ChatMessage> messages = new ArrayList<>();
|
||||||
|
ChatMessage userMessage = new ChatMessage(ChatMessageRole.USER.value(), "Hello, please introduce yourself");
|
||||||
|
messages.add(userMessage);
|
||||||
|
|
||||||
|
String requestId = String.format(REQUEST_ID_TEMPLATE, System.currentTimeMillis());
|
||||||
|
|
||||||
|
ChatCompletionCreateParams request = ChatCompletionCreateParams.builder()
|
||||||
|
.model(Constants.ModelChatGLM4)
|
||||||
|
.stream(Boolean.FALSE)
|
||||||
|
.messages(messages)
|
||||||
|
.requestId(requestId)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Prepare custom headers
|
||||||
|
Map<String, String> customHeaders = new HashMap<>();
|
||||||
|
customHeaders.put("X-Custom-User-ID", "test-user-123");
|
||||||
|
customHeaders.put("X-Request-Source", "junit-test");
|
||||||
|
customHeaders.put("Session-Id", "session-" + System.currentTimeMillis());
|
||||||
|
|
||||||
|
// Execute test
|
||||||
|
ChatCompletionResponse response = chatService.createChatCompletion(request, customHeaders);
|
||||||
|
|
||||||
|
// Verify results
|
||||||
|
assertNotNull(response, "Response should not be null");
|
||||||
|
assertTrue(response.isSuccess(), "Response should be successful");
|
||||||
|
assertNotNull(response.getData(), "Response data should not be null");
|
||||||
|
assertEquals(requestId, response.getData().getRequestId(), "Request ID should match");
|
||||||
|
assertNotNull(response.getData().getChoices(), "Response data should not be null");
|
||||||
|
assertFalse(response.getData().getChoices().isEmpty(), "Response data should not be empty");
|
||||||
|
assertNull(response.getError(), "Response error should be null");
|
||||||
|
logger.info("Synchronous chat completion with custom headers response: {}",
|
||||||
|
mapper.writeValueAsString(response));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Test Stream Chat Completion with Custom Headers")
|
||||||
|
@EnabledIfEnvironmentVariable(named = "ZAI_API_KEY", matches = "^[^.]+\\.[^.]+$")
|
||||||
|
void testStreamChatCompletionWithCustomHeaders() throws JsonProcessingException {
|
||||||
|
// Prepare test data
|
||||||
|
List<ChatMessage> messages = new ArrayList<>();
|
||||||
|
ChatMessage userMessage = new ChatMessage(ChatMessageRole.USER.value(),
|
||||||
|
"Please write a short poem about spring");
|
||||||
|
messages.add(userMessage);
|
||||||
|
|
||||||
|
String requestId = String.format(REQUEST_ID_TEMPLATE, System.currentTimeMillis());
|
||||||
|
|
||||||
|
ChatCompletionCreateParams request = ChatCompletionCreateParams.builder()
|
||||||
|
.model(Constants.ModelChatGLM4)
|
||||||
|
.stream(Boolean.TRUE)
|
||||||
|
.messages(messages)
|
||||||
|
.requestId(requestId)
|
||||||
|
.temperature(0.7F)
|
||||||
|
.maxTokens(100)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Prepare custom headers
|
||||||
|
Map<String, String> customHeaders = new HashMap<>();
|
||||||
|
customHeaders.put("X-Custom-User-ID", "stream-test-user-456");
|
||||||
|
customHeaders.put("X-Request-Source", "junit-stream-test");
|
||||||
|
customHeaders.put("X-Stream-Mode", "enabled");
|
||||||
|
customHeaders.put("Content-Type", "application/json");
|
||||||
|
|
||||||
|
// Execute test
|
||||||
|
ChatCompletionResponse response = chatService.createChatCompletion(request, customHeaders);
|
||||||
|
|
||||||
|
// Verify results
|
||||||
|
assertNotNull(response, "Response should not be null");
|
||||||
|
assertTrue(response.isSuccess(), "Response should be successful");
|
||||||
|
|
||||||
|
// Test stream data processing
|
||||||
|
AtomicInteger messageCount = new AtomicInteger(0);
|
||||||
|
AtomicBoolean isFirst = new AtomicBoolean(true);
|
||||||
|
|
||||||
|
response.getFlowable().doOnNext(modelData -> {
|
||||||
|
if (isFirst.getAndSet(false)) {
|
||||||
|
logger.info("Starting to receive stream response with custom headers:");
|
||||||
|
}
|
||||||
|
if (modelData.getChoices() != null && !modelData.getChoices().isEmpty()) {
|
||||||
|
Choice choice = modelData.getChoices().get(0);
|
||||||
|
if (choice.getDelta() != null && choice.getDelta().getContent() != null) {
|
||||||
|
logger.info("Received content: {}", choice.getDelta().getContent());
|
||||||
|
messageCount.incrementAndGet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.doOnComplete(() -> logger.info(
|
||||||
|
"Stream response with custom headers completed, received {} messages in total", messageCount.get()))
|
||||||
|
.blockingSubscribe();
|
||||||
|
|
||||||
|
assertTrue(messageCount.get() > 0, "Should receive at least one message");
|
||||||
|
|
||||||
|
logger.info("Stream chat completion with custom headers test completed");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Test Custom Headers Validation - Null Headers")
|
||||||
|
void testCustomHeadersValidation_NullHeaders() {
|
||||||
|
// Prepare test data
|
||||||
|
List<ChatMessage> messages = new ArrayList<>();
|
||||||
|
ChatMessage userMessage = new ChatMessage(ChatMessageRole.USER.value(), "Hello");
|
||||||
|
messages.add(userMessage);
|
||||||
|
|
||||||
|
ChatCompletionCreateParams request = ChatCompletionCreateParams.builder()
|
||||||
|
.model(Constants.ModelChatGLM4)
|
||||||
|
.stream(Boolean.FALSE)
|
||||||
|
.messages(messages)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Test with null custom headers
|
||||||
|
assertThrows(IllegalArgumentException.class, () -> {
|
||||||
|
chatService.createChatCompletion(request, null);
|
||||||
|
}, "Null custom headers should throw IllegalArgumentException");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Test Custom Headers with Empty Map")
|
||||||
|
@EnabledIfEnvironmentVariable(named = "ZAI_API_KEY", matches = "^[^.]+\\.[^.]+$")
|
||||||
|
void testCustomHeadersWithEmptyMap() throws JsonProcessingException {
|
||||||
|
// Prepare test data
|
||||||
|
List<ChatMessage> messages = new ArrayList<>();
|
||||||
|
ChatMessage userMessage = new ChatMessage(ChatMessageRole.USER.value(), "Hello");
|
||||||
|
messages.add(userMessage);
|
||||||
|
|
||||||
|
String requestId = String.format(REQUEST_ID_TEMPLATE, System.currentTimeMillis());
|
||||||
|
|
||||||
|
ChatCompletionCreateParams request = ChatCompletionCreateParams.builder()
|
||||||
|
.model(Constants.ModelChatGLM4)
|
||||||
|
.stream(Boolean.FALSE)
|
||||||
|
.messages(messages)
|
||||||
|
.requestId(requestId)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Test with empty custom headers map
|
||||||
|
Map<String, String> emptyHeaders = new HashMap<>();
|
||||||
|
ChatCompletionResponse response = chatService.createChatCompletion(request, emptyHeaders);
|
||||||
|
|
||||||
|
// Verify results
|
||||||
|
assertNotNull(response, "Response should not be null");
|
||||||
|
assertTrue(response.isSuccess(), "Response should be successful");
|
||||||
|
assertNotNull(response.getData(), "Response data should not be null");
|
||||||
|
logger.info("Chat completion with empty custom headers response: {}", mapper.writeValueAsString(response));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Test Custom Headers with Special Characters")
|
||||||
|
@EnabledIfEnvironmentVariable(named = "ZAI_API_KEY", matches = "^[^.]+\\.[^.]+$")
|
||||||
|
void testCustomHeadersWithSpecialCharacters() throws JsonProcessingException {
|
||||||
|
// Prepare test data
|
||||||
|
List<ChatMessage> messages = new ArrayList<>();
|
||||||
|
ChatMessage userMessage = new ChatMessage(ChatMessageRole.USER.value(), "Hello");
|
||||||
|
messages.add(userMessage);
|
||||||
|
|
||||||
|
String requestId = String.format(REQUEST_ID_TEMPLATE, System.currentTimeMillis());
|
||||||
|
|
||||||
|
ChatCompletionCreateParams request = ChatCompletionCreateParams.builder()
|
||||||
|
.model(Constants.ModelChatGLM4)
|
||||||
|
.stream(Boolean.FALSE)
|
||||||
|
.messages(messages)
|
||||||
|
.requestId(requestId)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Prepare custom headers with special characters
|
||||||
|
Map<String, String> customHeaders = new HashMap<>();
|
||||||
|
customHeaders.put("X-User-Agent", "ZAI-SDK/1.0 (Java; Test)");
|
||||||
|
customHeaders.put("X-Client-Version", "v1.2.3-beta");
|
||||||
|
customHeaders.put("X-Request-Timestamp", String.valueOf(System.currentTimeMillis()));
|
||||||
|
customHeaders.put("X-Trace-ID", "trace-" + UUID.randomUUID());
|
||||||
|
|
||||||
|
// Execute test
|
||||||
|
ChatCompletionResponse response = chatService.createChatCompletion(request, customHeaders);
|
||||||
|
|
||||||
|
// Verify results
|
||||||
|
assertNotNull(response, "Response should not be null");
|
||||||
|
assertTrue(response.isSuccess(), "Response should be successful");
|
||||||
|
assertNotNull(response.getData(), "Response data should not be null");
|
||||||
|
logger.info("Chat completion with special character headers response: {}", mapper.writeValueAsString(response));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,120 @@
|
||||||
|
package ai.z.openapi.service.chat;
|
||||||
|
|
||||||
|
import ai.z.openapi.service.model.ChatCompletionCreateParams;
|
||||||
|
import ai.z.openapi.service.model.ChatMessage;
|
||||||
|
import ai.z.openapi.service.model.ChatMessageRole;
|
||||||
|
import ai.z.openapi.service.model.ChatRequestWithHeaders;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit test for ChatRequestWithHeaders wrapper functionality. Tests the wrapper class
|
||||||
|
* used for custom headers in chat requests.
|
||||||
|
*/
|
||||||
|
class ChatServiceWithHeadersIntegrationTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testChatRequestWithHeaders_StreamingRequest() {
|
||||||
|
// Arrange
|
||||||
|
ChatCompletionCreateParams request = ChatCompletionCreateParams.builder()
|
||||||
|
.model("glm-4-flash")
|
||||||
|
.messages(Arrays
|
||||||
|
.asList(ChatMessage.builder().role(ChatMessageRole.USER.value()).content("Hello, world!").build()))
|
||||||
|
.stream(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Map<String, String> customHeaders = new HashMap<>();
|
||||||
|
customHeaders.put("X-Custom-User-ID", "user123");
|
||||||
|
customHeaders.put("X-Request-Source", "test");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
ChatRequestWithHeaders wrapper = new ChatRequestWithHeaders(request, customHeaders);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
assertNotNull(wrapper);
|
||||||
|
assertNotNull(wrapper.getRequest());
|
||||||
|
assertNotNull(wrapper.getCustomHeaders());
|
||||||
|
assertEquals(request, wrapper.getRequest());
|
||||||
|
assertEquals(customHeaders, wrapper.getCustomHeaders());
|
||||||
|
assertEquals(2, wrapper.getCustomHeaders().size());
|
||||||
|
assertEquals("user123", wrapper.getCustomHeaders().get("X-Custom-User-ID"));
|
||||||
|
assertEquals("test", wrapper.getCustomHeaders().get("X-Request-Source"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testChatRequestWithHeaders_NonStreamingRequest() {
|
||||||
|
// Arrange
|
||||||
|
ChatCompletionCreateParams request = ChatCompletionCreateParams.builder()
|
||||||
|
.model("glm-4-flash")
|
||||||
|
.messages(Arrays
|
||||||
|
.asList(ChatMessage.builder().role(ChatMessageRole.USER.value()).content("What is AI?").build()))
|
||||||
|
.stream(false) // Non-streaming request
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Map<String, String> customHeaders = new HashMap<>();
|
||||||
|
customHeaders.put("X-Custom-User-ID", "user456");
|
||||||
|
customHeaders.put("X-Request-Source", "test-sync");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
ChatRequestWithHeaders wrapper = new ChatRequestWithHeaders(request, customHeaders);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
assertNotNull(wrapper);
|
||||||
|
assertNotNull(wrapper.getRequest());
|
||||||
|
assertNotNull(wrapper.getCustomHeaders());
|
||||||
|
assertEquals(request, wrapper.getRequest());
|
||||||
|
assertEquals(customHeaders, wrapper.getCustomHeaders());
|
||||||
|
assertFalse(wrapper.getRequest().getStream()); // Verify non-streaming
|
||||||
|
assertEquals("user456", wrapper.getCustomHeaders().get("X-Custom-User-ID"));
|
||||||
|
assertEquals("test-sync", wrapper.getCustomHeaders().get("X-Request-Source"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testChatRequestWithHeaders_NullHeaders() {
|
||||||
|
// Arrange
|
||||||
|
ChatCompletionCreateParams request = ChatCompletionCreateParams.builder()
|
||||||
|
.model("glm-4-flash")
|
||||||
|
.messages(Arrays
|
||||||
|
.asList(ChatMessage.builder().role(ChatMessageRole.USER.value()).content("Test message").build()))
|
||||||
|
.stream(false)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
ChatRequestWithHeaders wrapper = new ChatRequestWithHeaders(request, null);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
assertNotNull(wrapper);
|
||||||
|
assertNotNull(wrapper.getRequest());
|
||||||
|
assertEquals(request, wrapper.getRequest());
|
||||||
|
// Custom headers are converted to empty map when null
|
||||||
|
assertNull(wrapper.getCustomHeaders());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testChatRequestWithHeaders_ToString() {
|
||||||
|
// Arrange
|
||||||
|
ChatCompletionCreateParams request = ChatCompletionCreateParams.builder()
|
||||||
|
.model("glm-4-flash")
|
||||||
|
.messages(Arrays
|
||||||
|
.asList(ChatMessage.builder().role(ChatMessageRole.USER.value()).content("Test message").build()))
|
||||||
|
.stream(false)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Map<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("X-Test", "value");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
ChatRequestWithHeaders wrapper = new ChatRequestWithHeaders(request, headers);
|
||||||
|
String toStringResult = wrapper.toString();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
assertNotNull(toStringResult);
|
||||||
|
assertTrue(toStringResult.contains("ChatRequestWithHeaders"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -37,13 +37,6 @@ public class FileServiceTest {
|
||||||
// Request ID template
|
// Request ID template
|
||||||
private static final String REQUEST_ID_TEMPLATE = "file-test-%d";
|
private static final String REQUEST_ID_TEMPLATE = "file-test-%d";
|
||||||
|
|
||||||
// Test file purposes
|
|
||||||
private static final String PURPOSE_FINE_TUNE = "fine-tune";
|
|
||||||
|
|
||||||
private static final String PURPOSE_ASSISTANTS = "assistants";
|
|
||||||
|
|
||||||
private static final String PURPOSE_BATCH = "batch";
|
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() {
|
void setUp() {
|
||||||
ZaiConfig zaiConfig = new ZaiConfig();
|
ZaiConfig zaiConfig = new ZaiConfig();
|
||||||
|
|
@ -74,7 +67,7 @@ public class FileServiceTest {
|
||||||
|
|
||||||
FileUploadParams request = FileUploadParams.builder()
|
FileUploadParams request = FileUploadParams.builder()
|
||||||
.filePath(tempFile.toString())
|
.filePath(tempFile.toString())
|
||||||
.purpose(PURPOSE_ASSISTANTS)
|
.purpose(UploadFilePurpose.AGENT.value())
|
||||||
.requestId(requestId)
|
.requestId(requestId)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
@ -87,7 +80,7 @@ public class FileServiceTest {
|
||||||
assertNotNull(response.getData(), "Response data should not be null");
|
assertNotNull(response.getData(), "Response data should not be null");
|
||||||
assertNotNull(response.getData().getId(), "File ID should not be null");
|
assertNotNull(response.getData().getId(), "File ID should not be null");
|
||||||
assertEquals("file", response.getData().getObject(), "Object type should be 'file'");
|
assertEquals("file", response.getData().getObject(), "Object type should be 'file'");
|
||||||
assertEquals(PURPOSE_ASSISTANTS, response.getData().getPurpose(), "Purpose should match");
|
assertEquals(UploadFilePurpose.AGENT.value(), response.getData().getPurpose(), "Purpose should match");
|
||||||
assertNotNull(response.getData().getFilename(), "Filename should not be null");
|
assertNotNull(response.getData().getFilename(), "Filename should not be null");
|
||||||
assertNotNull(response.getData().getBytes(), "File size should not be null");
|
assertNotNull(response.getData().getBytes(), "File size should not be null");
|
||||||
assertTrue(response.getData().getBytes() > 0, "File size should be greater than 0");
|
assertTrue(response.getData().getBytes() > 0, "File size should be greater than 0");
|
||||||
|
|
@ -119,7 +112,7 @@ public class FileServiceTest {
|
||||||
|
|
||||||
FileUploadParams request = FileUploadParams.builder()
|
FileUploadParams request = FileUploadParams.builder()
|
||||||
.filePath(tempFile.toString())
|
.filePath(tempFile.toString())
|
||||||
.purpose(PURPOSE_FINE_TUNE)
|
.purpose(UploadFilePurpose.FILE_EXTRACT.value())
|
||||||
.requestId(requestId)
|
.requestId(requestId)
|
||||||
.extraJson(extraJson)
|
.extraJson(extraJson)
|
||||||
.build();
|
.build();
|
||||||
|
|
@ -131,7 +124,8 @@ public class FileServiceTest {
|
||||||
assertNotNull(response, "Response should not be null");
|
assertNotNull(response, "Response should not be null");
|
||||||
assertTrue(response.isSuccess(), "Response should be successful");
|
assertTrue(response.isSuccess(), "Response should be successful");
|
||||||
assertNotNull(response.getData(), "Response data should not be null");
|
assertNotNull(response.getData(), "Response data should not be null");
|
||||||
assertEquals(PURPOSE_FINE_TUNE, response.getData().getPurpose(), "Purpose should match");
|
assertEquals(UploadFilePurpose.FILE_EXTRACT.value(), response.getData().getPurpose(),
|
||||||
|
"Purpose should match");
|
||||||
assertNull(response.getError(), "Response error should be null");
|
assertNull(response.getError(), "Response error should be null");
|
||||||
|
|
||||||
logger.info("File upload with extra JSON response: {}", mapper.writeValueAsString(response));
|
logger.info("File upload with extra JSON response: {}", mapper.writeValueAsString(response));
|
||||||
|
|
@ -149,7 +143,7 @@ public class FileServiceTest {
|
||||||
|
|
||||||
FileUploadParams request = FileUploadParams.builder()
|
FileUploadParams request = FileUploadParams.builder()
|
||||||
.filePath("/non/existent/file.txt")
|
.filePath("/non/existent/file.txt")
|
||||||
.purpose(PURPOSE_ASSISTANTS)
|
.purpose(UploadFilePurpose.AGENT.value())
|
||||||
.requestId(requestId)
|
.requestId(requestId)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
@ -187,7 +181,7 @@ public class FileServiceTest {
|
||||||
String requestId = String.format(REQUEST_ID_TEMPLATE, System.currentTimeMillis());
|
String requestId = String.format(REQUEST_ID_TEMPLATE, System.currentTimeMillis());
|
||||||
|
|
||||||
FileListParams request = FileListParams.builder()
|
FileListParams request = FileListParams.builder()
|
||||||
.purpose(PURPOSE_ASSISTANTS)
|
.purpose(UploadFilePurpose.AGENT.value())
|
||||||
.limit(5)
|
.limit(5)
|
||||||
.order("asc")
|
.order("asc")
|
||||||
.requestId(requestId)
|
.requestId(requestId)
|
||||||
|
|
@ -205,7 +199,8 @@ public class FileServiceTest {
|
||||||
// Verify purpose filter if files exist
|
// Verify purpose filter if files exist
|
||||||
if (response.getData().getData() != null && !response.getData().getData().isEmpty()) {
|
if (response.getData().getData() != null && !response.getData().getData().isEmpty()) {
|
||||||
response.getData().getData().forEach(file -> {
|
response.getData().getData().forEach(file -> {
|
||||||
assertEquals(PURPOSE_ASSISTANTS, file.getPurpose(), "All files should have the specified purpose");
|
assertEquals(UploadFilePurpose.AGENT.value(), file.getPurpose(),
|
||||||
|
"All files should have the specified purpose");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -269,7 +264,7 @@ public class FileServiceTest {
|
||||||
|
|
||||||
FileUploadParams uploadRequest = FileUploadParams.builder()
|
FileUploadParams uploadRequest = FileUploadParams.builder()
|
||||||
.filePath(tempFile.toString())
|
.filePath(tempFile.toString())
|
||||||
.purpose(PURPOSE_ASSISTANTS)
|
.purpose(UploadFilePurpose.FILE_EXTRACT.value())
|
||||||
.requestId(requestId)
|
.requestId(requestId)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -110,13 +110,13 @@ public class ImageServiceTest {
|
||||||
@DisplayName("Test Different Image Sizes")
|
@DisplayName("Test Different Image Sizes")
|
||||||
@EnabledIfEnvironmentVariable(named = "ZAI_API_KEY", matches = "^[^.]+\\.[^.]+$")
|
@EnabledIfEnvironmentVariable(named = "ZAI_API_KEY", matches = "^[^.]+\\.[^.]+$")
|
||||||
void testDifferentImageSizes() throws JsonProcessingException {
|
void testDifferentImageSizes() throws JsonProcessingException {
|
||||||
String[] sizes = { "256x256", "512x512", "1024x1024" };
|
String[] sizes = { "512x512", "1024x1024" };
|
||||||
|
|
||||||
for (String size : sizes) {
|
for (String size : sizes) {
|
||||||
String requestId = String.format(REQUEST_ID_TEMPLATE, System.currentTimeMillis());
|
String requestId = String.format(REQUEST_ID_TEMPLATE, System.currentTimeMillis());
|
||||||
|
|
||||||
CreateImageRequest request = CreateImageRequest.builder()
|
CreateImageRequest request = CreateImageRequest.builder()
|
||||||
.model(Constants.ModelCogView3Plus)
|
.model(Constants.ModelCogView4)
|
||||||
.prompt("A simple geometric pattern")
|
.prompt("A simple geometric pattern")
|
||||||
.size(size)
|
.size(size)
|
||||||
.requestId(requestId)
|
.requestId(requestId)
|
||||||
|
|
@ -124,7 +124,8 @@ public class ImageServiceTest {
|
||||||
|
|
||||||
ImageResponse response = imageService.createImage(request);
|
ImageResponse response = imageService.createImage(request);
|
||||||
|
|
||||||
assertNotNull(response, "Response should not be null for size: " + size);
|
assertNotNull(response.getData(), "Response should not be null for size: " + size);
|
||||||
|
assertEquals(200, response.getCode());
|
||||||
logger.info("Size {} response: {}", size, mapper.writeValueAsString(response));
|
logger.info("Size {} response: {}", size, mapper.writeValueAsString(response));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package ai.z.openapi.service.videos;
|
package ai.z.openapi.service.videos;
|
||||||
|
|
||||||
import ai.z.openapi.ZaiClient;
|
import ai.z.openapi.ZaiClient;
|
||||||
|
import ai.z.openapi.core.Constants;
|
||||||
import ai.z.openapi.core.config.ZaiConfig;
|
import ai.z.openapi.core.config.ZaiConfig;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
@ -35,11 +36,6 @@ public class VideosServiceTest {
|
||||||
// Request ID template
|
// Request ID template
|
||||||
private static final String REQUEST_ID_TEMPLATE = "video-test-%d";
|
private static final String REQUEST_ID_TEMPLATE = "video-test-%d";
|
||||||
|
|
||||||
// Video model constants
|
|
||||||
private static final String MODEL_COGVIDEOX = "cogvideox";
|
|
||||||
|
|
||||||
private static final String MODEL_COGVIDEO3 = "cogvideo-3";
|
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() {
|
void setUp() {
|
||||||
ZaiConfig zaiConfig = new ZaiConfig();
|
ZaiConfig zaiConfig = new ZaiConfig();
|
||||||
|
|
@ -67,7 +63,7 @@ public class VideosServiceTest {
|
||||||
String requestId = String.format(REQUEST_ID_TEMPLATE, System.currentTimeMillis());
|
String requestId = String.format(REQUEST_ID_TEMPLATE, System.currentTimeMillis());
|
||||||
|
|
||||||
VideoCreateParams request = VideoCreateParams.builder()
|
VideoCreateParams request = VideoCreateParams.builder()
|
||||||
.model(MODEL_COGVIDEOX)
|
.model(Constants.ModelCogVideoX3)
|
||||||
.prompt("A beautiful sunset over the ocean with waves gently crashing on the shore")
|
.prompt("A beautiful sunset over the ocean with waves gently crashing on the shore")
|
||||||
.requestId(requestId)
|
.requestId(requestId)
|
||||||
.withAudio(Boolean.TRUE)
|
.withAudio(Boolean.TRUE)
|
||||||
|
|
@ -80,6 +76,7 @@ public class VideosServiceTest {
|
||||||
|
|
||||||
// Verify results
|
// Verify results
|
||||||
assertNotNull(response, "Response should not be null");
|
assertNotNull(response, "Response should not be null");
|
||||||
|
assertEquals(200, response.getCode());
|
||||||
assertTrue(response.isSuccess(), "Response should be successful");
|
assertTrue(response.isSuccess(), "Response should be successful");
|
||||||
assertNotNull(response.getData(), "Response data should not be null");
|
assertNotNull(response.getData(), "Response data should not be null");
|
||||||
assertNotNull(response.getData().getId(), "Response data ID should not be null");
|
assertNotNull(response.getData().getId(), "Response data ID should not be null");
|
||||||
|
|
@ -95,7 +92,7 @@ public class VideosServiceTest {
|
||||||
String requestId = String.format(REQUEST_ID_TEMPLATE, System.currentTimeMillis());
|
String requestId = String.format(REQUEST_ID_TEMPLATE, System.currentTimeMillis());
|
||||||
|
|
||||||
VideoCreateParams request = VideoCreateParams.builder()
|
VideoCreateParams request = VideoCreateParams.builder()
|
||||||
.model(MODEL_COGVIDEOX)
|
.model(Constants.ModelCogVideoX3)
|
||||||
.prompt("A person walking in a beautiful garden")
|
.prompt("A person walking in a beautiful garden")
|
||||||
.requestId(requestId)
|
.requestId(requestId)
|
||||||
.build();
|
.build();
|
||||||
|
|
@ -114,6 +111,7 @@ public class VideosServiceTest {
|
||||||
|
|
||||||
// Verify result response
|
// Verify result response
|
||||||
assertNotNull(resultResponse, "Result response should not be null");
|
assertNotNull(resultResponse, "Result response should not be null");
|
||||||
|
assertEquals(200, resultResponse.getCode());
|
||||||
assertNotNull(resultResponse.getData(), "Result response data should not be null");
|
assertNotNull(resultResponse.getData(), "Result response data should not be null");
|
||||||
assertNotNull(resultResponse.getData().getId(), "Result response task ID should not be null");
|
assertNotNull(resultResponse.getData().getId(), "Result response task ID should not be null");
|
||||||
logger.info("Video generation result: taskId={}, response={}", taskId,
|
logger.info("Video generation result: taskId={}, response={}", taskId,
|
||||||
|
|
@ -138,7 +136,7 @@ public class VideosServiceTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@ValueSource(strings = { MODEL_COGVIDEOX, MODEL_COGVIDEO3 })
|
@ValueSource(strings = { Constants.ModelCogVideoX2, Constants.ModelCogVideoX3 })
|
||||||
@DisplayName("Test Different Video Models")
|
@DisplayName("Test Different Video Models")
|
||||||
@EnabledIfEnvironmentVariable(named = "ZAI_API_KEY", matches = "^[^.]+\\.[^.]+$")
|
@EnabledIfEnvironmentVariable(named = "ZAI_API_KEY", matches = "^[^.]+\\.[^.]+$")
|
||||||
void testDifferentModels(String model) throws JsonProcessingException {
|
void testDifferentModels(String model) throws JsonProcessingException {
|
||||||
|
|
@ -153,6 +151,7 @@ public class VideosServiceTest {
|
||||||
VideosResponse response = videosService.videoGenerations(request);
|
VideosResponse response = videosService.videoGenerations(request);
|
||||||
|
|
||||||
assertNotNull(response, "Response should not be null");
|
assertNotNull(response, "Response should not be null");
|
||||||
|
assertEquals(200, response.getCode());
|
||||||
logger.info("Model {} response: {}", model, mapper.writeValueAsString(response));
|
logger.info("Model {} response: {}", model, mapper.writeValueAsString(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -177,7 +176,7 @@ public class VideosServiceTest {
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Test Parameter Validation - Empty Prompt")
|
@DisplayName("Test Parameter Validation - Empty Prompt")
|
||||||
void testValidation_EmptyPrompt() {
|
void testValidation_EmptyPrompt() {
|
||||||
VideoCreateParams request = VideoCreateParams.builder().model(MODEL_COGVIDEOX).prompt("").build();
|
VideoCreateParams request = VideoCreateParams.builder().model(Constants.ModelCogVideoX3).prompt("").build();
|
||||||
|
|
||||||
assertThrows(IllegalArgumentException.class, () -> {
|
assertThrows(IllegalArgumentException.class, () -> {
|
||||||
videosService.videoGenerations(request);
|
videosService.videoGenerations(request);
|
||||||
|
|
@ -202,17 +201,18 @@ public class VideosServiceTest {
|
||||||
Base64.Encoder encoder = Base64.getEncoder();
|
Base64.Encoder encoder = Base64.getEncoder();
|
||||||
String imageUrl = encoder.encodeToString(bytes);
|
String imageUrl = encoder.encodeToString(bytes);
|
||||||
VideoCreateParams request = VideoCreateParams.builder()
|
VideoCreateParams request = VideoCreateParams.builder()
|
||||||
.model(MODEL_COGVIDEOX)
|
.model(Constants.ModelCogVideoX3)
|
||||||
.prompt("Transform this image into a dynamic video scene")
|
.prompt("Transform this image into a dynamic video scene")
|
||||||
.imageUrl(imageUrl)
|
.imageUrl(imageUrl)
|
||||||
.requestId(requestId)
|
.requestId(requestId)
|
||||||
.withAudio(Boolean.FALSE)
|
.withAudio(Boolean.FALSE)
|
||||||
.duration(3)
|
.duration(5)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
VideosResponse response = videosService.videoGenerations(request);
|
VideosResponse response = videosService.videoGenerations(request);
|
||||||
|
|
||||||
assertNotNull(response, "Response should not be null");
|
assertNotNull(response, "Response should not be null");
|
||||||
|
assertEquals(200, response.getCode());
|
||||||
logger.info("Video generation with image response: {}", mapper.writeValueAsString(response));
|
logger.info("Video generation with image response: {}", mapper.writeValueAsString(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -223,19 +223,20 @@ public class VideosServiceTest {
|
||||||
String requestId = String.format(REQUEST_ID_TEMPLATE, System.currentTimeMillis());
|
String requestId = String.format(REQUEST_ID_TEMPLATE, System.currentTimeMillis());
|
||||||
|
|
||||||
VideoCreateParams request = VideoCreateParams.builder()
|
VideoCreateParams request = VideoCreateParams.builder()
|
||||||
.model(MODEL_COGVIDEOX)
|
.model(Constants.ModelCogVideoX3)
|
||||||
.prompt("A futuristic city with flying cars and neon lights")
|
.prompt("A futuristic city with flying cars and neon lights")
|
||||||
.requestId(requestId)
|
.requestId(requestId)
|
||||||
.quality("high")
|
.quality("speed")
|
||||||
.withAudio(Boolean.TRUE)
|
.withAudio(Boolean.TRUE)
|
||||||
.size("1280x720")
|
.size("1280x720")
|
||||||
.duration(10)
|
.duration(5)
|
||||||
.fps(30)
|
.fps(30)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
VideosResponse response = videosService.videoGenerations(request);
|
VideosResponse response = videosService.videoGenerations(request);
|
||||||
|
|
||||||
assertNotNull(response, "Response should not be null");
|
assertNotNull(response, "Response should not be null");
|
||||||
|
assertEquals(200, response.getCode());
|
||||||
logger.info("Video generation with custom settings response: {}", mapper.writeValueAsString(response));
|
logger.info("Video generation with custom settings response: {}", mapper.writeValueAsString(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
BIN
core/src/test/resources/asr.mp3
Normal file
BIN
core/src/test/resources/asr.mp3
Normal file
Binary file not shown.
|
|
@ -21,7 +21,7 @@ public class AgentExample {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// Create client, recommended to set API Key via environment variable
|
// Create client, recommended to set API Key via environment variable
|
||||||
// export ZAI_API_KEY=your.api.key
|
// export ZAI_API_KEY=your.api_key
|
||||||
// for Z.ai use the `ZaiClient`, for Zhipu AI use the ZhipuAiClient
|
// for Z.ai use the `ZaiClient`, for Zhipu AI use the ZhipuAiClient
|
||||||
ZaiClient client = ZaiClient.builder().build();
|
ZaiClient client = ZaiClient.builder().build();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ public class AgentVideoExample {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// Create client, recommended to set API Key via environment variable
|
// Create client, recommended to set API Key via environment variable
|
||||||
// export ZAI_API_KEY=your.api.key
|
// export ZAI_API_KEY=your.api_key
|
||||||
// for Z.ai use the `ZaiClient`, for Zhipu AI use the ZhipuAiClient
|
// for Z.ai use the `ZaiClient`, for Zhipu AI use the ZhipuAiClient
|
||||||
ZaiClient client = ZaiClient.builder().build();
|
ZaiClient client = ZaiClient.builder().build();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,13 +19,13 @@ public class ChatAsyncCompletionExample {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// Create client, recommended to set API Key via environment variable
|
// Create client, recommended to set API Key via environment variable
|
||||||
// export ZAI_API_KEY=your.api.key
|
// export ZAI_API_KEY=your.api_key
|
||||||
// for Z.ai use the `ZaiClient`, for Zhipu AI use the ZhipuAiClient
|
// for Z.ai use the `ZaiClient`, for Zhipu AI use the ZhipuAiClient
|
||||||
ZhipuAiClient client = ZhipuAiClient.builder().build();
|
ZhipuAiClient client = ZhipuAiClient.builder().build();
|
||||||
|
|
||||||
// Or set API Key via code
|
// Or set API Key via code
|
||||||
// ZaiClient client = ZaiClient.builder()
|
// ZaiClient client = ZaiClient.builder()
|
||||||
// .apiKey("your.api.key")
|
// .apiKey("your.api_key")
|
||||||
// .build();
|
// .build();
|
||||||
|
|
||||||
// Create chat request
|
// Create chat request
|
||||||
|
|
|
||||||
|
|
@ -14,13 +14,13 @@ public class ChatCompletionExample {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// Create client, recommended to set API Key via environment variable
|
// Create client, recommended to set API Key via environment variable
|
||||||
// export ZAI_API_KEY=your.api.key
|
// export ZAI_API_KEY=your.api_key
|
||||||
// for Z.ai use the `ZaiClient`, for Zhipu AI use the ZhipuAiClient
|
// for Z.ai use the `ZaiClient`, for Zhipu AI use the ZhipuAiClient
|
||||||
ZhipuAiClient client = ZhipuAiClient.builder().build();
|
ZhipuAiClient client = ZhipuAiClient.builder().build();
|
||||||
|
|
||||||
// Or set API Key via code
|
// Or set API Key via code
|
||||||
// ZaiClient client = ZaiClient.builder()
|
// ZaiClient client = ZaiClient.builder()
|
||||||
// .apiKey("your.api.key")
|
// .apiKey("your.api_key")
|
||||||
// .build();
|
// .build();
|
||||||
|
|
||||||
// Create chat request
|
// Create chat request
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
package ai.z.openapi.samples;
|
||||||
|
|
||||||
|
import ai.z.openapi.ZhipuAiClient;
|
||||||
|
import ai.z.openapi.service.model.*;
|
||||||
|
import ai.z.openapi.core.Constants;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chat Completion with Custom Headers Example
|
||||||
|
* Demonstrates how to use ZaiClient for chat conversations with custom HTTP headers
|
||||||
|
*/
|
||||||
|
public class ChatCompletionWithCustomHeadersExample {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// Create client, recommended to set API Key via environment variable
|
||||||
|
// export ZAI_API_KEY=your.api_key
|
||||||
|
// for Z.ai use the `ZaiClient`, for Zhipu AI use the ZhipuAiClient
|
||||||
|
ZhipuAiClient client = ZhipuAiClient.builder().build();
|
||||||
|
|
||||||
|
// Create chat request
|
||||||
|
ChatCompletionCreateParams request = ChatCompletionCreateParams.builder()
|
||||||
|
.model(Constants.ModelChatGLM4_5)
|
||||||
|
.messages(Arrays.asList(
|
||||||
|
ChatMessage.builder()
|
||||||
|
.role(ChatMessageRole.USER.value())
|
||||||
|
.content("Hello, how are you?")
|
||||||
|
.build()
|
||||||
|
))
|
||||||
|
.stream(true) // Enable streaming for custom headers support
|
||||||
|
.temperature(0.7f)
|
||||||
|
.maxTokens(1024)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Create custom headers
|
||||||
|
Map<String, String> customHeaders = new HashMap<>();
|
||||||
|
customHeaders.put("X-Custom-User-ID", "user123");
|
||||||
|
customHeaders.put("X-Request-Source", "mobile-app");
|
||||||
|
customHeaders.put("Session-Id", "session-abc-123");
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Execute request with custom headers
|
||||||
|
// This works for both streaming and non-streaming requests
|
||||||
|
ChatCompletionResponse response = client.chat().createChatCompletion(request, customHeaders);
|
||||||
|
|
||||||
|
// Example for non-streaming request with custom headers
|
||||||
|
ChatCompletionCreateParams nonStreamingRequest = ChatCompletionCreateParams.builder()
|
||||||
|
.model(Constants.ModelChatGLM4_5)
|
||||||
|
.messages(Arrays.asList(
|
||||||
|
ChatMessage.builder()
|
||||||
|
.role(ChatMessageRole.USER.value())
|
||||||
|
.content("What is artificial intelligence?")
|
||||||
|
.build()
|
||||||
|
))
|
||||||
|
.stream(false) // Explicitly set to false for non-streaming
|
||||||
|
.temperature(0.7f)
|
||||||
|
.maxTokens(1024)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
ChatCompletionResponse nonStreamingResponse = client.chat()
|
||||||
|
.createChatCompletion(nonStreamingRequest, customHeaders);
|
||||||
|
|
||||||
|
System.out.println("Non-streaming response: " + nonStreamingResponse.getData());
|
||||||
|
|
||||||
|
if (response.isSuccess() && response.getFlowable() != null) {
|
||||||
|
System.out.println("Streaming response with custom headers:");
|
||||||
|
response.getFlowable().subscribe(
|
||||||
|
data -> {
|
||||||
|
// Handle streaming chunk
|
||||||
|
if (data.getChoices() != null && !data.getChoices().isEmpty()) {
|
||||||
|
String content = data.getChoices().get(0).getDelta().getContent();
|
||||||
|
if (content != null) {
|
||||||
|
System.out.print(content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error -> System.err.println("\nStream error: " + error.getMessage()),
|
||||||
|
() -> System.out.println("\nStream completed")
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
System.err.println("Error: " + response.getMsg());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("Exception occurred: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
package ai.z.openapi.samples;
|
package ai.z.openapi.samples;
|
||||||
|
|
||||||
import ai.z.openapi.ZaiClient;
|
import ai.z.openapi.ZaiClient;
|
||||||
|
import ai.z.openapi.ZhipuAiClient;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -12,14 +16,17 @@ public class ClientConfigurationExample {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|
||||||
System.out.println("=== Basic Configuration Example ===");
|
System.out.println("=== Basic Configuration Example ===");
|
||||||
ZaiClient basicClient = ZaiClient.builder().build();
|
ZaiClient basicClient = ZaiClient.builder().apiKey("xxx.xxx").build();
|
||||||
System.out.println("✓ Basic client created successfully");
|
System.out.println("✓ Basic client created successfully");
|
||||||
|
|
||||||
// Complete configuration example
|
// Complete configuration example
|
||||||
System.out.println("\n=== Complete Configuration Example ===");
|
System.out.println("\n=== Complete Configuration Example ===");
|
||||||
|
Map<String, String> customHeaders = new HashMap<>();
|
||||||
|
customHeaders.put("Session-Id", "custom-session-id-xx");
|
||||||
ZaiClient advancedClient = ZaiClient.builder()
|
ZaiClient advancedClient = ZaiClient.builder()
|
||||||
.apiKey("your.api.key")
|
.apiKey("your.api_key")
|
||||||
.baseUrl("https://api.z.ai/api/paas/v4/")
|
.baseUrl("https://api.z.ai/api/paas/v4/")
|
||||||
|
.customHeaders(customHeaders)
|
||||||
.enableTokenCache()
|
.enableTokenCache()
|
||||||
.tokenExpire(3600000) // 1 hour
|
.tokenExpire(3600000) // 1 hour
|
||||||
.connectionPool(10, 5, TimeUnit.MINUTES)
|
.connectionPool(10, 5, TimeUnit.MINUTES)
|
||||||
|
|
@ -28,14 +35,25 @@ public class ClientConfigurationExample {
|
||||||
|
|
||||||
// ZHIPU platform specific client
|
// ZHIPU platform specific client
|
||||||
System.out.println("\n=== ZHIPU Platform Specific Configuration ===");
|
System.out.println("\n=== ZHIPU Platform Specific Configuration ===");
|
||||||
ZaiClient zhipuClient = ZaiClient.ofZHIPU("your.api.key").build();
|
ZaiClient zhipuClient = ZaiClient.ofZHIPU("your.api_key").build();
|
||||||
System.out.println("✓ ZHIPU platform client created successfully");
|
System.out.println("✓ ZHIPU platform client created successfully");
|
||||||
|
|
||||||
|
ZhipuAiClient zhipuAiClient = ZhipuAiClient.builder()
|
||||||
|
.apiKey("your.api_key")
|
||||||
|
.baseUrl("https://api.z.ai/api/paas/v4/")
|
||||||
|
.customHeaders(customHeaders)
|
||||||
|
.enableTokenCache()
|
||||||
|
.tokenExpire(3600000) // 1 hour
|
||||||
|
.connectionPool(10, 5, TimeUnit.MINUTES)
|
||||||
|
.build();
|
||||||
|
System.out.println("✓ ZHIPU platform client created successfully");
|
||||||
|
|
||||||
// Custom configuration example
|
// Custom configuration example
|
||||||
System.out.println("\n=== Custom Configuration Example ===");
|
System.out.println("\n=== Custom Configuration Example ===");
|
||||||
ZaiClient customClient = ZaiClient.builder()
|
ZaiClient customClient = ZaiClient.builder()
|
||||||
.apiKey("your.api.key")
|
.apiKey("your.api_key")
|
||||||
.baseUrl("https://custom.api.endpoint/")
|
.baseUrl("https://custom.api.endpoint/")
|
||||||
|
.customHeaders(customHeaders)
|
||||||
.enableTokenCache()
|
.enableTokenCache()
|
||||||
.tokenExpire(7200000)
|
.tokenExpire(7200000)
|
||||||
.connectionPool(20, 10, TimeUnit.MINUTES)
|
.connectionPool(20, 10, TimeUnit.MINUTES)
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,13 @@ public class CogVideoX3Example {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// Create client, recommended to set API Key via environment variable
|
// Create client, recommended to set API Key via environment variable
|
||||||
// export ZAI_API_KEY=your.api.key
|
// export ZAI_API_KEY=your.api_key
|
||||||
// for Z.ai use the `ZaiClient`, for Zhipu AI use the ZhipuAiClient
|
// for Z.ai use the `ZaiClient`, for Zhipu AI use the ZhipuAiClient
|
||||||
ZaiClient client = ZaiClient.builder().build();
|
ZaiClient client = ZaiClient.builder().build();
|
||||||
|
|
||||||
// Or set API Key via code
|
// Or set API Key via code
|
||||||
// ZaiClient client = ZaiClient.builder()
|
// ZaiClient client = ZaiClient.builder()
|
||||||
// .apiKey("your.api.key")
|
// .apiKey("your.api_key")
|
||||||
// .build();
|
// .build();
|
||||||
|
|
||||||
// Video generation examples
|
// Video generation examples
|
||||||
|
|
|
||||||
|
|
@ -13,13 +13,13 @@ public class CogVideoXExample {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// Create client, recommended to set API Key via environment variable
|
// Create client, recommended to set API Key via environment variable
|
||||||
// export ZAI_API_KEY=your.api.key
|
// export ZAI_API_KEY=your.api_key
|
||||||
// for Z.ai use the `ZaiClient`, for Zhipu AI use the ZhipuAiClient
|
// for Z.ai use the `ZaiClient`, for Zhipu AI use the ZhipuAiClient
|
||||||
ZaiClient client = ZaiClient.builder().build();
|
ZaiClient client = ZaiClient.builder().build();
|
||||||
|
|
||||||
// Or set API Key via code
|
// Or set API Key via code
|
||||||
// ZaiClient client = ZaiClient.builder()
|
// ZaiClient client = ZaiClient.builder()
|
||||||
// .apiKey("your.api.key")
|
// .apiKey("your.api_key")
|
||||||
// .build();
|
// .build();
|
||||||
|
|
||||||
// Basic Video Generation
|
// Basic Video Generation
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ public class GLM41VThinkingExample {
|
||||||
|
|
||||||
// for Z.ai use the `ZaiClient`, for Zhipu AI use the ZhipuAiClient
|
// for Z.ai use the `ZaiClient`, for Zhipu AI use the ZhipuAiClient
|
||||||
ZaiClient client = ZaiClient.builder()
|
ZaiClient client = ZaiClient.builder()
|
||||||
.apiKey("your.api.key")
|
.apiKey("your.api_key")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
ChatCompletionCreateParams request = ChatCompletionCreateParams.builder()
|
ChatCompletionCreateParams request = ChatCompletionCreateParams.builder()
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ public class GLM4VPlusExample {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|
||||||
// for Z.ai use the `ZaiClient`, for Zhipu AI use the ZhipuAiClient
|
// for Z.ai use the `ZaiClient`, for Zhipu AI use the ZhipuAiClient
|
||||||
ZaiClient client = ZaiClient.builder().apiKey("your.api.key").build();
|
ZaiClient client = ZaiClient.builder().apiKey("your.api_key").build();
|
||||||
|
|
||||||
ChatCompletionCreateParams request = ChatCompletionCreateParams.builder()
|
ChatCompletionCreateParams request = ChatCompletionCreateParams.builder()
|
||||||
.model("glm-4v-plus-0111")
|
.model("glm-4v-plus-0111")
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ public class ViduAspectVideoExample {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// Create client, recommended to set API Key via environment variable
|
// Create client, recommended to set API Key via environment variable
|
||||||
// export ZAI_API_KEY=your.api.key
|
// export ZAI_API_KEY=your.api_key
|
||||||
// for Z.ai use the `ZaiClient`, for Zhipu AI use the ZhipuAiClient
|
// for Z.ai use the `ZaiClient`, for Zhipu AI use the ZhipuAiClient
|
||||||
ZaiClient client = ZaiClient.builder().build();
|
ZaiClient client = ZaiClient.builder().build();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ public class ViduImageToVideoExample {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// Create client, recommended to set API Key via environment variable
|
// Create client, recommended to set API Key via environment variable
|
||||||
// export ZAI_API_KEY=your.api.key
|
// export ZAI_API_KEY=your.api_key
|
||||||
// for Z.ai use the `ZaiClient`, for Zhipu AI use the ZhipuAiClient
|
// for Z.ai use the `ZaiClient`, for Zhipu AI use the ZhipuAiClient
|
||||||
ZaiClient client = ZaiClient.builder().build();
|
ZaiClient client = ZaiClient.builder().build();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ public class ViduStartEndVideoExample {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// Create client, recommended to set API Key via environment variable
|
// Create client, recommended to set API Key via environment variable
|
||||||
// export ZAI_API_KEY=your.api.key
|
// export ZAI_API_KEY=your.api_key
|
||||||
// for Z.ai use the `ZaiClient`, for Zhipu AI use the ZhipuAiClient
|
// for Z.ai use the `ZaiClient`, for Zhipu AI use the ZhipuAiClient
|
||||||
ZaiClient client = ZaiClient.builder().build();
|
ZaiClient client = ZaiClient.builder().build();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,13 +13,13 @@ public class ViduTextToVideoExample {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// Create client, recommended to set API Key via environment variable
|
// Create client, recommended to set API Key via environment variable
|
||||||
// export ZAI_API_KEY=your.api.key
|
// export ZAI_API_KEY=your.api_key
|
||||||
// for Z.ai use the `ZaiClient`, for Zhipu AI use the ZhipuAiClient
|
// for Z.ai use the `ZaiClient`, for Zhipu AI use the ZhipuAiClient
|
||||||
ZaiClient client = ZaiClient.builder().build();
|
ZaiClient client = ZaiClient.builder().build();
|
||||||
|
|
||||||
// Or set API Key via code
|
// Or set API Key via code
|
||||||
// ZaiClient client = ZaiClient.builder()
|
// ZaiClient client = ZaiClient.builder()
|
||||||
// .apiKey("your.api.key")
|
// .apiKey("your.api_key")
|
||||||
// .build();
|
// .build();
|
||||||
|
|
||||||
// Example: Generate video from text using Vidu
|
// Example: Generate video from text using Vidu
|
||||||
|
|
|
||||||
|
|
@ -23,13 +23,13 @@ public class WebSearchExample {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// Create client, recommended to set API Key via environment variable
|
// Create client, recommended to set API Key via environment variable
|
||||||
// export ZAI_API_KEY=your.api.key
|
// export ZAI_API_KEY=your.api_key
|
||||||
// for Z.ai use the `ZaiClient`, for Zhipu AI use the ZhipuAiClient
|
// for Z.ai use the `ZaiClient`, for Zhipu AI use the ZhipuAiClient
|
||||||
ZaiClient client = ZaiClient.builder().build();
|
ZaiClient client = ZaiClient.builder().build();
|
||||||
|
|
||||||
// Or set API Key via code
|
// Or set API Key via code
|
||||||
// ZaiClient client = ZaiClient.builder()
|
// ZaiClient client = ZaiClient.builder()
|
||||||
// .apiKey("your.api.key")
|
// .apiKey("your.api_key")
|
||||||
// .build();
|
// .build();
|
||||||
|
|
||||||
// Example 1: Basic Web Search
|
// Example 1: Basic Web Search
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue