Skip to content

Commit e92ae72

Browse files
feat: integrate SAA Python sandbox with dynamic dependencies (#587)
* feat: integrate SAA Python sandbox * refactor: organize Python sandbox packages
1 parent 3514577 commit e92ae72

66 files changed

Lines changed: 1733 additions & 2893 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎data-agent-management/pom.xml‎

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@
8383
<groupId>org.apache.commons</groupId>
8484
<artifactId>commons-lang3</artifactId>
8585
</dependency>
86+
<dependency>
87+
<groupId>com.google.guava</groupId>
88+
<artifactId>guava</artifactId>
89+
</dependency>
8690
<dependency>
8791
<groupId>com.mysql</groupId>
8892
<artifactId>mysql-connector-j</artifactId>
@@ -269,6 +273,16 @@
269273
<artifactId>spring-ai-alibaba-graph-core</artifactId>
270274
<version>${spring-ai-alibaba.version}</version>
271275
</dependency>
276+
<dependency>
277+
<groupId>com.alibaba.cloud.ai</groupId>
278+
<artifactId>spring-ai-alibaba-sandbox</artifactId>
279+
<version>${spring-ai-alibaba.version}</version>
280+
</dependency>
281+
<dependency>
282+
<groupId>org.tomlj</groupId>
283+
<artifactId>tomlj</artifactId>
284+
<version>${tomlj.version}</version>
285+
</dependency>
272286
<dependency>
273287
<groupId>org.springframework.ai</groupId>
274288
<artifactId>spring-ai-starter-model-chat-memory-repository-jdbc</artifactId>
@@ -371,16 +385,6 @@
371385
<artifactId>easyexcel</artifactId>
372386
<version>3.3.4</version>
373387
</dependency>
374-
<!-- Docker Java Client -->
375-
<dependency>
376-
<groupId>com.github.docker-java</groupId>
377-
<artifactId>docker-java-core</artifactId>
378-
</dependency>
379-
<dependency>
380-
<groupId>com.github.docker-java</groupId>
381-
<artifactId>docker-java-transport-zerodep</artifactId>
382-
</dependency>
383-
384388
</dependencies>
385389
<repositories>
386390
<repository>

‎data-agent-management/src/main/java/com/alibaba/cloud/ai/dataagent/config/DataAgentConfiguration.java‎

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@
1919
import com.alibaba.cloud.ai.dataagent.properties.DataAgentProperties;
2020
import com.alibaba.cloud.ai.dataagent.properties.FileStorageProperties;
2121
import com.alibaba.cloud.ai.dataagent.properties.OssStorageProperties;
22-
import com.alibaba.cloud.ai.dataagent.service.code.CodePoolExecutorService;
23-
import com.alibaba.cloud.ai.dataagent.service.code.CodePoolExecutorServiceFactory;
24-
import com.alibaba.cloud.ai.dataagent.service.code.docker.DockerExecutorFactory;
2522
import com.alibaba.cloud.ai.dataagent.service.file.FileStorageService;
2623
import com.alibaba.cloud.ai.dataagent.service.file.FileStorageServiceFactory;
2724
import com.alibaba.cloud.ai.dataagent.service.llm.LlmService;
@@ -127,13 +124,6 @@ public FileStorageService fileStorageService(FileStorageProperties properties,
127124
return new FileStorageServiceFactory(properties, ossStorageProperties).getObject();
128125
}
129126

130-
@Bean
131-
@ConditionalOnMissingBean(CodePoolExecutorService.class)
132-
public CodePoolExecutorService codePoolExecutorService(CodeExecutorProperties properties, LlmService llmService,
133-
DockerExecutorFactory dockerExecutorFactory) {
134-
return new CodePoolExecutorServiceFactory(properties, llmService, dockerExecutorFactory).getObject();
135-
}
136-
137127
@Bean
138128
@ConditionalOnMissingBean(RestClientCustomizer.class)
139129
public RestClientCustomizer restClientCustomizer(@Value("${rest.connect.timeout:600}") long connectTimeout,

‎data-agent-management/src/main/java/com/alibaba/cloud/ai/dataagent/properties/CodeExecutorProperties.java‎

Lines changed: 32 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@
1515
*/
1616
package com.alibaba.cloud.ai.dataagent.properties;
1717

18-
import com.alibaba.cloud.ai.dataagent.enums.CodePoolExecutorEnum;
1918
import lombok.Getter;
2019
import lombok.Setter;
2120
import org.springframework.boot.context.properties.ConfigurationProperties;
2221

22+
import java.time.Duration;
23+
2324
import static com.alibaba.cloud.ai.dataagent.constant.Constant.PROJECT_PROPERTIES_PREFIX;
2425

2526
/**
@@ -34,94 +35,59 @@ public class CodeExecutorProperties {
3435
public static final String CONFIG_PREFIX = PROJECT_PROPERTIES_PREFIX + ".code-executor";
3536

3637
/**
37-
* Specify implementation class of code container pool runtime service
38+
* Maximum container memory, in MB
3839
*/
39-
CodePoolExecutorEnum codePoolExecutor = CodePoolExecutorEnum.DOCKER;
40+
Long limitMemory = 500L;
4041

4142
/**
42-
* Service host, use default address if null
43+
* Number of container CPU cores
4344
*/
44-
String host = null;
45+
Long cpuCore = 1L;
4546

4647
/**
47-
* Image name, can customize image with common third-party dependencies to replace
48-
* this configuration
48+
* Python code execution time limit
4949
*/
50-
String imageName = "continuumio/anaconda3:latest";
50+
Duration codeTimeout = Duration.ofSeconds(60);
5151

5252
/**
53-
* Container name prefix
53+
* Python执行的最大重试次数
5454
*/
55-
String containerNamePrefix = "nl2sql-python-exec-";
55+
Integer pythonMaxTriesCount = 5;
5656

57-
/**
58-
* Task blocking queue size
59-
*/
60-
Integer taskQueueSize = 5;
57+
private Sandbox sandbox = new Sandbox();
6158

62-
/**
63-
* Maximum number of core containers
64-
*/
65-
Integer coreContainerNum = 2;
59+
@Getter
60+
@Setter
61+
public static class Sandbox {
6662

67-
/**
68-
* Maximum number of temporary containers
69-
*/
70-
Integer tempContainerNum = 2;
63+
String dockerHost = "unix:///var/run/docker.sock";
7164

72-
/**
73-
* Core thread count of thread pool
74-
*/
75-
Integer coreThreadSize = 5;
65+
String imageName = "agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-base:latest";
7666

77-
/**
78-
* Maximum thread count of thread pool
79-
*/
80-
Integer maxThreadSize = 5;
67+
String containerPrefix = "dataagent-sandbox-";
8168

82-
/**
83-
* Survival time of temporary containers, in minutes
84-
*/
85-
Integer tempContainerAliveTime = 5;
69+
Integer maxConcurrency = 4;
8670

87-
/**
88-
* Task survival time of thread pool, in seconds
89-
*/
90-
Long keepThreadAliveTime = 60L;
71+
Integer queueCapacity = 10;
9172

92-
/**
93-
* Task blocking queue size of thread pool
94-
*/
95-
Integer threadQueueSize = 10;
73+
Integer maxCodeBytes = 256 * 1024;
9674

97-
/**
98-
* Maximum container memory, in MB
99-
*/
100-
Long limitMemory = 500L;
75+
Integer maxInputBytes = 10 * 1024 * 1024;
10176

102-
/**
103-
* Number of container CPU cores
104-
*/
105-
Long cpuCore = 1L;
77+
Integer maxOutputBytes = 1024 * 1024;
10678

107-
/**
108-
* Python code execution time limit
109-
*/
110-
String codeTimeout = "60s";
79+
Integer maxErrorBytes = 256 * 1024;
11180

112-
/**
113-
* Maximum container runtime
114-
*/
115-
Long containerTimeout = 3000L;
81+
Integer maxMetadataBytes = 8 * 1024;
11682

117-
/**
118-
* Container network mode
119-
*/
120-
String networkMode = "none";
83+
Integer maxDependencies = 20;
12184

122-
/**
123-
* Python执行的最大重试次数
124-
*/
125-
Integer pythonMaxTriesCount = 5;
85+
String packageIndexUrl = "https://pypi.org/simple";
86+
87+
Duration dependencyInstallTimeout = Duration.ofMinutes(3);
88+
89+
Integer maxConnections = 4096;
90+
91+
}
12692

12793
}

‎data-agent-management/src/main/java/com/alibaba/cloud/ai/dataagent/service/code/CodePoolExecutorServiceFactory.java‎

Lines changed: 0 additions & 54 deletions
This file was deleted.

data-agent-management/src/main/java/com/alibaba/cloud/ai/dataagent/service/code/CodePoolExecutorService.java renamed to data-agent-management/src/main/java/com/alibaba/cloud/ai/dataagent/service/code/PythonCodeExecutorService.java

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,34 +15,34 @@
1515
*/
1616
package com.alibaba.cloud.ai.dataagent.service.code;
1717

18+
import java.util.List;
19+
1820
/**
19-
* 运行Python任务的容器池接口
20-
*
21-
* @author vlsmb
22-
* @since 2025/7/12
21+
* Executes generated Python code in an isolated sandbox.
2322
*/
24-
public interface CodePoolExecutorService {
23+
public interface PythonCodeExecutorService {
2524

2625
TaskResponse runTask(TaskRequest request);
2726

28-
record TaskRequest(String code, String input, String requirement) {
27+
record TaskRequest(String code, String input, List<String> dependencies) {
28+
29+
public TaskRequest {
30+
dependencies = dependencies == null ? List.of() : List.copyOf(dependencies);
31+
}
2932

3033
}
3134

3235
record TaskResponse(boolean isSuccess, boolean executionSuccessButResultFailed, String stdOut, String stdErr,
3336
String exceptionMsg) {
3437

35-
// 执行运行代码任务时发生异常
3638
public static TaskResponse exception(String msg) {
3739
return new TaskResponse(false, false, null, null, "An exception occurred while executing the task: " + msg);
3840
}
3941

40-
// 执行运行代码任务成功,并且代码正常返回
4142
public static TaskResponse success(String stdOut) {
4243
return new TaskResponse(true, false, stdOut, null, null);
4344
}
4445

45-
// 执行运行代码任务成功,但是代码异常返回
4646
public static TaskResponse failure(String stdOut, String stdErr) {
4747
return new TaskResponse(false, true, stdOut, stdErr, "StdErr: " + stdErr);
4848
}
@@ -54,10 +54,4 @@ public String toString() {
5454
}
5555
}
5656

57-
enum State {
58-
59-
READY, RUNNING, REMOVING
60-
61-
}
62-
6357
}

‎data-agent-management/src/main/java/com/alibaba/cloud/ai/dataagent/service/code/docker/DockerClientConnector.java‎

Lines changed: 0 additions & 28 deletions
This file was deleted.

0 commit comments

Comments
 (0)