diff --git a/examples/simple_sandbox_tool_example/pom.xml b/examples/simple_sandbox_tool_example/pom.xml
new file mode 100644
index 00000000..4d7b5c8f
--- /dev/null
+++ b/examples/simple_sandbox_tool_example/pom.xml
@@ -0,0 +1,67 @@
+
+
+ 4.0.0
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.2.0
+
+
+
+ com.example
+ agentscope-examples-simple
+ 1.0.0
+ AgentScope Spring MVC Demo
+ AgentScope simple sample project using Spring MVC
+
+
+ 17
+ 17
+ 17
+ UTF-8
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+ io.agentscope
+ agentscope-core
+ 0.2.0
+
+
+
+
+ io.agentscope
+ agentscope-runtime-agentscope
+ 1.0.0-BETA1
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ org.projectlombok
+ lombok
+
+
+
+
+
+
+
+
diff --git a/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/AgentScopeApplication.java b/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/AgentScopeApplication.java
new file mode 100644
index 00000000..d0e5bdb5
--- /dev/null
+++ b/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/AgentScopeApplication.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2025 the original author or authors.
+ *
+ * Licensed 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
+ *
+ * https://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 com.example.agentscope;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * AgentScope Spring Boot application main class
+ */
+@SpringBootApplication
+public class AgentScopeApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(AgentScopeApplication.class, args);
+
+ System.out.println("\n" + "=".repeat(70));
+ System.out.println("๐ AgentScope Demo started successfully!");
+ System.out.println("=".repeat(70));
+ System.out.println();
+
+ System.out.println("๐ก API endpoints:");
+ System.out.println(" โข Health check: http://localhost:8080/api/chat/health");
+ System.out.println(" โข Send message: http://localhost:8080/api/chat");
+ System.out.println(" โข View tools: http://localhost:8080/api/chat/tools");
+ System.out.println(" โข Reset conversation: http://localhost:8080/api/chat/reset");
+ System.out.println();
+
+ System.out.println("๐ ๏ธ Available tools:");
+ System.out.println(" โข Weather tool - query city weather and forecasts");
+ System.out.println(" โข Calculator tool - math operations (add, subtract, multiply, divide, power, sqrt)");
+ System.out.println(" โข Sandbox tool - sandbox browser search");
+ System.out.println();
+
+ System.out.println("๐ก Quick tests:");
+ System.out.println(" curl -X POST http://localhost:8080/api/chat \\");
+ System.out.println(" -H \"Content-Type: application/json\" \\");
+ System.out.println(" -d '{\"message\": \"How is the weather in Beijing today?\"}'");
+ System.out.println();
+
+ System.out.println("curl -X POST http://localhost:8080/api/chat \\\n" +
+ " -H \"Content-Type: application/json\" \\\n" +
+ " -d '{\"message\": \"Use the browser tool to search on Baidu for today'\\''s gold price\"}'");
+
+ System.out.println(" curl -X POST http://localhost:8080/api/chat \\");
+ System.out.println(" -H \"Content-Type: application/json\" \\");
+ System.out.println(" -d '{\"message\": \"Calculate 123 + 456\"}'");
+ System.out.println();
+
+ System.out.println("๐ More info:");
+ System.out.println(" โข See README.md for detailed docs");
+ System.out.println(" โข See QUICKSTART.md to get started quickly");
+ System.out.println(" โข Import AgentScope-API.postman_collection.json to test with Postman");
+ System.out.println();
+ System.out.println("=".repeat(70) + "\n");
+ }
+}
+
diff --git a/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/config/AgentConfig.java b/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/config/AgentConfig.java
new file mode 100644
index 00000000..5875b880
--- /dev/null
+++ b/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/config/AgentConfig.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2025 the original author or authors.
+ *
+ * Licensed 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
+ *
+ * https://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 com.example.agentscope.config;
+
+import com.example.agentscope.tools.CalculatorTool;
+import com.example.agentscope.tools.WeatherTool;
+import io.agentscope.core.ReActAgent;
+import io.agentscope.core.memory.InMemoryMemory;
+import io.agentscope.core.model.DashScopeChatModel;
+import io.agentscope.core.tool.Toolkit;
+import io.agentscope.runtime.engine.agents.agentscope.tools.ToolkitInit;
+import io.agentscope.runtime.engine.services.sandbox.SandboxService;
+import io.agentscope.runtime.sandbox.box.BrowserSandbox;
+import io.agentscope.runtime.sandbox.box.Sandbox;
+import io.agentscope.runtime.sandbox.manager.SandboxManager;
+import io.agentscope.runtime.sandbox.manager.client.config.BaseClientConfig;
+import io.agentscope.runtime.sandbox.manager.client.config.DockerClientConfig;
+import io.agentscope.runtime.sandbox.manager.model.ManagerConfig;
+import org.checkerframework.checker.units.qual.A;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Scope;
+
+/**
+ * AgentScope configuration class
+ * Configure Agent, Model, and Toolkit
+ */
+@Configuration
+public class AgentConfig {
+
+ @Value("${DASHSCOPE_API_KEY:#{null}}")
+ private String apiKey;
+
+ /**
+ * Configure the DashScope chat model
+ */
+ @Bean
+ public DashScopeChatModel chatModel() {
+ String key = apiKey != null ? apiKey : System.getenv("DASHSCOPE_API_KEY");
+
+ if (key == null || key.isEmpty()) {
+ throw new IllegalStateException(
+ "DASHSCOPE_API_KEY is not configured. Please set env var: export DASHSCOPE_API_KEY=your-api-key"
+ );
+ }
+
+ return DashScopeChatModel.builder()
+ .apiKey(key)
+ .modelName("qwen3-max")
+ .build();
+ }
+
+ /**
+ * Reuse SandboxService as a singleton
+ */
+ @Bean
+ public SandboxService sandboxService() {
+ BaseClientConfig clientConfig = DockerClientConfig.builder().build();
+ ManagerConfig managerConfig = ManagerConfig.builder()
+ .containerDeployment(clientConfig)
+ .build();
+
+ SandboxService service = new SandboxService(
+ new SandboxManager(managerConfig)
+ );
+ service.start();
+ return service;
+ }
+
+ /**
+ * Configure the toolkit and register all tools
+ */
+ @Bean
+ public Toolkit createToolkit(SandboxService sandboxService) {
+ Toolkit toolkit = new Toolkit();
+ WeatherTool weatherTool = new WeatherTool();
+ CalculatorTool calculatorTool = new CalculatorTool();
+
+ toolkit.registerTool(weatherTool);
+ toolkit.registerTool(calculatorTool);
+ try {
+ Sandbox sandbox = sandboxService.connect("userId", "sessionId", BrowserSandbox.class);
+ toolkit.registerTool(ToolkitInit.BrowserNavigateTool(sandbox));
+ if (sandbox instanceof BrowserSandbox browserSandbox) {
+ String desktopUrl = browserSandbox.getDesktopUrl();
+ System.out.println("GUI Desktop URL: " + desktopUrl);
+ }
+ } catch (Exception ignored) {
+ }
+ return toolkit;
+ }
+
+ /**
+ * Create an independent Agent for each request to avoid shared state
+ */
+ @Bean
+ @Scope("prototype")
+ public ReActAgent createAgentInstance(DashScopeChatModel chatModel, Toolkit toolkit) {
+ return ReActAgent.builder()
+ .name("Smart Assistant")
+ .sysPrompt("""
+ You are an intelligent assistant named "XiaoZhi". You can help users:
+ 1. Query weather information
+ 2. Perform mathematical calculations
+
+ Use the available tools to answer user questions and provide accurate and helpful responses.
+ Be friendly, professional, and clear in your answers.
+ """)
+ .model(chatModel)
+ .toolkit(toolkit)
+ .memory(new InMemoryMemory())
+ .maxIters(5)
+ .build();
+ }
+}
+
diff --git a/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/controller/ChatController.java b/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/controller/ChatController.java
new file mode 100644
index 00000000..09425fa2
--- /dev/null
+++ b/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/controller/ChatController.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2025 the original author or authors.
+ *
+ * Licensed 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
+ *
+ * https://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 com.example.agentscope.controller;
+
+import com.example.agentscope.model.ChatRequest;
+import com.example.agentscope.model.ChatResponse;
+import com.example.agentscope.service.ChatService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * Chat API controller
+ * Provide external REST API endpoints
+ */
+@RestController
+@RequestMapping("/chat")
+@CrossOrigin(origins = "*")
+public class ChatController {
+
+ @Autowired
+ private ChatService chatService;
+
+ /**
+ * Health check endpoint
+ */
+ @GetMapping("/health")
+ public ResponseEntity health() {
+ return ResponseEntity.ok("AgentScope service is running โ");
+ }
+
+ /**
+ * Send a message to the Agent
+ *
+ * @param request Chat request
+ * @return Chat response
+ */
+ @PostMapping
+ public ResponseEntity chat(@RequestBody ChatRequest request) {
+ try {
+ ChatResponse response = chatService.chat(request);
+ return ResponseEntity.ok(response);
+ } catch (Exception e) {
+ ChatResponse errorResponse = new ChatResponse();
+ errorResponse.setSuccess(false);
+ errorResponse.setMessage("An error occurred while processing the request: " + e.getMessage());
+ errorResponse.setError(e.getClass().getSimpleName());
+ return ResponseEntity.internalServerError().body(errorResponse);
+ }
+ }
+
+ /**
+ * Get available tool list
+ */
+ @GetMapping("/tools")
+ public ResponseEntity> getTools() {
+ try {
+ return ResponseEntity.ok(chatService.getAvailableTools());
+ } catch (Exception e) {
+ return ResponseEntity.internalServerError()
+ .body("Failed to get tool list: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Reset conversation history
+ */
+ @PostMapping("/reset")
+ public ResponseEntity reset() {
+ try {
+ chatService.resetMemory();
+ return ResponseEntity.ok("Conversation history reset โ");
+ } catch (Exception e) {
+ return ResponseEntity.internalServerError()
+ .body("Reset failed: " + e.getMessage());
+ }
+ }
+}
+
diff --git a/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/model/ChatRequest.java b/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/model/ChatRequest.java
new file mode 100644
index 00000000..b9a50b3e
--- /dev/null
+++ b/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/model/ChatRequest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2025 the original author or authors.
+ *
+ * Licensed 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
+ *
+ * https://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 com.example.agentscope.model;
+
+/**
+ * Chat request model
+ */
+public class ChatRequest {
+
+ private String message;
+ private String userName;
+
+ public ChatRequest() {
+ }
+
+ public ChatRequest(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ @Override
+ public String toString() {
+ return "ChatRequest{" +
+ "message='" + message + '\'' +
+ ", userName='" + userName + '\'' +
+ '}';
+ }
+}
+
diff --git a/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/model/ChatResponse.java b/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/model/ChatResponse.java
new file mode 100644
index 00000000..e665d765
--- /dev/null
+++ b/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/model/ChatResponse.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2025 the original author or authors.
+ *
+ * Licensed 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
+ *
+ * https://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 com.example.agentscope.model;
+
+/**
+ * Chat response model
+ */
+public class ChatResponse {
+
+ private boolean success;
+ private String message;
+ private String agentName;
+ private Long timestamp;
+ private Long processingTime;
+ private String error;
+
+ public ChatResponse() {
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getAgentName() {
+ return agentName;
+ }
+
+ public void setAgentName(String agentName) {
+ this.agentName = agentName;
+ }
+
+ public Long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(Long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public Long getProcessingTime() {
+ return processingTime;
+ }
+
+ public void setProcessingTime(Long processingTime) {
+ this.processingTime = processingTime;
+ }
+
+ public String getError() {
+ return error;
+ }
+
+ public void setError(String error) {
+ this.error = error;
+ }
+
+ @Override
+ public String toString() {
+ return "ChatResponse{" +
+ "success=" + success +
+ ", message='" + message + '\'' +
+ ", agentName='" + agentName + '\'' +
+ ", timestamp=" + timestamp +
+ ", processingTime=" + processingTime +
+ ", error='" + error + '\'' +
+ '}';
+ }
+}
+
diff --git a/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/model/ToolInfo.java b/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/model/ToolInfo.java
new file mode 100644
index 00000000..6918eb41
--- /dev/null
+++ b/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/model/ToolInfo.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2025 the original author or authors.
+ *
+ * Licensed 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
+ *
+ * https://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 com.example.agentscope.model;
+
+import java.util.Map;
+
+/**
+ * Tool info model
+ */
+public class ToolInfo {
+
+ private String name;
+ private String description;
+ private Map parameters;
+
+ public ToolInfo() {
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public Map getParameters() {
+ return parameters;
+ }
+
+ public void setParameters(Map parameters) {
+ this.parameters = parameters;
+ }
+
+ @Override
+ public String toString() {
+ return "ToolInfo{" +
+ "name='" + name + '\'' +
+ ", description='" + description + '\'' +
+ ", parameters=" + parameters +
+ '}';
+ }
+}
+
diff --git a/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/service/ChatService.java b/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/service/ChatService.java
new file mode 100644
index 00000000..ee2151e4
--- /dev/null
+++ b/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/service/ChatService.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2025 the original author or authors.
+ *
+ * Licensed 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
+ *
+ * https://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 com.example.agentscope.service;
+
+import com.example.agentscope.model.ChatRequest;
+import com.example.agentscope.model.ChatResponse;
+import com.example.agentscope.model.ToolInfo;
+import com.example.agentscope.tools.CalculatorTool;
+import com.example.agentscope.tools.WeatherTool;
+import io.agentscope.core.ReActAgent;
+import io.agentscope.core.memory.InMemoryMemory;
+import io.agentscope.core.message.Msg;
+import io.agentscope.core.message.MsgRole;
+import io.agentscope.core.message.TextBlock;
+import io.agentscope.core.model.DashScopeChatModel;
+import io.agentscope.core.tool.Toolkit;
+import io.agentscope.runtime.engine.agents.agentscope.tools.ToolkitInit;
+import io.agentscope.runtime.engine.services.sandbox.SandboxService;
+import io.agentscope.runtime.sandbox.box.BrowserSandbox;
+import io.agentscope.runtime.sandbox.box.Sandbox;
+import org.checkerframework.checker.units.qual.A;
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * Chat service
+ * Handle interaction logic with the Agent
+ */
+@Service
+public class ChatService {
+ @Autowired
+ private ObjectProvider agentProvider;
+
+ @Autowired
+ private Toolkit toolkit;
+
+
+ /**
+ * Handle chat requests
+ */
+ public ChatResponse chat(ChatRequest request) {
+ long startTime = System.currentTimeMillis();
+
+ System.out.println("\n" + "=".repeat(50));
+ System.out.println("๐จ Received user message: " + request.getMessage());
+ System.out.println("=".repeat(50));
+
+ try {
+ // Create user message
+ Msg userMsg = Msg.builder()
+ .name(request.getUserName() != null ? request.getUserName() : "user")
+ .role(MsgRole.USER)
+ .content(List.of(
+ TextBlock.builder()
+ .text(request.getMessage())
+ .build()
+ ))
+ .build();
+
+ // Invoke the Agent
+ ReActAgent agent = agentProvider.getObject();
+ Msg responseMsg = agent.call(userMsg).block();
+
+ long duration = System.currentTimeMillis() - startTime;
+ System.out.println("\nโ
Processing completed, duration: " + duration + "ms");
+ System.out.println("=".repeat(50) + "\n");
+
+ // Build response
+ ChatResponse response = new ChatResponse();
+ response.setSuccess(true);
+ if (responseMsg != null) {
+ response.setMessage(responseMsg.getTextContent());
+ }
+ response.setAgentName(agent.getName());
+ response.setTimestamp(System.currentTimeMillis());
+ response.setProcessingTime(duration);
+
+ return response;
+
+ } catch (Exception e) {
+ System.err.println("โ Processing failed: " + e.getMessage());
+
+ ChatResponse errorResponse = new ChatResponse();
+ errorResponse.setSuccess(false);
+ errorResponse.setMessage("Sorry, an issue occurred while processing your request.");
+ errorResponse.setError(e.getMessage());
+ errorResponse.setTimestamp(System.currentTimeMillis());
+
+ return errorResponse;
+ }
+ }
+
+ /**
+ * Get available tool list
+ */
+ public List getAvailableTools() {
+ return toolkit.getToolSchemas().stream()
+ .map(schema -> {
+ Map schemaMap = new HashMap<>();
+ if (schema != null) {
+ schema.forEach((k, v) -> schemaMap.put(String.valueOf(k), v));
+ }
+
+ ToolInfo info = new ToolInfo();
+ Object function = schemaMap.get("function");
+ if(function instanceof Map , ?>){
+ info.setName(((Map, ?>) function).get("name").toString());
+ info.setDescription(((Map, ?>) function).get("description").toString());
+ if(((Map, ?>) function).get("parameters") instanceof Map, ?> paramsMap){
+ Map paramMap = new HashMap<>();
+ paramsMap.forEach((k, v) -> paramMap.put(String.valueOf(k), v));
+ info.setParameters(paramMap);
+ }
+ }
+ return info;
+ })
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * Reset conversation memory
+ */
+ public void resetMemory() {
+ // Each request creates a new Agent; memory is not shared by default
+ System.out.println("๐ Reset request received (each request creates a new Agent by default)");
+ }
+}
+
diff --git a/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/service/ResourceService.java b/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/service/ResourceService.java
new file mode 100644
index 00000000..a59d8e8e
--- /dev/null
+++ b/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/service/ResourceService.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2025 the original author or authors.
+ *
+ * Licensed 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
+ *
+ * https://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 com.example.agentscope.service;
+
+import io.agentscope.runtime.engine.services.sandbox.SandboxService;
+import jakarta.annotation.PreDestroy;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class ResourceService {
+ @Autowired
+ public SandboxService sandboxService;
+
+ @PreDestroy
+ public void cleanup() {
+ System.out.println("CloseOperation: Releasing resources...");
+ sandboxService.stop();
+ }
+}
diff --git a/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/tools/CalculatorTool.java b/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/tools/CalculatorTool.java
new file mode 100644
index 00000000..60d2e86e
--- /dev/null
+++ b/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/tools/CalculatorTool.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2025 the original author or authors.
+ *
+ * Licensed 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
+ *
+ * https://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 com.example.agentscope.tools;
+
+import io.agentscope.core.tool.Tool;
+import io.agentscope.core.tool.ToolParam;
+import org.springframework.stereotype.Component;
+
+/**
+ * Calculator tool
+ * Provide basic mathematical operations
+ */
+@Component
+public class CalculatorTool {
+
+ /**
+ * Add two numbers
+ */
+ @Tool(description = "Calculate the sum of two numbers")
+ public double add(
+ @ToolParam(name = "a", description = "First number") double a,
+ @ToolParam(name = "b", description = "Second number") double b) {
+
+ System.out.println("โ Calculator invoked: " + a + " + " + b);
+ return a + b;
+ }
+
+ /**
+ * Subtract two numbers
+ */
+ @Tool(description = "Calculate the difference of two numbers")
+ public double subtract(
+ @ToolParam(name = "a", description = "Minuend") double a,
+ @ToolParam(name = "b", description = "Subtrahend") double b) {
+
+ System.out.println("โ Calculator invoked: " + a + " - " + b);
+ return a - b;
+ }
+
+ /**
+ * Multiply two numbers
+ */
+ @Tool(description = "Calculate the product of two numbers")
+ public double multiply(
+ @ToolParam(name = "a", description = "First number") double a,
+ @ToolParam(name = "b", description = "Second number") double b) {
+
+ System.out.println("โ๏ธ Calculator invoked: " + a + " ร " + b);
+ return a * b;
+ }
+
+ /**
+ * Divide two numbers
+ */
+ @Tool(description = "Calculate the quotient of two numbers")
+ public double divide(
+ @ToolParam(name = "a", description = "Dividend") double a,
+ @ToolParam(name = "b", description = "Divisor") double b) {
+
+ System.out.println("โ Calculator invoked: " + a + " รท " + b);
+
+ if (b == 0) {
+ throw new IllegalArgumentException("Divisor cannot be zero");
+ }
+ return a / b;
+ }
+
+ /**
+ * Calculate exponentiation
+ */
+ @Tool(description = "Calculate a number raised to a power")
+ public double power(
+ @ToolParam(name = "base", description = "Base") double base,
+ @ToolParam(name = "exponent", description = "Exponent") double exponent) {
+
+ System.out.println("๐ข Calculator invoked: " + base + " ^ " + exponent);
+ return Math.pow(base, exponent);
+ }
+
+ /**
+ * Calculate square root
+ */
+ @Tool(description = "Calculate the square root of a number")
+ public double sqrt(
+ @ToolParam(name = "number", description = "Number to calculate the square root of") double number) {
+
+ System.out.println("โ Calculator invoked: โ" + number);
+
+ if (number < 0) {
+ throw new IllegalArgumentException("Cannot calculate the square root of a negative number");
+ }
+ return Math.sqrt(number);
+ }
+}
+
diff --git a/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/tools/WeatherTool.java b/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/tools/WeatherTool.java
new file mode 100644
index 00000000..9bb57d97
--- /dev/null
+++ b/examples/simple_sandbox_tool_example/src/main/java/com/example/agentscope/tools/WeatherTool.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2025 the original author or authors.
+ *
+ * Licensed 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
+ *
+ * https://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 com.example.agentscope.tools;
+
+import io.agentscope.core.tool.Tool;
+import io.agentscope.core.tool.ToolParam;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+
+/**
+ * Weather query tool
+ * Provide city weather lookup using mock data
+ */
+@Component
+public class WeatherTool {
+
+ private final Random random = new Random();
+
+ // Mock weather database
+ private final Map weatherDatabase = new HashMap<>() {{
+ put("Beijing", new String[]{"Sunny", "Cloudy", "Overcast", "Light rain"});
+ put("Shanghai", new String[]{"Cloudy", "Light rain", "Sunny", "Overcast"});
+ put("Guangzhou", new String[]{"Sunny", "Cloudy", "Thunderstorm", "Sunny"});
+ put("Shenzhen", new String[]{"Cloudy", "Sunny", "Light rain", "Sunny"});
+ put("Hangzhou", new String[]{"Overcast", "Light rain", "Cloudy", "Sunny"});
+ put("Chengdu", new String[]{"Cloudy", "Overcast", "Light rain", "Cloudy"});
+ }};
+
+ /**
+ * Get current weather information for a specified city
+ *
+ * @param city City name (for example: Beijing, Shanghai, Guangzhou)
+ * @return Weather info string
+ */
+ @Tool(description = "Get current weather for a specified city, including condition and temperature")
+ public String getWeather(
+ @ToolParam(name = "city", description = "City name, for example: Beijing, Shanghai, Guangzhou")
+ String city) {
+
+ System.out.println("๐ค๏ธ Weather tool invoked: querying weather for " + city);
+
+ // Simulate querying weather
+ String[] conditions = weatherDatabase.getOrDefault(
+ city,
+ new String[]{"Sunny", "Cloudy", "Overcast", "Light rain"}
+ );
+
+ String condition = conditions[random.nextInt(conditions.length)];
+ int temperature = 15 + random.nextInt(20); // 15-35ยฐC
+ int humidity = 40 + random.nextInt(40); // 40-80%
+ String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm"));
+
+ return String.format(
+ "Weather for %s\n" +
+ "๐ Time: %s\n" +
+ "โ๏ธ Condition: %s\n" +
+ "๐ก๏ธ Temperature: %dยฐC\n" +
+ "๐ง Humidity: %d%%",
+ city, time, condition, temperature, humidity
+ );
+ }
+
+ /**
+ * Get the weather forecast for the coming days
+ *
+ * @param city City name
+ * @param days Number of forecast days (1-7 days)
+ * @return Weather forecast details
+ */
+ @Tool(description = "Get the weather forecast for a specified city for the next few days")
+ public String getForecast(
+ @ToolParam(name = "city", description = "City name")
+ String city,
+ @ToolParam(name = "days", description = "Number of forecast days, range 1-7")
+ int days) {
+
+ System.out.println("๐
Forecast tool invoked: querying weather for " + city + " for the next " + days + " days");
+
+ if (days < 1 || days > 7) {
+ return "Forecast days must be between 1 and 7";
+ }
+
+ StringBuilder forecast = new StringBuilder();
+ forecast.append(String.format("Weather forecast for %s for the next %d days\n", city, days));
+
+ String[] conditions = weatherDatabase.getOrDefault(
+ city,
+ new String[]{"Sunny", "Cloudy", "Overcast", "Light rain"}
+ );
+
+ for (int i = 1; i <= days; i++) {
+ String condition = conditions[random.nextInt(conditions.length)];
+ int tempHigh = 20 + random.nextInt(15);
+ int tempLow = 10 + random.nextInt(10);
+
+ forecast.append(String.format(
+ "\nDay %d: %s, temperature %d~%dยฐC",
+ i, condition, tempLow, tempHigh
+ ));
+ }
+
+ return forecast.toString();
+ }
+}
+