This is an automated email from the ASF dual-hosted git repository.

zbendhiba pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new a543ea524ff CAMEL-20935: introduce Camel LangChain4j Web Search 
component (#14928)
a543ea524ff is described below

commit a543ea524ff0572d33614761198605599e52cd24
Author: Zineb BENDHIBA <[email protected]>
AuthorDate: Fri Jul 26 09:01:53 2024 +0200

    CAMEL-20935: introduce Camel LangChain4j Web Search component (#14928)
---
 bom/camel-bom/pom.xml                              |   5 +
 catalog/camel-allcomponents/pom.xml                |   5 +
 .../camel-ai/camel-langchain4j-web-search/pom.xml  |  85 +++++++++
 .../LangChain4jWebSearchComponentConfigurer.java   |  57 ++++++
 ...angChain4jWebSearchConfigurationConfigurer.java | 111 ++++++++++++
 .../LangChain4jWebSearchEndpointConfigurer.java    | 122 +++++++++++++
 .../LangChain4jWebSearchEndpointUriFactory.java    |  81 +++++++++
 .../web/search/langchain4j-web-search.json         |  43 +++++
 .../services/org/apache/camel/component.properties |   7 +
 .../apache/camel/component/langchain4j-web-search  |   2 +
 .../configurer/langchain4j-web-search-component    |   2 +
 .../configurer/langchain4j-web-search-endpoint     |   2 +
 ...4j.web.search.LangChain4jWebSearchConfiguration |   2 +
 .../urifactory/langchain4j-web-search-endpoint     |   2 +
 .../docs/langchain4j-web-search-component.adoc     | 164 ++++++++++++++++++
 .../web/search/LangChain4jWebSearchComponent.java  |  55 ++++++
 .../search/LangChain4jWebSearchConfiguration.java  | 192 +++++++++++++++++++++
 .../web/search/LangChain4jWebSearchEndpoint.java   |  76 ++++++++
 .../web/search/LangChain4jWebSearchEngine.java     |  26 +++
 .../web/search/LangChain4jWebSearchProducer.java   | 112 ++++++++++++
 .../web/search/LangChain4jWebSearchResultType.java |  23 +++
 .../search/LangChain4jGoogleWebSearchEngineIT.java |  90 ++++++++++
 .../search/LangChain4jTavilyWebSearchEngineIT.java |  88 ++++++++++
 components/camel-ai/pom.xml                        |   1 +
 .../ROOT/examples/json/langchain4j-web-search.json |   1 +
 docs/components/modules/ROOT/nav.adoc              |   1 +
 .../pages/langchain4j-web-search-component.adoc    |   1 +
 parent/pom.xml                                     |   5 +
 28 files changed, 1361 insertions(+)

diff --git a/bom/camel-bom/pom.xml b/bom/camel-bom/pom.xml
index 63aad62abed..d4be05ec273 100644
--- a/bom/camel-bom/pom.xml
+++ b/bom/camel-bom/pom.xml
@@ -1327,6 +1327,11 @@
         <artifactId>camel-langchain4j-embeddings</artifactId>
         <version>4.8.0-SNAPSHOT</version>
       </dependency>
+      <dependency>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>camel-langchain4j-web-search</artifactId>
+        <version>4.8.0-SNAPSHOT</version>
+      </dependency>
       <dependency>
         <groupId>org.apache.camel</groupId>
         <artifactId>camel-language</artifactId>
diff --git a/catalog/camel-allcomponents/pom.xml 
b/catalog/camel-allcomponents/pom.xml
index 9f98de291c1..af7bc3a0e46 100644
--- a/catalog/camel-allcomponents/pom.xml
+++ b/catalog/camel-allcomponents/pom.xml
@@ -1122,6 +1122,11 @@
             <artifactId>camel-langchain4j-embeddings</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-langchain4j-web-search</artifactId>
+            <version>${project.version}</version>
+        </dependency>
         <dependency>
             <groupId>org.apache.camel</groupId>
             <artifactId>camel-language</artifactId>
diff --git a/components/camel-ai/camel-langchain4j-web-search/pom.xml 
b/components/camel-ai/camel-langchain4j-web-search/pom.xml
new file mode 100644
index 00000000000..bada1ca140f
--- /dev/null
+++ b/components/camel-ai/camel-langchain4j-web-search/pom.xml
@@ -0,0 +1,85 @@
+<?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/xsd/maven-4.0.0.xsd";>
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <artifactId>camel-ai-parent</artifactId>
+    <groupId>org.apache.camel</groupId>
+    <version>4.8.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>camel-langchain4j-web-search</artifactId>
+  <packaging>jar</packaging>
+  <name>Camel :: AI :: LangChain4j :: Web Search</name>
+  <description>LangChain4j Web Search</description>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-support</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-langchain4j-core</artifactId>
+    </dependency>
+
+    <!-- test dependencies -->
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-direct</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-test-junit5</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.assertj</groupId>
+      <artifactId>assertj-core</artifactId>
+      <version>${assertj-version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>dev.langchain4j</groupId>
+      <artifactId>langchain4j-web-search-engine-tavily</artifactId>
+      <version>${langchain4j-version}</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>dev.langchain4j</groupId>
+      <artifactId>langchain4j-web-search-engine-google-custom</artifactId>
+      <version>${langchain4j-version}</version>
+      <scope>test</scope>
+    </dependency>
+
+  </dependencies>
+</project>
+
diff --git 
a/components/camel-ai/camel-langchain4j-web-search/src/generated/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchComponentConfigurer.java
 
b/components/camel-ai/camel-langchain4j-web-search/src/generated/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchComponentConfigurer.java
new file mode 100644
index 00000000000..8d4f0ab598d
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-web-search/src/generated/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchComponentConfigurer.java
@@ -0,0 +1,57 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.langchain4j.web.search;
+
+import javax.annotation.processing.Generated;
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.support.component.PropertyConfigurerSupport;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@Generated("org.apache.camel.maven.packaging.EndpointSchemaGeneratorMojo")
+@SuppressWarnings("unchecked")
+public class LangChain4jWebSearchComponentConfigurer extends 
PropertyConfigurerSupport implements GeneratedPropertyConfigurer, 
PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String 
name, Object value, boolean ignoreCase) {
+        LangChain4jWebSearchComponent target = (LangChain4jWebSearchComponent) 
obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "autowiredenabled":
+        case "autowiredEnabled": 
target.setAutowiredEnabled(property(camelContext, boolean.class, value)); 
return true;
+        case "lazystartproducer":
+        case "lazyStartProducer": 
target.setLazyStartProducer(property(camelContext, boolean.class, value)); 
return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "autowiredenabled":
+        case "autowiredEnabled": return boolean.class;
+        case "lazystartproducer":
+        case "lazyStartProducer": return boolean.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        LangChain4jWebSearchComponent target = (LangChain4jWebSearchComponent) 
obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "autowiredenabled":
+        case "autowiredEnabled": return target.isAutowiredEnabled();
+        case "lazystartproducer":
+        case "lazyStartProducer": return target.isLazyStartProducer();
+        default: return null;
+        }
+    }
+}
+
diff --git 
a/components/camel-ai/camel-langchain4j-web-search/src/generated/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchConfigurationConfigurer.java
 
b/components/camel-ai/camel-langchain4j-web-search/src/generated/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchConfigurationConfigurer.java
new file mode 100644
index 00000000000..0a91667f75f
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-web-search/src/generated/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchConfigurationConfigurer.java
@@ -0,0 +1,111 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.langchain4j.web.search;
+
+import javax.annotation.processing.Generated;
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import 
org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchConfiguration;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@Generated("org.apache.camel.maven.packaging.GenerateConfigurerMojo")
+@SuppressWarnings("unchecked")
+public class LangChain4jWebSearchConfigurationConfigurer extends 
org.apache.camel.support.component.PropertyConfigurerSupport implements 
GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String 
name, Object value, boolean ignoreCase) {
+        
org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchConfiguration
 target = 
(org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchConfiguration)
 obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "additionalparams":
+        case "additionalParams": 
target.setAdditionalParams(property(camelContext, java.util.Map.class, value)); 
return true;
+        case "geolocation":
+        case "geoLocation": target.setGeoLocation(property(camelContext, 
java.lang.String.class, value)); return true;
+        case "language": target.setLanguage(property(camelContext, 
java.lang.String.class, value)); return true;
+        case "maxresults":
+        case "maxResults": target.setMaxResults(property(camelContext, 
java.lang.Integer.class, value)); return true;
+        case "resulttype":
+        case "resultType": target.setResultType(property(camelContext, 
org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchResultType.class,
 value)); return true;
+        case "safesearch":
+        case "safeSearch": target.setSafeSearch(property(camelContext, 
java.lang.Boolean.class, value)); return true;
+        case "startindex":
+        case "startIndex": target.setStartIndex(property(camelContext, 
java.lang.Integer.class, value)); return true;
+        case "startpage":
+        case "startPage": target.setStartPage(property(camelContext, 
java.lang.Integer.class, value)); return true;
+        case "websearchengine":
+        case "webSearchEngine": 
target.setWebSearchEngine(property(camelContext, 
dev.langchain4j.web.search.WebSearchEngine.class, value)); return true;
+        case "websearchrequest":
+        case "webSearchRequest": 
target.setWebSearchRequest(property(camelContext, 
dev.langchain4j.web.search.WebSearchRequest.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "additionalparams":
+        case "additionalParams": return java.util.Map.class;
+        case "geolocation":
+        case "geoLocation": return java.lang.String.class;
+        case "language": return java.lang.String.class;
+        case "maxresults":
+        case "maxResults": return java.lang.Integer.class;
+        case "resulttype":
+        case "resultType": return 
org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchResultType.class;
+        case "safesearch":
+        case "safeSearch": return java.lang.Boolean.class;
+        case "startindex":
+        case "startIndex": return java.lang.Integer.class;
+        case "startpage":
+        case "startPage": return java.lang.Integer.class;
+        case "websearchengine":
+        case "webSearchEngine": return 
dev.langchain4j.web.search.WebSearchEngine.class;
+        case "websearchrequest":
+        case "webSearchRequest": return 
dev.langchain4j.web.search.WebSearchRequest.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        
org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchConfiguration
 target = 
(org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchConfiguration)
 obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "additionalparams":
+        case "additionalParams": return target.getAdditionalParams();
+        case "geolocation":
+        case "geoLocation": return target.getGeoLocation();
+        case "language": return target.getLanguage();
+        case "maxresults":
+        case "maxResults": return target.getMaxResults();
+        case "resulttype":
+        case "resultType": return target.getResultType();
+        case "safesearch":
+        case "safeSearch": return target.getSafeSearch();
+        case "startindex":
+        case "startIndex": return target.getStartIndex();
+        case "startpage":
+        case "startPage": return target.getStartPage();
+        case "websearchengine":
+        case "webSearchEngine": return target.getWebSearchEngine();
+        case "websearchrequest":
+        case "webSearchRequest": return target.getWebSearchRequest();
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getCollectionValueType(Object target, String name, boolean 
ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "additionalparams":
+        case "additionalParams": return java.lang.Object.class;
+        default: return null;
+        }
+    }
+}
+
diff --git 
a/components/camel-ai/camel-langchain4j-web-search/src/generated/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchEndpointConfigurer.java
 
b/components/camel-ai/camel-langchain4j-web-search/src/generated/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchEndpointConfigurer.java
new file mode 100644
index 00000000000..e280ad92a41
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-web-search/src/generated/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchEndpointConfigurer.java
@@ -0,0 +1,122 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.langchain4j.web.search;
+
+import javax.annotation.processing.Generated;
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.support.component.PropertyConfigurerSupport;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@Generated("org.apache.camel.maven.packaging.EndpointSchemaGeneratorMojo")
+@SuppressWarnings("unchecked")
+public class LangChain4jWebSearchEndpointConfigurer extends 
PropertyConfigurerSupport implements GeneratedPropertyConfigurer, 
PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String 
name, Object value, boolean ignoreCase) {
+        LangChain4jWebSearchEndpoint target = (LangChain4jWebSearchEndpoint) 
obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "additionalparams":
+        case "additionalParams": 
target.getConfiguration().setAdditionalParams(property(camelContext, 
java.util.Map.class, value)); return true;
+        case "geolocation":
+        case "geoLocation": 
target.getConfiguration().setGeoLocation(property(camelContext, 
java.lang.String.class, value)); return true;
+        case "language": 
target.getConfiguration().setLanguage(property(camelContext, 
java.lang.String.class, value)); return true;
+        case "lazystartproducer":
+        case "lazyStartProducer": 
target.setLazyStartProducer(property(camelContext, boolean.class, value)); 
return true;
+        case "maxresults":
+        case "maxResults": 
target.getConfiguration().setMaxResults(property(camelContext, 
java.lang.Integer.class, value)); return true;
+        case "resulttype":
+        case "resultType": 
target.getConfiguration().setResultType(property(camelContext, 
org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchResultType.class,
 value)); return true;
+        case "safesearch":
+        case "safeSearch": 
target.getConfiguration().setSafeSearch(property(camelContext, 
java.lang.Boolean.class, value)); return true;
+        case "startindex":
+        case "startIndex": 
target.getConfiguration().setStartIndex(property(camelContext, 
java.lang.Integer.class, value)); return true;
+        case "startpage":
+        case "startPage": 
target.getConfiguration().setStartPage(property(camelContext, 
java.lang.Integer.class, value)); return true;
+        case "websearchengine":
+        case "webSearchEngine": 
target.getConfiguration().setWebSearchEngine(property(camelContext, 
dev.langchain4j.web.search.WebSearchEngine.class, value)); return true;
+        case "websearchrequest":
+        case "webSearchRequest": 
target.getConfiguration().setWebSearchRequest(property(camelContext, 
dev.langchain4j.web.search.WebSearchRequest.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public String[] getAutowiredNames() {
+        return new String[]{"additionalParams", "webSearchEngine", 
"webSearchRequest"};
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "additionalparams":
+        case "additionalParams": return java.util.Map.class;
+        case "geolocation":
+        case "geoLocation": return java.lang.String.class;
+        case "language": return java.lang.String.class;
+        case "lazystartproducer":
+        case "lazyStartProducer": return boolean.class;
+        case "maxresults":
+        case "maxResults": return java.lang.Integer.class;
+        case "resulttype":
+        case "resultType": return 
org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchResultType.class;
+        case "safesearch":
+        case "safeSearch": return java.lang.Boolean.class;
+        case "startindex":
+        case "startIndex": return java.lang.Integer.class;
+        case "startpage":
+        case "startPage": return java.lang.Integer.class;
+        case "websearchengine":
+        case "webSearchEngine": return 
dev.langchain4j.web.search.WebSearchEngine.class;
+        case "websearchrequest":
+        case "webSearchRequest": return 
dev.langchain4j.web.search.WebSearchRequest.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        LangChain4jWebSearchEndpoint target = (LangChain4jWebSearchEndpoint) 
obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "additionalparams":
+        case "additionalParams": return 
target.getConfiguration().getAdditionalParams();
+        case "geolocation":
+        case "geoLocation": return target.getConfiguration().getGeoLocation();
+        case "language": return target.getConfiguration().getLanguage();
+        case "lazystartproducer":
+        case "lazyStartProducer": return target.isLazyStartProducer();
+        case "maxresults":
+        case "maxResults": return target.getConfiguration().getMaxResults();
+        case "resulttype":
+        case "resultType": return target.getConfiguration().getResultType();
+        case "safesearch":
+        case "safeSearch": return target.getConfiguration().getSafeSearch();
+        case "startindex":
+        case "startIndex": return target.getConfiguration().getStartIndex();
+        case "startpage":
+        case "startPage": return target.getConfiguration().getStartPage();
+        case "websearchengine":
+        case "webSearchEngine": return 
target.getConfiguration().getWebSearchEngine();
+        case "websearchrequest":
+        case "webSearchRequest": return 
target.getConfiguration().getWebSearchRequest();
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getCollectionValueType(Object target, String name, boolean 
ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "additionalparams":
+        case "additionalParams": return java.lang.Object.class;
+        default: return null;
+        }
+    }
+}
+
diff --git 
a/components/camel-ai/camel-langchain4j-web-search/src/generated/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchEndpointUriFactory.java
 
b/components/camel-ai/camel-langchain4j-web-search/src/generated/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchEndpointUriFactory.java
new file mode 100644
index 00000000000..a13d6262bad
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-web-search/src/generated/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchEndpointUriFactory.java
@@ -0,0 +1,81 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.langchain4j.web.search;
+
+import javax.annotation.processing.Generated;
+import java.net.URISyntaxException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.camel.spi.EndpointUriFactory;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@Generated("org.apache.camel.maven.packaging.GenerateEndpointUriFactoryMojo")
+public class LangChain4jWebSearchEndpointUriFactory extends 
org.apache.camel.support.component.EndpointUriFactorySupport implements 
EndpointUriFactory {
+
+    private static final String BASE = ":searchId";
+
+    private static final Set<String> PROPERTY_NAMES;
+    private static final Set<String> SECRET_PROPERTY_NAMES;
+    private static final Set<String> MULTI_VALUE_PREFIXES;
+    static {
+        Set<String> props = new HashSet<>(12);
+        props.add("additionalParams");
+        props.add("geoLocation");
+        props.add("language");
+        props.add("lazyStartProducer");
+        props.add("maxResults");
+        props.add("resultType");
+        props.add("safeSearch");
+        props.add("searchId");
+        props.add("startIndex");
+        props.add("startPage");
+        props.add("webSearchEngine");
+        props.add("webSearchRequest");
+        PROPERTY_NAMES = Collections.unmodifiableSet(props);
+        SECRET_PROPERTY_NAMES = Collections.emptySet();
+        MULTI_VALUE_PREFIXES = Collections.emptySet();
+    }
+
+    @Override
+    public boolean isEnabled(String scheme) {
+        return "langchain4j-web-search".equals(scheme);
+    }
+
+    @Override
+    public String buildUri(String scheme, Map<String, Object> properties, 
boolean encode) throws URISyntaxException {
+        String syntax = scheme + BASE;
+        String uri = syntax;
+
+        Map<String, Object> copy = new HashMap<>(properties);
+
+        uri = buildPathParameter(syntax, uri, "searchId", null, true, copy);
+        uri = buildQueryParameters(uri, copy, encode);
+        return uri;
+    }
+
+    @Override
+    public Set<String> propertyNames() {
+        return PROPERTY_NAMES;
+    }
+
+    @Override
+    public Set<String> secretPropertyNames() {
+        return SECRET_PROPERTY_NAMES;
+    }
+
+    @Override
+    public Set<String> multiValuePrefixes() {
+        return MULTI_VALUE_PREFIXES;
+    }
+
+    @Override
+    public boolean isLenientProperties() {
+        return false;
+    }
+}
+
diff --git 
a/components/camel-ai/camel-langchain4j-web-search/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/web/search/langchain4j-web-search.json
 
b/components/camel-ai/camel-langchain4j-web-search/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/web/search/langchain4j-web-search.json
new file mode 100644
index 00000000000..f882cf829f5
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-web-search/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/web/search/langchain4j-web-search.json
@@ -0,0 +1,43 @@
+{
+  "component": {
+    "kind": "component",
+    "name": "langchain4j-web-search",
+    "title": "LangChain4j Web Search",
+    "description": "LangChain4j Web Search Engine",
+    "deprecated": false,
+    "firstVersion": "4.8.0",
+    "label": "ai",
+    "javaType": 
"org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchComponent",
+    "supportLevel": "Preview",
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-langchain4j-web-search",
+    "version": "4.8.0-SNAPSHOT",
+    "scheme": "langchain4j-web-search",
+    "extendsScheme": "",
+    "syntax": "langchain4j-web-search:searchId",
+    "async": false,
+    "api": false,
+    "consumerOnly": false,
+    "producerOnly": true,
+    "lenientProperties": false,
+    "remote": true
+  },
+  "componentProperties": {
+    "lazyStartProducer": { "index": 0, "kind": "property", "displayName": 
"Lazy Start Producer", "group": "producer", "label": "producer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether the producer should be started lazy (on the first message). By 
starting lazy you can use this to allow CamelContext and routes to startup in 
situations where a producer may otherwise fail [...]
+    "autowiredEnabled": { "index": 1, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
+  },
+  "properties": {
+    "searchId": { "index": 0, "kind": "path", "displayName": "Search Id", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The id" },
+    "additionalParams": { "index": 1, "kind": "parameter", "displayName": 
"Additional Params", "group": "producer", "label": "", "required": false, 
"type": "object", "javaType": "java.util.Map<java.lang.String, 
java.lang.Object>", "deprecated": false, "deprecationNote": "", "autowired": 
true, "secret": false, "configurationClass": 
"org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchConfiguration",
 "configurationField": "configuration", "description": "The additionalPar [...]
+    "geoLocation": { "index": 2, "kind": "parameter", "displayName": "Geo 
Location", "group": "producer", "label": "", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchConfiguration",
 "configurationField": "configuration", "description": "The geoLocation is the 
desired geolocation for search results. Each search engine  [...]
+    "language": { "index": 3, "kind": "parameter", "displayName": "Language", 
"group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchConfiguration",
 "configurationField": "configuration", "description": "The language is the 
desired language for search results. The expected values may vary dep [...]
+    "maxResults": { "index": 4, "kind": "parameter", "displayName": "Max 
Results", "group": "producer", "label": "", "required": true, "type": 
"integer", "javaType": "java.lang.Integer", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
"1", "configurationClass": 
"org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchConfiguration",
 "configurationField": "configuration", "description": "The maxResults is the 
expected number o [...]
+    "resultType": { "index": 5, "kind": "parameter", "displayName": "Result 
Type", "group": "producer", "label": "", "required": true, "type": "object", 
"javaType": 
"org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchResultType",
 "enum": [ "LANGCHAIN4J_WEB_SEARCH_ORGANIC_RESULT", "CONTENT", "SNIPPET" ], 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "defaultValue": "CONTENT", "configurationClass": 
"org.apache.camel.component.langchain4 [...]
+    "safeSearch": { "index": 6, "kind": "parameter", "displayName": "Safe 
Search", "group": "producer", "label": "", "required": false, "type": 
"boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchConfiguration",
 "configurationField": "configuration", "description": "The safeSearch is the 
safe search flag, indicating whether to enable or disable sa [...]
+    "startIndex": { "index": 7, "kind": "parameter", "displayName": "Start 
Index", "group": "producer", "label": "", "required": false, "type": "integer", 
"javaType": "java.lang.Integer", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchConfiguration",
 "configurationField": "configuration", "description": "The startIndex is the 
start index for search results, which may vary depending on  [...]
+    "startPage": { "index": 8, "kind": "parameter", "displayName": "Start 
Page", "group": "producer", "label": "", "required": false, "type": "integer", 
"javaType": "java.lang.Integer", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchConfiguration",
 "configurationField": "configuration", "description": "The startPage is the 
start page number for search results" },
+    "webSearchEngine": { "index": 9, "kind": "parameter", "displayName": "Web 
Search Engine", "group": "producer", "label": "", "required": true, "type": 
"object", "javaType": "dev.langchain4j.web.search.WebSearchEngine", 
"deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, 
"configurationClass": 
"org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchConfiguration",
 "configurationField": "configuration", "description": "The WebSearchEngine 
engine [...]
+    "lazyStartProducer": { "index": 10, "kind": "parameter", "displayName": 
"Lazy Start Producer", "group": "producer (advanced)", "label": 
"producer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether the producer should be started 
lazy (on the first message). By starting lazy you can use this to allow 
CamelContext and routes to startup in situations where a produ [...]
+    "webSearchRequest": { "index": 11, "kind": "parameter", "displayName": 
"Web Search Request", "group": "advanced", "label": "advanced", "required": 
false, "type": "object", "javaType": 
"dev.langchain4j.web.search.WebSearchRequest", "deprecated": false, 
"deprecationNote": "", "autowired": true, "secret": false, 
"configurationClass": 
"org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchConfiguration",
 "configurationField": "configuration", "description": "The webSearch [...]
+  }
+}
diff --git 
a/components/camel-ai/camel-langchain4j-web-search/src/generated/resources/META-INF/services/org/apache/camel/component.properties
 
b/components/camel-ai/camel-langchain4j-web-search/src/generated/resources/META-INF/services/org/apache/camel/component.properties
new file mode 100644
index 00000000000..b5b7ff362be
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-web-search/src/generated/resources/META-INF/services/org/apache/camel/component.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+components=langchain4j-web-search
+groupId=org.apache.camel
+artifactId=camel-langchain4j-web-search
+version=4.8.0-SNAPSHOT
+projectName=Camel :: AI :: LangChain4j :: Web Search
+projectDescription=LangChain4j Web Search
diff --git 
a/components/camel-ai/camel-langchain4j-web-search/src/generated/resources/META-INF/services/org/apache/camel/component/langchain4j-web-search
 
b/components/camel-ai/camel-langchain4j-web-search/src/generated/resources/META-INF/services/org/apache/camel/component/langchain4j-web-search
new file mode 100644
index 00000000000..f5d8e91d577
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-web-search/src/generated/resources/META-INF/services/org/apache/camel/component/langchain4j-web-search
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchComponent
diff --git 
a/components/camel-ai/camel-langchain4j-web-search/src/generated/resources/META-INF/services/org/apache/camel/configurer/langchain4j-web-search-component
 
b/components/camel-ai/camel-langchain4j-web-search/src/generated/resources/META-INF/services/org/apache/camel/configurer/langchain4j-web-search-component
new file mode 100644
index 00000000000..62e7d2413d7
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-web-search/src/generated/resources/META-INF/services/org/apache/camel/configurer/langchain4j-web-search-component
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchComponentConfigurer
diff --git 
a/components/camel-ai/camel-langchain4j-web-search/src/generated/resources/META-INF/services/org/apache/camel/configurer/langchain4j-web-search-endpoint
 
b/components/camel-ai/camel-langchain4j-web-search/src/generated/resources/META-INF/services/org/apache/camel/configurer/langchain4j-web-search-endpoint
new file mode 100644
index 00000000000..6b16d2f8683
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-web-search/src/generated/resources/META-INF/services/org/apache/camel/configurer/langchain4j-web-search-endpoint
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchEndpointConfigurer
diff --git 
a/components/camel-ai/camel-langchain4j-web-search/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchConfiguration
 
b/components/camel-ai/camel-langchain4j-web-search/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchConfiguration
new file mode 100644
index 00000000000..58253746407
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-web-search/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchConfiguration
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchConfigurationConfigurer
diff --git 
a/components/camel-ai/camel-langchain4j-web-search/src/generated/resources/META-INF/services/org/apache/camel/urifactory/langchain4j-web-search-endpoint
 
b/components/camel-ai/camel-langchain4j-web-search/src/generated/resources/META-INF/services/org/apache/camel/urifactory/langchain4j-web-search-endpoint
new file mode 100644
index 00000000000..39e3e075134
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-web-search/src/generated/resources/META-INF/services/org/apache/camel/urifactory/langchain4j-web-search-endpoint
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchEndpointUriFactory
diff --git 
a/components/camel-ai/camel-langchain4j-web-search/src/main/docs/langchain4j-web-search-component.adoc
 
b/components/camel-ai/camel-langchain4j-web-search/src/main/docs/langchain4j-web-search-component.adoc
new file mode 100644
index 00000000000..ac6483137bc
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-web-search/src/main/docs/langchain4j-web-search-component.adoc
@@ -0,0 +1,164 @@
+= LangChain4j Web Search Component
+:doctitle: LangChain4j Web Search
+:shortname: langchain4j-web-search
+:artifactid: camel-langchain4j-web-search
+:description: LangChain4j Web Search Engine
+:since: 4.8
+:supportlevel: Preview
+:tabs-sync-option:
+:component-header: Only producer is supported
+//Manually maintained attributes
+:group: AI
+:camel-spring-boot-name: langchain4j-web-search
+
+*Since Camel {since}*
+
+*{component-header}*
+
+The LangChain4j Web Search component provides support to perform a web search 
using the https://docs.langchain4j.dev/[LangChain4j] Web Search Engines.
+
+Maven users will need to add the following dependency to their `pom.xml`
+for this component:
+
+[source,xml]
+----
+<dependency>
+    <groupId>org.apache.camel</groupId>
+    <artifactId>camel-langchain4j-web-search</artifactId>
+    <version>x.x.x</version>
+    <!-- use the same version as your Camel core version -->
+</dependency>
+----
+
+
+== URI format
+
+[source]
+----
+langchain4j-web-search:searchId[?options]
+----
+
+Where *searchId* can be any string to uniquely identify the endpoint
+
+
+// component-configure options: START
+
+// component-configure options: END
+
+// component options: START
+include::partial$component-configure-options.adoc[]
+include::partial$component-endpoint-options.adoc[]
+// component options: END
+
+// endpoint options: START
+
+// endpoint options: END
+
+// component headers: START
+include::partial$component-endpoint-headers.adoc[]
+// component headers: END
+
+include::spring-boot:partial$starter.adoc[]
+
+
+== Using a specific Web Search Engine
+The Camel LangChain4j web search component provides an abstraction for 
interacting with various types of Web Search Engines supported by 
https://github.com/langchain4j/langchain4j[LangChain4j].
+
+To integrate with a specific Web Search Engine, users should follow these 
steps:
+
+=== Example of integrating with Tavily
+Add the dependency for LangChain4j Tavily Web Search Engine support :
+
+[source,xml]
+----
+<dependency>
+      <groupId>dev.langchain4j</groupId>
+      <artifactId>langchain4j-web-search-engine-tavily</artifactId>
+    <version>x.x.x</version>
+</dependency>
+----
+
+Init the Tavily Web Search Engine, and add it to the Camel Registry:
+Initialize the Tavily Web Search Engine, and bind it to the Camel Registry:
+
+[source, java]
+----
+@BindToRegistry("web-search-engine")
+WebSearchEngine tavilyWebSearchEngine = TavilyWebSearchEngine.builder()
+    .apiKey(tavilyApiKey)
+    .includeRawContent(true)
+    .build();
+----
+
+The web search engine will be autowired automatically if its bound name is 
`web-search-engine`. Otherwise, it should be added as a configured parameter to 
the Camel route.
+
+Example of route:
+
+[source, java]
+----
+ from("direct:web-search")
+      
.to("langchain4j-web-search:test?webSearchEngine=#web-search-engine-test")
+----
+
+[NOTE]
+====
+To switch to another Web Search Engine and its corresponding dependency, 
simply replace the `langchain4j-web-search-engine-tavily` dependency with the 
appropriate dependency for the desired web search engine. Update the 
initialization parameters accordingly in the code snippet provided above.
+====
+
+== Customizing Web Search Results
+By default, the `maxResults` property is set to 1. You can adjust this value 
to retrieve a list of results.
+
+=== Retrieving single result or list of strings
+When `maxResults` is set to 1, you can by default retrieve by default the 
content as a single string.
+Example:
+
+[source, java]
+----
+String response = template.requestBody("langchain4j-web-search:test", "Who won 
the European Cup in 2024?", String.class);
+----
+
+When `maxResults` is greater than 1, you can retrieve a list of strings.
+Example:
+
+[source, java]
+----
+List<String> responses = 
template.requestBody("langchain4j-web-search:test?maxResults=3", "Who won the 
European Cup in 2024?", List.class);
+----
+
+=== Retrieve different types of Results
+You can get different type of Results.
+
+When `resultType` = SNIPPET, you will get a single or list (depending of 
`maxResults` value) of Strings containing the snippets.
+
+When `resultType` = LANGCHAIN4J_WEB_SEARCH_ORGANIC_RESULT, you will get a 
single or list (depending of `maxResults` value) of Objects of type 
`WebSearchOrganicResult` containing all the response created under the hood by 
Langchain4j Web Search.
+
+== Advanced usage of WebSearchRequest
+
+When defining a WebSearchRequest, the Camel LangChain4j web search component 
will default to this request, instead of creating one from the body and config 
parameters.
+
+[NOTE]
+====
+When using a WebSearchRequest, the body and the parameters of the search will 
be ignored. Use this parameter with caution.
+====
+
+A WebSearchRequest should be bound to the registry.
+
+Example of binding the request to the registry.
+
+[source, java]
+----
+@BindToRegistry("web-search-request")
+WebSearchRequest request = WebSearchRequest.builder()
+    .searchTerms("Who won the European Cup in 2024?")
+    .maxResults(2)
+    .build();
+----
+
+The request will be autowired automatically if its bound name is 
`web-search-request`. Otherwise, it should be added as a configured parameter 
to the Camel route.
+
+Example of route:
+[source, java]
+----
+ from("direct:web-search")
+      .to("langchain4j-web-search:test?webSearchRequest=#searchRequestTest");
+----
diff --git 
a/components/camel-ai/camel-langchain4j-web-search/src/main/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchComponent.java
 
b/components/camel-ai/camel-langchain4j-web-search/src/main/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchComponent.java
new file mode 100644
index 00000000000..b1dab154dac
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-web-search/src/main/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchComponent.java
@@ -0,0 +1,55 @@
+/*
+ * 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 org.apache.camel.component.langchain4j.web.search;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.annotations.Component;
+import org.apache.camel.support.DefaultComponent;
+
+@Component(LangChain4jWebSearchEngine.SCHEME)
+public class LangChain4jWebSearchComponent extends DefaultComponent {
+
+    @Metadata
+    private LangChain4jWebSearchConfiguration configuration;
+
+    public LangChain4jWebSearchComponent() {
+        this(null);
+    }
+
+    public LangChain4jWebSearchComponent(CamelContext context) {
+        super(context);
+        this.configuration = new LangChain4jWebSearchConfiguration();
+    }
+
+    public LangChain4jWebSearchConfiguration getConfiguration() {
+        return configuration;
+    }
+
+    @Override
+    protected Endpoint createEndpoint(String uri, String remaining, 
Map<String, Object> parameters) throws Exception {
+        LangChain4jWebSearchConfiguration configuration = 
this.configuration.copy();
+
+        LangChain4jWebSearchEndpoint endpoint = new 
LangChain4jWebSearchEndpoint(uri, this, remaining, configuration);
+        setProperties(endpoint, parameters);
+
+        return endpoint;
+    }
+}
diff --git 
a/components/camel-ai/camel-langchain4j-web-search/src/main/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchConfiguration.java
 
b/components/camel-ai/camel-langchain4j-web-search/src/main/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchConfiguration.java
new file mode 100644
index 00000000000..46a18746c11
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-web-search/src/main/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchConfiguration.java
@@ -0,0 +1,192 @@
+/*
+ * 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 org.apache.camel.component.langchain4j.web.search;
+
+import java.util.Map;
+
+import dev.langchain4j.web.search.WebSearchEngine;
+import dev.langchain4j.web.search.WebSearchRequest;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriParams;
+
+@Configurer
+@UriParams
+public class LangChain4jWebSearchConfiguration implements Cloneable {
+
+    @Metadata(required = true, autowired = true)
+    @UriParam
+    private WebSearchEngine webSearchEngine;
+
+    @Metadata(required = true, defaultValue = "CONTENT")
+    @UriParam
+    private LangChain4jWebSearchResultType resultType = 
LangChain4jWebSearchResultType.CONTENT;
+
+    @Metadata(required = true, defaultValue = "1")
+    @UriParam
+    private Integer maxResults = 1;
+    @UriParam
+    private String language;
+    @UriParam
+    private String geoLocation;
+    @UriParam
+    private Integer startPage;
+    @UriParam
+    private Integer startIndex;
+    @UriParam
+    private Boolean safeSearch;
+    @UriParam
+    @Metadata(autowired = true)
+    private Map<String, Object> additionalParams;
+
+    @UriParam(label = "advanced")
+    @Metadata(autowired = true)
+    private WebSearchRequest webSearchRequest;
+
+    public WebSearchEngine getWebSearchEngine() {
+        return webSearchEngine;
+    }
+
+    /**
+     * The {@link WebSearchEngine} engine to use. This is mandatory. Use one 
of the implementations from Langchain4j web
+     * search engines.
+     */
+    public void setWebSearchEngine(WebSearchEngine webSearchEngine) {
+        this.webSearchEngine = webSearchEngine;
+    }
+
+    public LangChain4jWebSearchResultType getResultType() {
+        return resultType;
+    }
+
+    /**
+     * The {@link #resultType} is the result type of the request. Valid values 
are
+     * LANGCHAIN4J_WEB_SEARCH_ORGANIC_RESULT, CONTENT, or SNIPPET. CONTENT is 
the default value; it will return a list
+     * of String . You can also specify to return either the Langchain4j Web 
Search Organic Result object (using
+     * `LANGCHAIN4J_WEB_SEARCH_ORGANIC_RESULT`) or snippet (using `SNIPPET`) 
for each result. If {@link #maxResults} is
+     * equal to 1, the response will be a single object instead of a list.
+     */
+    public void setResultType(LangChain4jWebSearchResultType resultType) {
+        this.resultType = resultType;
+    }
+
+    /**
+     * The {@link #maxResults} is the expected number of results to be found 
if the search request were made. Each
+     * search engine may have a different limit for the maximum number of 
results that can be returned.
+     *
+     * @return
+     */
+    public Integer getMaxResults() {
+        return maxResults;
+    }
+
+    public void setMaxResults(Integer maxResults) {
+        this.maxResults = maxResults;
+    }
+
+    /**
+     * The {@link #language} is the desired language for search results. The 
expected values may vary depending on the
+     * search engine.
+     *
+     * @return
+     */
+    public String getLanguage() {
+        return language;
+    }
+
+    public void setLanguage(String language) {
+        this.language = language;
+    }
+
+    public String getGeoLocation() {
+        return geoLocation;
+    }
+
+    /**
+     * The {@link #geoLocation} is the desired geolocation for search results. 
Each search engine may have a different
+     * set of supported geolocations.
+     */
+    public void setGeoLocation(String geoLocation) {
+        this.geoLocation = geoLocation;
+    }
+
+    public Integer getStartPage() {
+        return startPage;
+    }
+
+    /**
+     * The {@link #startPage} is the start page number for search results
+     */
+    public void setStartPage(Integer startPage) {
+        this.startPage = startPage;
+    }
+
+    public Integer getStartIndex() {
+        return startIndex;
+    }
+
+    /**
+     * The {@link #startIndex} is the start index for search results, which 
may vary depending on the search engine.
+     */
+    public void setStartIndex(Integer startIndex) {
+        this.startIndex = startIndex;
+    }
+
+    public Boolean getSafeSearch() {
+        return safeSearch;
+    }
+
+    /**
+     * The {@link #safeSearch} is the safe search flag, indicating whether to 
enable or disable safe search.
+     */
+    public void setSafeSearch(Boolean safeSearch) {
+        this.safeSearch = safeSearch;
+    }
+
+    public Map<String, Object> getAdditionalParams() {
+        return additionalParams;
+    }
+
+    /**
+     * The {@link #additionalParams} is the additional parameters for the 
search request are a map of key-value pairs
+     * that represent additional parameters for the search request.
+     */
+    public void setAdditionalParams(Map<String, Object> additionalParams) {
+        this.additionalParams = additionalParams;
+    }
+
+    public WebSearchRequest getWebSearchRequest() {
+        return webSearchRequest;
+    }
+
+    /**
+     * The {@link #webSearchRequest} is the custom WebSearchRequest - advanced
+     */
+    public void setWebSearchRequest(WebSearchRequest webSearchRequest) {
+        this.webSearchRequest = webSearchRequest;
+    }
+
+    public LangChain4jWebSearchConfiguration copy() {
+        try {
+            return (LangChain4jWebSearchConfiguration) super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new RuntimeCamelException(e);
+        }
+    }
+}
diff --git 
a/components/camel-ai/camel-langchain4j-web-search/src/main/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchEndpoint.java
 
b/components/camel-ai/camel-langchain4j-web-search/src/main/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchEndpoint.java
new file mode 100644
index 00000000000..ea3e75441a6
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-web-search/src/main/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchEndpoint.java
@@ -0,0 +1,76 @@
+/*
+ * 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 org.apache.camel.component.langchain4j.web.search;
+
+import org.apache.camel.Category;
+import org.apache.camel.Component;
+import org.apache.camel.Consumer;
+import org.apache.camel.Processor;
+import org.apache.camel.Producer;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.UriEndpoint;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriPath;
+import org.apache.camel.support.DefaultEndpoint;
+
+/**
+ * LangChain4j Web Search Engine
+ */
+@UriEndpoint(firstVersion = "4.8.0", scheme = 
LangChain4jWebSearchEngine.SCHEME, title = "LangChain4j Web Search",
+             syntax = "langchain4j-web-search:searchId", producerOnly = true, 
category = {
+                     Category.AI
+             }, headersClass = LangChain4jWebSearchEngine.Headers.class)
+public class LangChain4jWebSearchEndpoint extends DefaultEndpoint {
+
+    @Metadata(required = true)
+    @UriPath(description = "The id")
+    private final String searchId;
+
+    @UriParam
+    private LangChain4jWebSearchConfiguration configuration;
+
+    public LangChain4jWebSearchEndpoint(
+                                        String endpointUri,
+                                        Component component,
+                                        String searchId,
+                                        LangChain4jWebSearchConfiguration 
configuration) {
+
+        super(endpointUri, component);
+
+        this.searchId = searchId;
+        this.configuration = configuration;
+    }
+
+    public String getSearchId() {
+        return searchId;
+    }
+
+    public LangChain4jWebSearchConfiguration getConfiguration() {
+        return configuration;
+    }
+
+    @Override
+    public Producer createProducer() throws Exception {
+        return new LangChain4jWebSearchProducer(this);
+    }
+
+    @Override
+    public Consumer createConsumer(Processor processor) throws Exception {
+        throw new UnsupportedOperationException("Consumer is not implemented 
for this component");
+    }
+
+}
diff --git 
a/components/camel-ai/camel-langchain4j-web-search/src/main/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchEngine.java
 
b/components/camel-ai/camel-langchain4j-web-search/src/main/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchEngine.java
new file mode 100644
index 00000000000..a731fd8d74a
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-web-search/src/main/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchEngine.java
@@ -0,0 +1,26 @@
+/*
+ * 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 org.apache.camel.component.langchain4j.web.search;
+
+public class LangChain4jWebSearchEngine {
+    public static final String SCHEME = "langchain4j-web-search";
+
+    public static class Headers {
+
+    }
+
+}
diff --git 
a/components/camel-ai/camel-langchain4j-web-search/src/main/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchProducer.java
 
b/components/camel-ai/camel-langchain4j-web-search/src/main/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchProducer.java
new file mode 100644
index 00000000000..10d9242b3dd
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-web-search/src/main/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchProducer.java
@@ -0,0 +1,112 @@
+/*
+ * 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 org.apache.camel.component.langchain4j.web.search;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import dev.langchain4j.web.search.WebSearchEngine;
+import dev.langchain4j.web.search.WebSearchOrganicResult;
+import dev.langchain4j.web.search.WebSearchRequest;
+import dev.langchain4j.web.search.WebSearchResults;
+import org.apache.camel.Exchange;
+import org.apache.camel.support.DefaultProducer;
+import org.apache.camel.util.ObjectHelper;
+
+public class LangChain4jWebSearchProducer extends DefaultProducer {
+
+    private WebSearchEngine webSearchEngine;
+
+    public LangChain4jWebSearchProducer(LangChain4jWebSearchEndpoint endpoint) 
{
+        super(endpoint);
+    }
+
+    @Override
+    public LangChain4jWebSearchEndpoint getEndpoint() {
+        return (LangChain4jWebSearchEndpoint) super.getEndpoint();
+    }
+
+    @Override
+    public void process(Exchange exchange) throws Exception {
+        // check if there's a custom WebSearchRequest -- advanced
+        WebSearchRequest webSearchRequest = 
getEndpoint().getConfiguration().getWebSearchRequest();
+
+        // build a Web Search Request
+        if (webSearchRequest == null) {
+            final String searchTerms = 
exchange.getMessage().getMandatoryBody(String.class);
+            webSearchRequest = WebSearchRequest.builder()
+                    .searchTerms(searchTerms)
+                    
.maxResults(getEndpoint().getConfiguration().getMaxResults())
+                    .language(getEndpoint().getConfiguration().getLanguage())
+                    
.geoLocation(getEndpoint().getConfiguration().getGeoLocation())
+                    .startPage(getEndpoint().getConfiguration().getStartPage())
+                    
.startIndex(getEndpoint().getConfiguration().getStartIndex())
+                    
.additionalParams(getEndpoint().getConfiguration().getAdditionalParams())
+                    .build();
+        }
+
+        // perform the request
+        WebSearchResults webSearchResults = 
webSearchEngine.search(webSearchRequest);
+
+        // exrtact the list
+        List<WebSearchOrganicResult> resultList = webSearchResults.results();
+
+        // compute the response
+        computeResponse(resultList, exchange, webSearchRequest.maxResults());
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+        this.webSearchEngine = 
getEndpoint().getConfiguration().getWebSearchEngine();
+        ObjectHelper.notNull(webSearchEngine, "webSearchEngine");
+    }
+
+    /**
+     * Computes the response of the web search based on the configuration and 
input results.
+     *
+     * @param webSearchOrganicResults the list of WebSearchOrganicResult 
objects to process
+     * @param exchange                the Apache Camel Exchange object
+     * @param maxResults              maxResults
+     */
+    private void computeResponse(List<WebSearchOrganicResult> 
webSearchOrganicResults, Exchange exchange, Integer maxResults) {
+        // Check if the input list is null or empty and handle it gracefully
+        if (webSearchOrganicResults == null || 
webSearchOrganicResults.isEmpty()) {
+            exchange.getIn().setBody(null);
+            return;
+        }
+
+        // return a single object as a response
+        if (maxResults == 1) {
+            switch (getEndpoint().getConfiguration().getResultType()) {
+                case LANGCHAIN4J_WEB_SEARCH_ORGANIC_RESULT -> 
exchange.getIn().setBody(webSearchOrganicResults.get(0));
+                case CONTENT -> 
exchange.getIn().setBody(webSearchOrganicResults.get(0).content());
+                case SNIPPET -> 
exchange.getIn().setBody(webSearchOrganicResults.get(0).snippet());
+            }
+        } else { // return a List of Objects as a response
+            switch (getEndpoint().getConfiguration().getResultType()) {
+                case LANGCHAIN4J_WEB_SEARCH_ORGANIC_RESULT -> 
exchange.getIn().setBody(webSearchOrganicResults);
+                case CONTENT -> exchange.getIn()
+                        
.setBody(webSearchOrganicResults.stream().map(WebSearchOrganicResult::content)
+                                .collect(Collectors.toList()));
+                case SNIPPET -> exchange.getIn()
+                        
.setBody(webSearchOrganicResults.stream().map(WebSearchOrganicResult::snippet)
+                                .collect(Collectors.toList()));
+            }
+        }
+    }
+}
diff --git 
a/components/camel-ai/camel-langchain4j-web-search/src/main/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchResultType.java
 
b/components/camel-ai/camel-langchain4j-web-search/src/main/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchResultType.java
new file mode 100644
index 00000000000..4b4b9d2f595
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-web-search/src/main/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchResultType.java
@@ -0,0 +1,23 @@
+/*
+ * 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 org.apache.camel.component.langchain4j.web.search;
+
+public enum LangChain4jWebSearchResultType {
+    LANGCHAIN4J_WEB_SEARCH_ORGANIC_RESULT,
+    CONTENT,
+    SNIPPET
+}
diff --git 
a/components/camel-ai/camel-langchain4j-web-search/src/test/java/org/apache/camel/component/langchain4j/web/search/LangChain4jGoogleWebSearchEngineIT.java
 
b/components/camel-ai/camel-langchain4j-web-search/src/test/java/org/apache/camel/component/langchain4j/web/search/LangChain4jGoogleWebSearchEngineIT.java
new file mode 100644
index 00000000000..594ce4ffd8c
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-web-search/src/test/java/org/apache/camel/component/langchain4j/web/search/LangChain4jGoogleWebSearchEngineIT.java
@@ -0,0 +1,90 @@
+/*
+ * 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 org.apache.camel.component.langchain4j.web.search;
+
+import java.util.List;
+
+import dev.langchain4j.web.search.WebSearchEngine;
+import dev.langchain4j.web.search.WebSearchRequest;
+import 
dev.langchain4j.web.search.google.customsearch.GoogleCustomWebSearchEngine;
+import org.apache.camel.BindToRegistry;
+import org.apache.camel.Exchange;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
+
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+// Instruction to generate one 
https://developers.google.com/custom-search/v1/overview
+@EnabledIfEnvironmentVariable(named = "GOOGLE_API_KEY", matches = ".*")
+// Instructions to create a Google search engine 
https://developers.google.com/custom-search/docs/tutorial/creatingcse
+@EnabledIfEnvironmentVariable(named = "GOOGLE_SEARCH_ENGINE_ID", matches = 
".*")
+public class LangChain4jGoogleWebSearchEngineIT extends CamelTestSupport {
+    public static final String WEB_SEARCH_URI = 
"langchain4j-web-search:googleTest";
+
+    @BindToRegistry("web-search-engine")
+    WebSearchEngine googleSearchEngine = GoogleCustomWebSearchEngine.builder()
+            .apiKey(System.getenv("GOOGLE_API_KEY"))
+            .csi(System.getenv("GOOGLE_SEARCH_ENGINE_ID"))
+            .logRequests(true)
+            .logResponses(true)
+            .build();
+
+    @BindToRegistry("web-search-request")
+    WebSearchRequest request = WebSearchRequest.builder()
+            .searchTerms("Who won the European Cup in 2024?")
+            .maxResults(2)
+            .build();
+
+    @Test
+    void testSimpleSearch() {
+        String uri = String.format("%s?resultType=%s", WEB_SEARCH_URI, 
LangChain4jWebSearchResultType.SNIPPET);
+        Exchange result = fluentTemplate.to(uri)
+                .withBody("Who won the European Cup in 2024?")
+                .request(Exchange.class);
+
+        assertNotNull(result, "An Exchange is expected.");
+
+        String organicResult = result.getIn().getBody(String.class);
+        assertNotNull(organicResult, "For this web search a snippet value is 
expected as a String.");
+    }
+
+    @Test
+    void testSearchWithParams() {
+        String uri = 
String.format("%s?maxResults=2&language=fr&resultType=%s", WEB_SEARCH_URI,
+                LangChain4jWebSearchResultType.SNIPPET);
+
+        Exchange result = fluentTemplate.to(uri)
+                .withBody("Qui a gagné la coupe d'Europe en 2024?")
+                .request(Exchange.class);
+
+        assertNotNull(result, "An Exchange is expected.");
+
+        List<String> listResult = result.getIn().getBody(List.class);
+        assertNotNull(listResult, "The list results from the Google Search 
Engine shouldn't be null.");
+        assertNotEquals(0, listResult.get(0),
+                "The list results from the Google Search Engine shouldn't be 
empty. It's the value of the snippet as a Strng");
+    }
+
+    @Test
+    void advancedRequestTest() {
+        List<String> response = template.requestBody(WEB_SEARCH_URI, null, 
List.class);
+        assertNotNull(response, "An Exchange is expected.");
+        assertNotEquals(0, response.get(0), "The list results from the Google 
Search Engine shouldn't be empty.");
+    }
+}
diff --git 
a/components/camel-ai/camel-langchain4j-web-search/src/test/java/org/apache/camel/component/langchain4j/web/search/LangChain4jTavilyWebSearchEngineIT.java
 
b/components/camel-ai/camel-langchain4j-web-search/src/test/java/org/apache/camel/component/langchain4j/web/search/LangChain4jTavilyWebSearchEngineIT.java
new file mode 100644
index 00000000000..1dc93f532a8
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-web-search/src/test/java/org/apache/camel/component/langchain4j/web/search/LangChain4jTavilyWebSearchEngineIT.java
@@ -0,0 +1,88 @@
+/*
+ * 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 org.apache.camel.component.langchain4j.web.search;
+
+import java.util.List;
+
+import dev.langchain4j.web.search.WebSearchEngine;
+import dev.langchain4j.web.search.WebSearchOrganicResult;
+import dev.langchain4j.web.search.WebSearchRequest;
+import dev.langchain4j.web.search.tavily.TavilyWebSearchEngine;
+import org.apache.camel.BindToRegistry;
+import org.apache.camel.Exchange;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
+
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+// Get an API key at https://app.tavily.com/
+@EnabledIfEnvironmentVariable(named = "TAVILY_API_KEY", matches = ".*")
+public class LangChain4jTavilyWebSearchEngineIT extends CamelTestSupport {
+    public static final String WEB_SEARCH_URI = 
"langchain4j-web-search:tavilyTest";
+
+    @BindToRegistry("web-search-engine")
+    WebSearchEngine tavilyWebSearchEngine = TavilyWebSearchEngine.builder()
+            .apiKey(System.getenv("TAVILY_API_KEY"))
+            .includeRawContent(true)
+            .build();
+
+    @BindToRegistry("web-search-request")
+    WebSearchRequest request = WebSearchRequest.builder()
+            .searchTerms("Who won the European Cup in 2024?")
+            .maxResults(2)
+            .build();
+
+    @Test
+    void testSimpleSearch() {
+        Exchange result = fluentTemplate.to(WEB_SEARCH_URI)
+                .withBody("Who won the European Cup in 2024?")
+                .request(Exchange.class);
+
+        assertNotNull(result, "An Exchange is expected.");
+
+        String organicResult = result.getIn().getBody(String.class);
+        assertNotNull(organicResult, "For this web search a content value is 
expected as a String.");
+    }
+
+    @Test
+    void testSearchWithParams() {
+        String uri = String.format("%s?maxResults=2&resultType=%s", 
WEB_SEARCH_URI,
+                
LangChain4jWebSearchResultType.LANGCHAIN4J_WEB_SEARCH_ORGANIC_RESULT);
+
+        Exchange result = fluentTemplate.to(uri)
+                .withBody("Who won the European Cup in 2024?")
+                .request(Exchange.class);
+
+        assertNotNull(result, "An Exchange is expected.");
+
+        List<WebSearchOrganicResult> listResult = 
result.getIn().getBody(List.class);
+        assertNotNull(listResult, "The list results from the Tavily Search 
Engine shouldn't be null.");
+        assertNotEquals(0, listResult.get(0), "The list results from the 
Tavily Search Engine shouldn't be empty.");
+        assertNotNull(listResult.get(0).content(), "The first result from the 
Tavily Search Engine should contain content.");
+
+    }
+
+    @Test
+    void advancedRequestTest() {
+        List<String> response = template.requestBody(WEB_SEARCH_URI, null, 
List.class);
+        assertNotNull(response, "An Exchange is expected.");
+        assertNotEquals(0, response.get(0), "The list results from the Tavily 
Search Engine shouldn't be empty.");
+    }
+
+}
diff --git a/components/camel-ai/pom.xml b/components/camel-ai/pom.xml
index ada306d3cfe..30b7d33fa74 100644
--- a/components/camel-ai/pom.xml
+++ b/components/camel-ai/pom.xml
@@ -39,6 +39,7 @@
         <module>camel-langchain4j-core</module>
         <module>camel-langchain4j-chat</module>
         <module>camel-langchain4j-embeddings</module>
+        <module>camel-langchain4j-web-search</module>
         <module>camel-milvus</module>
         <module>camel-pinecone</module>
         <module>camel-qdrant</module>
diff --git 
a/docs/components/modules/ROOT/examples/json/langchain4j-web-search.json 
b/docs/components/modules/ROOT/examples/json/langchain4j-web-search.json
new file mode 120000
index 00000000000..ce0432d6b37
--- /dev/null
+++ b/docs/components/modules/ROOT/examples/json/langchain4j-web-search.json
@@ -0,0 +1 @@
+../../../../../../components/camel-ai/camel-langchain4j-web-search/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/web/search/langchain4j-web-search.json
\ No newline at end of file
diff --git a/docs/components/modules/ROOT/nav.adoc 
b/docs/components/modules/ROOT/nav.adoc
index b6ca855b85d..17470b8cf78 100644
--- a/docs/components/modules/ROOT/nav.adoc
+++ b/docs/components/modules/ROOT/nav.adoc
@@ -9,6 +9,7 @@
 *** xref:djl-component.adoc[Deep Java Library]
 *** xref:langchain4j-chat-component.adoc[langChain4j Chat]
 *** xref:langchain4j-embeddings-component.adoc[LangChain4j Embeddings]
+*** xref:langchain4j-web-search-component.adoc[LangChain4j Web Search]
 *** xref:milvus-component.adoc[Milvus]
 *** xref:pinecone-component.adoc[Pinecone]
 *** xref:qdrant-component.adoc[Qdrant]
diff --git 
a/docs/components/modules/ROOT/pages/langchain4j-web-search-component.adoc 
b/docs/components/modules/ROOT/pages/langchain4j-web-search-component.adoc
new file mode 120000
index 00000000000..c8328e90e3d
--- /dev/null
+++ b/docs/components/modules/ROOT/pages/langchain4j-web-search-component.adoc
@@ -0,0 +1 @@
+../../../../../components/camel-ai/camel-langchain4j-web-search/src/main/docs/langchain4j-web-search-component.adoc
\ No newline at end of file
diff --git a/parent/pom.xml b/parent/pom.xml
index 7949383e746..5f0dad26113 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -1743,6 +1743,11 @@
                 <artifactId>camel-langchain4j-embeddings</artifactId>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>org.apache.camel</groupId>
+                <artifactId>camel-langchain4j-web-search</artifactId>
+                <version>${project.version}</version>
+            </dependency>
             <dependency>
                 <groupId>org.apache.camel</groupId>
                 <artifactId>camel-language</artifactId>

Reply via email to