chore: remove the client params apiId and apiSecret, fix cache token bug (#58)
This commit is contained in:
parent
a3cfd23511
commit
8f5f986298
8 changed files with 204 additions and 57 deletions
|
|
@ -54,16 +54,6 @@ public class ZaiConfig {
|
|||
*/
|
||||
private String apiKey;
|
||||
|
||||
/**
|
||||
* API id component.
|
||||
*/
|
||||
private String apiId;
|
||||
|
||||
/**
|
||||
* API secret component.
|
||||
*/
|
||||
private String apiSecret;
|
||||
|
||||
/**
|
||||
* Custom Http Request Headers
|
||||
*/
|
||||
|
|
@ -84,7 +74,8 @@ public class ZaiConfig {
|
|||
/**
|
||||
* Flag to disable token caching.
|
||||
*/
|
||||
private boolean disableTokenCache;
|
||||
@Builder.Default
|
||||
private boolean disableTokenCache = true;
|
||||
|
||||
/**
|
||||
* Maximum number of idle connections in the connection pool.
|
||||
|
|
@ -96,7 +87,7 @@ public class ZaiConfig {
|
|||
* Keep alive duration for connections in the pool (in seconds).
|
||||
*/
|
||||
@Builder.Default
|
||||
private long connectionPoolKeepAliveDuration = 1;
|
||||
private long connectionPoolKeepAliveDuration = 10;
|
||||
|
||||
/**
|
||||
* Time unit for connection pool keep alive duration.
|
||||
|
|
@ -149,10 +140,8 @@ public class ZaiConfig {
|
|||
this.apiKey = apiKey;
|
||||
String[] arrStr = apiKey.split("\\.");
|
||||
if (arrStr.length != 2) {
|
||||
throw new RuntimeException("invalid apiSecretKey");
|
||||
throw new RuntimeException("invalid api Key");
|
||||
}
|
||||
this.apiId = arrStr[0];
|
||||
this.apiSecret = arrStr[1];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -166,8 +155,6 @@ public class ZaiConfig {
|
|||
if (arrStr.length != 2) {
|
||||
throw new RuntimeException("invalid api Key");
|
||||
}
|
||||
this.apiId = arrStr[0];
|
||||
this.apiSecret = arrStr[1];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -194,38 +181,10 @@ public class ZaiConfig {
|
|||
if (value != null && !value.isEmpty()) {
|
||||
// Parse value and set components
|
||||
this.apiKey = value;
|
||||
String[] arrStr = value.split("\\.");
|
||||
if (arrStr.length == 2) {
|
||||
this.apiId = arrStr[0];
|
||||
this.apiSecret = arrStr[1];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
return apiKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets API key with system property and environment variable fallback.
|
||||
*/
|
||||
public String getApiId() {
|
||||
if (apiId != null && !apiId.isEmpty()) {
|
||||
return apiId;
|
||||
}
|
||||
getApiKey();
|
||||
return apiId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets API secret with system property and environment variable fallback.
|
||||
*/
|
||||
public String getApiSecret() {
|
||||
if (apiSecret != null && !apiSecret.isEmpty()) {
|
||||
return apiSecret;
|
||||
}
|
||||
getApiKey();
|
||||
return apiSecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets expire millis with system property and environment variable fallback.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -44,7 +44,12 @@ public class TokenManager {
|
|||
* @return valid JWT token
|
||||
*/
|
||||
public String getToken(ZaiConfig config) {
|
||||
String tokenCacheKey = genTokenCacheKey(config.getApiId());
|
||||
String[] arrStr = config.getApiKey().split("\\.");
|
||||
if (arrStr.length != 2) {
|
||||
throw new RuntimeException("invalid api Key");
|
||||
}
|
||||
String appId = arrStr[0];
|
||||
String tokenCacheKey = genTokenCacheKey(appId);
|
||||
String cacheToken = cache.get(tokenCacheKey);
|
||||
if (StringUtils.isNotEmpty(cacheToken)) {
|
||||
return cacheToken;
|
||||
|
|
@ -62,9 +67,15 @@ public class TokenManager {
|
|||
private static String createJwt(ZaiConfig config) {
|
||||
Algorithm alg;
|
||||
String algId = config.getAlg();
|
||||
String[] arrStr = config.getApiKey().split("\\.");
|
||||
if (arrStr.length != 2) {
|
||||
throw new RuntimeException("invalid api Key");
|
||||
}
|
||||
String appId = arrStr[0];
|
||||
String apiSecret = arrStr[1];
|
||||
if ("HS256".equals(algId)) {
|
||||
try {
|
||||
alg = Algorithm.HMAC256(config.getApiSecret().getBytes(StandardCharsets.UTF_8));
|
||||
alg = Algorithm.HMAC256(apiSecret.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
catch (Exception e) {
|
||||
logger.error("Failed to create HMAC256 algorithm", e);
|
||||
|
|
@ -79,7 +90,7 @@ public class TokenManager {
|
|||
|
||||
Map<String, Object> payload = new HashMap<>();
|
||||
// here the api_key is the apiId
|
||||
payload.put("api_key", config.getApiId());
|
||||
payload.put("api_key", appId);
|
||||
payload.put("exp", System.currentTimeMillis() + config.getExpireMillis() + DELAY_EXPIRE_TIME);
|
||||
payload.put("timestamp", Calendar.getInstance().getTimeInMillis());
|
||||
Map<String, Object> headerClaims = new HashMap<>();
|
||||
|
|
|
|||
|
|
@ -38,8 +38,7 @@ public class ChatAsyncCompletionExample {
|
|||
.build()
|
||||
))
|
||||
.stream(false)
|
||||
.temperature(0.7f)
|
||||
.maxTokens(1024)
|
||||
.temperature(1.0f)
|
||||
.build();
|
||||
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -35,8 +35,7 @@ public class ChatCompletionExample {
|
|||
.stream(false)
|
||||
.thinking(ChatThinking.builder().type(ChatThinkingType.ENABLED.value()).build())
|
||||
.responseFormat(ResponseFormat.builder().type(ResponseFormatType.TEXT.value()).build())
|
||||
.temperature(0.7f)
|
||||
.maxTokens(1024)
|
||||
.temperature(1.0f)
|
||||
.build();
|
||||
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -30,8 +30,6 @@ public class ChatCompletionWithCustomHeadersExample {
|
|||
.build()
|
||||
))
|
||||
.stream(true) // Enable streaming for custom headers support
|
||||
.temperature(0.7f)
|
||||
.maxTokens(1024)
|
||||
.build();
|
||||
|
||||
// Create custom headers
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
package ai.z.openapi.samples;
|
||||
|
||||
import ai.z.openapi.ZhipuAiClient;
|
||||
import ai.z.openapi.service.model.ChatCompletionCreateParams;
|
||||
import ai.z.openapi.service.model.ChatCompletionResponse;
|
||||
import ai.z.openapi.service.model.ChatMessage;
|
||||
import ai.z.openapi.service.model.ChatMessageRole;
|
||||
import ai.z.openapi.service.model.ChatThinking;
|
||||
import ai.z.openapi.service.model.ChatThinkingType;
|
||||
import ai.z.openapi.service.model.ChatTool;
|
||||
import ai.z.openapi.service.model.ChatToolType;
|
||||
import ai.z.openapi.service.model.MCPTool;
|
||||
import ai.z.openapi.service.model.ResponseFormat;
|
||||
import ai.z.openapi.service.model.ResponseFormatType;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* Chat Completion Example
|
||||
* Demonstrates how to use ZaiClient for basic chat conversations
|
||||
*/
|
||||
public class ChatCompletionWithMcpServerUrlExample {
|
||||
|
||||
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();
|
||||
|
||||
// Or set API Key via code
|
||||
// ZaiClient client = ZaiClient.builder()
|
||||
// .apiKey("your.api_key")
|
||||
// .build();
|
||||
|
||||
// Create chat request
|
||||
ChatCompletionCreateParams request = ChatCompletionCreateParams.builder()
|
||||
.model("glm-4.6")
|
||||
.messages(Collections.singletonList(
|
||||
ChatMessage.builder()
|
||||
.role(ChatMessageRole.USER.value())
|
||||
.content("Hello, how to learn english?")
|
||||
.build()
|
||||
))
|
||||
.stream(false)
|
||||
.thinking(ChatThinking.builder().type(ChatThinkingType.ENABLED.value()).build())
|
||||
.responseFormat(ResponseFormat.builder().type(ResponseFormatType.TEXT.value()).build())
|
||||
.temperature(1.0f)
|
||||
.maxTokens(1024)
|
||||
.tools(Collections.singletonList(ChatTool.builder()
|
||||
.type(ChatToolType.MCP.value())
|
||||
.mcp(MCPTool.builder()
|
||||
.server_url("https://open.bigmodel.cn/api/mcp-broker/proxy/sogou-baike/sse")
|
||||
.server_label("sogou-baike")
|
||||
.transport_type("sse")
|
||||
.headers(Collections.singletonMap("Authorization", "Bearer " + System.getProperty("ZAI_API_KEY")))
|
||||
.build())
|
||||
.build()))
|
||||
.build();
|
||||
|
||||
try {
|
||||
// Execute request
|
||||
ChatCompletionResponse response = client.chat().createChatCompletion(request);
|
||||
|
||||
if (response.isSuccess()) {
|
||||
Object content = response.getData().getChoices().get(0).getMessage();
|
||||
System.out.println("Response: " + content);
|
||||
} else {
|
||||
System.err.println("Error: " + response.getMsg());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("Exception occurred: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
108
samples/src/main/ai.z.openapi.samples/CustomClientExample.java
Normal file
108
samples/src/main/ai.z.openapi.samples/CustomClientExample.java
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
package ai.z.openapi.samples;
|
||||
|
||||
import ai.z.openapi.ZhipuAiClient;
|
||||
import ai.z.openapi.core.Constants;
|
||||
import ai.z.openapi.core.config.ZaiConfig;
|
||||
import ai.z.openapi.service.model.ChatCompletionCreateParams;
|
||||
import ai.z.openapi.service.model.ChatCompletionResponse;
|
||||
import ai.z.openapi.service.model.ChatMessage;
|
||||
import ai.z.openapi.service.model.ChatMessageRole;
|
||||
import ai.z.openapi.service.model.ChatThinking;
|
||||
import ai.z.openapi.service.model.ChatThinkingType;
|
||||
import ai.z.openapi.service.model.Choice;
|
||||
import ai.z.openapi.service.model.Delta;
|
||||
import ai.z.openapi.service.model.ResponseFormat;
|
||||
import ai.z.openapi.service.model.ResponseFormatType;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Chat Completion Example
|
||||
* Demonstrates how to use ZaiClient for basic chat conversations
|
||||
*/
|
||||
public class CustomClientExample {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// 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
|
||||
ZaiConfig zaiConfig = ZaiConfig.builder()
|
||||
.apiKey(System.getenv("ZAI_API_KEY"))
|
||||
.baseUrl(Constants.ZHIPU_AI_BASE_URL)
|
||||
.customHeaders(Collections.emptyMap())
|
||||
.disableTokenCache(true)
|
||||
.requestTimeOut(600)
|
||||
.timeOutTimeUnit(TimeUnit.SECONDS)
|
||||
.connectTimeout(60)
|
||||
.connectionPoolKeepAliveDuration(10)
|
||||
.connectionPoolTimeUnit(TimeUnit.SECONDS)
|
||||
.connectionPoolMaxIdleConnections(20)
|
||||
.build();
|
||||
|
||||
ZhipuAiClient client = new ZhipuAiClient(zaiConfig);
|
||||
|
||||
// Or set API Key via code
|
||||
// ZaiClient client = ZaiClient.builder()
|
||||
// .apiKey("your.api_key")
|
||||
// .build();
|
||||
|
||||
// Create chat request
|
||||
ChatCompletionCreateParams request = ChatCompletionCreateParams.builder()
|
||||
.model("glm-4.6")
|
||||
.messages(Arrays.asList(
|
||||
ChatMessage.builder()
|
||||
.role(ChatMessageRole.USER.value())
|
||||
.content("Hello, are you there")
|
||||
.build()
|
||||
))
|
||||
.stream(true)
|
||||
.thinking(ChatThinking.builder().type(ChatThinkingType.ENABLED.value()).build())
|
||||
.responseFormat(ResponseFormat.builder().type(ResponseFormatType.TEXT.value()).build())
|
||||
.temperature(1.0f)
|
||||
.build();
|
||||
|
||||
// Create latch to wait for streaming completion
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
|
||||
try {
|
||||
// Execute request
|
||||
ChatCompletionResponse response = client.chat().createChatCompletion(request);
|
||||
|
||||
if (response.isSuccess() && response.getFlowable() != null) {
|
||||
System.out.println("Starting streaming response...");
|
||||
response.getFlowable().subscribe(
|
||||
data -> {
|
||||
// Process each streaming response chunk
|
||||
if (data.getChoices() != null && !data.getChoices().isEmpty()) {
|
||||
// Get content of current chunk
|
||||
Choice choice = data.getChoices().get(0);
|
||||
System.out.print(choice + "\n");
|
||||
}
|
||||
},
|
||||
error -> {
|
||||
System.err.println("\nStream error: " + error.getMessage());
|
||||
latch.countDown(); // Release latch on error
|
||||
},
|
||||
// Process streaming response completion event
|
||||
() -> {
|
||||
System.out.println("\nStreaming response completed");
|
||||
latch.countDown(); // Release latch on completion
|
||||
}
|
||||
);
|
||||
|
||||
// Wait for streaming to complete (max 60 seconds)
|
||||
latch.await(60, TimeUnit.SECONDS);
|
||||
} else {
|
||||
System.err.println("Error: " + response.getMsg());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("Exception occurred: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -30,7 +30,7 @@ public class CustomTimeoutExample {
|
|||
|
||||
// Create chat request
|
||||
ChatCompletionCreateParams request = ChatCompletionCreateParams.builder()
|
||||
.model(Constants.ModelChatGLM4_5)
|
||||
.model("glm-4.6")
|
||||
.messages(Arrays.asList(
|
||||
ChatMessage.builder()
|
||||
.role(ChatMessageRole.USER.value())
|
||||
|
|
@ -40,8 +40,6 @@ public class CustomTimeoutExample {
|
|||
.stream(false)
|
||||
.thinking(ChatThinking.builder().type(ChatThinkingType.ENABLED.value()).build())
|
||||
.responseFormat(ResponseFormat.builder().type(ResponseFormatType.TEXT.value()).build())
|
||||
.temperature(0.7f)
|
||||
.maxTokens(1024)
|
||||
.build();
|
||||
|
||||
try {
|
||||
|
|
|
|||
Loading…
Reference in a new issue