codeexecutor

package
v0.0.0-...-3ab8af9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 23, 2025 License: Apache-2.0 Imports: 23 Imported by: 0

Documentation

Overview

Package codeexecutor provides secure code execution with multiple backends and safety controls.

The codeexecutor package implements the types.CodeExecutor interface with three distinct execution backends, each offering different levels of security and functionality for running code generated by agents or provided by users.

Execution Backends

The package provides three execution strategies:

  • BuiltInExecutor: Uses model's native code execution (Gemini 2.0+)
  • ContainerExecutor: Docker-based sandboxing with resource limits
  • LocalExecutor: Direct host execution (requires explicit opt-in)

Security Model

Execution backends are ordered by security level:

  1. BuiltInExecutor: Safest - Uses model's built-in sandboxed execution
  2. ContainerExecutor: Secure - Docker isolation with network restrictions
  3. LocalExecutor: Unsafe - Direct host execution (development only)

The choice of executor depends on security requirements and available infrastructure.

Basic Usage

Creating executors:

// Built-in executor (safest)
executor := codeexecutor.NewBuiltInExecutor()

// Container executor (secure)
executor, err := codeexecutor.NewContainerExecutor(
	codeexecutor.WithImage("python:3.11-slim"),
	codeexecutor.WithTimeout(30*time.Second),
)

// Local executor (unsafe - requires explicit opt-in)
executor := codeexecutor.NewLocalExecutor(
	codeexecutor.WithAllowUnsafe(true),
	codeexecutor.WithWorkDir("/tmp/code-execution"),
)

Executing code:

input := &types.CodeExecutionInput{
	Code:     "print('Hello, World!')",
	Language: "python",
}

result, err := executor.ExecuteCode(ctx, invocationContext, input)
if err != nil {
	log.Fatal(err)
}

fmt.Println("Output:", result.Output)
fmt.Println("Exit Code:", result.ExitCode)

Execution Features

Stateful Execution:

  • Variables and imports persist across Execute calls
  • Useful for iterative development and data analysis
  • Configurable via execution options

Long-Running Operations:

  • Support for operations that take extended time
  • Proper timeout and cancellation handling
  • Progress reporting capabilities

Data File Optimization:

  • Automatic extraction and processing of CSV and data files
  • Direct file attachment to execution environment
  • Optimized for large datasets

Configuration Options

Executors support extensive configuration:

executor := codeexecutor.NewContainerExecutor(
	codeexecutor.WithStateful(true),           // Enable stateful execution
	codeexecutor.WithLongRunning(true),        // Support long operations
	codeexecutor.WithOptimizeDataFiles(true),  // Optimize data file handling
	codeexecutor.WithMaxRetries(3),            // Retry failed executions
	codeexecutor.WithRetryDelay(time.Second),  // Delay between retries
	codeexecutor.WithTimeout(60*time.Second),  // Execution timeout
)

Language Support

The package supports multiple programming languages:

  • Python (most common for AI/ML tasks)
  • JavaScript/Node.js
  • R (data analysis)
  • Bash/Shell scripts
  • Custom language support via container images

Language detection is automatic based on code patterns and explicit hints.

Container Execution

ContainerExecutor provides robust sandboxing:

executor, err := codeexecutor.NewContainerExecutor(
	codeexecutor.WithImage("python:3.11-slim"),
	codeexecutor.WithMemoryLimit("512m"),
	codeexecutor.WithCPULimit("1.0"),
	codeexecutor.WithNetworkDisabled(true),
	codeexecutor.WithTimeout(30*time.Second),
)

Features:

  • Resource limits (memory, CPU, disk)
  • Network isolation
  • Filesystem sandboxing
  • Custom Docker images
  • Automatic cleanup

Error Handling and Retries

Robust error handling with configurable retry logic:

// Execution errors are automatically retried
result, err := executor.ExecuteCode(ctx, ictx, input)
if err != nil {
	// Check if retries were exhausted
	if execErr, ok := err.(*types.ExecutionError); ok {
		fmt.Printf("Failed after %d attempts\n", execErr.Attempts)
	}
}

Integration with Agents

Code executors integrate seamlessly with the agent system:

agent := agent.NewLLMAgent(ctx, "coder",
	agent.WithCodeExecutor(executor),
	agent.WithInstruction("You can execute code to solve problems"),
)

Agents automatically:

  • Extract code blocks from responses
  • Execute code using the configured executor
  • Include execution results in conversation context
  • Handle errors and retries transparently

Thread Safety

All executors are safe for concurrent use. However, stateful executors maintain per-session state, so concurrent executions within the same session may interfere with each other.

Resource Management

Proper resource cleanup is essential:

defer executor.Close() // Always close executors

Executors manage:

  • Docker containers and images
  • Temporary files and directories
  • Network connections
  • Background processes

Best Practices

  1. Use BuiltInExecutor when supported by the model
  2. Use ContainerExecutor for production deployments
  3. Never use LocalExecutor in production
  4. Always set appropriate timeouts
  5. Configure resource limits for containers
  6. Handle errors and retries appropriately
  7. Close executors when done

Index

Constants

View Source
const (
	ContextKey            = "_code_execution_context"
	SessionIDKey          = "execution_session_id"
	ProcessedFileNamesKey = "processed_input_files"
	InputFileKey          = "_code_executor_input_files"
	ErrorCountKey         = "_code_executor_error_counts"

	CodeExecutionResultsKey = "_code_execution_results"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type BuiltInExecutor

type BuiltInExecutor struct {
	// contains filtered or unexported fields
}

BuiltInExecutor uses the model's built-in code execution capabilities. This is supported by Gemini 2.0+ models with native code execution tools.

func NewBuiltInExecutor

func NewBuiltInExecutor(opts ...types.ExecutionOption) *BuiltInExecutor

NewBuiltInExecutor creates a new built-in executor using the model's native capabilities.

func (*BuiltInExecutor) Close

func (e *BuiltInExecutor) Close() error

Close implements types.CodeExecutor.

func (*BuiltInExecutor) CodeBlockDelimiters

func (e *BuiltInExecutor) CodeBlockDelimiters() []types.DelimiterPair

CodeBlockDelimiters implements types.CodeExecutor.

func (*BuiltInExecutor) ErrorRetryAttempts

func (e *BuiltInExecutor) ErrorRetryAttempts() int

ErrorRetryAttempts implements types.CodeExecutor.

func (*BuiltInExecutor) ExecuteCode

ExecuteCode implements types.CodeExecutor.

func (*BuiltInExecutor) ExecutionResultDelimiters

func (e *BuiltInExecutor) ExecutionResultDelimiters() types.DelimiterPair

ExecutionResultDelimiters implements types.CodeExecutor.

func (*BuiltInExecutor) IsLongRunning

func (e *BuiltInExecutor) IsLongRunning() bool

IsLongRunning implements types.CodeExecutor.

func (*BuiltInExecutor) IsStateful

func (e *BuiltInExecutor) IsStateful() bool

IsStateful implements types.CodeExecutor.

func (*BuiltInExecutor) OptimizeDataFile

func (e *BuiltInExecutor) OptimizeDataFile() bool

OptimizeDataFile implements types.CodeExecutor.

func (*BuiltInExecutor) ProcessLLMRequest

func (a *BuiltInExecutor) ProcessLLMRequest(ctx context.Context, request *types.LLMRequest)

ProcessLLMRequest processes the LLM request to ensure it has the necessary configuration for code execution.

type CodeBlock

type CodeBlock struct {
	Language string
	Code     string
	Start    int // Starting position in original text
	End      int // Ending position in original text
}

CodeBlock represents a parsed code block with language and content.

type CodeBlockParser

type CodeBlockParser struct {
	// contains filtered or unexported fields
}

CodeBlockParser extracts code blocks from text using configurable delimiters.

func NewCodeBlockParser

func NewCodeBlockParser(delimiters []types.DelimiterPair) *CodeBlockParser

NewCodeBlockParser creates a new parser with the given delimiters.

func NewDefaultCodeBlockParser

func NewDefaultCodeBlockParser() *CodeBlockParser

NewDefaultCodeBlockParser creates a parser with default delimiters.

func (*CodeBlockParser) ExtractCodeBlocks

func (p *CodeBlockParser) ExtractCodeBlocks(text string) ([]*CodeBlock, error)

ExtractCodeBlocks extracts all code blocks from the given text.

func (*CodeBlockParser) FilterByLanguage

func (p *CodeBlockParser) FilterByLanguage(blocks []*CodeBlock, languages ...string) []*CodeBlock

FilterByLanguage returns only code blocks matching the specified languages. If no languages are specified, all blocks are returned.

type CodeExecutionUtils

type CodeExecutionUtils struct{}

CodeExecutionUtils represents an utility functions for code execution.

func NewCodeExecutionUtils

func NewCodeExecutionUtils() *CodeExecutionUtils

NewCodeExecutionUtils creates a new instance of CodeExecutionUtils.

func (*CodeExecutionUtils) BuildCodeExecutionResultPart

func (e *CodeExecutionUtils) BuildCodeExecutionResultPart(codeExecutionResult *types.CodeExecutionResult) *genai.Part

BuildCodeExecutionResultPart builds the code execution result part from the code execution result.

func (*CodeExecutionUtils) BuildExecutableCodePart

func (e *CodeExecutionUtils) BuildExecutableCodePart(code string) *genai.Part

BuildExecutableCodePart builds an executable code part with code string.

func (*CodeExecutionUtils) ConvertCodeExecutionParts

func (e *CodeExecutionUtils) ConvertCodeExecutionParts(content *genai.Content, codeBlockDelimiter, executionResultDelimiters types.DelimiterPair)

ConvertCodeExecutionParts converts the code execution parts to text parts in a *genai.Content.

func (*CodeExecutionUtils) ExtractCodeAndTruncateContent

func (e *CodeExecutionUtils) ExtractCodeAndTruncateContent(content *genai.Content, codeBlockDelimiters []types.DelimiterPair) string

ExtractCodeAndTruncateContent extracts the first code block from the content and truncate everything after it.

func (*CodeExecutionUtils) GetEncodedFileContent

func (e *CodeExecutionUtils) GetEncodedFileContent(data []byte) []byte

GetEncodedFileContent gets the file content as a base64-encoded bytes.

type CodeExecutorContext

type CodeExecutorContext struct {
	// contains filtered or unexported fields
}

CodeExecutorContext manages persistent state for code execution sessions. It tracks execution history, error counts, and file management across multiple execution calls.

func GetContextFromInvocation

func GetContextFromInvocation(ictx *types.InvocationContext, executionID string) *CodeExecutorContext

GetContextFromInvocation extracts or creates a CodeExecutorContext from an InvocationContext. This enables isolated code execution state management per invocation while maintaining session-level persistence across multiple execution calls.

The function creates a State object from the session's state map and uses the provided execution ID for context isolation. If executionID is empty, it falls back to the invocation ID from the context.

Returns nil if the invocation context or its session is nil.

func NewExecutionContext

func NewExecutionContext(sessionState *types.State) *CodeExecutorContext

NewExecutionContext creates a new execution context with the given execution ID.

func (*CodeExecutorContext) AddExecutionResult

func (ec *CodeExecutorContext) AddExecutionResult(result *types.CodeExecutionResult)

AddExecutionResult adds an execution result to the context. This is a convenience method that extracts the execution details from the result.

func (*CodeExecutorContext) AddInputFiles

func (ec *CodeExecutorContext) AddInputFiles(files ...*types.CodeExecutionFile)

AddInputFiles adds files to the input files list.

func (*CodeExecutorContext) AddProcessedFileNames

func (ec *CodeExecutorContext) AddProcessedFileNames(fileNames ...string)

AddProcessedFileNames adds file names to the processed files list.

func (*CodeExecutorContext) ClearInputFiles

func (ec *CodeExecutorContext) ClearInputFiles(files ...*types.CodeExecutionFile)

ClearInputFiles removes the input files and processed file names to the code executor context.

func (*CodeExecutorContext) GetErrorCount

func (ec *CodeExecutorContext) GetErrorCount(invocationID string) int

GetErrorCount returns the error count for the given invocation ID.

func (*CodeExecutorContext) GetExecutionID

func (ec *CodeExecutorContext) GetExecutionID() string

GetExecutionID returns the execution ID for this context.

func (*CodeExecutorContext) GetInputFiles

func (ec *CodeExecutorContext) GetInputFiles() []*types.CodeExecutionFile

GetInputFiles returns a copy of the input files.

func (*CodeExecutorContext) GetProcessedFileNames

func (ec *CodeExecutorContext) GetProcessedFileNames() []string

GetProcessedFileNames returns a copy of the processed file names.

func (*CodeExecutorContext) GetStateDelta

func (ec *CodeExecutorContext) GetStateDelta() map[string]any

GetStateDelta gets the state delta to update in the persistent session state.

func (*CodeExecutorContext) IncrementErrorCount

func (ec *CodeExecutorContext) IncrementErrorCount(invocationID string)

IncrementErrorCount increments the error count for the given invocation ID.

func (*CodeExecutorContext) ResetErrorCount

func (ec *CodeExecutorContext) ResetErrorCount(invocationID string)

ResetErrorCount resets the error count from the session state.

func (*CodeExecutorContext) SetExecutionID

func (ec *CodeExecutorContext) SetExecutionID(executionID string)

SetExecutionID updates the execution ID for this context.

func (*CodeExecutorContext) UpdateExecutionResult

func (ec *CodeExecutorContext) UpdateExecutionResult(invocationID, code, stdout, stderr string)

UpdateExecutionResult updates the execution result for the given invocation ID. If the result doesn't exist, it will be added.

type ContainerExecutor

type ContainerExecutor struct {
	// contains filtered or unexported fields
}

ContainerExecutor represents a code executor that uses a custom container to execute code.

This provides a safer execution environment compared to local execution.

func NewContainerExecutor

func NewContainerExecutor(opts ...any) (*ContainerExecutor, error)

NewContainerExecutor creates a new container-based code executor.

func (*ContainerExecutor) Close

func (e *ContainerExecutor) Close() error

Close implements types.CodeExecutor.

func (*ContainerExecutor) CodeBlockDelimiters

func (e *ContainerExecutor) CodeBlockDelimiters() []types.DelimiterPair

CodeBlockDelimiters implements types.CodeExecutor.

func (*ContainerExecutor) ErrorRetryAttempts

func (e *ContainerExecutor) ErrorRetryAttempts() int

ErrorRetryAttempts implements types.CodeExecutor.

func (*ContainerExecutor) ExecuteCode

ExecuteCode implements types.CodeExecutor.

func (*ContainerExecutor) ExecutionResultDelimiters

func (e *ContainerExecutor) ExecutionResultDelimiters() types.DelimiterPair

ExecutionResultDelimiters implements types.CodeExecutor.

func (*ContainerExecutor) IsLongRunning

func (e *ContainerExecutor) IsLongRunning() bool

IsLongRunning implements types.CodeExecutor.

func (*ContainerExecutor) IsStateful

func (e *ContainerExecutor) IsStateful() bool

IsStateful implements types.CodeExecutor.

func (*ContainerExecutor) OptimizeDataFile

func (e *ContainerExecutor) OptimizeDataFile() bool

OptimizeDataFile implements types.CodeExecutor.

type ContainerExecutorOption

type ContainerExecutorOption func(*ContainerExecutor)

ContainerExecutorOption is a functional option for configuring ContainerExecutor.

func WithCPULimit

func WithCPULimit(limit int64) ContainerExecutorOption

WithCPULimit sets the CPU limit for containers (in nano CPUs).

func WithDockerClient

func WithDockerClient(client *client.Client) ContainerExecutorOption

WithDockerClient sets a custom Docker client.

func WithDockerImage

func WithDockerImage(dockerImage string) ContainerExecutorOption

WithDockerImage sets the Docker image to use for execution.

func WithDockerfile

func WithDockerfile(dockerfile string) ContainerExecutorOption

WithDockerfile sets the Dockerfile to use for execution.

func WithMemoryLimit

func WithMemoryLimit(limit int64) ContainerExecutorOption

WithMemoryLimit sets the memory limit for containers (in bytes).

type ExecutionResultFormatter

type ExecutionResultFormatter struct {
	// contains filtered or unexported fields
}

ExecutionResultFormatter formats execution results with configurable delimiters.

func NewDefaultExecutionResultFormatter

func NewDefaultExecutionResultFormatter() *ExecutionResultFormatter

NewDefaultExecutionResultFormatter creates a formatter with default delimiters.

func NewExecutionResultFormatter

func NewExecutionResultFormatter(delimiters types.DelimiterPair) *ExecutionResultFormatter

NewExecutionResultFormatter creates a new formatter with the given delimiters.

func (*ExecutionResultFormatter) ExtractExecutionResults

func (f *ExecutionResultFormatter) ExtractExecutionResults(text string) ([]string, error)

ExtractExecutionResults extracts execution results from formatted text.

func (*ExecutionResultFormatter) FormatInlineResult

func (f *ExecutionResultFormatter) FormatInlineResult(result *types.CodeExecutionResult) string

FormatInlineResult formats a short inline result without delimiters.

func (*ExecutionResultFormatter) FormatResult

func (f *ExecutionResultFormatter) FormatResult(result *types.CodeExecutionResult) string

FormatResult formats an execution result with delimiters.

type LocalExecutor

type LocalExecutor struct {
	// contains filtered or unexported fields
}

LocalExecutor executes code in the local environment.

WARNING: This executor is inherently unsafe as it runs arbitrary code with the same privileges as the calling process. Use only in trusted environments.

func NewLocalExecutor

func NewLocalExecutor(opts ...any) (*LocalExecutor, error)

NewLocalExecutor creates a new local code executor.

NOTE(adk-go): This executor requires explicit opt-in to unsafe execution.

func (*LocalExecutor) Close

func (e *LocalExecutor) Close() error

Close implements types.CodeExecutor.

func (*LocalExecutor) CodeBlockDelimiters

func (e *LocalExecutor) CodeBlockDelimiters() []types.DelimiterPair

CodeBlockDelimiters implements types.CodeExecutor.

func (*LocalExecutor) ErrorRetryAttempts

func (e *LocalExecutor) ErrorRetryAttempts() int

ErrorRetryAttempts implements types.CodeExecutor.

func (*LocalExecutor) ExecuteCode

ExecuteCode implements types.CodeExecutor.

func (*LocalExecutor) ExecutionResultDelimiters

func (e *LocalExecutor) ExecutionResultDelimiters() types.DelimiterPair

ExecutionResultDelimiters implements types.CodeExecutor.

func (*LocalExecutor) IsLongRunning

func (e *LocalExecutor) IsLongRunning() bool

IsLongRunning implements types.CodeExecutor.

func (*LocalExecutor) IsStateful

func (e *LocalExecutor) IsStateful() bool

IsStateful implements types.CodeExecutor.

func (*LocalExecutor) OptimizeDataFile

func (e *LocalExecutor) OptimizeDataFile() bool

OptimizeDataFile implements types.CodeExecutor.

type LocalExecutorOption

type LocalExecutorOption func(*LocalExecutor)

LocalExecutorOption is a functional option for configuring LocalExecutor.

func WithAllowUnsafe

func WithAllowUnsafe(allow bool) LocalExecutorOption

WithAllowUnsafe explicitly enables unsafe local execution. This is required to use the LocalExecutor due to security implications.

func WithStateful

func WithStateful(stateful bool) LocalExecutorOption

WithStateful enables stateful execution mode where variables persist between calls.

func WithWorkDir

func WithWorkDir(dir string) LocalExecutorOption

WithWorkDir sets a specific working directory for code execution.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL