graal: cleanup (#297)
This commit is contained in:
parent
949bc25f63
commit
ba7fabaa50
|
@ -14,8 +14,8 @@ jobs:
|
|||
java-version: '8'
|
||||
distribution: 'temurin'
|
||||
cache: 'maven'
|
||||
- name: Build with JDK 8 (excluding modules requiring JDK 11)
|
||||
run: mvn --batch-mode install -DskipITs -pl !langchain4j-opensearch
|
||||
- name: Build with JDK 8 (excluding modules requiring JDK 11 and 17)
|
||||
run: mvn --batch-mode install -DskipITs -pl !langchain4j-opensearch,!langchain4j-graal
|
||||
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v3
|
||||
|
@ -26,6 +26,15 @@ jobs:
|
|||
- name: Build modules requiring JDK 11
|
||||
run: mvn --batch-mode install -DskipITs -pl langchain4j-opensearch
|
||||
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'temurin'
|
||||
cache: 'maven'
|
||||
- name: Build modules requiring JDK 17
|
||||
run: mvn --batch-mode install -DskipITs -pl langchain4j-graal
|
||||
|
||||
# For checking some compliance things (require a recent JDK due to plugins so in a separate step)
|
||||
compliance:
|
||||
runs-on: ubuntu-latest
|
||||
|
|
|
@ -14,22 +14,23 @@
|
|||
<packaging>pom</packaging>
|
||||
|
||||
<name>LangChain4j BOM</name>
|
||||
<description>Bill of Materials pom for getting full, complete set of compatible versions
|
||||
of LangChain4j components
|
||||
</description>
|
||||
<description>Bill of Materials POM for getting full, complete set of compatible versions of LangChain4j modules</description>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-spring-boot-starter</artifactId>
|
||||
|
@ -37,41 +38,49 @@
|
|||
</dependency>
|
||||
|
||||
<!-- model providers -->
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-open-ai</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-azure-open-ai</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-hugging-face</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-local-ai</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-vertex-ai</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-dashscope</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-ollama</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-bedrock</artifactId>
|
||||
|
@ -79,56 +88,75 @@
|
|||
</dependency>
|
||||
|
||||
<!-- embedding stores -->
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-cassandra</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-chroma</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-elasticsearch</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-milvus</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-opensearch</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-pinecone</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-redis</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-vespa</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-weaviate</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-pgvector</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-pinecone</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-redis</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-vespa</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-weaviate</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- other -->
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-graal</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
|
|
@ -7,43 +7,47 @@
|
|||
<parent>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-parent</artifactId>
|
||||
<version>0.23.0</version>
|
||||
<version>0.24.0</version>
|
||||
<relativePath>../langchain4j-parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
|
||||
<artifactId>langchain4j-graal</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>LangChain4j integration with Graal JDK</name>
|
||||
|
||||
<name>LangChain4j integration with GraalVM Polyglot/Truffle</name>
|
||||
<description>Implementation of JavaScript and Python code execution tools using GraalVM Polyglot/Truffle</description>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<graalvm.version>23.1.1</graalvm.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-core</artifactId>
|
||||
<version>0.23.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.graalvm.polyglot</groupId>
|
||||
<artifactId>polyglot</artifactId>
|
||||
<version>23.1.0</version>
|
||||
<version>${graalvm.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.graalvm.polyglot</groupId>
|
||||
<artifactId>js</artifactId>
|
||||
<version>23.1.0</version>
|
||||
<version>${graalvm.version}</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.graalvm.polyglot</groupId>
|
||||
<artifactId>python</artifactId>
|
||||
<version>23.1.0</version>
|
||||
<version>${graalvm.version}</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
|
||||
|
@ -66,17 +70,42 @@
|
|||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j</artifactId>
|
||||
<version>${parent.version}</version>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-junit-jupiter</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-open-ai</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.honton.chas</groupId>
|
||||
<artifactId>license-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<!-- org.graalvm.polyglot has a UPL-1 license -->
|
||||
<skipCompliance>true</skipCompliance>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -1,40 +0,0 @@
|
|||
package dev.langchain4j.agen.tool.graal;
|
||||
|
||||
import dev.langchain4j.agent.tool.P;
|
||||
import dev.langchain4j.agent.tool.Tool;
|
||||
import org.graalvm.polyglot.Context;
|
||||
import org.graalvm.polyglot.HostAccess;
|
||||
import org.graalvm.polyglot.SandboxPolicy;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
/**
|
||||
* A tool that executes JS code using Graal JS
|
||||
*/
|
||||
public class GraalJavascriptExecutionTool {
|
||||
|
||||
|
||||
@Tool("You are an agent designed to write and execute javascript code to answer questions.\n" +
|
||||
"You have access to a javascript REPL, which you can use to execute js code.\n" +
|
||||
"If you get an error, debug your code and try again.\n" +
|
||||
"Only use the output of your code to answer the question. \n" +
|
||||
"You might know the answer without running any code, but you should still run the code to get the answer.\n" +
|
||||
"If it does not seem like you can write code to answer the question, just return \"I don't know\" as the answer")
|
||||
public String executeJavaScriptCode(
|
||||
@P("JavaScript code to execute, result MUST be returned by the code")
|
||||
String javaScriptCode
|
||||
) {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
ByteArrayOutputStream err = new ByteArrayOutputStream();
|
||||
|
||||
// GraalVM community edition supports only sandbox policy TRUSTED or CONSTRAINED.
|
||||
try (Context context = Context.newBuilder("js")
|
||||
.sandbox(SandboxPolicy.CONSTRAINED)
|
||||
.allowHostAccess(HostAccess.UNTRUSTED)
|
||||
.out(new ByteArrayOutputStream())
|
||||
.err(new ByteArrayOutputStream())
|
||||
.build()) {
|
||||
return String.valueOf(context.eval("js", javaScriptCode).as(Object.class));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
package dev.langchain4j.agen.tool.graal;
|
||||
|
||||
import dev.langchain4j.agent.tool.P;
|
||||
import dev.langchain4j.agent.tool.Tool;
|
||||
import org.graalvm.polyglot.Context;
|
||||
import org.graalvm.polyglot.HostAccess;
|
||||
import org.graalvm.polyglot.SandboxPolicy;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
/**
|
||||
* A tool that executes Python code using GraalPython
|
||||
*/
|
||||
public class GraalPythonExecutionTool {
|
||||
|
||||
|
||||
@Tool("You are an agent designed to write and execute python code to answer questions.\n" +
|
||||
"You have access to a python REPL, which you can use to execute python code.\n" +
|
||||
"If you get an error, debug your code and try again.\n" +
|
||||
"Only use the output of your code to answer the question. \n" +
|
||||
"You might know the answer without running any code, but you should still run the code to get the answer.\n" +
|
||||
"If it does not seem like you can write code to answer the question, just return \"I don't know\" as the answer")
|
||||
public String executePythonCode(
|
||||
@P("Python code to execute, result MUST be returned by the code")
|
||||
String pythonCode
|
||||
) {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
ByteArrayOutputStream err = new ByteArrayOutputStream();
|
||||
|
||||
// The language python can only be used up to the TRUSTED sandbox policy.
|
||||
try (Context context = Context.
|
||||
newBuilder("python")
|
||||
.sandbox(SandboxPolicy.CONSTRAINED)
|
||||
.out(out)
|
||||
.err(err)
|
||||
.allowHostAccess(HostAccess.UNTRUSTED)
|
||||
.build())
|
||||
{
|
||||
return String.valueOf(context.eval("python", pythonCode).as(Object.class));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package dev.langchain4j.agent.tool.graal;
|
||||
|
||||
import dev.langchain4j.agent.tool.P;
|
||||
import dev.langchain4j.agent.tool.Tool;
|
||||
import dev.langchain4j.code.CodeExecutionEngine;
|
||||
import dev.langchain4j.code.graal.GraalJavaScriptExecutionEngine;
|
||||
|
||||
/**
|
||||
* A tool that executes provided JavaScript code using GraalVM Polyglot/Truffle.
|
||||
* Attention! It might be dangerous to execute the code, see {@link GraalJavaScriptExecutionEngine} for more details.
|
||||
*/
|
||||
public class GraalJavaScriptExecutionTool {
|
||||
|
||||
private final CodeExecutionEngine engine = new GraalJavaScriptExecutionEngine();
|
||||
|
||||
@Tool("MUST be used for accurate calculations: math, sorting, filtering, aggregating, string processing, etc")
|
||||
public String executeJavaScriptCode(@P("JavaScript code to execute, result MUST be returned by the code") String code) {
|
||||
return engine.execute(code);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package dev.langchain4j.agent.tool.graal;
|
||||
|
||||
import dev.langchain4j.agent.tool.P;
|
||||
import dev.langchain4j.agent.tool.Tool;
|
||||
import dev.langchain4j.code.CodeExecutionEngine;
|
||||
import dev.langchain4j.code.graal.GraalPythonExecutionEngine;
|
||||
|
||||
/**
|
||||
* A tool that executes provided Python code using GraalVM Polyglot/Truffle.
|
||||
* Attention! It might be dangerous to execute the code, see {@link GraalPythonExecutionEngine} for more details.
|
||||
*/
|
||||
public class GraalPythonExecutionTool {
|
||||
|
||||
private final CodeExecutionEngine engine = new GraalPythonExecutionEngine();
|
||||
|
||||
@Tool("MUST be used for accurate calculations: math, sorting, filtering, aggregating, string processing, etc")
|
||||
public String executePythonCode(@P("Python code to execute, result MUST be returned by the code") String code) {
|
||||
return engine.execute(code);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package dev.langchain4j.code.graal;
|
||||
|
||||
import dev.langchain4j.code.CodeExecutionEngine;
|
||||
import org.graalvm.polyglot.Context;
|
||||
import org.graalvm.polyglot.HostAccess;
|
||||
import org.graalvm.polyglot.SandboxPolicy;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import static org.graalvm.polyglot.HostAccess.UNTRUSTED;
|
||||
import static org.graalvm.polyglot.SandboxPolicy.CONSTRAINED;
|
||||
|
||||
/**
|
||||
* {@link CodeExecutionEngine} that uses GraalVM Polyglot/Truffle to execute provided JavaScript code.
|
||||
* Attention! It might be dangerous to execute the code, see {@link SandboxPolicy#CONSTRAINED}
|
||||
* and {@link HostAccess#UNTRUSTED} for more details.
|
||||
*/
|
||||
public class GraalJavaScriptExecutionEngine implements CodeExecutionEngine {
|
||||
|
||||
@Override
|
||||
public String execute(String code) {
|
||||
OutputStream outputStream = new ByteArrayOutputStream();
|
||||
try (Context context = Context.newBuilder("js")
|
||||
.sandbox(CONSTRAINED)
|
||||
.allowHostAccess(UNTRUSTED)
|
||||
.out(outputStream)
|
||||
.err(outputStream)
|
||||
.build()) {
|
||||
Object result = context.eval("js", code).as(Object.class);
|
||||
return String.valueOf(result);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package dev.langchain4j.code.graal;
|
||||
|
||||
import dev.langchain4j.code.CodeExecutionEngine;
|
||||
import org.graalvm.polyglot.Context;
|
||||
import org.graalvm.polyglot.HostAccess;
|
||||
import org.graalvm.polyglot.SandboxPolicy;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import static org.graalvm.polyglot.HostAccess.UNTRUSTED;
|
||||
import static org.graalvm.polyglot.SandboxPolicy.TRUSTED;
|
||||
|
||||
/**
|
||||
* {@link CodeExecutionEngine} that uses GraalVM Polyglot/Truffle to execute provided Python code.
|
||||
* Attention! It might be dangerous to execute the code, see {@link SandboxPolicy#TRUSTED}
|
||||
* and {@link HostAccess#UNTRUSTED} for more details.
|
||||
*/
|
||||
public class GraalPythonExecutionEngine implements CodeExecutionEngine {
|
||||
|
||||
@Override
|
||||
public String execute(String code) {
|
||||
OutputStream outputStream = new ByteArrayOutputStream();
|
||||
try (Context context = Context.newBuilder("python")
|
||||
.sandbox(TRUSTED)
|
||||
.allowHostAccess(UNTRUSTED)
|
||||
.out(outputStream)
|
||||
.err(outputStream)
|
||||
.build()) {
|
||||
Object result = context.eval("python", code).as(Object.class);
|
||||
return String.valueOf(result);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
package dev.langchain4j.agen.tool.graal;
|
||||
|
||||
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
|
||||
import dev.langchain4j.model.chat.ChatLanguageModel;
|
||||
import dev.langchain4j.model.openai.OpenAiChatModel;
|
||||
import dev.langchain4j.service.AiServices;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class GraalPolyglotAiServiceTool {
|
||||
|
||||
public static final String OPENAI_API_KEY = System.getenv("OPENAI_API_KEY");
|
||||
|
||||
interface Assistant {
|
||||
|
||||
String chat(String userMessage);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void jsTool() {
|
||||
ChatLanguageModel model = OpenAiChatModel.builder()
|
||||
.apiKey(OPENAI_API_KEY)
|
||||
.logRequests(true)
|
||||
.build();
|
||||
|
||||
Assistant assistant = AiServices.builder(Assistant.class)
|
||||
.chatLanguageModel(model)
|
||||
.tools(new GraalJavascriptExecutionTool())
|
||||
.chatMemory(MessageWindowChatMemory.withMaxMessages(10))
|
||||
.build();
|
||||
|
||||
Assertions.assertTrue(Boolean.parseBoolean(assistant.chat("Is 146837 a prime? Just return true or false")));
|
||||
Assertions.assertFalse(Boolean.parseBoolean(assistant.chat("Is 146955 a prime? Just return true or false")));
|
||||
}
|
||||
@Test
|
||||
public void pythonTool() {
|
||||
ChatLanguageModel model = OpenAiChatModel.builder()
|
||||
.apiKey(OPENAI_API_KEY)
|
||||
.logRequests(true)
|
||||
.build();
|
||||
|
||||
Assistant assistant = AiServices.builder(Assistant.class)
|
||||
.chatLanguageModel(model)
|
||||
.tools(new GraalPythonExecutionTool())
|
||||
.chatMemory(MessageWindowChatMemory.withMaxMessages(10))
|
||||
.build();
|
||||
|
||||
Assertions.assertTrue(Boolean.parseBoolean(assistant.chat("Is 146837 a prime? Just return true or false")));
|
||||
Assertions.assertFalse(Boolean.parseBoolean(assistant.chat("Is 146955 a prime? Just return true or false")));
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
package dev.langchain4j.agen.tool.graal;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import dev.langchain4j.agent.tool.ToolExecutionRequest;
|
||||
import dev.langchain4j.agent.tool.ToolExecutor;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
|
||||
class GraalPolyglotExecutionToolTest {
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @throws NoSuchMethodException
|
||||
*/
|
||||
@Test
|
||||
public void testJavascriptTool() throws NoSuchMethodException
|
||||
{
|
||||
GraalJavascriptExecutionTool jsTool = new GraalJavascriptExecutionTool();
|
||||
String pythonCode = "function fibonacci(num) { \n" +
|
||||
" if (num <= 1) return 1; \n" +
|
||||
" \n" +
|
||||
" return fibonacci(num - 1) + fibonacci(num - 2); \n" +
|
||||
"} \n" +
|
||||
"fibonacci(10)";
|
||||
|
||||
ToolExecutionRequest request = ToolExecutionRequest.builder()
|
||||
.arguments( new Gson().toJson(Map.of("arg0", pythonCode)))
|
||||
.build();
|
||||
|
||||
ToolExecutor toolExecutor = new ToolExecutor(jsTool, GraalJavascriptExecutionTool.class.getDeclaredMethod("executeJavaScriptCode", String.class));
|
||||
|
||||
String result = toolExecutor.execute(request);
|
||||
Integer fib_of_10 = new Gson().fromJson( result, Integer.class);
|
||||
assertThat(fib_of_10).isEqualTo(89);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPythonTool() throws NoSuchMethodException
|
||||
{
|
||||
GraalPythonExecutionTool jsTool = new GraalPythonExecutionTool();
|
||||
String pythonCode = "def fibonacci_of(n):\n" +
|
||||
" if n <= 1: # Base case\n" +
|
||||
" return 1\n" +
|
||||
" return fibonacci_of(n - 1) + fibonacci_of(n - 2) # Recursive case\n" +
|
||||
"fibonacci_of(10)";
|
||||
|
||||
ToolExecutionRequest request = ToolExecutionRequest.builder()
|
||||
.arguments( new Gson().toJson(Map.of("arg0", pythonCode)))
|
||||
.build();
|
||||
|
||||
ToolExecutor toolExecutor = new ToolExecutor(jsTool, GraalPythonExecutionTool.class.getDeclaredMethod("executePythonCode", String.class));
|
||||
|
||||
String result = toolExecutor.execute(request);
|
||||
Integer fib_of_10 = new Gson().fromJson( result, Integer.class);
|
||||
|
||||
assertThat(fib_of_10).isEqualTo(89);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package dev.langchain4j.agent.tool.graal;
|
||||
|
||||
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
|
||||
import dev.langchain4j.model.openai.OpenAiChatModel;
|
||||
import dev.langchain4j.service.AiServices;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
class GraalJavaScriptExecutionToolIT {
|
||||
|
||||
interface Assistant {
|
||||
|
||||
String chat(String userMessage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_execute_tool() {
|
||||
|
||||
GraalJavaScriptExecutionTool tool = spy(new GraalJavaScriptExecutionTool());
|
||||
|
||||
Assistant assistant = AiServices.builder(Assistant.class)
|
||||
.chatLanguageModel(OpenAiChatModel.withApiKey(System.getenv("OPENAI_API_KEY")))
|
||||
.tools(tool)
|
||||
.chatMemory(MessageWindowChatMemory.withMaxMessages(10))
|
||||
.build();
|
||||
|
||||
String answer = assistant.chat("What is the square root of 485906798473894056 in scientific notation?");
|
||||
|
||||
assertThat(answer).contains("6.97");
|
||||
|
||||
verify(tool).executeJavaScriptCode(contains("485906798473894056"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package dev.langchain4j.agent.tool.graal;
|
||||
|
||||
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
|
||||
import dev.langchain4j.model.openai.OpenAiChatModel;
|
||||
import dev.langchain4j.service.AiServices;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
class GraalPythonExecutionToolIT {
|
||||
|
||||
interface Assistant {
|
||||
|
||||
String chat(String userMessage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_execute_tool() {
|
||||
|
||||
GraalPythonExecutionTool tool = spy(new GraalPythonExecutionTool());
|
||||
|
||||
Assistant assistant = AiServices.builder(Assistant.class)
|
||||
.chatLanguageModel(OpenAiChatModel.withApiKey(System.getenv("OPENAI_API_KEY")))
|
||||
.tools(tool)
|
||||
.chatMemory(MessageWindowChatMemory.withMaxMessages(10))
|
||||
.build();
|
||||
|
||||
String answer = assistant.chat("What is the square root of 485906798473894056 in scientific notation?");
|
||||
|
||||
assertThat(answer).contains("6.97");
|
||||
|
||||
verify(tool).executePythonCode(contains("485906798473894056"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package dev.langchain4j.code.graal;
|
||||
|
||||
import dev.langchain4j.code.CodeExecutionEngine;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class GraalJavaScriptExecutionEngineTest {
|
||||
|
||||
CodeExecutionEngine engine = new GraalJavaScriptExecutionEngine();
|
||||
|
||||
@Test
|
||||
void should_execute_code() {
|
||||
|
||||
String code = """
|
||||
function fibonacci(n) {
|
||||
if (n <= 1) return n;
|
||||
return fibonacci(n - 1) + fibonacci(n - 2);
|
||||
}
|
||||
|
||||
fibonacci(10)
|
||||
""";
|
||||
|
||||
String result = engine.execute(code);
|
||||
|
||||
assertThat(result).isEqualTo("55");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package dev.langchain4j.code.graal;
|
||||
|
||||
import dev.langchain4j.code.CodeExecutionEngine;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class GraalPythonExecutionEngineTest {
|
||||
|
||||
CodeExecutionEngine engine = new GraalPythonExecutionEngine();
|
||||
|
||||
@Test
|
||||
void should_execute_code() {
|
||||
|
||||
String code = """
|
||||
def fibonacci(n):
|
||||
if n <= 1:
|
||||
return n
|
||||
else:
|
||||
return fibonacci(n-1) + fibonacci(n-2)
|
||||
|
||||
fibonacci(10)
|
||||
""";
|
||||
|
||||
String result = engine.execute(code);
|
||||
|
||||
assertThat(result).isEqualTo("55");
|
||||
}
|
||||
}
|
|
@ -49,6 +49,12 @@
|
|||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-core</artifactId>
|
||||
|
@ -63,6 +69,12 @@
|
|||
<type>test-jar</type>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-open-ai</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.ai4j</groupId>
|
||||
<artifactId>openai4j</artifactId>
|
||||
|
|
|
@ -143,26 +143,4 @@
|
|||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>compliance</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>compliance</name>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.honton.chas</groupId>
|
||||
<artifactId>license-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<skipCompliance>true</skipCompliance>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
|
@ -105,27 +105,4 @@
|
|||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>compliance</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>compliance</name>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.honton.chas</groupId>
|
||||
<artifactId>license-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<!-- the pinecone module has non-permissive licenses -->
|
||||
<skipCompliance>true</skipCompliance>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
2
pom.xml
2
pom.xml
|
@ -34,8 +34,8 @@
|
|||
<module>langchain4j-elasticsearch</module>
|
||||
<module>langchain4j-milvus</module>
|
||||
<module>langchain4j-opensearch</module>
|
||||
<module>langchain4j-pinecone</module>
|
||||
<module>langchain4j-pgvector</module>
|
||||
<module>langchain4j-pinecone</module>
|
||||
<module>langchain4j-redis</module>
|
||||
<module>langchain4j-vespa</module>
|
||||
<module>langchain4j-weaviate</module>
|
||||
|
|
Loading…
Reference in New Issue