This is an automated email from the ASF dual-hosted git repository.
fmariani pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-spring-boot-examples.git
The following commit(s) were added to refs/heads/main by this push:
new 95f6ff9 Camel Spring AI Example
95f6ff9 is described below
commit 95f6ff958e91a1b4a22ef43b7ca1e6fbf0bdc831
Author: Croway <[email protected]>
AuthorDate: Tue Nov 25 18:38:24 2025 +0100
Camel Spring AI Example
---
README.adoc | 4 +-
ai-agent/README.adoc | 174 +++++++++++++++++++++
ai-agent/input/camel-intro.txt | 1 +
ai-agent/input/spring-ai-intro.txt | 1 +
ai-agent/pom.xml | 172 ++++++++++++++++++++
.../src/main/java/sample/camel/Application.java | 36 +++++
ai-agent/src/main/java/sample/camel/ChatRoute.java | 37 +++++
ai-agent/src/main/java/sample/camel/ToolRoute.java | 66 ++++++++
.../main/java/sample/camel/VectorStoreRoute.java | 50 ++++++
ai-agent/src/main/resources/application-prod.yaml | 46 ++++++
ai-agent/src/main/resources/application.yaml | 34 ++++
pom.xml | 1 +
12 files changed, 621 insertions(+), 1 deletion(-)
diff --git a/README.adoc b/README.adoc
index 089d030..ce0de15 100644
--- a/README.adoc
+++ b/README.adoc
@@ -27,12 +27,14 @@ readme's instructions.
=== Examples
// examples: START
-Number of Examples: 67 (0 deprecated)
+Number of Examples: 68 (0 deprecated)
[width="100%",cols="4,2,4",options="header"]
|===
| Example | Category | Description
+| link:ai-agent/README.adoc[Ai Agent] (ai-agent) | AI | An example showing how
to work with Camel Spring AI for chat, tools, and vector store
+
| link:aot-basic/readme.adoc[Aot Basic] (aot-basic) | AOT | Example on how to
leverage Spring Boot AOT in Camel Spring Boot
| link:endpointdsl/readme.adoc[Endpointdsl] (endpointdsl) | Beginner | Using
type-safe Endpoint DSL
diff --git a/ai-agent/README.adoc b/ai-agent/README.adoc
new file mode 100644
index 0000000..b333c87
--- /dev/null
+++ b/ai-agent/README.adoc
@@ -0,0 +1,174 @@
+== Spring Boot Example with Spring AI Agent
+
+=== Introduction
+
+This example demonstrates how to use Apache Camel with Spring AI to build
AI-powered integration applications. The example showcases three key
capabilities:
+
+1. *Chat* - Basic conversational AI using the Spring AI Chat component
+2. *Tools* - Function calling where the AI can invoke Camel routes as tools
+3. *Vector Store* - Semantic search using document embeddings with Qdrant
+
+The example uses Ollama as the AI model provider with the granite4:3b model
for chat and embeddinggemma:300m for embeddings, and Qdrant as the vector
database.
+
+==== Design Principles
+
+This example follows Apache Camel Spring AI's design philosophy of separating
concerns:
+
+* *Business Logic in Camel Routes* - The route definitions focus purely on
integration logic and data flow
+* *Infrastructure Configuration in application.yaml* - All non-functional
requirements such as AI model selection, connection parameters, temperature
settings, and external service endpoints are externalized to configuration files
+
+This separation enables:
+
+* Easy switching between different AI providers (e.g., Ollama, OpenAI, Azure)
without changing route code
+* Environment-specific configurations (dev, staging, production) with
different models or endpoints
+* Clear distinction between what the integration does (routes) and how it
connects (configuration)
+
+=== Prerequisites
+
+==== Camel JBang
+Install Camel JBang to easily run infrastructure services:
+
+ $ curl -Ls https://sh.jbang.dev | bash -s - trust add
https://github.com/apache/camel/
+ $ curl -Ls https://sh.jbang.dev | bash -s - app install --fresh --force
camel@apache/camel
+
+Or if you already have JBang installed:
+
+ $ jbang app install camel@apache/camel
+
+==== Ollama
+You need to have Ollama installed and running locally. Install Ollama from
https://ollama.ai and then pull the required models:
+
+ $ ollama pull granite4:3b
+ $ ollama pull embeddinggemma:300m
+
+The granite4:3b model is used for chat and the embeddinggemma:300m model is
used for embeddings.
+
+Make sure Ollama is running on `http://localhost:11434` (default port) or
update the `application.yaml` accordingly.
+
+NOTE: While you can use `camel infra run ollama` to run Ollama via Docker, be
aware of performance limitations. On macOS, the Docker image cannot utilize GPU
acceleration, making it extremely slow. Additionally, when running the Camel
Ollama test-infra, both the Ollama Docker image and the default model
(granite4, ~3GB) need to be downloaded on first run, which can be very
time-consuming. For better performance, it's recommended to install Ollama
natively.
+
+==== Qdrant
+Use Camel JBang to run Qdrant:
+
+ $ camel infra run qdrant
+
+Qdrant will be available on `http://localhost:6333`.
+
+=== Components Used
+
+* `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
+* `spring-ai-starter-model-ollama` - Spring AI Ollama model support
+* `spring-ai-starter-vector-store-qdrant` - Qdrant vector store integration
+
+=== Routes Overview
+
+NOTE: The routes use timer delays to ensure proper startup sequence. The chat
route executes immediately on startup, the vector store query executes after a
10 second delay, and the tool chat route executes after a 20 second delay.
+
+==== ChatRoute
+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.
+
+==== VectorStoreRoute
+Demonstrates semantic search using vector embeddings with Qdrant:
+
+* Watches the `input` directory for `.txt` files and adds them to the Qdrant
vector store
+* Performs a sample similarity search query after a 10 second delay
+* Documents are automatically embedded and stored in Qdrant
+* Returns the top 3 most similar documents with a similarity threshold of 0.5
+
+=== Build
+
+You can build this example using:
+
+ $ mvn package
+
+=== Run
+
+You can run this example using:
+
+ $ mvn spring-boot:run
+
+=== Usage
+
+1. The chat route will automatically execute and ask questions about Apache
Camel
+2. The tool route will demonstrate AI function calling with the weather tool
(executes after 20 seconds)
+3. The vector store route will:
+ * Add sample documents from the `input` folder to the Qdrant vector store
on startup
+ * Execute a sample similarity search query after 10 seconds
+ * You can add more `.txt` files to the `input` folder to expand the
knowledge base
+
+=== Expected Output
+
+You should see in the console:
+
+* AI responses to the chat questions
+* Weather tool being called when the AI needs weather information
+* Vector store adding documents to Qdrant and performing a similarity search
+* The most relevant documents with similarity scores for the query
+
+The example will continue running and watching the `input` directory for new
documents. Press Ctrl+C to stop.
+
+[source]
+----
+2025-11-25T17:24:21.770+01:00 INFO 51706 --- [ - timer://chat] chatRoute
: Sending question to AI: What is Apache Camel?
+2025-11-25T17:24:29.858+01:00 INFO 51706 --- [ - timer://chat] chatRoute
: AI Response: Apache Camel is an open-source
integration framework based on known Java connectivity standards...
+
+
+2025-11-25T17:24:21.771+01:00 INFO 51706 --- [ - file://input] addDocuments
: Adding document camel-intro.txt to vector store
+2025-11-25T17:24:22.048+01:00 INFO 51706 --- [ - file://input] addDocuments
: Successfully added camel-intro.txt to vector store
+2025-11-25T17:24:22.048+01:00 INFO 51706 --- [ - file://input] addDocuments
: Adding document spring-ai-intro.txt to vector store
+2025-11-25T17:24:22.183+01:00 INFO 51706 --- [ - file://input] addDocuments
: Successfully added spring-ai-intro.txt to vector
store
+2025-11-25T17:34:08.998+01:00 INFO 52622 --- [mer://queryDocs] queryDocuments
: Querying vector store with: What is Apache Camel
and what does it do?
+2025-11-25T17:34:09.206+01:00 INFO 52622 --- [mer://queryDocs] queryDocuments
: Retrieved 1 documents from vector store
+2025-11-25T17:34:09.217+01:00 INFO 52622 --- [mer://queryDocs] queryDocuments
: Document text: Apache Camel is an open-source
integration framework based on Enterprise Integration Patterns. It provides a
rule-based routing and mediation engine which enables you to define routing and
mediation rules in various domain-specific languages.
+
+
+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.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 ponde [...]
+----
+
+=== Configuration
+
+The AI configuration can be modified in `src/main/resources/application.yaml`:
+
+* Change the Ollama base URL if running on a different host/port
+* Switch to a different model (ensure it's pulled in Ollama first)
+* Adjust the temperature for more/less creative responses
+* Modify Qdrant host/port if running on a different location
+* Change the collection name for different use cases
+* Modify topK in VectorStoreRoute for more/fewer search results
+
+==== Production Profile with OpenAI
+
+The example includes a production profile that uses OpenAI instead of Ollama.
To use it, activate the `prod` Maven profile and set the required environment
variables:
+
+[source,bash]
+----
+export OPENAI_CHAT_MODEL=gpt-4o
+export OPENAI_CHAT_BASE_URL=https://api.openai.com
+export OPENAI_CHAT_API_KEY=your-openai-api-key
+export OPENAI_EMBEDDING_MODEL=text-embedding-3-small
+export OPENAI_EMBEDDING_BASE_URL=https://api.openai.com
+export OPENAI_EMBEDDING_API_KEY=your-openai-api-key
+
+mvn spring-boot:run -Pprod -Dspring-boot.run.profiles=prod
+----
+
+The production profile configuration is in
`src/main/resources/application-prod.yaml` and uses environment variables for
flexibility. You can customize the models and base URLs to use different
OpenAI-compatible endpoints (e.g., Azure OpenAI, local OpenAI-compatible
servers).
+
+=== Help and contributions
+
+If you hit any problem using Camel or have some feedback, then please
+https://camel.apache.org/community/support/[let us know].
+
+We also love contributors, so
+https://camel.apache.org/community/contributing/[get involved] :-)
+
+The Camel riders!
diff --git a/ai-agent/input/camel-intro.txt b/ai-agent/input/camel-intro.txt
new file mode 100644
index 0000000..1f832b6
--- /dev/null
+++ b/ai-agent/input/camel-intro.txt
@@ -0,0 +1 @@
+Apache Camel is an open-source integration framework based on Enterprise
Integration Patterns. It provides a rule-based routing and mediation engine
which enables you to define routing and mediation rules in various
domain-specific languages.
\ No newline at end of file
diff --git a/ai-agent/input/spring-ai-intro.txt
b/ai-agent/input/spring-ai-intro.txt
new file mode 100644
index 0000000..f01af94
--- /dev/null
+++ b/ai-agent/input/spring-ai-intro.txt
@@ -0,0 +1 @@
+Spring AI provides abstractions for AI services including chat models,
embeddings, and vector stores. It enables developers to build AI-powered
applications using familiar Spring patterns and practices.
\ No newline at end of file
diff --git a/ai-agent/pom.xml b/ai-agent/pom.xml
new file mode 100644
index 0000000..87feaa8
--- /dev/null
+++ b/ai-agent/pom.xml
@@ -0,0 +1,172 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.camel.springboot.example</groupId>
+ <artifactId>examples</artifactId>
+ <version>4.17.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>camel-example-spring-boot-ai-agent</artifactId>
+ <name>Camel SB Examples :: Spring AI Agent</name>
+ <description>An example showing how to work with Camel Spring AI for chat,
tools, and vector store</description>
+
+ <properties>
+ <category>AI</category>
+
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+ <spring-ai-version>1.1.0</spring-ai-version>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <!-- Camel BOM -->
+ <dependency>
+ <groupId>org.apache.camel.springboot</groupId>
+ <artifactId>camel-spring-boot-bom</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <!-- Spring Boot BOM -->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-dependencies</artifactId>
+ <version>${spring-boot-version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <!-- Spring AI BOM -->
+ <dependency>
+ <groupId>org.springframework.ai</groupId>
+ <artifactId>spring-ai-bom</artifactId>
+ <version>${spring-ai-version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+
+ <!-- Spring Boot -->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter</artifactId>
+ </dependency>
+
+ <!-- Camel -->
+ <dependency>
+ <groupId>org.apache.camel.springboot</groupId>
+ <artifactId>camel-spring-boot-starter</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.springboot</groupId>
+ <artifactId>camel-spring-ai-chat-starter</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.springboot</groupId>
+ <artifactId>camel-spring-ai-vector-store-starter</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.springboot</groupId>
+ <artifactId>camel-spring-ai-tools-starter</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.springboot</groupId>
+ <artifactId>camel-file-starter</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.springboot</groupId>
+ <artifactId>camel-http-starter</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.springboot</groupId>
+ <artifactId>camel-jq-starter</artifactId>
+ </dependency>
+
+ <!-- Spring AI Vector Store - Qdrant -->
+ <dependency>
+ <groupId>org.springframework.ai</groupId>
+ <artifactId>spring-ai-starter-vector-store-qdrant</artifactId>
+ </dependency>
+
+ <!-- test -->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-test-spring-junit5</artifactId>
+ <version>${camel-version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ <profiles>
+ <profile>
+ <id>default</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <dependencies>
+ <!-- Spring AI Ollama -->
+ <dependency>
+ <groupId>org.springframework.ai</groupId>
+ <artifactId>spring-ai-starter-model-ollama</artifactId>
+ </dependency>
+ </dependencies>
+ </profile>
+ <profile>
+ <id>prod</id>
+ <dependencies>
+ <!-- Spring AI OpenAI -->
+ <dependency>
+ <groupId>org.springframework.ai</groupId>
+ <artifactId>spring-ai-starter-model-openai</artifactId>
+ </dependency>
+ </dependencies>
+ </profile>
+ </profiles>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <version>${spring-boot-version}</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/ai-agent/src/main/java/sample/camel/Application.java
b/ai-agent/src/main/java/sample/camel/Application.java
new file mode 100644
index 0000000..b9b171e
--- /dev/null
+++ b/ai-agent/src/main/java/sample/camel/Application.java
@@ -0,0 +1,36 @@
+/*
+ * 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 sample.camel;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * A sample Spring Boot application that demonstrates Camel Spring AI
integration
+ * with chat, tools, and vector store capabilities.
+ */
+@SpringBootApplication
+public class Application {
+
+ /**
+ * A main method to start this application.
+ */
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+
+}
diff --git a/ai-agent/src/main/java/sample/camel/ChatRoute.java
b/ai-agent/src/main/java/sample/camel/ChatRoute.java
new file mode 100644
index 0000000..d524a85
--- /dev/null
+++ b/ai-agent/src/main/java/sample/camel/ChatRoute.java
@@ -0,0 +1,37 @@
+/*
+ * 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 sample.camel;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.springframework.stereotype.Component;
+
+/**
+ * Route that demonstrates basic chat functionality with Spring AI.
+ */
+@Component
+public class ChatRoute extends RouteBuilder {
+
+ @Override
+ public void configure() throws Exception {
+ from("timer:chat?repeatCount=1")
+ .routeId("chatRoute")
+ .setBody(constant("What is Apache Camel?"))
+ .log("Sending question to AI: ${body}")
+ .to("spring-ai-chat:chat")
+ .log("AI Response: ${body}");
+ }
+}
diff --git a/ai-agent/src/main/java/sample/camel/ToolRoute.java
b/ai-agent/src/main/java/sample/camel/ToolRoute.java
new file mode 100644
index 0000000..0b981f2
--- /dev/null
+++ b/ai-agent/src/main/java/sample/camel/ToolRoute.java
@@ -0,0 +1,66 @@
+/*
+ * 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 sample.camel;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.springframework.stereotype.Component;
+
+/**
+ * Route that demonstrates Spring AI tool/function calling capabilities.
+ * The AI can invoke the weather tool to get current weather information.
+ */
+@Component
+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"
+ + "¶meter.location=string"
+ + "¶meter.location.description=The city, e.g. Rome"
+ + "¶meter.location.required=true")
+ .routeId("weatherTool")
+ .log("Weather tool called for location: ${header.location}")
+ .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
+ 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")
+ .setHeader("latitude", jq(".results[0].latitude"))
+ .setHeader("longitude", jq(".results[0].longitude"))
+ .setHeader("location", simple("${header.savedLocation}"));
+
+ // 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.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."));
+
+ // Route that uses AI with function calling
+ from("timer:toolChat?repeatCount=1&delay=20000")
+ .routeId("toolChatRoute")
+ .setBody(constant("What is the weather like in Rome, Italy? Answer
with English slang"))
+ .log("Sending question with tool capability to AI: ${body}")
+ .to("spring-ai-chat:toolChat?tags=weather")
+ .log("AI Response with tool usage: ${body}");
+ }
+}
diff --git a/ai-agent/src/main/java/sample/camel/VectorStoreRoute.java
b/ai-agent/src/main/java/sample/camel/VectorStoreRoute.java
new file mode 100644
index 0000000..5a2c64f
--- /dev/null
+++ b/ai-agent/src/main/java/sample/camel/VectorStoreRoute.java
@@ -0,0 +1,50 @@
+/*
+ * 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 sample.camel;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.springframework.stereotype.Component;
+
+/**
+ * Route that demonstrates Spring AI vector store capabilities.
+ * Stores documents from files and performs similarity search.
+ */
+@Component
+public class VectorStoreRoute extends RouteBuilder {
+
+ @Override
+ public void configure() throws Exception {
+ // Route to add documents from files to the vector store
+ from("file:input?noop=true&include=.*\\.txt")
+ .routeId("addDocuments")
+ .log("Adding document ${header.CamelFileName} to vector store")
+ .convertBodyTo(String.class)
+ .to("spring-ai-vector-store:myStore?operation=ADD")
+ .log("Successfully added ${header.CamelFileName} to vector store");
+
+ // Route to query the vector store using similarity search
+ from("timer:queryDocs?repeatCount=1&delay=10000")
+ .routeId("queryDocuments")
+ .setBody(constant("What is Apache Camel and what does it do?"))
+ .log("Querying vector store with: ${body}")
+
.to("spring-ai-vector-store:myStore?operation=SIMILARITY_SEARCH&topK=3&similarityThreshold=0.5")
+ .log("Retrieved ${body.size()} documents from vector store")
+ .split(body())
+ .log("Document text: ${body.text}")
+ .end();
+ }
+}
diff --git a/ai-agent/src/main/resources/application-prod.yaml
b/ai-agent/src/main/resources/application-prod.yaml
new file mode 100644
index 0000000..05d4ce1
--- /dev/null
+++ b/ai-agent/src/main/resources/application-prod.yaml
@@ -0,0 +1,46 @@
+camel:
+ main:
+ run-controller: true
+ name: CamelSpringAI
+
+spring:
+ main:
+ web-application-type: none
+ ai:
+ model:
+ chat: openai
+ embedding:
+ text: openai
+ multimodal: off
+ audio:
+ speech: off
+ transcription: off
+ image: off
+ moderation: off
+ openai:
+ chat:
+ model: ${OPENAI_CHAT_MODEL}
+ options:
+ temperature: 0.7
+ model: ${OPENAI_CHAT_MODEL}
+ base-url: ${OPENAI_CHAT_BASE_URL}
+ api-key: ${OPENAI_CHAT_API_KEY}
+ embedding:
+ model: ${OPENAI_EMBEDDING_MODEL}
+ base-url: ${OPENAI_EMBEDDING_BASE_URL}
+ api-key: ${OPENAI_EMBEDDING_API_KEY}
+ options:
+ model: ${OPENAI_EMBEDDING_MODEL}
+ vectorstore:
+ qdrant:
+ host: localhost
+ port: 6334
+ collection-name: camel-ai-docs
+ initialize-schema: true
+ use-tls: false
+
+logging:
+ level:
+ org.apache.camel: INFO
+ sample.camel: INFO
+ org.springframework.ai: INFO
diff --git a/ai-agent/src/main/resources/application.yaml
b/ai-agent/src/main/resources/application.yaml
new file mode 100644
index 0000000..c1c2aee
--- /dev/null
+++ b/ai-agent/src/main/resources/application.yaml
@@ -0,0 +1,34 @@
+camel:
+ main:
+ run-controller: true
+ name: CamelSpringAI
+
+spring:
+ main:
+ web-application-type: none
+ ai:
+ model:
+ chat: ollama
+ embedding:
+ text: ollama
+ ollama:
+ base-url: http://localhost:11434
+ chat:
+ model: granite4:3b
+ options:
+ temperature: 0.7
+ embedding:
+ model: embeddinggemma:300m
+ vectorstore:
+ qdrant:
+ host: localhost
+ port: 6334
+ collection-name: camel-ai-docs
+ initialize-schema: true
+ use-tls: false
+
+logging:
+ level:
+ org.apache.camel: INFO
+ sample.camel: INFO
+ org.springframework.ai: INFO
diff --git a/pom.xml b/pom.xml
index 3f7dd1b..6f9e617 100644
--- a/pom.xml
+++ b/pom.xml
@@ -38,6 +38,7 @@
<module>spring-boot</module>
<module>activemq</module>
<module>actuator-http-metrics</module>
+ <module>ai-agent</module>
<module>amqp</module>
<module>aot-basic</module>
<module>arangodb</module>