From 74160e737bdd71d8ea1e4512635ad52136d8f8fc Mon Sep 17 00:00:00 2001 From: croway Date: Fri, 7 Aug 2026 09:40:49 +0200 Subject: [PATCH 1/2] CAMEL-23382: migrate ai-agent example from spring-ai-tools to ai-tool --- ai-agent/README.adoc | 4 ++-- ai-agent/pom.xml | 4 ++-- ai-agent/src/main/java/sample/camel/ToolRoute.java | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ai-agent/README.adoc b/ai-agent/README.adoc index d0e3b08ca..564f9e6bf 100644 --- a/ai-agent/README.adoc +++ b/ai-agent/README.adoc @@ -58,7 +58,7 @@ Qdrant will be available on `http://localhost:6333`. * `camel-spring-ai-chat-starter` - Camel Spring AI chat integration * `camel-spring-ai-vector-store-starter` - Camel Spring AI vector store integration -* `camel-spring-ai-tools-starter` - Camel Spring AI tools/function calling +* `camel-ai-tool-starter` - Camel AI tools/function calling * `spring-ai-starter-model-ollama` - Spring AI Ollama model support * `spring-ai-starter-vector-store-qdrant` - Qdrant vector store integration @@ -70,7 +70,7 @@ NOTE: The routes use timer delays to ensure proper startup sequence. The chat ro Demonstrates basic chat functionality. Sends questions to the AI model and logs the responses. Executes immediately on startup. ==== ToolRoute -Shows how to define tools (functions) that the AI can call. The example includes a weather tool that the AI can invoke when asked about weather information. The tool is defined using the `spring-ai-tools` component with parameters. The tool chat route executes after a 20 second delay to ensure all services are ready. +Shows how to define tools (functions) that the AI can call. The example includes a weather tool that the AI can invoke when asked about weather information. The tool is defined using the `ai-tool` component with parameters. The tool chat route executes after a 20 second delay to ensure all services are ready. ==== VectorStoreRoute Demonstrates semantic search using vector embeddings with Qdrant: diff --git a/ai-agent/pom.xml b/ai-agent/pom.xml index dfb53c5e5..117055faf 100644 --- a/ai-agent/pom.xml +++ b/ai-agent/pom.xml @@ -36,7 +36,7 @@ UTF-8 UTF-8 - 2.0.0-M2 + 2.0.0 @@ -91,7 +91,7 @@ org.apache.camel.springboot - camel-spring-ai-tools-starter + camel-ai-tool-starter org.apache.camel.springboot diff --git a/ai-agent/src/main/java/sample/camel/ToolRoute.java b/ai-agent/src/main/java/sample/camel/ToolRoute.java index 0b981f2a7..cffe803b1 100644 --- a/ai-agent/src/main/java/sample/camel/ToolRoute.java +++ b/ai-agent/src/main/java/sample/camel/ToolRoute.java @@ -20,7 +20,7 @@ import org.springframework.stereotype.Component; /** - * Route that demonstrates Spring AI tool/function calling capabilities. + * Route that demonstrates AI tool/function calling capabilities. * The AI can invoke the weather tool to get current weather information. */ @Component @@ -29,7 +29,7 @@ public class ToolRoute extends RouteBuilder { @Override public void configure() throws Exception { // Define the weather tool that can be called by the AI - from("spring-ai-tools:weatherTool?tags=weather&description=Get the current weather for a location" + from("ai-tool:weatherTool?tags=weather&description=Get the current weather for a location" + "¶meter.location=string" + "¶meter.location.description=The city, e.g. Rome" + "¶meter.location.required=true") @@ -53,7 +53,7 @@ public void configure() throws Exception { from("direct:fetchWeather") .routeId("fetchWeatherRoute") .toD("https://api.open-meteo.com/v1/forecast?latitude=${header.latitude}&longitude=${header.longitude}¤t=temperature_2m,weather_code,precipitation,wind_speed_10m,wind_direction_10m,relative_humidity_2m,cloud_cover&temperature_unit=celsius&wind_speed_unit=kmh") - .setBody(simple("The weather in ${header.location} is ${jq(.current.temperature_2m)} degrees Celsius with ${jq(.current.relative_humidity_2m)}% humidity, ${jq(.current.cloud_cover)}% cloud cover, wind speed ${jq(.current.wind_speed_10m)} km/h from ${jq(.current.wind_direction_10m)} degrees, and ${jq(.current.precipitation)} mm precipitation.")); + .setBody(simple("The weather in ${header.savedLocation} is ${jq(.current.temperature_2m)} degrees Celsius with ${jq(.current.relative_humidity_2m)}% humidity, ${jq(.current.cloud_cover)}% cloud cover, wind speed ${jq(.current.wind_speed_10m)} km/h from ${jq(.current.wind_direction_10m)} degrees, and ${jq(.current.precipitation)} mm precipitation.")); // Route that uses AI with function calling from("timer:toolChat?repeatCount=1&delay=20000") From 24ec35604485e68b0520e7d6c217eca5f705522e Mon Sep 17 00:00:00 2001 From: croway Date: Fri, 7 Aug 2026 09:46:49 +0200 Subject: [PATCH 2/2] CAMEL-23382: rename weather tool parameter to city to avoid HTTP Location header collision --- ai-agent/README.adoc | 2 +- .../src/main/java/sample/camel/ToolRoute.java | 20 +++++++++---------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/ai-agent/README.adoc b/ai-agent/README.adoc index 564f9e6bf..2827e0adc 100644 --- a/ai-agent/README.adoc +++ b/ai-agent/README.adoc @@ -128,7 +128,7 @@ The example will continue running and watching the `input` directory for new doc 2025-11-25T17:51:41.445+01:00 INFO 54308 --- [imer://toolChat] toolChatRoute : Sending question with tool capability to AI: What is the weather like in Rome, Italy? Answer with English slang -2025-11-25T17:51:43.520+01:00 INFO 54308 --- [imer://toolChat] weatherTool : Weather tool called for location: Rome +2025-11-25T17:51:43.520+01:00 INFO 54308 --- [imer://toolChat] weatherTool : Weather tool called for city: Rome 2025-11-25T17:51:43.739+01:00 INFO 54308 --- [imer://toolChat] weatherTool : Geocoding result - Latitude: 41.89193, Longitude: 12.51133 2025-11-25T17:51:43.858+01:00 INFO 54308 --- [imer://toolChat] weatherTool : Weather tool response: The weather in is 12.4 degrees Celsius with 87% humidity, 100% cloud cover, wind speed 2.9 km/h from 7 degrees, and 0.2 mm precipitation. 2025-11-25T17:51:47.786+01:00 INFO 54308 --- [imer://toolChat] toolChatRoute : AI Response with tool usage: So, Rome's got it pretty mild out there right now – about **12.4°C**, feels like a cool breeze with that high humidity hanging around at **87%**. No rain in sight (just **0.2mm**), and the sky’s practically overcast (**100% cloud cover**) thanks to those gentle winds from the north‑west at **7°** – perfect for grabbing an espresso outside while you ponder life, love, or just how many more layers you need before it gets chilly again! diff --git a/ai-agent/src/main/java/sample/camel/ToolRoute.java b/ai-agent/src/main/java/sample/camel/ToolRoute.java index cffe803b1..1e1b43041 100644 --- a/ai-agent/src/main/java/sample/camel/ToolRoute.java +++ b/ai-agent/src/main/java/sample/camel/ToolRoute.java @@ -29,31 +29,29 @@ public class ToolRoute extends RouteBuilder { @Override public void configure() throws Exception { // Define the weather tool that can be called by the AI - from("ai-tool:weatherTool?tags=weather&description=Get the current weather for a location" - + "¶meter.location=string" - + "¶meter.location.description=The city, e.g. Rome" - + "¶meter.location.required=true") + from("ai-tool:weatherTool?tags=weather&description=Get the current weather for a city" + + "¶meter.city=string" + + "¶meter.city.description=The city, e.g. Rome" + + "¶meter.city.required=true") .routeId("weatherTool") - .log("Weather tool called for location: ${header.location}") + .log("Weather tool called for city: ${header.city}") .to("direct:geocode") .log("Geocoding result - Latitude: ${header.latitude}, Longitude: ${header.longitude}") .to("direct:fetchWeather") .log("Weather tool response: ${body}"); - // Geocoding route - convert location name to coordinates + // Geocoding route - convert city name to coordinates from("direct:geocode") .routeId("geocodeRoute") - .setHeader("savedLocation", simple("${header.location}")) - .toD("https://geocoding-api.open-meteo.com/v1/search?name=${header.location}&count=1&language=en&format=json") + .toD("https://geocoding-api.open-meteo.com/v1/search?name=${header.city}&count=1&language=en&format=json") .setHeader("latitude", jq(".results[0].latitude")) - .setHeader("longitude", jq(".results[0].longitude")) - .setHeader("location", simple("${header.savedLocation}")); + .setHeader("longitude", jq(".results[0].longitude")); // Weather fetching route - get current weather for coordinates from("direct:fetchWeather") .routeId("fetchWeatherRoute") .toD("https://api.open-meteo.com/v1/forecast?latitude=${header.latitude}&longitude=${header.longitude}¤t=temperature_2m,weather_code,precipitation,wind_speed_10m,wind_direction_10m,relative_humidity_2m,cloud_cover&temperature_unit=celsius&wind_speed_unit=kmh") - .setBody(simple("The weather in ${header.savedLocation} is ${jq(.current.temperature_2m)} degrees Celsius with ${jq(.current.relative_humidity_2m)}% humidity, ${jq(.current.cloud_cover)}% cloud cover, wind speed ${jq(.current.wind_speed_10m)} km/h from ${jq(.current.wind_direction_10m)} degrees, and ${jq(.current.precipitation)} mm precipitation.")); + .setBody(simple("The weather in ${header.city} is ${jq(.current.temperature_2m)} degrees Celsius with ${jq(.current.relative_humidity_2m)}% humidity, ${jq(.current.cloud_cover)}% cloud cover, wind speed ${jq(.current.wind_speed_10m)} km/h from ${jq(.current.wind_direction_10m)} degrees, and ${jq(.current.precipitation)} mm precipitation.")); // Route that uses AI with function calling from("timer:toolChat?repeatCount=1&delay=20000")