This is an automated email from the ASF dual-hosted git repository. lburgazzoli 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 a58b929167f Create a langchain4j-core module a58b929167f is described below commit a58b929167fa55ceced2a20f4d8b4163485f6eba Author: Luca Burgazzoli <lburgazz...@gmail.com> AuthorDate: Mon May 27 19:01:41 2024 +0200 Create a langchain4j-core module --- bom/camel-bom/pom.xml | 5 ++ catalog/camel-allcomponents/pom.xml | 5 ++ components/camel-ai/camel-langchain4j-chat/pom.xml | 5 +- .../pom.xml | 35 +++++------ .../core/LangChain4jConverterLoader.java | 54 +++++++++++++++++ .../services/org/apache/camel/TypeConverterLoader | 2 + .../services/org/apache/camel/other.properties | 7 +++ .../src/generated/resources/langchain4j-core.json | 15 +++++ .../component/langchain4j/core/LangChain4j.java | 25 ++++++++ .../langchain4j/core/LangChain4jConverter.java | 67 ++++++++++++++++++++++ .../langchain4j/core/LangChain4jConverterTest.java | 51 ++++++++++++++++ .../src/test/resources/log4j2.properties | 35 +++++++++++ .../camel-ai/camel-langchain4j-embeddings/pom.xml | 5 +- components/camel-ai/pom.xml | 1 + .../others/examples/json/langchain4j-core.json | 1 + parent/pom.xml | 5 ++ 16 files changed, 296 insertions(+), 22 deletions(-) diff --git a/bom/camel-bom/pom.xml b/bom/camel-bom/pom.xml index e62328dcf25..a250592fbbd 100644 --- a/bom/camel-bom/pom.xml +++ b/bom/camel-bom/pom.xml @@ -1297,6 +1297,11 @@ <artifactId>camel-langchain4j-chat</artifactId> <version>4.7.0-SNAPSHOT</version> </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-langchain4j-core</artifactId> + <version>4.7.0-SNAPSHOT</version> + </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-langchain4j-embeddings</artifactId> diff --git a/catalog/camel-allcomponents/pom.xml b/catalog/camel-allcomponents/pom.xml index 2dfc5615942..daf1adf8836 100644 --- a/catalog/camel-allcomponents/pom.xml +++ b/catalog/camel-allcomponents/pom.xml @@ -1107,6 +1107,11 @@ <artifactId>camel-langchain4j-chat</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-langchain4j-core</artifactId> + <version>${project.version}</version> + </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-langchain4j-embeddings</artifactId> diff --git a/components/camel-ai/camel-langchain4j-chat/pom.xml b/components/camel-ai/camel-langchain4j-chat/pom.xml index a5ac9a1ba94..604500a8feb 100644 --- a/components/camel-ai/camel-langchain4j-chat/pom.xml +++ b/components/camel-ai/camel-langchain4j-chat/pom.xml @@ -40,9 +40,8 @@ <artifactId>camel-support</artifactId> </dependency> <dependency> - <groupId>dev.langchain4j</groupId> - <artifactId>langchain4j</artifactId> - <version>${langchain4j-version}</version> + <groupId>org.apache.camel</groupId> + <artifactId>camel-langchain4j-core</artifactId> </dependency> <!-- for testing --> diff --git a/components/camel-ai/camel-langchain4j-chat/pom.xml b/components/camel-ai/camel-langchain4j-core/pom.xml similarity index 72% copy from components/camel-ai/camel-langchain4j-chat/pom.xml copy to components/camel-ai/camel-langchain4j-core/pom.xml index a5ac9a1ba94..734bf4b554b 100644 --- a/components/camel-ai/camel-langchain4j-chat/pom.xml +++ b/components/camel-ai/camel-langchain4j-core/pom.xml @@ -28,43 +28,46 @@ <version>4.7.0-SNAPSHOT</version> </parent> - <artifactId>camel-langchain4j-chat</artifactId> + <artifactId>camel-langchain4j-core</artifactId> <packaging>jar</packaging> - <name>Camel :: LangChain4j :: Chat</name> - <description>LangChain4j Chat component</description> + <name>Camel :: LangChain4j :: Core</name> + <description>LangChain4j Core</description> - <dependencies> + <properties> + <firstVersion>4.7.0</firstVersion> + <label>ai</label> + <title>LangChain4j Core</title> + <supportLevel>Experimental</supportLevel> + </properties> + <dependencies> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-support</artifactId> </dependency> <dependency> <groupId>dev.langchain4j</groupId> - <artifactId>langchain4j</artifactId> + <artifactId>langchain4j-core</artifactId> <version>${langchain4j-version}</version> </dependency> - <!-- for testing --> + + <!-- test --> <dependency> <groupId>org.apache.camel</groupId> - <artifactId>camel-test-spring-junit5</artifactId> + <artifactId>camel-test-junit5</artifactId> <scope>test</scope> </dependency> <dependency> - <groupId>dev.langchain4j</groupId> - <artifactId>langchain4j-ollama</artifactId> - <version>${langchain4j-version}</version> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> <scope>test</scope> </dependency> <dependency> - <groupId>org.apache.camel</groupId> - <artifactId>camel-test-infra-ollama</artifactId> - <version>${project.version}</version> - <type>test-jar</type> + <groupId>org.assertj</groupId> + <artifactId>assertj-core</artifactId> + <version>${assertj-version}</version> <scope>test</scope> </dependency> - </dependencies> - </project> diff --git a/components/camel-ai/camel-langchain4j-core/src/generated/java/org/apache/camel/component/langchain4j/core/LangChain4jConverterLoader.java b/components/camel-ai/camel-langchain4j-core/src/generated/java/org/apache/camel/component/langchain4j/core/LangChain4jConverterLoader.java new file mode 100644 index 00000000000..ee39897cdc5 --- /dev/null +++ b/components/camel-ai/camel-langchain4j-core/src/generated/java/org/apache/camel/component/langchain4j/core/LangChain4jConverterLoader.java @@ -0,0 +1,54 @@ +/* Generated by camel build tools - do NOT edit this file! */ +package org.apache.camel.component.langchain4j.core; + +import javax.annotation.processing.Generated; + +import org.apache.camel.CamelContext; +import org.apache.camel.CamelContextAware; +import org.apache.camel.DeferredContextBinding; +import org.apache.camel.Exchange; +import org.apache.camel.TypeConversionException; +import org.apache.camel.TypeConverterLoaderException; +import org.apache.camel.spi.TypeConverterLoader; +import org.apache.camel.spi.TypeConverterRegistry; +import org.apache.camel.support.SimpleTypeConverter; +import org.apache.camel.support.TypeConverterSupport; +import org.apache.camel.util.DoubleMap; + +/** + * Generated by camel build tools - do NOT edit this file! + */ +@Generated("org.apache.camel.maven.packaging.TypeConverterLoaderGeneratorMojo") +@SuppressWarnings("unchecked") +@DeferredContextBinding +public final class LangChain4jConverterLoader implements TypeConverterLoader, CamelContextAware { + + private CamelContext camelContext; + + public LangChain4jConverterLoader() { + } + + @Override + public void setCamelContext(CamelContext camelContext) { + this.camelContext = camelContext; + } + + @Override + public CamelContext getCamelContext() { + return camelContext; + } + + @Override + public void load(TypeConverterRegistry registry) throws TypeConverterLoaderException { + registerConverters(registry); + } + + private void registerConverters(TypeConverterRegistry registry) { + addTypeConverter(registry, dev.langchain4j.data.document.Document.class, java.lang.String.class, false, + (type, exchange, value) -> org.apache.camel.component.langchain4j.core.LangChain4jConverter.toDocument((java.lang.String) value, exchange)); + } + + private static void addTypeConverter(TypeConverterRegistry registry, Class<?> toType, Class<?> fromType, boolean allowNull, SimpleTypeConverter.ConversionMethod method) { + registry.addTypeConverter(toType, fromType, new SimpleTypeConverter(allowNull, method)); + } +} diff --git a/components/camel-ai/camel-langchain4j-core/src/generated/resources/META-INF/services/org/apache/camel/TypeConverterLoader b/components/camel-ai/camel-langchain4j-core/src/generated/resources/META-INF/services/org/apache/camel/TypeConverterLoader new file mode 100644 index 00000000000..37d8e16ece7 --- /dev/null +++ b/components/camel-ai/camel-langchain4j-core/src/generated/resources/META-INF/services/org/apache/camel/TypeConverterLoader @@ -0,0 +1,2 @@ +# Generated by camel build tools - do NOT edit this file! +org.apache.camel.component.langchain4j.core.LangChain4jConverterLoader diff --git a/components/camel-ai/camel-langchain4j-core/src/generated/resources/META-INF/services/org/apache/camel/other.properties b/components/camel-ai/camel-langchain4j-core/src/generated/resources/META-INF/services/org/apache/camel/other.properties new file mode 100644 index 00000000000..e9d95a2b607 --- /dev/null +++ b/components/camel-ai/camel-langchain4j-core/src/generated/resources/META-INF/services/org/apache/camel/other.properties @@ -0,0 +1,7 @@ +# Generated by camel build tools - do NOT edit this file! +name=langchain4j-core +groupId=org.apache.camel +artifactId=camel-langchain4j-core +version=4.7.0-SNAPSHOT +projectName=Camel :: LangChain4j :: Core +projectDescription=LangChain4j Core diff --git a/components/camel-ai/camel-langchain4j-core/src/generated/resources/langchain4j-core.json b/components/camel-ai/camel-langchain4j-core/src/generated/resources/langchain4j-core.json new file mode 100644 index 00000000000..1846eaa6c0f --- /dev/null +++ b/components/camel-ai/camel-langchain4j-core/src/generated/resources/langchain4j-core.json @@ -0,0 +1,15 @@ +{ + "other": { + "kind": "other", + "name": "langchain4j-core", + "title": "LangChain4j Core", + "description": "LangChain4j Core", + "deprecated": false, + "firstVersion": "4.7.0", + "label": "ai", + "supportLevel": "Experimental", + "groupId": "org.apache.camel", + "artifactId": "camel-langchain4j-core", + "version": "4.7.0-SNAPSHOT" + } +} diff --git a/components/camel-ai/camel-langchain4j-core/src/main/java/org/apache/camel/component/langchain4j/core/LangChain4j.java b/components/camel-ai/camel-langchain4j-core/src/main/java/org/apache/camel/component/langchain4j/core/LangChain4j.java new file mode 100644 index 00000000000..1409cefc214 --- /dev/null +++ b/components/camel-ai/camel-langchain4j-core/src/main/java/org/apache/camel/component/langchain4j/core/LangChain4j.java @@ -0,0 +1,25 @@ +/* + * 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.core; + +public final class LangChain4j { + public static final String METADATA_PREFIX = "langchain4j.metadata."; + public static final int METADATA_PREFIX_LEN = METADATA_PREFIX.length(); + + private LangChain4j() { + } +} diff --git a/components/camel-ai/camel-langchain4j-core/src/main/java/org/apache/camel/component/langchain4j/core/LangChain4jConverter.java b/components/camel-ai/camel-langchain4j-core/src/main/java/org/apache/camel/component/langchain4j/core/LangChain4jConverter.java new file mode 100644 index 00000000000..59ce0de10d3 --- /dev/null +++ b/components/camel-ai/camel-langchain4j-core/src/main/java/org/apache/camel/component/langchain4j/core/LangChain4jConverter.java @@ -0,0 +1,67 @@ +/* + * 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.core; + +import java.util.HashMap; +import java.util.Map; + +import dev.langchain4j.data.document.Document; +import dev.langchain4j.data.document.Metadata; +import org.apache.camel.Converter; +import org.apache.camel.Exchange; + +/** + * Converter methods to convert from / to LangChain4j types. + */ +@Converter(generateLoader = true) +public class LangChain4jConverter { + + @Converter + public static Document toDocument(String value, Exchange exchange) { + return Document.document( + value, + toMetadata(exchange)); + } + + private static Metadata toMetadata(Exchange exchange) { + if (exchange == null) { + return new Metadata(); + } + if (exchange.getMessage() == null) { + return new Metadata(); + } + + Map<String, Object> metadata = null; + Map<String, Object> headers = exchange.getMessage().getHeaders(); + + for (Map.Entry<String, Object> entry : headers.entrySet()) { + if (!entry.getKey().startsWith(LangChain4j.METADATA_PREFIX)) { + continue; + } + + if (metadata == null) { + metadata = new HashMap<>(); + } + + metadata.put( + entry.getKey().substring(LangChain4j.METADATA_PREFIX_LEN), + entry.getValue()); + } + + return metadata != null ? Metadata.from(metadata) : new Metadata(); + } +} diff --git a/components/camel-ai/camel-langchain4j-core/src/test/java/org/apache/camel/component/langchain4j/core/LangChain4jConverterTest.java b/components/camel-ai/camel-langchain4j-core/src/test/java/org/apache/camel/component/langchain4j/core/LangChain4jConverterTest.java new file mode 100644 index 00000000000..68c071b9f1c --- /dev/null +++ b/components/camel-ai/camel-langchain4j-core/src/test/java/org/apache/camel/component/langchain4j/core/LangChain4jConverterTest.java @@ -0,0 +1,51 @@ +/* + * 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.core; + +import dev.langchain4j.data.document.Document; +import org.apache.camel.Exchange; +import org.apache.camel.NoTypeConversionAvailableException; +import org.apache.camel.support.DefaultExchange; +import org.apache.camel.test.junit5.CamelTestSupport; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class LangChain4jConverterTest extends CamelTestSupport { + + @Test + public void testConverter() throws NoTypeConversionAvailableException { + Document doc = context.getTypeConverter().mandatoryConvertTo(Document.class, "foo"); + assertThat(doc.text()).isEqualTo("foo"); + + Exchange exchange = new DefaultExchange(context); + exchange.getMessage().setHeader(LangChain4j.METADATA_PREFIX + "meta1", 1); + exchange.getMessage().setHeader(LangChain4j.METADATA_PREFIX + "meta2", "baz"); + exchange.getMessage().setHeader("meta3", "ignored"); + + Document docWithMetadata = context.getTypeConverter().mandatoryConvertTo( + Document.class, + exchange, + "bar"); + + assertThat(docWithMetadata.text()).isEqualTo("bar"); + assertThat(docWithMetadata.metadata().toMap()) + .containsEntry("meta1", 1) + .containsEntry("meta2", "baz") + .doesNotContainKey("meta3"); + } +} diff --git a/components/camel-ai/camel-langchain4j-core/src/test/resources/log4j2.properties b/components/camel-ai/camel-langchain4j-core/src/test/resources/log4j2.properties new file mode 100644 index 00000000000..7fad857f000 --- /dev/null +++ b/components/camel-ai/camel-langchain4j-core/src/test/resources/log4j2.properties @@ -0,0 +1,35 @@ +## --------------------------------------------------------------------------- +## 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. +## --------------------------------------------------------------------------- + +appender.file.type = File +appender.file.name = file +appender.file.fileName = target/camel-langchain4j-core-test.log +appender.file.layout.type = PatternLayout +appender.file.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n + +appender.out.type = Console +appender.out.name = out +appender.out.layout.type = PatternLayout +appender.out.layout.pattern = [%30.30t] %-30.30c{1} %-5p %m%n + +rootLogger.level = INFO +rootLogger.appenderRef.file.ref = file +# To log to stdout +#rootLogger.appenderRef.out.ref = out + +logger.camel-langchain4j-core.name = org.apache.camel.component.langchain4j.core +logger.camel-langchain4j-core.level = DEBUG diff --git a/components/camel-ai/camel-langchain4j-embeddings/pom.xml b/components/camel-ai/camel-langchain4j-embeddings/pom.xml index 88e4a6f1f84..1c2a71b9007 100644 --- a/components/camel-ai/camel-langchain4j-embeddings/pom.xml +++ b/components/camel-ai/camel-langchain4j-embeddings/pom.xml @@ -48,9 +48,8 @@ <artifactId>camel-support</artifactId> </dependency> <dependency> - <groupId>dev.langchain4j</groupId> - <artifactId>langchain4j-core</artifactId> - <version>${langchain4j-version}</version> + <groupId>org.apache.camel</groupId> + <artifactId>camel-langchain4j-core</artifactId> </dependency> <!-- test dependencies --> diff --git a/components/camel-ai/pom.xml b/components/camel-ai/pom.xml index 57c625d53e3..c5804547095 100644 --- a/components/camel-ai/pom.xml +++ b/components/camel-ai/pom.xml @@ -36,6 +36,7 @@ <modules> <module>camel-chatscript</module> <module>camel-djl</module> + <module>camel-langchain4j-core</module> <module>camel-langchain4j-chat</module> <module>camel-langchain4j-embeddings</module> </modules> diff --git a/docs/components/modules/others/examples/json/langchain4j-core.json b/docs/components/modules/others/examples/json/langchain4j-core.json new file mode 120000 index 00000000000..49f0f1d8d08 --- /dev/null +++ b/docs/components/modules/others/examples/json/langchain4j-core.json @@ -0,0 +1 @@ +../../../../../../components/camel-ai/camel-langchain4j-core/src/generated/resources/langchain4j-core.json \ No newline at end of file diff --git a/parent/pom.xml b/parent/pom.xml index ff989fea5c8..e4df94274e6 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -1724,6 +1724,11 @@ <artifactId>camel-langchain4j-chat</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-langchain4j-core</artifactId> + <version>${project.version}</version> + </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-langchain4j-embeddings</artifactId>