From 1ff142fc75297ef69ca3de3813c3342d61de3de3 Mon Sep 17 00:00:00 2001 From: erasernoob <1490910338@qq.com> Date: Wed, 25 Dec 2024 22:31:08 +0800 Subject: [PATCH 1/4] update: merge the pullrequest --- .../pom.xml | 65 ++++++++++ .../GoogleTranslateAutoConfiguration.java | 27 ++++ .../GoogleTranslateProperties.java | 38 ++++++ .../GoogleTranslateService.java | 118 ++++++++++++++++++ .../googletranslate/MainApplication.java | 12 ++ ...ot.autoconfigure.AutoConfiguration.imports | 1 + .../src/test/java/GoogleTranslateTest.java | 41 ++++++ .../translate/TranslateProperties.java | 1 - pom.xml | 1 + 9 files changed, 303 insertions(+), 1 deletion(-) create mode 100644 community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/pom.xml create mode 100644 community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateAutoConfiguration.java create mode 100644 community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateProperties.java create mode 100644 community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateService.java create mode 100644 community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/MainApplication.java create mode 100644 community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/resources/META-INF.spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/test/java/GoogleTranslateTest.java diff --git a/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/pom.xml b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/pom.xml new file mode 100644 index 000000000..334a2208b --- /dev/null +++ b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/pom.xml @@ -0,0 +1,65 @@ + + + 4.0.0 + + com.alibaba.cloud.ai + spring-ai-alibaba + ${revision} + ../../../pom.xml + + +spring-ai-alibaba-starter-function-calling-googletranslate +spring-ai-alibaba-starter-plugin-googletranslate +Translate tool for Spring AI Alibaba + + + + org.springframework.ai + spring-ai-spring-boot-autoconfigure + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + org.springframework.boot + spring-boot-starter-webflux + + + + com.google.code.gson + gson + + + org.springframework.boot + spring-boot-test + test + + + org.springframework.ai + spring-ai-core + test + + + org.springframework.boot + spring-boot-starter-test + test + + + org.jetbrains + annotations + 24.0.1 + test + + + + + +spring-ai-alibaba-plugin-googletranslate + + \ No newline at end of file diff --git a/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateAutoConfiguration.java b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateAutoConfiguration.java new file mode 100644 index 000000000..2d6431c44 --- /dev/null +++ b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateAutoConfiguration.java @@ -0,0 +1,27 @@ +package com.alibaba.cloud.ai.functioncalling.googletranslate; + + +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Description; + +/** + * @author erasernoob + */ +@ConditionalOnClass({ GoogleTranslateService.class }) +@EnableConfigurationProperties(GoogleTranslateProperties.class) +@ConditionalOnProperty(prefix = "spring.ai.alibaba.functioncalling.googletranlate", name = "enabled", + havingValue = "true") +public class GoogleTranslateAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + @Description("Implement natural language translation capabilities.") + public GoogleTranslateService GoogleTranslateFunction(GoogleTranslateProperties properties) { + return new GoogleTranslateService(properties); + } +} diff --git a/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateProperties.java b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateProperties.java new file mode 100644 index 000000000..19f2e9753 --- /dev/null +++ b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateProperties.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.cloud.ai.functioncalling.googletranslate; + + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * @author erasernoob + */ +@ConfigurationProperties(prefix = "spring.ai.alibaba.plugin.googletranslate") +public class GoogleTranslateProperties { + + private String apiKey; + + public String getApiKey() { + return apiKey; + } + + public void setApiKey(String apiKey) { + this.apiKey = apiKey; + } +} diff --git a/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateService.java b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateService.java new file mode 100644 index 000000000..44e8185a7 --- /dev/null +++ b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateService.java @@ -0,0 +1,118 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.cloud.ai.functioncalling.googletranslate; +import com.fasterxml.jackson.annotation.JsonClassDescription; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyDescription; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpHeaders; +import org.springframework.util.StringUtils; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.util.UriComponentsBuilder; +import reactor.core.publisher.Mono; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +/** + * @author erasernoob + */ +public class GoogleTranslateService implements Function { + + private static final Logger log = LoggerFactory.getLogger(GoogleTranslateService.class); + + private static final String TRANSLATE_HOST = "https://translation.googleapis.com"; + + private static final String TRANSLATE_PATH = "/language/translate/v2"; + + private final GoogleTranslateProperties properties; + + private final WebClient webClient; + + public GoogleTranslateService(GoogleTranslateProperties properties) { + assert StringUtils.hasText(properties.getApiKey()); + this.properties = properties; + this.webClient = WebClient.builder() + .defaultHeader("Content-Type", "application/json") + .build(); + } + @Override + public Response apply(Request request) { + if ( request == null || !StringUtils.hasText(properties.getApiKey()) || + !StringUtils.hasText(request.text) || !StringUtils.hasText(request.targetLanguage) + ) {return null;} + + String requestUrl = UriComponentsBuilder.fromHttpUrl(TRANSLATE_HOST + TRANSLATE_PATH) + .queryParam("key", properties.getApiKey()) + .queryParam("target", request.targetLanguage) + .queryParam("q", request.text) + .queryParam("format", "text") + .toUriString(); + try { + Mono responseMono = webClient.post().uri(requestUrl).retrieve().bodyToMono(String.class); + + String responseData = responseMono.block(); + assert responseData != null; + log.info("GoogleTranslation request: {}, response: {}", request.text, responseData); + return parseResponseData(responseData, request.text); + } catch (Exception e) { + log.error("Using the googleTranslate service failed due to {}", e.getMessage()); + } + return null; + } + + private Response parseResponseData(String responseData, String q) { + Gson gson = new Gson(); + Map response = gson.fromJson(responseData, + new TypeToken>() {}.getType()); + if (response.containsKey("error")) { + Map errorMap = (Map) response.get("error"); + log.error("GoogleTranslation service failed due to {}", errorMap.get("message").toString()); + return null; + } + + Map data = (Map) response.get("data"); + List> translationsList = (List>) data.get("translation"); + if ( translationsList == null || translationsList.isEmpty()) { + log.error("Invalid response format: 'translation' list is empty."); + return null; + } + + Map translationResult = new HashMap<>(); + for (Map translation : translationsList) { + translationResult.put(q, translation.get("translatedText")); + } + return new Response(translationResult); + } + + public record Request( + @JsonProperty(required = true, + value = "text")@JsonPropertyDescription("Content that needs to be translated") String text, + @JsonProperty(required = true, value = "targetLanguage") + @JsonPropertyDescription("the target language to translate into") + String targetLanguage + ) {} + + @JsonClassDescription("Response to translate text to the target language") + public record Response(Map translatedTexts) {} +} diff --git a/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/MainApplication.java b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/MainApplication.java new file mode 100644 index 000000000..0a607e82e --- /dev/null +++ b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/MainApplication.java @@ -0,0 +1,12 @@ +package com.alibaba.cloud.ai.functioncalling.googletranslate; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class MainApplication { + public static void main(String[] args) { + SpringApplication.run(MainApplication.class, args); + } + +} diff --git a/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/resources/META-INF.spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/resources/META-INF.spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000..e4f87b6bb --- /dev/null +++ b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/resources/META-INF.spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +com.alibaba.cloud.ai.functioncalling.translate.GoogleTranslateAutoConfiguration diff --git a/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/test/java/GoogleTranslateTest.java b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/test/java/GoogleTranslateTest.java new file mode 100644 index 000000000..edae12edb --- /dev/null +++ b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/test/java/GoogleTranslateTest.java @@ -0,0 +1,41 @@ +import com.alibaba.cloud.ai.functioncalling.googletranslate.GoogleTranslateService; +import com.sun.tools.javac.Main; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.ai.chat.client.ChatClient; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author 北极星 + */ +@SpringBootTest +@ContextConfiguration(classes = Main.class) +public class GoogleTranslateTest { + + private static final Logger log = LoggerFactory.getLogger(GoogleTranslateTest.class); + + private final ChatClient chatClient; + + public GoogleTranslateTest(@NotNull ChatClient.Builder chatClientBuilder) { + this.chatClient = chatClientBuilder.build(); + } + + /** + * 微软翻译 + * + * @link + * 版本号 version 3.0 + * ApplicationYml spring.ai.alibaba.functioncalling.microsofttranslate 传入 api-key + */ + @Test + protected void GoogleTranslate () { + String text = "你好,spring-ai-alibaba!"; + + String ans = chatClient.prompt().functions("googleTranslateFunction").user(text).call().content(); + log.info("translated text -> : ${}", ans); + } +} \ No newline at end of file diff --git a/community/function-calling/spring-ai-alibaba-starter-function-calling-translate/src/main/java/com/alibaba/cloud/ai/functioncalling/translate/TranslateProperties.java b/community/function-calling/spring-ai-alibaba-starter-function-calling-translate/src/main/java/com/alibaba/cloud/ai/functioncalling/translate/TranslateProperties.java index b29977b99..7d327958e 100644 --- a/community/function-calling/spring-ai-alibaba-starter-function-calling-translate/src/main/java/com/alibaba/cloud/ai/functioncalling/translate/TranslateProperties.java +++ b/community/function-calling/spring-ai-alibaba-starter-function-calling-translate/src/main/java/com/alibaba/cloud/ai/functioncalling/translate/TranslateProperties.java @@ -36,5 +36,4 @@ public String getApiKey() { public void setApiKey(String apiKey) { this.apiKey = apiKey; } - } diff --git a/pom.xml b/pom.xml index f7ef464af..b7afdcdbc 100644 --- a/pom.xml +++ b/pom.xml @@ -46,6 +46,7 @@ community/function-calling/spring-ai-alibaba-starter-function-calling-regex community/function-calling/spring-ai-alibaba-starter-function-calling-jsonprocessor community/function-calling/spring-ai-alibaba-starter-function-calling-serpapi + community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate community/document-readers/github-reader community/document-readers/poi-document-reader From bfe48c25ded0d31da6621ae5da2ae672ee829a87 Mon Sep 17 00:00:00 2001 From: erasernoob <1490910338@qq.com> Date: Fri, 27 Dec 2024 23:01:35 +0800 Subject: [PATCH 2/4] fix: use the jackson instead and fix some bug --- .../pom.xml | 108 ++++++++++-------- .../GoogleTranslateAutoConfiguration.java | 2 +- .../GoogleTranslateService.java | 54 +++++---- .../googletranslate/MainApplication.java | 12 -- .../src/test/java/GoogleTranslateTest.java | 41 ------- 5 files changed, 91 insertions(+), 126 deletions(-) delete mode 100644 community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/MainApplication.java delete mode 100644 community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/test/java/GoogleTranslateTest.java diff --git a/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/pom.xml b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/pom.xml index 334a2208b..2016fb02b 100644 --- a/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/pom.xml +++ b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/pom.xml @@ -1,63 +1,71 @@ - + + + + 4.0.0 + - com.alibaba.cloud.ai - spring-ai-alibaba - ${revision} - ../../../pom.xml + com.alibaba.cloud.ai + spring-ai-alibaba + ${revision} + ../../../pom.xml -spring-ai-alibaba-starter-function-calling-googletranslate -spring-ai-alibaba-starter-plugin-googletranslate -Translate tool for Spring AI Alibaba + spring-ai-alibaba-starter-function-calling-googletranslate + spring-ai-alibaba-starter-function-calling-googletranslate + Translate tool for Spring AI Alibaba + https://github.com/alibaba/spring-ai-alibaba + + https://github.com/alibaba/spring-ai-alibaba + git://github.com/alibaba/spring-ai-alibaba.git + git@github.com:alibaba/spring-ai-alibaba.git + + + + + + org.springframework.ai + spring-ai-spring-boot-autoconfigure + - - - org.springframework.ai - spring-ai-spring-boot-autoconfigure - + + org.springframework.boot + spring-boot-configuration-processor + true + - - org.springframework.boot - spring-boot-configuration-processor - true - + + org.springframework.boot + spring-boot-starter-webflux + - - org.springframework.boot - spring-boot-starter-webflux - + + com.fasterxml.jackson.core + jackson-annotations + + + com.google.code.gson + gson + - - com.google.code.gson - gson - - - org.springframework.boot - spring-boot-test - test - - - org.springframework.ai - spring-ai-core - test - - - org.springframework.boot - spring-boot-starter-test - test - - - org.jetbrains - annotations - 24.0.1 - test - + - spring-ai-alibaba-plugin-googletranslate diff --git a/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateAutoConfiguration.java b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateAutoConfiguration.java index 2d6431c44..64e0ffeb8 100644 --- a/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateAutoConfiguration.java +++ b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateAutoConfiguration.java @@ -21,7 +21,7 @@ public class GoogleTranslateAutoConfiguration { @Bean @ConditionalOnMissingBean @Description("Implement natural language translation capabilities.") - public GoogleTranslateService GoogleTranslateFunction(GoogleTranslateProperties properties) { + public GoogleTranslateService googleTranslateFunction(GoogleTranslateProperties properties) { return new GoogleTranslateService(properties); } } diff --git a/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateService.java b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateService.java index 44e8185a7..a4904f30a 100644 --- a/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateService.java +++ b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateService.java @@ -19,6 +19,11 @@ import com.fasterxml.jackson.annotation.JsonClassDescription; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyDescription; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import org.slf4j.Logger; @@ -58,8 +63,8 @@ public GoogleTranslateService(GoogleTranslateProperties properties) { } @Override public Response apply(Request request) { - if ( request == null || !StringUtils.hasText(properties.getApiKey()) || - !StringUtils.hasText(request.text) || !StringUtils.hasText(request.targetLanguage) + if ( request == null || request.text == null || request.text.isEmpty() || + !StringUtils.hasText(properties.getApiKey()) || !StringUtils.hasText(request.targetLanguage) ) {return null;} String requestUrl = UriComponentsBuilder.fromHttpUrl(TRANSLATE_HOST + TRANSLATE_PATH) @@ -81,33 +86,38 @@ public Response apply(Request request) { return null; } - private Response parseResponseData(String responseData, String q) { - Gson gson = new Gson(); - Map response = gson.fromJson(responseData, - new TypeToken>() {}.getType()); - if (response.containsKey("error")) { - Map errorMap = (Map) response.get("error"); - log.error("GoogleTranslation service failed due to {}", errorMap.get("message").toString()); - return null; - } - - Map data = (Map) response.get("data"); - List> translationsList = (List>) data.get("translation"); - if ( translationsList == null || translationsList.isEmpty()) { - log.error("Invalid response format: 'translation' list is empty."); + private Response parseResponseData(String responseData, List query) { + ObjectMapper mapper = new ObjectMapper(); + Map translationResult = new HashMap<>(); + try { + JsonNode rootNode = mapper.readTree(responseData); + JsonNode data = rootNode.path("data"); + if (data == null || data.isNull()) { + translateFailed(rootNode); + return null; + } + JsonNode translations = data.path("translations"); + assert translations != null; + assert query.size() == translations.size(); + for (int i = 0; i < translations.size(); i++) { + translationResult.put(query.get(i), translations.get(i).asText()); + } + return new Response(translationResult); + } catch(Exception e) { + log.error("failed to convert the response to json object due to {}", e.getMessage()); return null; } + } - Map translationResult = new HashMap<>(); - for (Map translation : translationsList) { - translationResult.put(q, translation.get("translatedText")); - } - return new Response(translationResult); + private void translateFailed(JsonNode rootNode) { + String errorMessage = rootNode.path("error").path("message").asText(); + String code = rootNode.path("error").path("code").asText(); + log.info("Translate Text Failed. message:{} code:{}", errorMessage, code); } public record Request( @JsonProperty(required = true, - value = "text")@JsonPropertyDescription("Content that needs to be translated") String text, + value = "text")@JsonPropertyDescription("Content that needs to be translated") List text, @JsonProperty(required = true, value = "targetLanguage") @JsonPropertyDescription("the target language to translate into") String targetLanguage diff --git a/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/MainApplication.java b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/MainApplication.java deleted file mode 100644 index 0a607e82e..000000000 --- a/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/MainApplication.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.alibaba.cloud.ai.functioncalling.googletranslate; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class MainApplication { - public static void main(String[] args) { - SpringApplication.run(MainApplication.class, args); - } - -} diff --git a/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/test/java/GoogleTranslateTest.java b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/test/java/GoogleTranslateTest.java deleted file mode 100644 index edae12edb..000000000 --- a/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/test/java/GoogleTranslateTest.java +++ /dev/null @@ -1,41 +0,0 @@ -import com.alibaba.cloud.ai.functioncalling.googletranslate.GoogleTranslateService; -import com.sun.tools.javac.Main; -import org.jetbrains.annotations.NotNull; -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.ai.chat.client.ChatClient; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.ContextConfiguration; - -/** - * @author 北极星 - */ -@SpringBootTest -@ContextConfiguration(classes = Main.class) -public class GoogleTranslateTest { - - private static final Logger log = LoggerFactory.getLogger(GoogleTranslateTest.class); - - private final ChatClient chatClient; - - public GoogleTranslateTest(@NotNull ChatClient.Builder chatClientBuilder) { - this.chatClient = chatClientBuilder.build(); - } - - /** - * 微软翻译 - * - * @link - * 版本号 version 3.0 - * ApplicationYml spring.ai.alibaba.functioncalling.microsofttranslate 传入 api-key - */ - @Test - protected void GoogleTranslate () { - String text = "你好,spring-ai-alibaba!"; - - String ans = chatClient.prompt().functions("googleTranslateFunction").user(text).call().content(); - log.info("translated text -> : ${}", ans); - } -} \ No newline at end of file From 7f1ccf1029483077f92539a6851cb88fa379b890 Mon Sep 17 00:00:00 2001 From: erasernoob <1490910338@qq.com> Date: Sat, 28 Dec 2024 09:52:42 +0800 Subject: [PATCH 3/4] udpate: add the license header --- .../GoogleTranslateAutoConfiguration.java | 31 ++- .../GoogleTranslateProperties.java | 30 ++- .../GoogleTranslateService.java | 185 +++++++++--------- 3 files changed, 131 insertions(+), 115 deletions(-) diff --git a/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateAutoConfiguration.java b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateAutoConfiguration.java index 64e0ffeb8..464c8098d 100644 --- a/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateAutoConfiguration.java +++ b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateAutoConfiguration.java @@ -1,6 +1,20 @@ +/* + * Copyright 2024-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.alibaba.cloud.ai.functioncalling.googletranslate; - import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -15,13 +29,14 @@ @ConditionalOnClass({ GoogleTranslateService.class }) @EnableConfigurationProperties(GoogleTranslateProperties.class) @ConditionalOnProperty(prefix = "spring.ai.alibaba.functioncalling.googletranlate", name = "enabled", - havingValue = "true") + havingValue = "true") public class GoogleTranslateAutoConfiguration { - @Bean - @ConditionalOnMissingBean - @Description("Implement natural language translation capabilities.") - public GoogleTranslateService googleTranslateFunction(GoogleTranslateProperties properties) { - return new GoogleTranslateService(properties); - } + @Bean + @ConditionalOnMissingBean + @Description("Implement natural language translation capabilities.") + public GoogleTranslateService googleTranslateFunction(GoogleTranslateProperties properties) { + return new GoogleTranslateService(properties); + } + } diff --git a/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateProperties.java b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateProperties.java index 19f2e9753..32f48b9fc 100644 --- a/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateProperties.java +++ b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateProperties.java @@ -1,12 +1,11 @@ /* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at + * Copyright 2024-2025 the original author or authors. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,10 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.alibaba.cloud.ai.functioncalling.googletranslate; - import org.springframework.boot.context.properties.ConfigurationProperties; /** @@ -26,13 +23,14 @@ @ConfigurationProperties(prefix = "spring.ai.alibaba.plugin.googletranslate") public class GoogleTranslateProperties { - private String apiKey; + private String apiKey; + + public String getApiKey() { + return apiKey; + } - public String getApiKey() { - return apiKey; - } + public void setApiKey(String apiKey) { + this.apiKey = apiKey; + } - public void setApiKey(String apiKey) { - this.apiKey = apiKey; - } } diff --git a/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateService.java b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateService.java index a4904f30a..d8663d19a 100644 --- a/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateService.java +++ b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/src/main/java/com/alibaba/cloud/ai/functioncalling/googletranslate/GoogleTranslateService.java @@ -1,12 +1,11 @@ /* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at + * Copyright 2024-2025 the original author or authors. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.alibaba.cloud.ai.functioncalling.googletranslate; + import com.fasterxml.jackson.annotation.JsonClassDescription; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyDescription; @@ -42,87 +41,91 @@ /** * @author erasernoob */ -public class GoogleTranslateService implements Function { - - private static final Logger log = LoggerFactory.getLogger(GoogleTranslateService.class); - - private static final String TRANSLATE_HOST = "https://translation.googleapis.com"; - - private static final String TRANSLATE_PATH = "/language/translate/v2"; - - private final GoogleTranslateProperties properties; - - private final WebClient webClient; - - public GoogleTranslateService(GoogleTranslateProperties properties) { - assert StringUtils.hasText(properties.getApiKey()); - this.properties = properties; - this.webClient = WebClient.builder() - .defaultHeader("Content-Type", "application/json") - .build(); - } - @Override - public Response apply(Request request) { - if ( request == null || request.text == null || request.text.isEmpty() || - !StringUtils.hasText(properties.getApiKey()) || !StringUtils.hasText(request.targetLanguage) - ) {return null;} - - String requestUrl = UriComponentsBuilder.fromHttpUrl(TRANSLATE_HOST + TRANSLATE_PATH) - .queryParam("key", properties.getApiKey()) - .queryParam("target", request.targetLanguage) - .queryParam("q", request.text) - .queryParam("format", "text") - .toUriString(); - try { - Mono responseMono = webClient.post().uri(requestUrl).retrieve().bodyToMono(String.class); - - String responseData = responseMono.block(); - assert responseData != null; - log.info("GoogleTranslation request: {}, response: {}", request.text, responseData); - return parseResponseData(responseData, request.text); - } catch (Exception e) { - log.error("Using the googleTranslate service failed due to {}", e.getMessage()); - } - return null; - } - - private Response parseResponseData(String responseData, List query) { - ObjectMapper mapper = new ObjectMapper(); - Map translationResult = new HashMap<>(); - try { - JsonNode rootNode = mapper.readTree(responseData); - JsonNode data = rootNode.path("data"); - if (data == null || data.isNull()) { - translateFailed(rootNode); - return null; - } - JsonNode translations = data.path("translations"); - assert translations != null; - assert query.size() == translations.size(); - for (int i = 0; i < translations.size(); i++) { - translationResult.put(query.get(i), translations.get(i).asText()); - } - return new Response(translationResult); - } catch(Exception e) { - log.error("failed to convert the response to json object due to {}", e.getMessage()); - return null; - } - } - - private void translateFailed(JsonNode rootNode) { - String errorMessage = rootNode.path("error").path("message").asText(); - String code = rootNode.path("error").path("code").asText(); - log.info("Translate Text Failed. message:{} code:{}", errorMessage, code); - } - - public record Request( - @JsonProperty(required = true, - value = "text")@JsonPropertyDescription("Content that needs to be translated") List text, - @JsonProperty(required = true, value = "targetLanguage") - @JsonPropertyDescription("the target language to translate into") - String targetLanguage - ) {} - - @JsonClassDescription("Response to translate text to the target language") - public record Response(Map translatedTexts) {} +public class GoogleTranslateService + implements Function { + + private static final Logger log = LoggerFactory.getLogger(GoogleTranslateService.class); + + private static final String TRANSLATE_HOST = "https://translation.googleapis.com"; + + private static final String TRANSLATE_PATH = "/language/translate/v2"; + + private final GoogleTranslateProperties properties; + + private final WebClient webClient; + + public GoogleTranslateService(GoogleTranslateProperties properties) { + assert StringUtils.hasText(properties.getApiKey()); + this.properties = properties; + this.webClient = WebClient.builder().defaultHeader("Content-Type", "application/json").build(); + } + + @Override + public Response apply(Request request) { + if (request == null || request.text == null || request.text.isEmpty() + || !StringUtils.hasText(properties.getApiKey()) || !StringUtils.hasText(request.targetLanguage)) { + return null; + } + + String requestUrl = UriComponentsBuilder.fromHttpUrl(TRANSLATE_HOST + TRANSLATE_PATH) + .queryParam("key", properties.getApiKey()) + .queryParam("target", request.targetLanguage) + .queryParam("q", request.text) + .queryParam("format", "text") + .toUriString(); + try { + Mono responseMono = webClient.post().uri(requestUrl).retrieve().bodyToMono(String.class); + + String responseData = responseMono.block(); + assert responseData != null; + log.info("GoogleTranslation request: {}, response: {}", request.text, responseData); + return parseResponseData(responseData, request.text); + } + catch (Exception e) { + log.error("Using the googleTranslate service failed due to {}", e.getMessage()); + } + return null; + } + + private Response parseResponseData(String responseData, List query) { + ObjectMapper mapper = new ObjectMapper(); + Map translationResult = new HashMap<>(); + try { + JsonNode rootNode = mapper.readTree(responseData); + JsonNode data = rootNode.path("data"); + if (data == null || data.isNull()) { + translateFailed(rootNode); + return null; + } + JsonNode translations = data.path("translations"); + assert translations != null; + assert query.size() == translations.size(); + for (int i = 0; i < translations.size(); i++) { + translationResult.put(query.get(i), translations.get(i).asText()); + } + return new Response(translationResult); + } + catch (Exception e) { + log.error("failed to convert the response to json object due to {}", e.getMessage()); + return null; + } + } + + private void translateFailed(JsonNode rootNode) { + String errorMessage = rootNode.path("error").path("message").asText(); + String code = rootNode.path("error").path("code").asText(); + log.info("Translate Text Failed. message:{} code:{}", errorMessage, code); + } + + public record Request( + @JsonProperty(required = true, + value = "text") @JsonPropertyDescription("Content that needs to be translated") List text, + @JsonProperty(required = true, + value = "targetLanguage") @JsonPropertyDescription("the target language to translate into") String targetLanguage) { + } + + @JsonClassDescription("Response to translate text to the target language") + public record Response(Map translatedTexts) { + } + } From 095deecc4f7ac93a756c6c304b8c142925ff4d03 Mon Sep 17 00:00:00 2001 From: erasernoob <1490910338@qq.com> Date: Sat, 28 Dec 2024 16:30:01 +0800 Subject: [PATCH 4/4] styles: fix all the format mistakes --- .../pom.xml | 14 ++------------ .../GoogleTranslateAutoConfiguration.java | 2 +- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/pom.xml b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/pom.xml index 2016fb02b..80676b371 100644 --- a/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/pom.xml +++ b/community/function-calling/spring-ai-alibaba-starter-function-calling-googletranslate/pom.xml @@ -1,7 +1,7 @@