Skip to content

Commit 5facd5f

Browse files
committed
add python code executor
1 parent 231c792 commit 5facd5f

File tree

14 files changed

+220
-26
lines changed

14 files changed

+220
-26
lines changed

executor-model/src/main/java/com/javaaidev/llmcodeexecutor/executor/model/CopiedFile.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
public class CopiedFile {
66

77
/**
8-
* Path of a copied file
8+
* Path of a copied file in the host machine
99
*
1010
*/
1111
private String path;
@@ -20,7 +20,7 @@ public CopiedFile() {
2020
/**
2121
*
2222
* @param path
23-
* Path of a copied file.
23+
* Path of a copied file in the host machine.
2424
*/
2525
public CopiedFile(String path) {
2626
super();
@@ -32,15 +32,15 @@ public static CopiedFile.CopiedFileBuilderBase builder() {
3232
}
3333

3434
/**
35-
* Path of a copied file
35+
* Path of a copied file in the host machine
3636
*
3737
*/
3838
public String getPath() {
3939
return path;
4040
}
4141

4242
/**
43-
* Path of a copied file
43+
* Path of a copied file in the host machine
4444
*
4545
*/
4646
public void setPath(String path) {

executor-model/src/main/java/com/javaaidev/llmcodeexecutor/executor/model/OutputFileCollectionConfig.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,17 @@
1010
public class OutputFileCollectionConfig {
1111

1212
/**
13-
* Should output files be loaded as string
13+
* Should output files created in the container be loaded as string
1414
*
1515
*/
1616
private Boolean loadFiles;
1717
/**
18-
* Should output files be copied to a directory
18+
* Should output files created in the container be copied to a directory
1919
*
2020
*/
2121
private Boolean copyFiles;
2222
/**
23-
* Directory to copy output files
23+
* Target directory of the host machine to copy output files
2424
*
2525
*/
2626
private String copiedFilesPath;
@@ -42,11 +42,11 @@ public OutputFileCollectionConfig() {
4242
* @param includedFilePattern
4343
* Glob patterns to include files for loading or copying.
4444
* @param copyFiles
45-
* Should output files be copied to a directory.
45+
* Should output files created in the container be copied to a directory.
4646
* @param copiedFilesPath
47-
* Directory to copy output files.
47+
* Target directory of the host machine to copy output files.
4848
* @param loadFiles
49-
* Should output files be loaded as string.
49+
* Should output files created in the container be loaded as string.
5050
*/
5151
public OutputFileCollectionConfig(Boolean loadFiles, Boolean copyFiles, String copiedFilesPath, String includedFilePattern) {
5252
super();
@@ -61,47 +61,47 @@ public static OutputFileCollectionConfig.OutputFileCollectionConfigBuilderBase b
6161
}
6262

6363
/**
64-
* Should output files be loaded as string
64+
* Should output files created in the container be loaded as string
6565
*
6666
*/
6767
public Boolean getLoadFiles() {
6868
return loadFiles;
6969
}
7070

7171
/**
72-
* Should output files be loaded as string
72+
* Should output files created in the container be loaded as string
7373
*
7474
*/
7575
public void setLoadFiles(Boolean loadFiles) {
7676
this.loadFiles = loadFiles;
7777
}
7878

7979
/**
80-
* Should output files be copied to a directory
80+
* Should output files created in the container be copied to a directory
8181
*
8282
*/
8383
public Boolean getCopyFiles() {
8484
return copyFiles;
8585
}
8686

8787
/**
88-
* Should output files be copied to a directory
88+
* Should output files created in the container be copied to a directory
8989
*
9090
*/
9191
public void setCopyFiles(Boolean copyFiles) {
9292
this.copyFiles = copyFiles;
9393
}
9494

9595
/**
96-
* Directory to copy output files
96+
* Target directory of the host machine to copy output files
9797
*
9898
*/
9999
public String getCopiedFilesPath() {
100100
return copiedFilesPath;
101101
}
102102

103103
/**
104-
* Directory to copy output files
104+
* Target directory of the host machine to copy output files
105105
*
106106
*/
107107
public void setCopiedFilesPath(String copiedFilesPath) {

executors/java/src/test/kotlin/com/javaaidev/llmcodeexecutor/executor/java/JavaCodeExecutorTest.kt

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package com.javaaidev.llmcodeexecutor.executor.java
22

33
import com.javaaidev.llmcodeexecutor.executor.model.ExecuteCodeParameters
44
import org.junit.jupiter.api.Test
5+
import kotlin.test.assertEquals
6+
import kotlin.test.assertNotNull
57

68
class JavaCodeExecutorTest {
79
@Test
@@ -17,6 +19,30 @@ class JavaCodeExecutorTest {
1719
""".trimIndent()
1820
)
1921
)
20-
kotlin.test.assertEquals("Hello", result.output.trim())
22+
assertEquals("Hello", result.output.trim())
23+
}
24+
25+
@Test
26+
fun codeFileName() {
27+
val result = JavaCodeExecutor().execute(
28+
ExecuteCodeParameters(
29+
"""
30+
import java.time.LocalDateTime;
31+
import java.time.format.DateTimeFormatter;
32+
33+
public class CurrentTime {
34+
public static void main(String[] args) {
35+
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
36+
LocalDateTime now = LocalDateTime.now();
37+
System.out.println("Current time: " + now.format(formatter));
38+
}
39+
}
40+
""".trimIndent(),
41+
"CurrentTime.java",
42+
null
43+
)
44+
)
45+
assertNotNull(result.output)
46+
assertEquals("", result.error)
2147
}
2248
}

executors/python/src/main/kotlin/com/javaaidev/llmcodeexecutor/executor/python/PythonCodeExecutor.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class PythonCodeExecutor(private val config: ExecuteCodeConfiguration? = null) {
1616
request: ExecuteCodeParameters
1717
): ExecuteCodeReturnType {
1818
val codeDir = Files.createTempDirectory("code_executor")
19-
val codeFile = "app.py"
19+
val codeFile = (request.codeFileName ?: "").ifBlank { "app.py" }
2020
Files.writeString(codeDir.resolve(codeFile), request.code)
2121
val codeExecutor = LLMCodeExecutor(
2222
CodeExecutorConfig(

justfile

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ generateJavaContainerImages: build
1414
profiles/java/base-21.json --output=container-images/java/base-21
1515

1616
downloadCodeGeneratorCli:
17-
mvn dependency:copy -Dartifact=com.javaaidev.easyllmtools:code-generator-cli:0.1.8 -DoutputDirectory=target -Dmdep.stripVersion=true
17+
mvn dependency:copy -Dartifact=com.javaaidev.easyllmtools:code-generator-cli:0.1.9 -DoutputDirectory=target -Dmdep.stripVersion=true
1818

1919
generateCodeExecutorModel: downloadCodeGeneratorCli
2020
java -jar target/code-generator-cli.jar simple \
@@ -40,5 +40,22 @@ generateCodeExecutorJava: downloadCodeGeneratorCli
4040
--artifact-id=tool-java --artifact-version=0.2.0 \
4141
--model-package-name=com.javaaidev.llmcodeexecutor.executor.model \
4242
--package-name=com.javaaidev.llmcodeexecutor.executor.java \
43-
--tool-description="Execute Java code with following libraries: guava, commons-lang3, jackson, okhttp" \
43+
--llm-tool-name="ExecuteJavaCode" \
44+
--tool-description="Execute Java code with following libraries: guava, commons-lang3, jackson, okhttp. Code is executed in a container. Always write files to the current directory." \
45+
llm-tool-spec/code-executor.json
46+
47+
generateCodeExecutorPython: downloadCodeGeneratorCli
48+
java -jar target/code-generator-cli.jar simple \
49+
--output=tools/python \
50+
--no-model-files \
51+
--tool-id-prefix=python \
52+
--parent-group-id=com.javaaidev.llmcodeexecutor \
53+
--parent-artifact-id=tools \
54+
--parent-artifact-version=0.2.0 \
55+
--group-id=com.javaaidev.llmcodeexecutor \
56+
--artifact-id=tool-python --artifact-version=0.2.0 \
57+
--model-package-name=com.javaaidev.llmcodeexecutor.executor.model \
58+
--package-name=com.javaaidev.llmcodeexecutor.executor.python \
59+
--llm-tool-name="ExecutePythonCode" \
60+
--tool-description="Execute Python code with following libraries: numpy, pandas, seaborn, tabulate, sympy. Code is executed in a container. Always write files to the current directory." \
4461
llm-tool-spec/code-executor.json

llm-tool-spec/code-executor.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@
1919
"properties": {
2020
"loadFiles": {
2121
"type": "boolean",
22-
"description": "Should output files be loaded as string"
22+
"description": "Should output files created in the container be loaded as string"
2323
},
2424
"copyFiles": {
2525
"type": "boolean",
26-
"description": "Should output files be copied to a directory"
26+
"description": "Should output files created in the container be copied to a directory"
2727
},
2828
"copiedFilesPath": {
2929
"type": "string",
30-
"description": "Directory to copy output files"
30+
"description": "Target directory of the host machine to copy output files"
3131
},
3232
"includedFilePattern": {
3333
"type": "string",
@@ -75,7 +75,7 @@
7575
"properties": {
7676
"path": {
7777
"type": "string",
78-
"description": "Path of a copied file"
78+
"description": "Path of a copied file in the host machine"
7979
}
8080
}
8181
}

tools/java/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
<dependency>
3131
<groupId>com.javaaidev.easyllmtools</groupId>
3232
<artifactId>llm-tool-spec</artifactId>
33-
<version>0.1.8</version>
33+
<version>0.1.9</version>
3434
</dependency>
3535
<dependency>
3636
<groupId>com.javaaidev.llmcodeexecutor</groupId>

tools/java/src/main/java/com/javaaidev/llmcodeexecutor/executor/java/AbstractExecuteCode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public String getId() {
2020

2121
@Override
2222
public String getName() {
23-
return "ExecuteCode";
23+
return "ExecuteJavaCode";
2424
}
2525

2626
@Override

tools/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,6 @@
1616

1717
<modules>
1818
<module>java</module>
19+
<module>python</module>
1920
</modules>
2021
</project>

tools/python/pom.xml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0"
2+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
6+
7+
<parent>
8+
<groupId>com.javaaidev.llmcodeexecutor</groupId>
9+
<artifactId>tools</artifactId>
10+
<version>0.2.0</version>
11+
</parent>
12+
13+
14+
<groupId>com.javaaidev.llmcodeexecutor</groupId>
15+
<artifactId>tool-python</artifactId>
16+
<version>0.2.0</version>
17+
<packaging>jar</packaging>
18+
19+
<name>ExecutePythonCode</name>
20+
<description>Execute Python code with following libraries: numpy, pandas, seaborn, tabulate,
21+
sympy
22+
</description>
23+
24+
<properties>
25+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
26+
<maven.compiler.source>1.8</maven.compiler.source>
27+
<maven.compiler.target>1.8</maven.compiler.target>
28+
</properties>
29+
30+
<dependencies>
31+
<dependency>
32+
<groupId>com.javaaidev.easyllmtools</groupId>
33+
<artifactId>llm-tool-spec</artifactId>
34+
<version>0.1.9</version>
35+
</dependency>
36+
<dependency>
37+
<groupId>com.javaaidev.llmcodeexecutor</groupId>
38+
<artifactId>code-executor-model</artifactId>
39+
<version>0.2.0</version>
40+
</dependency>
41+
<dependency>
42+
<groupId>com.javaaidev.llmcodeexecutor</groupId>
43+
<artifactId>executor-python</artifactId>
44+
<version>0.2.0</version>
45+
</dependency>
46+
</dependencies>
47+
48+
<build>
49+
<sourceDirectory>src/main/java</sourceDirectory>
50+
<plugins>
51+
<plugin>
52+
<groupId>org.apache.maven.plugins</groupId>
53+
<artifactId>maven-compiler-plugin</artifactId>
54+
<version>3.11.0</version>
55+
<configuration>
56+
<source>${maven.compiler.source}</source>
57+
<target>${maven.compiler.target}</target>
58+
</configuration>
59+
</plugin>
60+
</plugins>
61+
</build>
62+
</project>
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.javaaidev.llmcodeexecutor.executor.python;
2+
3+
import com.javaaidev.easyllmtools.llmtoolspec.Tool;
4+
import com.javaaidev.llmcodeexecutor.executor.model.ExecuteCodeConfiguration;
5+
import com.javaaidev.llmcodeexecutor.executor.model.ExecuteCodeParameters;
6+
import com.javaaidev.llmcodeexecutor.executor.model.ExecuteCodeReturnType;
7+
8+
public abstract class AbstractExecuteCode implements Tool<ExecuteCodeParameters, ExecuteCodeReturnType> {
9+
10+
protected ExecuteCodeConfiguration config;
11+
12+
protected AbstractExecuteCode(final ExecuteCodeConfiguration config) {
13+
this.config = config;
14+
}
15+
16+
@Override
17+
public String getId() {
18+
return "pythonExecuteCode";
19+
}
20+
21+
@Override
22+
public String getName() {
23+
return "ExecutePythonCode";
24+
}
25+
26+
@Override
27+
public String getDescription() {
28+
return "Execute Python code with following libraries: numpy, pandas, seaborn, tabulate, sympy.Code is executed in a container. Always write files to the current directory.";
29+
}
30+
31+
@Override
32+
public String getParametersSchema() {
33+
return "{\"type\":\"object\",\"properties\":{\"code\":{\"type\":\"string\",\"description\":\"Code to execute\"},\"codeFileName\":{\"type\":\"string\",\"description\":\"Name of code file\"},\"outputFileCollectionConfig\":{\"type\":\"object\",\"description\":\"Configuration of collecting output files\",\"properties\":{\"loadFiles\":{\"type\":\"boolean\",\"description\":\"Should output files created in the container be loaded as string\"},\"copyFiles\":{\"type\":\"boolean\",\"description\":\"Should output files created in the container be copied to a directory\"},\"copiedFilesPath\":{\"type\":\"string\",\"description\":\"Target directory of the host machine to copy output files\"},\"includedFilePattern\":{\"type\":\"string\",\"description\":\"Glob patterns to include files for loading or copying\"}}}},\"required\":[\"code\"]}";
34+
}
35+
36+
@Override
37+
public String getReturnTypeSchema() {
38+
return "{\"type\":\"object\",\"properties\":{\"output\":{\"type\":\"string\",\"description\":\"Output of code execution\"},\"error\":{\"type\":\"string\",\"description\":\"Error when executing code\"},\"loadedFiles\":{\"type\":\"array\",\"description\":\"Loaded files\",\"items\":{\"type\":\"object\",\"properties\":{\"mimeType\":{\"type\":\"string\",\"description\":\"MIME type of a loaded file\"},\"data\":{\"type\":\"string\",\"description\":\"Content of a loaded file\"}}}},\"copiedFiles\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path of a copied file in the host machine\"}}}}}}";
39+
}
40+
41+
@Override
42+
public String getExamples() {
43+
return "{}";
44+
}
45+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.javaaidev.llmcodeexecutor.executor.python;
2+
3+
import com.javaaidev.llmcodeexecutor.executor.model.ExecuteCodeConfiguration;
4+
import com.javaaidev.llmcodeexecutor.executor.model.ExecuteCodeParameters;
5+
import com.javaaidev.llmcodeexecutor.executor.model.ExecuteCodeReturnType;
6+
import java.lang.reflect.Type;
7+
8+
public class ExecuteCode extends AbstractExecuteCode {
9+
10+
public ExecuteCode(final ExecuteCodeConfiguration config) {
11+
super(config);
12+
}
13+
14+
@Override
15+
public Type getRequestType() {
16+
return ExecuteCodeParameters.class;
17+
}
18+
19+
@Override
20+
public ExecuteCodeReturnType call(final ExecuteCodeParameters parameters) {
21+
return new PythonCodeExecutor(config).execute(parameters);
22+
}
23+
}

0 commit comments

Comments
 (0)