Skip to content

Latest commit

Β 

History

History
818 lines (614 loc) Β· 22.3 KB

File metadata and controls

818 lines (614 loc) Β· 22.3 KB

Code Execution Guide (CodeSpace)

This guide covers code execution capabilities in AgentBay SDK's CodeSpace environment. CodeSpace provides a dedicated development environment optimized for running code in Python, JavaScript, R, and Java.

πŸ“‹ Table of Contents

🎯 Overview

CodeSpace is AgentBay's development-focused environment that provides:

  • Multi-language Support - Run Python, JavaScript/Node.js, R, and Java code
  • Isolated Execution - Secure, containerized code execution
  • Enhanced Results - Rich output formats including HTML, images, charts, and more
  • Development Tools - Pre-installed interpreters and development utilities
  • File Operations - Read and write files for script execution

πŸ”§ CodeSpace Environment

Creating a CodeSpace Session

To use code execution features, create a session with the code_latest image:

from agentbay import AgentBay
from agentbay import CreateSessionParams

agent_bay = AgentBay(api_key="your-api-key")

session_params = CreateSessionParams(image_id="code_latest")
result = agent_bay.create(session_params)

if result.success:
    session = result.session
    print(f"CodeSpace session created: {session.session_id}")
else:
    print(f"Failed to create session: {result.error_message}")

Important: The run_code() method requires image_id="code_latest" when creating the session.

Recommended Aliases (Non-breaking)

AgentBay SDK provides non-breaking aliases to improve ergonomics and LLM-generated code success rate:

  • Prefer session.code.run(...) or session.code.execute(...) (aliases of run_code(...))
  • Prefer session.command.run(...) (alias of execute_command(...))
  • Prefer session.fs (alias of session.file_system) for file operations

✨ Enhanced Code Execution

AgentBay now provides enhanced code execution results with rich output formats and detailed execution information.

Enhanced Result Structure

from agentbay import AgentBay, CreateSessionParams, EnhancedCodeExecutionResult

agent_bay = AgentBay(api_key="your-api-key")
session_params = CreateSessionParams(image_id="code_latest")
result = agent_bay.create(session_params)

if result.success:
    session = result.session
    
    code = """
print("Hello, Enhanced AgentBay!")
result = 2 + 2
print(f"2 + 2 = {result}")
result
"""
    
    result = session.code.run(code, "python")
    
    # Enhanced result provides rich information
    print(f"Success: {result.success}")
    print(f"Execution time: {result.execution_time}s")
    print(f"Request ID: {result.request_id}")
    
    # Access logs
    print(f"Stdout: {result.logs.stdout}")
    print(f"Stderr: {result.logs.stderr}")
    
    # Access results in multiple formats
    for i, res in enumerate(result.results):
        print(f"Result {i}: {res.text}")
        print(f"Available formats: {res.formats()}")
    
    # Backward compatibility - still works
    print(f"Result (legacy): {result.result}")
    
    session.delete()

Working with Result Types

Use CodeExecutionResult (the code-execution model) instead of the agent module's ExecutionResult to avoid type confusion.

from agentbay import (
    AgentBay, 
    CreateSessionParams,
    EnhancedCodeExecutionResult,
    CodeExecutionResult,
    ExecutionLogs,
    ExecutionError
)

# Type checking and handling
result = session.code.run(code, "python")

if isinstance(result, EnhancedCodeExecutionResult):
    # Access execution logs
    if isinstance(result.logs, ExecutionLogs):
        print(f"Stdout lines: {len(result.logs.stdout)}")
        print(f"Stderr lines: {len(result.logs.stderr)}")
    
    # Process multiple results
    for exec_result in result.results:
        if isinstance(exec_result, CodeExecutionResult):
            if exec_result.text:
                print(f"Text output: {exec_result.text}")
            if exec_result.html:
                print(f"HTML output: {exec_result.html}")
    
    # Handle errors
    if result.error and isinstance(result.error, ExecutionError):
        print(f"Error: {result.error.name} - {result.error.value}")

🐍 Python Code Execution

Basic Python Execution

from agentbay import AgentBay
from agentbay import CreateSessionParams

agent_bay = AgentBay(api_key="your-api-key")

session_params = CreateSessionParams(image_id="code_latest")
result = agent_bay.create(session_params)

if result.success:
    session = result.session
    
    code = """
import os
import sys
print(f"Python version: {sys.version}")
print(f"Current directory: {os.getcwd()}")
print("Hello from AgentBay!")
"""
    
    result = session.code.run(code, "python")
    if result.success:
        print("Output:", result.result)
        # Output: Python version: 3.11.2 (main, Apr 28 2025, 14:11:48) [GCC 12.2.0]
        #         Current directory: /workspace
        #         Hello from AgentBay!
    else:
        print("Execution failed:", result.error_message)
    
    agent_bay.delete(session)

Python with Calculations

session_params = CreateSessionParams(image_id="code_latest")
result = agent_bay.create(session_params)

if result.success:
    session = result.session
    
    code = """
import math

# Calculate factorial
def factorial(n):
    return math.factorial(n)

# Fibonacci sequence
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

print(f"Factorial of 10: {factorial(10)}")
print(f"Fibonacci of 10: {fibonacci(10)}")

# List comprehension
squares = [x**2 for x in range(1, 11)]
print(f"Squares: {squares}")
"""
    
    result = session.code.run_code(code, "python")
    if result.success:
        print("Output:", result.result)
        # Output: Factorial of 10: 3628800
        #         Fibonacci of 10: 55
        #         Squares: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
    
    agent_bay.delete(session)

πŸ““ Jupyter-like Python Execution (Context Persistence)

When you call session.code.run() (or session.code.run_code()) multiple times within the same session, the Python runtime may preserve an interactive execution context (similar to a Jupyter kernel). This enables workflows like:

  • Defining variables and functions once, then reusing them in later calls
  • Iterative exploration and debugging
  • Notebook-style step-by-step execution

Notes:

  • This behavior applies to Python in the CodeSpace environment (image_id="code_latest").
  • Context persistence is scoped to a single session. Creating a new session starts a new context.
  • If your workflow relies on persistence, avoid calling session.delete() until the end.

Example: Define Once, Use Later

from agentbay import AgentBay, CreateSessionParams

agent_bay = AgentBay(api_key="your-api-key")
session_result = agent_bay.create(CreateSessionParams(image_id="code_latest"))
session = session_result.session

setup = """
x = 41
def add(a, b):
    return a + b
print("CONTEXT_SETUP_DONE")
""".strip()

use = """
print(f"CONTEXT_VALUE:{x + 1}")
print(f"CONTEXT_FUNC:{add(1, 2)}")
""".strip()

session.code.run(setup, "python")
result = session.code.run(use, "python")
print(result.result)

session.delete()

You can also run the verified end-to-end examples in this repository:

  • Async: python/docs/examples/_async/codespace/jupyter_context_persistence.py
  • Sync: python/docs/examples/_sync/codespace/jupyter_context_persistence.py

R and Java Context Persistence (Jupyter-like)

In CodeSpace, you can also use the same notebook-style workflow with R and Java. Within the same session, you can define variables in one run_code() call and reuse them in subsequent calls.

Verified end-to-end examples in this repository:

  • Async: python/docs/examples/_async/codespace/jupyter_context_persistence_r_java.py
  • Sync: python/docs/examples/_sync/codespace/jupyter_context_persistence_r_java.py

🟨 JavaScript Code Execution

Node.js Code Execution

from agentbay import AgentBay
from agentbay import CreateSessionParams

agent_bay = AgentBay(api_key="your-api-key")

session_params = CreateSessionParams(image_id="code_latest")
result = agent_bay.create(session_params)

if result.success:
    session = result.session
    
    js_code = """
const fs = require('fs');
const path = require('path');

console.log('Node.js version:', process.version);
console.log('Current directory:', process.cwd());

// Create a simple file
fs.writeFileSync('/tmp/hello.txt', 'Hello from Node.js!');
console.log('File created successfully');
"""
    
    result = session.code.run_code(js_code, "javascript")
    if result.success:
        print("Output:", result.result)
        # Output: Node.js version: v18.20.5
        #         Current directory: /workspace
        #         File created successfully
    else:
        print("Execution failed:", result.error_message)
    
    agent_bay.delete(session)

JavaScript with Data Processing

session_params = CreateSessionParams(image_id="code_latest")
result = agent_bay.create(session_params)

if result.success:
    session = result.session
    
    js_code = """
// Array operations
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

const sum = numbers.reduce((a, b) => a + b, 0);
const avg = sum / numbers.length;
const squares = numbers.map(x => x * x);

console.log('Numbers:', numbers);
console.log('Sum:', sum);
console.log('Average:', avg);
console.log('Squares:', squares);

// Object manipulation
const data = {
    name: 'AgentBay',
    version: '1.0',
    features: ['Python', 'JavaScript', 'R', 'Java', 'File I/O']
};

console.log('\\nData:', JSON.stringify(data, null, 2));
"""
    
    result = session.code.run_code(js_code, "javascript")
    if result.success:
        print("Output:", result.result)
        # Output: Numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        #         Sum: 55
        #         Average: 5.5
        #         Squares: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
        #         
        #         Data: {
        #           "name": "AgentBay",
        #           "version": "1.0",
        #           "features": [
        #             "Python",
        #             "JavaScript",
        #             "File I/O"
        #           ]
        #         }
    
    agent_bay.delete(session)

🎨 Rich Output Formats

AgentBay's enhanced code execution supports multiple output formats including HTML, images, charts, and more.

HTML Output

from agentbay import AgentBay, CreateSessionParams

agent_bay = AgentBay(api_key="your-api-key")
session_params = CreateSessionParams(image_id="code_latest")
result = agent_bay.create(session_params)

if result.success:
    session = result.session
    
    code = """
from IPython.display import display, HTML

# Create HTML output
html_content = '''
<div style="background: #f0f8ff; padding: 20px; border-radius: 10px;">
    <h2 style="color: #2e8b57;">AgentBay Results</h2>
    <p>This is <strong>HTML output</strong> from code execution!</p>
    <ul>
        <li>Rich formatting</li>
        <li>Interactive elements</li>
        <li>Custom styling</li>
    </ul>
</div>
'''

display(HTML(html_content))
"""
    
    result = session.code.run_code(code, "python")
    
    # Check for HTML output
    for res in result.results:
        if res.html:
            print("HTML output found:")
            print(res.html)
    
    session.delete()

Markdown Output

code = """
from IPython.display import display, Markdown

markdown_content = '''
# AgentBay Code Execution

## Features

- **Enhanced Results**: Multiple output formats
- **Rich Content**: HTML, Markdown, Images
- **Performance**: Execution timing and metadata

### Example Table

| Language | Support | Performance |
|----------|---------|-------------|
| Python   | βœ…      | Excellent   |
| JavaScript| βœ…     | Excellent   |

> This is generated from code execution!
'''

display(Markdown(markdown_content))
"""

result = session.code.run_code(code, "python")

# Check for Markdown output
for res in result.results:
    if res.markdown:
        print("Markdown output found:")
        print(res.markdown)

Image Output (Charts and Plots)

code = """
import matplotlib.pyplot as plt
import numpy as np

# Create a simple plot
x = np.linspace(0, 10, 100)
y = np.sin(x)

plt.figure(figsize=(10, 6))
plt.plot(x, y, 'b-', linewidth=2, label='sin(x)')
plt.title('Sine Wave Generated by AgentBay')
plt.xlabel('x')
plt.ylabel('sin(x)')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
"""

result = session.code.run_code(code, "python")

# Check for image output
for res in result.results:
    if res.png:
        print("PNG image found (base64 encoded)")
        # res.png contains base64 encoded image data
    if res.jpeg:
        print("JPEG image found (base64 encoded)")
        # res.jpeg contains base64 encoded image data

SVG Output

code = """
from IPython.display import display, SVG

svg_content = '''
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
  <circle cx="100" cy="100" r="80" fill="#4CAF50" stroke="#2E7D32" stroke-width="4"/>
  <text x="100" y="110" text-anchor="middle" fill="white" font-size="16" font-family="Arial">
    AgentBay
  </text>
</svg>
'''

display(SVG(svg_content))
"""

result = session.code.run_code(code, "python")

# Check for SVG output
for res in result.results:
    if res.svg:
        print("SVG output found:")
        print(res.svg)

LaTeX Mathematical Expressions

code = r"""
from IPython.display import display, Latex

latex_content = r'''
\begin{align}
E &= mc^2 \\
F &= ma \\
\nabla \cdot \mathbf{E} &= \frac{\rho}{\epsilon_0}
\end{align}
'''

display(Latex(latex_content))
"""

result = session.code.run_code(code, "python")

# Check for LaTeX output
for res in result.results:
    if res.latex:
        print("LaTeX output found:")
        print(res.latex)

Chart Data (Vega-Lite)

code = """
# Simulate chart output with structured data
class MockChart:
    def _repr_mimebundle_(self, include=None, exclude=None):
        return {
            "application/vnd.vegalite.v4+json": {
                "data": {"values": [
                    {"x": "A", "y": 28},
                    {"x": "B", "y": 55},
                    {"x": "C", "y": 43},
                    {"x": "D", "y": 91}
                ]},
                "mark": "bar",
                "encoding": {
                    "x": {"field": "x", "type": "nominal"},
                    "y": {"field": "y", "type": "quantitative"}
                }
            }
        }

from IPython.display import display
display(MockChart())
"""

result = session.code.run_code(code, "python")

# Check for chart data
for res in result.results:
    if res.chart:
        print("Chart data found:")
        print(res.chart)

πŸ“ Code Execution with File I/O

Writing and Executing Scripts

from agentbay import AgentBay

agent_bay = AgentBay(api_key="your-api-key")
result = agent_bay.create()

if result.success:
    session = result.session
    
    script_content = """
import json
import sys

data = {
    'message': 'Hello from uploaded script',
    'args': sys.argv[1:] if len(sys.argv) > 1 else []
}

with open('/tmp/output.json', 'w') as f:
    json.dump(data, f, indent=2)

print(json.dumps(data, indent=2))
"""
    
    write_result = session.file_system.write_file("/tmp/script.py", script_content)
    if write_result.success:
        print("Script uploaded successfully")
        
        exec_result = session.command.execute_command("python3 /tmp/script.py arg1 arg2")
        if exec_result.success:
            print("Script output:", exec_result.output)
            # Script output: {
            #   "message": "Hello from uploaded script",
            #   "args": [
            #     "arg1",
            #     "arg2"
            #   ]
            # }
            
            output_result = session.file_system.read_file("/tmp/output.json")
            if output_result.success:
                print("Output file content:", output_result.content)
                # Output file content: {
                #   "message": "Hello from uploaded script",
                #   "args": [
                #     "arg1",
                #     "arg2"
                #   ]
                # }
        else:
            print("Execution failed:", exec_result.error_message)
    else:
        print("Failed to write script:", write_result.error_message)
    
    agent_bay.delete(session)

Multi-file Projects

from agentbay import AgentBay
from agentbay import CreateSessionParams

agent_bay = AgentBay(api_key="your-api-key")

session_params = CreateSessionParams(image_id="code_latest")
result = agent_bay.create(session_params)

if result.success:
    session = result.session
    
    session.file_system.create_directory("/workspace/myproject")
    
    main_py = """
from utils import greet

if __name__ == "__main__":
    print(greet("AgentBay"))
"""
    
    utils_py = """
def greet(name):
    return f"Hello, {name}!"
"""
    
    session.file_system.write_file("/workspace/myproject/main.py", main_py)
    session.file_system.write_file("/workspace/myproject/utils.py", utils_py)
    
    result = session.command.execute_command("cd /workspace/myproject && python3 main.py")
    if result.success:
        print("Project output:", result.output)
        # Project output: Hello, AgentBay!
    else:
        print("Execution failed:", result.error_message)
    
    agent_bay.delete(session)

πŸ’‘ Best Practices

1. Use Enhanced Result Types

Always use the enhanced result types for better type safety and functionality:

from agentbay import EnhancedCodeExecutionResult, CodeExecutionResult

result = session.code.run_code(code, "python")

# Type-safe access to enhanced features
if isinstance(result, EnhancedCodeExecutionResult):
    # Access execution metadata
    print(f"Execution time: {result.execution_time}s")
    
    # Check all available output formats
    for res in result.results:
        if isinstance(res, CodeExecutionResult):
            formats = res.formats()
            print(f"Available formats: {formats}")

2. Handle Multiple Output Formats

Code execution can produce multiple types of output. Check all available formats:

result = session.code.run_code(code, "python")

for i, res in enumerate(result.results):
    print(f"Result {i}:")
    
    if res.text:
        print(f"  Text: {res.text}")
    if res.html:
        print(f"  HTML available: {len(res.html)} chars")
    if res.png:
        print(f"  PNG image available")
    if res.markdown:
        print(f"  Markdown available")
    if res.chart:
        print(f"  Chart data available")

3. Monitor Execution Logs

Use the enhanced logging capabilities to debug and monitor your code:

result = session.code.run_code(code, "python")

# Check stdout and stderr separately
if result.logs.stdout:
    print("Standard output:")
    for line in result.logs.stdout:
        print(f"  {line.strip()}")

if result.logs.stderr:
    print("Error output:")
    for line in result.logs.stderr:
        print(f"  {line.strip()}")

4. Use Timeout for Long-Running Code

The default timeout for run_code() is 60 seconds. Note: Due to gateway limitations, each request cannot exceed 60 seconds.

# Default timeout is 60 seconds
result = session.code.run_code(code, "python")

# You can specify a custom timeout (max 60 seconds)
result = session.code.run_code(code, "python", timeout_s=60)

5. Error Handling with Enhanced Details

Take advantage of enhanced error information:

result = session.code.run_code(code, "python")

if not result.success:
    # Check for detailed error information
    if result.error:
        print(f"Error type: {result.error.name}")
        print(f"Error message: {result.error.value}")
        print(f"Traceback: {result.error.traceback}")
    else:
        # Fallback to basic error message
        print(f"Error: {result.error_message}")
    
    # Check stderr for additional error details
    if result.logs.stderr:
        print("Additional error output:")
        for line in result.logs.stderr:
            print(f"  {line.strip()}")

6. Use Standard Library Only

CodeSpace comes with Python and Node.js standard libraries pre-installed. For best performance and reliability, use only built-in modules:

Python: os, sys, json, math, datetime, re, matplotlib, numpy, etc.
JavaScript: fs, path, os, crypto, etc.

7. Backward Compatibility

The enhanced results maintain backward compatibility with existing code:

# Old way (still works)
result = session.code.run_code(code, "python")
print(result.result)  # Returns combined text output

# New way (recommended)
result = session.code.run_code(code, "python")
for res in result.results:
    if res.is_main_result:
        print(res.text)  # Get the main result specifically

πŸ“š Related Documentation

πŸ†˜ Getting Help

Happy coding with AgentBay CodeSpace! πŸš€