diff --git a/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/ZhipuAiApi.java b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/ZhipuAiApi.java index 93819fa1..ec022c3c 100644 --- a/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/ZhipuAiApi.java +++ b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/ZhipuAiApi.java @@ -1,5 +1,10 @@ package dev.langchain4j.community.model.zhipu; +import dev.langchain4j.community.model.zhipu.assistant.AssistantCompletion; +import dev.langchain4j.community.model.zhipu.assistant.AssistantSupportResponse; +import dev.langchain4j.community.model.zhipu.assistant.conversation.ConversationRequest; +import dev.langchain4j.community.model.zhipu.assistant.conversation.ConversationResponse; +import dev.langchain4j.community.model.zhipu.assistant.problem.ProblemsResponse; import dev.langchain4j.community.model.zhipu.chat.ChatCompletionRequest; import dev.langchain4j.community.model.zhipu.chat.ChatCompletionResponse; import dev.langchain4j.community.model.zhipu.embedding.EmbeddingRequest; @@ -9,8 +14,10 @@ import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.http.Body; +import retrofit2.http.GET; import retrofit2.http.Headers; import retrofit2.http.POST; +import retrofit2.http.Path; import retrofit2.http.Streaming; interface ZhipuAiApi { @@ -31,4 +38,25 @@ interface ZhipuAiApi { @POST("api/paas/v4/images/generations") @Headers({"Content-Type: application/json"}) Call generations(@Body ImageRequest request); + + @GET("api/llm-application/open/v2/application/{app_id}/variables") + @Headers({"Content-Type: application/json"}) + Call variables(@Path("app_id") String appId); + + @POST("api/llm-application/open/v2/application/{app_id}/conversation") + @Headers({"Content-Type: application/json"}) + Call conversation(@Path("app_id") String appId); + + @POST("api/llm-application/open/v2/application/generate_request_id") + @Headers({"Content-Type: application/json"}) + Call generateRequestId(@Body ConversationRequest request); + + @Streaming + @POST("api/llm-application/open/v2/model-api/{id}/sse-invoke") + @Headers({"Content-Type: application/json"}) + Call sseInvoke(@Path("id") String id); + + @GET("api/llm-application/open/history_session_record/{app_id}/{conversation_id}") + @Headers({"Content-Type: application/json"}) + Call sessionRecord(@Path("app_id") String appId, @Path("conversation_id") String conversationId); } diff --git a/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/ZhipuAiAssistant.java b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/ZhipuAiAssistant.java new file mode 100644 index 00000000..cd5278d4 --- /dev/null +++ b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/ZhipuAiAssistant.java @@ -0,0 +1,185 @@ +package dev.langchain4j.community.model.zhipu; + +import static dev.langchain4j.internal.Utils.getOrDefault; +import static dev.langchain4j.spi.ServiceHelper.loadFactories; +import static java.time.Duration.ofSeconds; + +import dev.langchain4j.community.model.zhipu.assistant.AssistantKeyValuePair; +import dev.langchain4j.community.model.zhipu.assistant.AssistantType; +import dev.langchain4j.community.model.zhipu.assistant.conversation.ConversationId; +import dev.langchain4j.community.model.zhipu.assistant.conversation.ConversationRequest; +import dev.langchain4j.community.model.zhipu.assistant.problem.Problems; +import dev.langchain4j.community.model.zhipu.spi.ZhipuAssistantBuilderFactory; +import dev.langchain4j.data.message.AiMessage; +import dev.langchain4j.model.StreamingResponseHandler; +import java.time.Duration; +import java.util.List; + +/** + * QingLiu Agent + */ +public class ZhipuAiAssistant { + + private final String appId; + private final ZhipuAssistantClient client; + + public ZhipuAiAssistant( + String baseUrl, + String apiKey, + String appId, + Boolean logRequests, + Boolean logResponses, + Duration callTimeout, + Duration connectTimeout, + Duration readTimeout, + Duration writeTimeout) { + this.appId = appId; + this.client = ZhipuAssistantClient.builder() + .baseUrl(getOrDefault(baseUrl, "https://open.bigmodel.cn/")) + .apiKey(apiKey) + .callTimeout(getOrDefault(callTimeout, ofSeconds(60))) + .connectTimeout(connectTimeout) + .writeTimeout(writeTimeout) + .readTimeout(readTimeout) + .logRequests(getOrDefault(logRequests, false)) + .logResponses(getOrDefault(logResponses, false)) + .build(); + } + + public static ZhipuAiAssistantBuilder builder() { + for (ZhipuAssistantBuilderFactory factories : loadFactories(ZhipuAssistantBuilderFactory.class)) { + return factories.get(); + } + return new ZhipuAiAssistantBuilder(); + } + + /** + * Obtain the input parameters of the intelligent agent (application). + */ + public List variables() { + return client.variables(appId); + } + + /** + * Create a new session + */ + public String getConversationId() { + ConversationId conversation = client.conversation(appId); + return conversation.getConversationId(); + } + + /** + * Create session request. + * @param conversationId Conversation ID + * @param keyValuePairs input parameters + */ + public String getRequestId(String conversationId, List keyValuePairs) { + ConversationRequest request = ConversationRequest.builder() + .appId(appId) + .conversationId(conversationId) + .keyValuePairs(keyValuePairs) + .build(); + return client.generate(request).getId(); + } + + public void generate( + String conversationId, + List keyValuePairs, + StreamingResponseHandler handler) { + String requestId = getRequestId(conversationId, keyValuePairs); + this.generate(requestId, handler); + } + + public void generate(String requestId, StreamingResponseHandler handler) { + client.sseInvoke(requestId, handler); + } + + /** + * Recommended questions + * + * @param conversationId Conversation ID + */ + public Problems sessionRecord(String conversationId) { + return client.sessionRecord(appId, conversationId); + } + + public AssistantKeyValuePair initMessage(String content) { + AssistantKeyValuePair keyValuePair = new AssistantKeyValuePair(); + keyValuePair.setId("user"); + keyValuePair.setName("用户提问"); + keyValuePair.setType(AssistantType.INPUT.serialize()); + keyValuePair.setValue(content); + return keyValuePair; + } + + public static class ZhipuAiAssistantBuilder { + + private String baseUrl; + private String apiKey; + private String appId; + private Boolean logRequests; + private Boolean logResponses; + private Duration callTimeout; + private Duration connectTimeout; + private Duration readTimeout; + private Duration writeTimeout; + + public ZhipuAiAssistantBuilder baseUrl(String baseUrl) { + this.baseUrl = baseUrl; + return this; + } + + public ZhipuAiAssistantBuilder apiKey(String apiKey) { + this.apiKey = apiKey; + return this; + } + + public ZhipuAiAssistantBuilder appId(String appId) { + this.appId = appId; + return this; + } + + public ZhipuAiAssistantBuilder logRequests(Boolean logRequests) { + this.logRequests = logRequests; + return this; + } + + public ZhipuAiAssistantBuilder logResponses(Boolean logResponses) { + this.logResponses = logResponses; + return this; + } + + public ZhipuAiAssistantBuilder callTimeout(Duration callTimeout) { + this.callTimeout = callTimeout; + return this; + } + + public ZhipuAiAssistantBuilder connectTimeout(Duration connectTimeout) { + this.connectTimeout = connectTimeout; + return this; + } + + public ZhipuAiAssistantBuilder readTimeout(Duration readTimeout) { + this.readTimeout = readTimeout; + return this; + } + + public ZhipuAiAssistantBuilder writeTimeout(Duration writeTimeout) { + this.writeTimeout = writeTimeout; + return this; + } + + public ZhipuAiAssistant build() { + return new ZhipuAiAssistant( + this.baseUrl, + this.apiKey, + this.appId, + this.logRequests, + this.logResponses, + this.callTimeout, + this.connectTimeout, + this.readTimeout, + this.writeTimeout); + } + } +} diff --git a/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/ZhipuAssistantClient.java b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/ZhipuAssistantClient.java new file mode 100644 index 00000000..4a170f87 --- /dev/null +++ b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/ZhipuAssistantClient.java @@ -0,0 +1,384 @@ +package dev.langchain4j.community.model.zhipu; + +import static dev.langchain4j.community.model.zhipu.DefaultZhipuAiHelper.aiMessageFrom; +import static dev.langchain4j.community.model.zhipu.DefaultZhipuAiHelper.finishReasonFrom; +import static dev.langchain4j.community.model.zhipu.DefaultZhipuAiHelper.getFinishReason; +import static dev.langchain4j.community.model.zhipu.DefaultZhipuAiHelper.toChatErrorResponse; +import static dev.langchain4j.community.model.zhipu.DefaultZhipuAiHelper.tokenUsageFrom; +import static dev.langchain4j.community.model.zhipu.Json.OBJECT_MAPPER; +import static retrofit2.converter.jackson.JacksonConverterFactory.create; + +import dev.langchain4j.community.model.zhipu.assistant.AssistantCompletion; +import dev.langchain4j.community.model.zhipu.assistant.AssistantExtraInput; +import dev.langchain4j.community.model.zhipu.assistant.AssistantKeyValuePair; +import dev.langchain4j.community.model.zhipu.assistant.AssistantNodeData; +import dev.langchain4j.community.model.zhipu.assistant.AssistantSupportResponse; +import dev.langchain4j.community.model.zhipu.assistant.conversation.ConversationId; +import dev.langchain4j.community.model.zhipu.assistant.conversation.ConversationRequest; +import dev.langchain4j.community.model.zhipu.assistant.conversation.ConversationResponse; +import dev.langchain4j.community.model.zhipu.assistant.problem.Problems; +import dev.langchain4j.community.model.zhipu.assistant.problem.ProblemsResponse; +import dev.langchain4j.community.model.zhipu.chat.ChatCompletionResponse; +import dev.langchain4j.community.model.zhipu.shared.Usage; +import dev.langchain4j.data.message.AiMessage; +import dev.langchain4j.internal.Utils; +import dev.langchain4j.model.StreamingResponseHandler; +import dev.langchain4j.model.output.FinishReason; +import dev.langchain4j.model.output.Response; +import dev.langchain4j.model.output.TokenUsage; +import java.io.IOException; +import java.time.Duration; +import java.util.List; +import java.util.Objects; +import okhttp3.OkHttpClient; +import okhttp3.ResponseBody; +import okhttp3.sse.EventSource; +import okhttp3.sse.EventSourceListener; +import okhttp3.sse.EventSources; +import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import retrofit2.Retrofit; + +public class ZhipuAssistantClient { + private static final Logger log = LoggerFactory.getLogger(ZhipuAssistantClient.class); + + private final ZhipuAiApi zhipuAiApi; + private final OkHttpClient okHttpClient; + private final Boolean logResponses; + + public ZhipuAssistantClient(Builder builder) { + OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder() + .callTimeout(builder.callTimeout) + .connectTimeout(builder.connectTimeout) + .readTimeout(builder.readTimeout) + .writeTimeout(builder.writeTimeout) + .addInterceptor(new AuthorizationInterceptor(builder.apiKey)); + + if (builder.logRequests) { + okHttpClientBuilder.addInterceptor(new RequestLoggingInterceptor()); + } + + this.logResponses = builder.logResponses; + if (builder.logResponses) { + okHttpClientBuilder.addInterceptor(new ResponseLoggingInterceptor()); + } + + this.okHttpClient = okHttpClientBuilder.build(); + Retrofit retrofit = (new Retrofit.Builder()) + .baseUrl(Utils.ensureTrailingForwardSlash(builder.baseUrl)) + .client(this.okHttpClient) + .addConverterFactory(create(OBJECT_MAPPER)) + .build(); + this.zhipuAiApi = retrofit.create(ZhipuAiApi.class); + } + + public static Builder builder() { + return new Builder(); + } + + public List variables(String appId) { + retrofit2.Response retrofitResponse; + try { + retrofitResponse = zhipuAiApi.variables(appId).execute(); + if (retrofitResponse.isSuccessful()) { + final AssistantSupportResponse body = retrofitResponse.body(); + if (Objects.nonNull(body)) { + if (!body.isSuccess()) { + log.error("获取智能体输入参数失败,原因为:【{}】", body.getMessage()); + throw new ZhipuAiException(body.getCode() + "", body.getMessage()); + } + return body.getData(); + } + throw toException(retrofitResponse); + } else { + throw toException(retrofitResponse); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public ConversationId conversation(String appId) { + retrofit2.Response retrofitResponse; + try { + retrofitResponse = zhipuAiApi.conversation(appId).execute(); + if (retrofitResponse.isSuccessful()) { + final ConversationResponse body = retrofitResponse.body(); + if (Objects.nonNull(body)) { + if (!body.isSuccess()) { + log.error("创建新会话失败,原因为:【{}】", body.getMessage()); + throw new ZhipuAiException(body.getCode() + "", body.getMessage()); + } + return body.getData(); + } + throw toException(retrofitResponse); + } else { + throw toException(retrofitResponse); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public ConversationId generate(ConversationRequest request) { + retrofit2.Response retrofitResponse; + try { + retrofitResponse = zhipuAiApi.generateRequestId(request).execute(); + if (retrofitResponse.isSuccessful()) { + final ConversationResponse body = retrofitResponse.body(); + if (Objects.nonNull(body)) { + if (!body.isSuccess()) { + log.error("创建对话或创作请求失败,原因为:【{}】", body.getMessage()); + throw new ZhipuAiException(body.getCode() + "", body.getMessage()); + } + return body.getData(); + } + throw toException(retrofitResponse); + } else { + throw toException(retrofitResponse); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + void sseInvoke(String requestId, StreamingResponseHandler handler) { + EventSourceListener eventSourceListener = new EventSourceListener() { + final StringBuffer contentBuilder = new StringBuffer(); + TokenUsage tokenUsage; + FinishReason finishReason; + AssistantCompletion completion; + + @Override + public void onOpen(@NotNull EventSource eventSource, @NotNull okhttp3.Response response) { + if (logResponses) { + log.debug("onOpen()"); + } + } + + @Override + public void onEvent(@NotNull EventSource eventSource, String id, String type, @NotNull String data) { + if (logResponses) { + log.debug("onEvent(): type:{} | data: {}", type, data); + } + if ("[DONE]".equals(data) || "finish".equals(type)) { + AiMessage aiMessage = AiMessage.from(contentBuilder.toString()); + Response response = Response.from(aiMessage, tokenUsage, finishReason); + handler.onComplete(response); + } else if ("errorhandle".equalsIgnoreCase(type) || "errorhandler".equalsIgnoreCase(type)) { + try { + completion = OBJECT_MAPPER.readValue(data, AssistantCompletion.class); + Usage usageInfo = completion.getUsage(); + if (usageInfo != null) { + this.tokenUsage = tokenUsageFrom(usageInfo); + } + AiMessage aiMessage = AiMessage.from(completion.getMsg()); + Response response = Response.from(aiMessage, this.tokenUsage, FinishReason.OTHER); + handler.onComplete(response); + } catch (Exception exception) { + handleResponseException(exception, handler); + } + } else { + try { + completion = OBJECT_MAPPER.readValue(data, AssistantCompletion.class); + String chunk = completion.getMsg(); + if (chunk != null) { + contentBuilder.append(chunk); + handler.onNext(chunk); + } + AssistantExtraInput extraInput = completion.getExtraInput(); + if (extraInput != null) { + final AssistantNodeData nodeData = extraInput.getNodeData(); + if (nodeData != null) { + if ("finished".equals(nodeData.getNodeStatus())) { + this.finishReason = FinishReason.STOP; + } else if ("sensitive".equals(nodeData.getNodeStatus())) { + this.finishReason = FinishReason.CONTENT_FILTER; + } + } + } + Usage usageInfo = completion.getUsage(); + if (usageInfo != null) { + this.tokenUsage = tokenUsageFrom(usageInfo); + } + } catch (Exception exception) { + handleResponseException(exception, handler); + } + } + } + + @Override + public void onFailure(@NotNull EventSource eventSource, Throwable t, okhttp3.Response response) { + if (logResponses) { + log.debug("onFailure()", t); + } + Throwable throwable = Utils.getOrDefault(t, new ZhipuAiException(response)); + handleResponseException(throwable, handler); + } + + @Override + public void onClosed(@NotNull EventSource eventSource) { + if (logResponses) { + log.debug("onClosed()"); + } + } + }; + EventSources.createFactory(this.okHttpClient) + .newEventSource(zhipuAiApi.sseInvoke(requestId).request(), eventSourceListener); + } + + public Problems sessionRecord(String appId, String conversationId) { + retrofit2.Response retrofitResponse; + try { + retrofitResponse = zhipuAiApi.sessionRecord(appId, conversationId).execute(); + if (retrofitResponse.isSuccessful()) { + final ProblemsResponse body = retrofitResponse.body(); + if (Objects.nonNull(body)) { + if (!body.isSuccess()) { + log.error("获取推荐问题失败,原因为:【{}】", body.getMessage()); + throw new ZhipuAiException("1200", body.getMessage()); + } + return body.getData(); + } + throw toException(retrofitResponse); + } else { + throw toException(retrofitResponse); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private void handleResponseException(Throwable throwable, StreamingResponseHandler handler) { + + if (throwable instanceof ZhipuAiException) { + ChatCompletionResponse errorResponse = toChatErrorResponse(throwable); + Response messageResponse = Response.from( + aiMessageFrom(errorResponse), + tokenUsageFrom(errorResponse.getUsage()), + finishReasonFrom(getFinishReason(throwable))); + handler.onComplete(messageResponse); + } else { + handler.onError(throwable); + } + } + + private RuntimeException toException(retrofit2.Response retrofitResponse) throws IOException { + int code = retrofitResponse.code(); + if (code >= 400) { + try (ResponseBody errorBody = retrofitResponse.errorBody()) { + if (errorBody != null) { + String errorBodyString = errorBody.string(); + String errorMessage = String.format("status code: %s; body: %s", code, errorBodyString); + log.error("Error response: {}", errorMessage); + return new RuntimeException(errorMessage); + } + } + } + return new RuntimeException(retrofitResponse.message()); + } + + public static class Builder { + private String baseUrl; + private String apiKey; + private Duration callTimeout; + private Duration connectTimeout; + private Duration readTimeout; + private Duration writeTimeout; + private boolean logRequests; + private boolean logResponses; + + private Builder() { + this.baseUrl = "https://open.bigmodel.cn/"; + this.callTimeout = Duration.ofSeconds(60L); + this.connectTimeout = Duration.ofSeconds(60L); + this.readTimeout = Duration.ofSeconds(60L); + this.writeTimeout = Duration.ofSeconds(60L); + } + + public Builder baseUrl(String baseUrl) { + if (baseUrl != null && !baseUrl.trim().isEmpty()) { + this.baseUrl = baseUrl.endsWith("/") ? baseUrl : baseUrl + "/"; + return this; + } else { + throw new IllegalArgumentException("baseUrl cannot be null or empty"); + } + } + + public Builder apiKey(String apiKey) { + if (apiKey != null && !apiKey.trim().isEmpty()) { + this.apiKey = apiKey; + return this; + } else { + throw new IllegalArgumentException("apiKey cannot be null or empty. "); + } + } + + public Builder callTimeout(Duration callTimeout) { + if (callTimeout == null) { + throw new IllegalArgumentException("callTimeout cannot be null"); + } else { + this.callTimeout = callTimeout; + return this; + } + } + + public Builder connectTimeout(Duration connectTimeout) { + if (connectTimeout == null) { + throw new IllegalArgumentException("connectTimeout cannot be null"); + } else { + this.connectTimeout = connectTimeout; + return this; + } + } + + public Builder readTimeout(Duration readTimeout) { + if (readTimeout == null) { + throw new IllegalArgumentException("readTimeout cannot be null"); + } else { + this.readTimeout = readTimeout; + return this; + } + } + + public Builder writeTimeout(Duration writeTimeout) { + if (writeTimeout == null) { + throw new IllegalArgumentException("writeTimeout cannot be null"); + } else { + this.writeTimeout = writeTimeout; + return this; + } + } + + public Builder logRequests() { + return this.logRequests(true); + } + + public Builder logRequests(Boolean logRequests) { + if (logRequests == null) { + logRequests = false; + } + + this.logRequests = logRequests; + return this; + } + + public Builder logResponses() { + return this.logResponses(true); + } + + public Builder logResponses(Boolean logResponses) { + if (logResponses == null) { + logResponses = false; + } + + this.logResponses = logResponses; + return this; + } + + public ZhipuAssistantClient build() { + return new ZhipuAssistantClient(this); + } + } +} diff --git a/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/AssistantBlockData.java b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/AssistantBlockData.java new file mode 100644 index 00000000..7fe199fb --- /dev/null +++ b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/AssistantBlockData.java @@ -0,0 +1,69 @@ +package dev.langchain4j.community.model.zhipu.assistant; + +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy; +import com.fasterxml.jackson.databind.annotation.JsonNaming; + +@JsonInclude(NON_NULL) +@JsonNaming(SnakeCaseStrategy.class) +@JsonIgnoreProperties(ignoreUnknown = true) +public class AssistantBlockData { + + private String input; + private String blockType; + private String blockName; + private String errorMsg; + private String blockDur; + private AssistantOutPut outPut; + + public String getInput() { + return input; + } + + public void setInput(String input) { + this.input = input; + } + + public String getBlockType() { + return blockType; + } + + public void setBlockType(String blockType) { + this.blockType = blockType; + } + + public String getBlockName() { + return blockName; + } + + public void setBlockName(String blockName) { + this.blockName = blockName; + } + + public String getErrorMsg() { + return errorMsg; + } + + public void setErrorMsg(String errorMsg) { + this.errorMsg = errorMsg; + } + + public String getBlockDur() { + return blockDur; + } + + public void setBlockDur(String blockDur) { + this.blockDur = blockDur; + } + + public AssistantOutPut getOutPut() { + return outPut; + } + + public void setOutPut(AssistantOutPut outPut) { + this.outPut = outPut; + } +} diff --git a/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/AssistantCompletion.java b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/AssistantCompletion.java new file mode 100644 index 00000000..1d3de978 --- /dev/null +++ b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/AssistantCompletion.java @@ -0,0 +1,46 @@ +package dev.langchain4j.community.model.zhipu.assistant; + +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import dev.langchain4j.community.model.zhipu.shared.Usage; + +/** + * This class represents the completion data returned by an assistant. + */ +@JsonInclude(NON_NULL) +@JsonNaming(SnakeCaseStrategy.class) +@JsonIgnoreProperties(ignoreUnknown = true) +public class AssistantCompletion { + + private String msg; + private AssistantExtraInput extraInput; + private Usage usage; + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public AssistantExtraInput getExtraInput() { + return extraInput; + } + + public void setExtraInput(AssistantExtraInput extraInput) { + this.extraInput = extraInput; + } + + public Usage getUsage() { + return usage; + } + + public void setUsage(Usage usage) { + this.usage = usage; + } +} diff --git a/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/AssistantExtraInput.java b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/AssistantExtraInput.java new file mode 100644 index 00000000..8f52c0aa --- /dev/null +++ b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/AssistantExtraInput.java @@ -0,0 +1,60 @@ +package dev.langchain4j.community.model.zhipu.assistant; + +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy; +import com.fasterxml.jackson.databind.annotation.JsonNaming; + +@JsonInclude(NON_NULL) +@JsonNaming(SnakeCaseStrategy.class) +@JsonIgnoreProperties(ignoreUnknown = true) +public class AssistantExtraInput { + + private String requestId; + private String nodeId; + private String pushType; + private AssistantNodeData nodeData; + private AssistantBlockData blockData; + + public String getRequestId() { + return requestId; + } + + public void setRequestId(String requestId) { + this.requestId = requestId; + } + + public String getNodeId() { + return nodeId; + } + + public void setNodeId(String nodeId) { + this.nodeId = nodeId; + } + + public String getPushType() { + return pushType; + } + + public void setPushType(String pushType) { + this.pushType = pushType; + } + + public AssistantNodeData getNodeData() { + return nodeData; + } + + public void setNodeData(AssistantNodeData nodeData) { + this.nodeData = nodeData; + } + + public AssistantBlockData getBlockData() { + return blockData; + } + + public void setBlockData(AssistantBlockData blockData) { + this.blockData = blockData; + } +} diff --git a/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/AssistantKeyValuePair.java b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/AssistantKeyValuePair.java new file mode 100644 index 00000000..60f22416 --- /dev/null +++ b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/AssistantKeyValuePair.java @@ -0,0 +1,107 @@ +package dev.langchain4j.community.model.zhipu.assistant; + +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import dev.langchain4j.community.model.zhipu.assistant.file.FileData; +import java.util.List; + +@JsonInclude(NON_NULL) +@JsonNaming(SnakeCaseStrategy.class) +@JsonIgnoreProperties(ignoreUnknown = true) +public class AssistantKeyValuePair { + + private String id; + private String name; + private String type; + private String value; + private String tips; + private List allowValues; + private List files; + private List ivfiles; + private InputTemplate inputTemplate; + private List inputTemplates; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getTips() { + return tips; + } + + public void setTips(String tips) { + this.tips = tips; + } + + public List getAllowValues() { + return allowValues; + } + + public void setAllowValues(List allowValues) { + this.allowValues = allowValues; + } + + public List getFiles() { + return files; + } + + public void setFiles(List files) { + this.files = files; + } + + public List getIvfiles() { + return ivfiles; + } + + public void setIvfiles(List ivfiles) { + this.ivfiles = ivfiles; + } + + public InputTemplate getInputTemplate() { + return inputTemplate; + } + + public void setInputTemplate(InputTemplate inputTemplate) { + this.inputTemplate = inputTemplate; + } + + public List getInputTemplates() { + return inputTemplates; + } + + public void setInputTemplates(List inputTemplates) { + this.inputTemplates = inputTemplates; + } +} diff --git a/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/AssistantNodeData.java b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/AssistantNodeData.java new file mode 100644 index 00000000..855cef27 --- /dev/null +++ b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/AssistantNodeData.java @@ -0,0 +1,60 @@ +package dev.langchain4j.community.model.zhipu.assistant; + +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy; +import com.fasterxml.jackson.databind.annotation.JsonNaming; + +@JsonInclude(NON_NULL) +@JsonNaming(SnakeCaseStrategy.class) +@JsonIgnoreProperties(ignoreUnknown = true) +public class AssistantNodeData { + + private String nodeId; + private String nodeType; + private String nodeName; + private String nodeStatus; + private String nodeDur; + + public String getNodeId() { + return nodeId; + } + + public void setNodeId(String nodeId) { + this.nodeId = nodeId; + } + + public String getNodeType() { + return nodeType; + } + + public void setNodeType(String nodeType) { + this.nodeType = nodeType; + } + + public String getNodeName() { + return nodeName; + } + + public void setNodeName(String nodeName) { + this.nodeName = nodeName; + } + + public String getNodeStatus() { + return nodeStatus; + } + + public void setNodeStatus(String nodeStatus) { + this.nodeStatus = nodeStatus; + } + + public String getNodeDur() { + return nodeDur; + } + + public void setNodeDur(String nodeDur) { + this.nodeDur = nodeDur; + } +} diff --git a/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/AssistantOutPut.java b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/AssistantOutPut.java new file mode 100644 index 00000000..21e66d9c --- /dev/null +++ b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/AssistantOutPut.java @@ -0,0 +1,41 @@ +package dev.langchain4j.community.model.zhipu.assistant; + +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy; +import com.fasterxml.jackson.databind.annotation.JsonNaming; + +@JsonInclude(NON_NULL) +@JsonNaming(SnakeCaseStrategy.class) +@JsonIgnoreProperties(ignoreUnknown = true) +public class AssistantOutPut { + private String functionExecTime; + private String modelExecTime; + private String outContent; + + public String getFunctionExecTime() { + return functionExecTime; + } + + public void setFunctionExecTime(String functionExecTime) { + this.functionExecTime = functionExecTime; + } + + public String getModelExecTime() { + return modelExecTime; + } + + public void setModelExecTime(String modelExecTime) { + this.modelExecTime = modelExecTime; + } + + public String getOutContent() { + return outContent; + } + + public void setOutContent(String outContent) { + this.outContent = outContent; + } +} diff --git a/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/AssistantSupportResponse.java b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/AssistantSupportResponse.java new file mode 100644 index 00000000..349619fa --- /dev/null +++ b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/AssistantSupportResponse.java @@ -0,0 +1,46 @@ +package dev.langchain4j.community.model.zhipu.assistant; + +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import java.util.List; + +@JsonInclude(NON_NULL) +@JsonNaming(SnakeCaseStrategy.class) +@JsonIgnoreProperties(ignoreUnknown = true) +public class AssistantSupportResponse implements ClientResponse> { + private Integer code; + private String message; + private List data; + + public Integer getCode() { + return code; + } + + @Override + public void setCode(Integer code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + @Override + public void setMessage(String message) { + this.message = message; + } + + @Override + public List getData() { + return data; + } + + @Override + public void setData(List data) { + this.data = data; + } +} diff --git a/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/AssistantType.java b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/AssistantType.java new file mode 100644 index 00000000..d1a96e63 --- /dev/null +++ b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/AssistantType.java @@ -0,0 +1,18 @@ +package dev.langchain4j.community.model.zhipu.assistant; + +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Locale; + +public enum AssistantType { + INPUT, + SELECTION_LIST, + UPLOAD_FILE, + UPLOAD_IMAGE, + UPLOAD_VIDEO, + INPUT_TEMPLATE; + + @JsonValue + public String serialize() { + return name().toLowerCase(Locale.ROOT); + } +} diff --git a/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/ClientResponse.java b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/ClientResponse.java new file mode 100644 index 00000000..0e415b9e --- /dev/null +++ b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/ClientResponse.java @@ -0,0 +1,20 @@ +package dev.langchain4j.community.model.zhipu.assistant; + +import java.util.Objects; + +public interface ClientResponse { + + T getData(); + + void setData(T data); + + void setCode(Integer code); + + Integer getCode(); + + void setMessage(String message); + + default boolean isSuccess() { + return Objects.equals(getCode(), 200); + } +} diff --git a/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/InputTemplate.java b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/InputTemplate.java new file mode 100644 index 00000000..f0a17941 --- /dev/null +++ b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/InputTemplate.java @@ -0,0 +1,34 @@ +package dev.langchain4j.community.model.zhipu.assistant; + +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import java.util.List; + +@JsonInclude(NON_NULL) +@JsonNaming(SnakeCaseStrategy.class) +@JsonIgnoreProperties(ignoreUnknown = true) +public class InputTemplate { + + private String splicingTemplate; + private List options; + + public String getSplicingTemplate() { + return splicingTemplate; + } + + public void setSplicingTemplate(String splicingTemplate) { + this.splicingTemplate = splicingTemplate; + } + + public List getOptions() { + return options; + } + + public void setOptions(List options) { + this.options = options; + } +} diff --git a/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/conversation/ConversationId.java b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/conversation/ConversationId.java new file mode 100644 index 00000000..7bdf4eee --- /dev/null +++ b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/conversation/ConversationId.java @@ -0,0 +1,33 @@ +package dev.langchain4j.community.model.zhipu.assistant.conversation; + +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy; +import com.fasterxml.jackson.databind.annotation.JsonNaming; + +@JsonInclude(NON_NULL) +@JsonNaming(SnakeCaseStrategy.class) +@JsonIgnoreProperties(ignoreUnknown = true) +public class ConversationId { + + private String id; + private String conversationId; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getConversationId() { + return conversationId; + } + + public void setConversationId(String conversationId) { + this.conversationId = conversationId; + } +} diff --git a/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/conversation/ConversationRequest.java b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/conversation/ConversationRequest.java new file mode 100644 index 00000000..c4137b6c --- /dev/null +++ b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/conversation/ConversationRequest.java @@ -0,0 +1,159 @@ +package dev.langchain4j.community.model.zhipu.assistant.conversation; + +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import dev.langchain4j.community.model.zhipu.assistant.AssistantKeyValuePair; +import java.util.List; + +@JsonInclude(NON_NULL) +@JsonNaming(SnakeCaseStrategy.class) +@JsonIgnoreProperties(ignoreUnknown = true) +public class ConversationRequest { + + private String appId; + private String conversationId; + private String assistantId; + private List keyValuePairs; + private List documentIds; + private List knowledgeIds; + + public ConversationRequest() {} + + public ConversationRequest( + String appId, + String conversationId, + String assistantId, + List keyValuePairs, + List documentIds, + List knowledgeIds) { + this.appId = appId; + this.conversationId = conversationId; + this.assistantId = assistantId; + this.keyValuePairs = keyValuePairs; + this.documentIds = documentIds; + this.knowledgeIds = knowledgeIds; + } + + public static ConversationRequestBuilder builder() { + return new ConversationRequestBuilder(); + } + + public String getAppId() { + return appId; + } + + public void setAppId(String appId) { + this.appId = appId; + } + + public String getConversationId() { + return conversationId; + } + + public void setConversationId(String conversationId) { + this.conversationId = conversationId; + } + + public String getAssistantId() { + return assistantId; + } + + public void setAssistantId(String assistantId) { + this.assistantId = assistantId; + } + + public List getKeyValuePairs() { + return keyValuePairs; + } + + public void setKeyValuePairs(List keyValuePairs) { + this.keyValuePairs = keyValuePairs; + } + + public List getDocumentIds() { + return documentIds; + } + + public void setDocumentIds(List documentIds) { + this.documentIds = documentIds; + } + + public List getKnowledgeIds() { + return knowledgeIds; + } + + public void setKnowledgeIds(List knowledgeIds) { + this.knowledgeIds = knowledgeIds; + } + + public static class ConversationRequestBuilder { + /** + * 智能体(应用)id + */ + private String appId; + + /** + * 会话 ID + */ + private String conversationId; + + /** + * 智能体 ID(目前无用) + */ + private String assistantId; + + /** + * 输入模版中的变量列表 + */ + private List keyValuePairs; + + /** + * 适用问答类智能体(应用): 用于知识筛选, 不传默认使用智能体(应用)配置 + */ + private List documentIds; + + /** + * 适用问答类智能体(应用): 用于知识筛选, 不传默认使用智能体(应用)配置 + */ + private List knowledgeIds; + + public ConversationRequestBuilder appId(String appId) { + this.appId = appId; + return this; + } + + public ConversationRequestBuilder conversationId(String conversationId) { + this.conversationId = conversationId; + return this; + } + + public ConversationRequestBuilder assistantId(String assistantId) { + this.assistantId = assistantId; + return this; + } + + public ConversationRequestBuilder keyValuePairs(List keyValuePairs) { + this.keyValuePairs = keyValuePairs; + return this; + } + + public ConversationRequestBuilder documentIds(List documentIds) { + this.documentIds = documentIds; + return this; + } + + public ConversationRequestBuilder knowledgeIds(List knowledgeIds) { + this.knowledgeIds = knowledgeIds; + return this; + } + + public ConversationRequest build() { + return new ConversationRequest( + appId, conversationId, assistantId, keyValuePairs, documentIds, knowledgeIds); + } + } +} diff --git a/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/conversation/ConversationResponse.java b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/conversation/ConversationResponse.java new file mode 100644 index 00000000..ba0d608c --- /dev/null +++ b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/conversation/ConversationResponse.java @@ -0,0 +1,45 @@ +package dev.langchain4j.community.model.zhipu.assistant.conversation; + +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import dev.langchain4j.community.model.zhipu.assistant.ClientResponse; + +@JsonInclude(NON_NULL) +@JsonNaming(SnakeCaseStrategy.class) +@JsonIgnoreProperties(ignoreUnknown = true) +public class ConversationResponse implements ClientResponse { + private Integer code; + private String message; + private ConversationId data; + + public Integer getCode() { + return code; + } + + @Override + public void setCode(Integer code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + @Override + public void setMessage(String message) { + this.message = message; + } + + @Override + public ConversationId getData() { + return data; + } + + public void setData(ConversationId data) { + this.data = data; + } +} diff --git a/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/file/FileData.java b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/file/FileData.java new file mode 100644 index 00000000..dc117f1d --- /dev/null +++ b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/file/FileData.java @@ -0,0 +1,30 @@ +package dev.langchain4j.community.model.zhipu.assistant.file; + +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; + +@JsonInclude(NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class FileData { + + private Integer type; + private String url; + + public Integer getType() { + return type; + } + + public void setType(Integer type) { + this.type = type; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } +} diff --git a/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/problem/Problems.java b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/problem/Problems.java new file mode 100644 index 00000000..fd467174 --- /dev/null +++ b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/problem/Problems.java @@ -0,0 +1,24 @@ +package dev.langchain4j.community.model.zhipu.assistant.problem; + +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import java.util.List; + +/** + * This class represents the Problems data for a specific conversation. + */ +@JsonInclude(NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class Problems { + private List problems; + + public List getProblems() { + return problems; + } + + public void setProblems(List problems) { + this.problems = problems; + } +} diff --git a/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/problem/ProblemsResponse.java b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/problem/ProblemsResponse.java new file mode 100644 index 00000000..add4d50e --- /dev/null +++ b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/assistant/problem/ProblemsResponse.java @@ -0,0 +1,42 @@ +package dev.langchain4j.community.model.zhipu.assistant.problem; + +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import dev.langchain4j.community.model.zhipu.assistant.ClientResponse; + +@JsonInclude(NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class ProblemsResponse implements ClientResponse { + private Integer code; + private String message; + private Problems data; + + public Integer getCode() { + return code; + } + + @Override + public void setCode(Integer code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + @Override + public void setMessage(String message) { + this.message = message; + } + + @Override + public Problems getData() { + return data; + } + + public void setData(Problems data) { + this.data = data; + } +} diff --git a/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/shared/ErrorResponse.java b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/shared/ErrorResponse.java index d4c2f209..24ba6290 100644 --- a/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/shared/ErrorResponse.java +++ b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/shared/ErrorResponse.java @@ -1,8 +1,16 @@ package dev.langchain4j.community.model.zhipu.shared; +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import java.util.List; import java.util.Map; +@JsonInclude(NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) public class ErrorResponse { + private List contentFilter; private Map error; public Map getError() { @@ -12,4 +20,12 @@ public Map getError() { public void setError(Map error) { this.error = error; } + + public List getContentFilter() { + return contentFilter; + } + + public void setContentFilter(List contentFilter) { + this.contentFilter = contentFilter; + } } diff --git a/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/shared/SensitiveFilter.java b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/shared/SensitiveFilter.java new file mode 100644 index 00000000..e7b73d30 --- /dev/null +++ b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/shared/SensitiveFilter.java @@ -0,0 +1,25 @@ +package dev.langchain4j.community.model.zhipu.shared; + +/** + * Illegal or harmful information: Severity level. + */ +public class SensitiveFilter { + private String role; + private Integer level; + + public String getRole() { + return role; + } + + public void setRole(final String role) { + this.role = role; + } + + public Integer getLevel() { + return level; + } + + public void setLevel(final Integer level) { + this.level = level; + } +} diff --git a/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/spi/ZhipuAssistantBuilderFactory.java b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/spi/ZhipuAssistantBuilderFactory.java new file mode 100644 index 00000000..1eb8a30a --- /dev/null +++ b/models/langchain4j-community-zhipu-ai/src/main/java/dev/langchain4j/community/model/zhipu/spi/ZhipuAssistantBuilderFactory.java @@ -0,0 +1,9 @@ +package dev.langchain4j.community.model.zhipu.spi; + +import dev.langchain4j.community.model.zhipu.ZhipuAiAssistant; +import java.util.function.Supplier; + +/** + * A factory for building {@link ZhipuAiAssistant.ZhipuAiAssistantBuilder} instances. + */ +public interface ZhipuAssistantBuilderFactory extends Supplier {} diff --git a/models/langchain4j-community-zhipu-ai/src/test/java/dev/langchain4j/community/model/zhipu/ZhipuAiAssistantIT.java b/models/langchain4j-community-zhipu-ai/src/test/java/dev/langchain4j/community/model/zhipu/ZhipuAiAssistantIT.java new file mode 100644 index 00000000..d374109f --- /dev/null +++ b/models/langchain4j-community-zhipu-ai/src/test/java/dev/langchain4j/community/model/zhipu/ZhipuAiAssistantIT.java @@ -0,0 +1,89 @@ +package dev.langchain4j.community.model.zhipu; + +import static java.time.Duration.ofSeconds; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; + +import dev.langchain4j.community.model.zhipu.assistant.AssistantKeyValuePair; +import dev.langchain4j.community.model.zhipu.assistant.problem.Problems; +import dev.langchain4j.data.message.AiMessage; +import dev.langchain4j.internal.Utils; +import dev.langchain4j.model.StreamingResponseHandler; +import dev.langchain4j.model.output.Response; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; + +@EnabledIfEnvironmentVariable(named = "ZHIPU_API_KEY", matches = ".+") +class ZhipuAiAssistantIT { + private static final String apiKey = System.getenv("ZHIPU_API_KEY"); + // Your own appId + private static final String appId = ""; + + ZhipuAiAssistant chatModel = ZhipuAiAssistant.builder() + .apiKey(apiKey) + .appId(appId) + .connectTimeout(ofSeconds(60)) + .writeTimeout(ofSeconds(60)) + .readTimeout(ofSeconds(60)) + .callTimeout(ofSeconds(60)) + .build(); + + @Test + void should_generate_answer_and_return_token_usage() + throws ExecutionException, InterruptedException, TimeoutException { + if (Utils.isNullOrEmpty(appId)) { + return; + } + CompletableFuture> future = new CompletableFuture<>(); + + StreamingResponseHandler handler = new StreamingResponseHandler() { + + @Override + public void onNext(String token) { + fail("onNext() must not be called"); + } + + @Override + public void onError(Throwable error) { + fail("OnError() must not be called"); + } + + @Override + public void onComplete(Response response) { + future.complete(response); + } + }; + + // given + AssistantKeyValuePair keyValuePair = chatModel.initMessage("中国首都在哪里"); + // 消息入库 + chatModel.generate(getConversationId(), List.of(keyValuePair), handler); + + Response response = future.get(5, SECONDS); + // then + assertThat(response.content().text()).contains("北京"); + } + + @Test + void recommend_problems() { + if (Utils.isNullOrEmpty(appId)) { + return; + } + String conversationId = getConversationId(); + Problems problems = chatModel.sessionRecord(conversationId); + assertThat(problems.getProblems()).isNotEmpty(); + } + + /** + * create conversationId + * @return conversationId + */ + public String getConversationId() { + return chatModel.getConversationId(); + } +}