diff --git a/src/main/java/com/broadcom/tanzu/demos/springai101/weather/WeatherFunctions.java b/src/main/java/com/broadcom/tanzu/demos/springai101/weather/WeatherFunctions.java new file mode 100644 index 0000000..1165f4c --- /dev/null +++ b/src/main/java/com/broadcom/tanzu/demos/springai101/weather/WeatherFunctions.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2024 Broadcom, Inc. or its affiliates + * + * 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 + * + * 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.broadcom.tanzu.demos.springai101.weather; + +class WeatherFunctions { + public static final String GET_WEATHER_BY_CITY = "getWeatherByCity"; + public static final String GET_WEATHER_BY_CITIES = "getWeatherByCities"; + + private WeatherFunctions() { + } +} diff --git a/src/main/java/com/broadcom/tanzu/demos/springai101/function/WeatherV1Controller.java b/src/main/java/com/broadcom/tanzu/demos/springai101/weather/WeatherV1Controller.java similarity index 92% rename from src/main/java/com/broadcom/tanzu/demos/springai101/function/WeatherV1Controller.java rename to src/main/java/com/broadcom/tanzu/demos/springai101/weather/WeatherV1Controller.java index ac0a89a..2138bc3 100644 --- a/src/main/java/com/broadcom/tanzu/demos/springai101/function/WeatherV1Controller.java +++ b/src/main/java/com/broadcom/tanzu/demos/springai101/weather/WeatherV1Controller.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.broadcom.tanzu.demos.springai101.function; +package com.broadcom.tanzu.demos.springai101.weather; import org.springframework.ai.chat.client.ChatClient; import org.springframework.http.MediaType; @@ -35,7 +35,7 @@ String weather(@RequestParam("city") String city) { // Rely on a function to get additional (live) data. return chatClient.prompt() .user(p -> p.text("What is the current temperature in {city}?").param("city", city)) - .functions(Functions.GET_WEATHER_BY_CITY) + .functions(WeatherFunctions.GET_WEATHER_BY_CITY) .call() .content(); } diff --git a/src/main/java/com/broadcom/tanzu/demos/springai101/function/WeatherV2Controller.java b/src/main/java/com/broadcom/tanzu/demos/springai101/weather/WeatherV2Controller.java similarity index 93% rename from src/main/java/com/broadcom/tanzu/demos/springai101/function/WeatherV2Controller.java rename to src/main/java/com/broadcom/tanzu/demos/springai101/weather/WeatherV2Controller.java index 43516d8..117f7b9 100644 --- a/src/main/java/com/broadcom/tanzu/demos/springai101/function/WeatherV2Controller.java +++ b/src/main/java/com/broadcom/tanzu/demos/springai101/weather/WeatherV2Controller.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.broadcom.tanzu.demos.springai101.function; +package com.broadcom.tanzu.demos.springai101.weather; import org.springframework.ai.chat.client.ChatClient; import org.springframework.http.MediaType; @@ -36,7 +36,7 @@ TemperatureResponse weather(@RequestParam("city") String city) { // This allows you to use AI generated responses without having to manually parse the content. return chatClient.prompt() .user(p -> p.text("What is the current temperature in {city}?").param("city", city)) - .functions(Functions.GET_WEATHER_BY_CITY) + .functions(WeatherFunctions.GET_WEATHER_BY_CITY) .call() .entity(TemperatureResponse.class); } diff --git a/src/main/java/com/broadcom/tanzu/demos/springai101/function/WeatherV3Controller.java b/src/main/java/com/broadcom/tanzu/demos/springai101/weather/WeatherV3Controller.java similarity index 83% rename from src/main/java/com/broadcom/tanzu/demos/springai101/function/WeatherV3Controller.java rename to src/main/java/com/broadcom/tanzu/demos/springai101/weather/WeatherV3Controller.java index 600b392..a8943c4 100644 --- a/src/main/java/com/broadcom/tanzu/demos/springai101/function/WeatherV3Controller.java +++ b/src/main/java/com/broadcom/tanzu/demos/springai101/weather/WeatherV3Controller.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.broadcom.tanzu.demos.springai101.function; +package com.broadcom.tanzu.demos.springai101.weather; import org.springframework.ai.chat.client.ChatClient; import org.springframework.http.MediaType; @@ -33,10 +33,10 @@ class WeatherV3Controller { @GetMapping(value = "/weather/v3", produces = MediaType.TEXT_PLAIN_VALUE) String weather(@RequestParam("q") String query) { // Use this endpoint to query your LLM with any requests. - // Whenever you ask for weather information for one or more cities, the functions will be automatically called. + // Whenever you ask for weather information from one or more cities, functions are automatically called as needed. return chatClient.prompt() .user(query) - .functions(Functions.GET_WEATHER_BY_CITY, Functions.GET_WEATHER_BY_CITIES) + .functions(WeatherFunctions.GET_WEATHER_BY_CITY, WeatherFunctions.GET_WEATHER_BY_CITIES) .call() .content(); } diff --git a/src/main/java/com/broadcom/tanzu/demos/springai101/function/WeatherV4Controller.java b/src/main/java/com/broadcom/tanzu/demos/springai101/weather/WeatherV4Controller.java similarity index 94% rename from src/main/java/com/broadcom/tanzu/demos/springai101/function/WeatherV4Controller.java rename to src/main/java/com/broadcom/tanzu/demos/springai101/weather/WeatherV4Controller.java index df0b4a6..e8d3dc1 100644 --- a/src/main/java/com/broadcom/tanzu/demos/springai101/function/WeatherV4Controller.java +++ b/src/main/java/com/broadcom/tanzu/demos/springai101/weather/WeatherV4Controller.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.broadcom.tanzu.demos.springai101.function; +package com.broadcom.tanzu.demos.springai101.weather; import org.springframework.ai.chat.client.ChatClient; import org.springframework.http.MediaType; @@ -45,7 +45,7 @@ TemperatureResponse weather(@RequestParam("u") URL url) { Then, get the current weather for this city. """) .media(MimeTypeUtils.IMAGE_JPEG, url)) - .functions(Functions.GET_WEATHER_BY_CITY) + .functions(WeatherFunctions.GET_WEATHER_BY_CITY) .call() .entity(TemperatureResponse.class); } diff --git a/src/main/java/com/broadcom/tanzu/demos/springai101/weather/Weather.java b/src/main/java/com/broadcom/tanzu/demos/springai101/weather/impl/Weather.java similarity index 91% rename from src/main/java/com/broadcom/tanzu/demos/springai101/weather/Weather.java rename to src/main/java/com/broadcom/tanzu/demos/springai101/weather/impl/Weather.java index 1832b8f..7cb6184 100644 --- a/src/main/java/com/broadcom/tanzu/demos/springai101/weather/Weather.java +++ b/src/main/java/com/broadcom/tanzu/demos/springai101/weather/impl/Weather.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.broadcom.tanzu.demos.springai101.weather; +package com.broadcom.tanzu.demos.springai101.weather.impl; /** * Hold weather information for a city. @@ -22,7 +22,7 @@ * @param city city name * @param temperature temperature in Celsius */ -public record Weather( +record Weather( String city, float temperature ) { diff --git a/src/main/java/com/broadcom/tanzu/demos/springai101/weather/WeatherApi.java b/src/main/java/com/broadcom/tanzu/demos/springai101/weather/impl/WeatherApi.java similarity index 96% rename from src/main/java/com/broadcom/tanzu/demos/springai101/weather/WeatherApi.java rename to src/main/java/com/broadcom/tanzu/demos/springai101/weather/impl/WeatherApi.java index f4dad6e..5c14416 100644 --- a/src/main/java/com/broadcom/tanzu/demos/springai101/weather/WeatherApi.java +++ b/src/main/java/com/broadcom/tanzu/demos/springai101/weather/impl/WeatherApi.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.broadcom.tanzu.demos.springai101.weather; +package com.broadcom.tanzu.demos.springai101.weather.impl; import com.fasterxml.jackson.annotation.JsonProperty; import org.springframework.http.MediaType; diff --git a/src/main/java/com/broadcom/tanzu/demos/springai101/weather/WeatherApiConfig.java b/src/main/java/com/broadcom/tanzu/demos/springai101/weather/impl/WeatherApiConfig.java similarity index 97% rename from src/main/java/com/broadcom/tanzu/demos/springai101/weather/WeatherApiConfig.java rename to src/main/java/com/broadcom/tanzu/demos/springai101/weather/impl/WeatherApiConfig.java index 4862576..e06095c 100644 --- a/src/main/java/com/broadcom/tanzu/demos/springai101/weather/WeatherApiConfig.java +++ b/src/main/java/com/broadcom/tanzu/demos/springai101/weather/impl/WeatherApiConfig.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.broadcom.tanzu.demos.springai101.weather; +package com.broadcom.tanzu.demos.springai101.weather.impl; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; diff --git a/src/main/java/com/broadcom/tanzu/demos/springai101/function/Functions.java b/src/main/java/com/broadcom/tanzu/demos/springai101/weather/impl/WeatherFunctionsConfig.java similarity index 82% rename from src/main/java/com/broadcom/tanzu/demos/springai101/function/Functions.java rename to src/main/java/com/broadcom/tanzu/demos/springai101/weather/impl/WeatherFunctionsConfig.java index bb38e14..b621cfb 100644 --- a/src/main/java/com/broadcom/tanzu/demos/springai101/function/Functions.java +++ b/src/main/java/com/broadcom/tanzu/demos/springai101/weather/impl/WeatherFunctionsConfig.java @@ -14,10 +14,8 @@ * limitations under the License. */ -package com.broadcom.tanzu.demos.springai101.function; +package com.broadcom.tanzu.demos.springai101.weather.impl; -import com.broadcom.tanzu.demos.springai101.weather.Weather; -import com.broadcom.tanzu.demos.springai101.weather.WeatherService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; @@ -32,21 +30,18 @@ import java.util.stream.Collectors; @Configuration(proxyBeanMethods = false) -class Functions { - public static final String GET_WEATHER_BY_CITY = "getWeatherByCity"; - public static final String GET_WEATHER_BY_CITIES = "getWeatherByCities"; - - private final Logger logger = LoggerFactory.getLogger(Functions.class); +class WeatherFunctionsConfig { + private final Logger logger = LoggerFactory.getLogger(WeatherFunctionsConfig.class); @Bean @Description(""" Get the current weather in a given city, including temperature (in Celsius). - Call this function if you need to get the weather for a single city. + Call this function if you need to get the weather in a single city. """) Function getWeatherByCity(WeatherService weatherService) { // Map a Spring AI function (including description which will be used by the LLM) to your business function. return req -> { - logger.info("Loading weather in {} using OpenWeatherMap", req.city()); + logger.info("Loading weather from {} using OpenWeatherMap", req.city()); return weatherService.getWeatherByCity(req.city()); }; } @@ -55,7 +50,7 @@ Function getWeatherByCity(WeatherService weatherService) @Description(""" Get the current weather in different cities, all at once. The result is a map of weather details (including temperature in Celsius) by city. - Call this function to optimize calls when you need to get the weather for different cities. + Call this function to optimize calls when you need to get the weather in different cities. """) Function> getWeatherByCities(WeatherService weatherService, AsyncTaskExecutor taskExecutor) { return req -> { @@ -67,7 +62,7 @@ Function> getWeatherByCities(WeatherServic final var tasks = new ArrayList>(req.cities().length); for (final var city : req.cities()) { final var task = taskExecutor.submitCompletable(() -> { - logger.debug("Asynchronously loading weather in {} using OpenWeatherMap", city); + logger.debug("Asynchronously loading weather from {} using OpenWeatherMap", city); return weatherService.getWeatherByCity(city); }); tasks.add(task); diff --git a/src/main/java/com/broadcom/tanzu/demos/springai101/weather/WeatherService.java b/src/main/java/com/broadcom/tanzu/demos/springai101/weather/impl/WeatherService.java similarity index 94% rename from src/main/java/com/broadcom/tanzu/demos/springai101/weather/WeatherService.java rename to src/main/java/com/broadcom/tanzu/demos/springai101/weather/impl/WeatherService.java index 4fd8ce9..5f0a747 100644 --- a/src/main/java/com/broadcom/tanzu/demos/springai101/weather/WeatherService.java +++ b/src/main/java/com/broadcom/tanzu/demos/springai101/weather/impl/WeatherService.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.broadcom.tanzu.demos.springai101.weather; +package com.broadcom.tanzu.demos.springai101.weather.impl; import io.micrometer.observation.Observation; import io.micrometer.observation.ObservationRegistry; import org.springframework.stereotype.Service; @Service -public class WeatherService { +class WeatherService { private final WeatherApi api; private final ObservationRegistry observationRegistry;