Class: LittleGhost::Sandbox

Inherits:
Object
  • Object
show all
Defined in:
lib/little_ghost/sandbox.rb

Overview

A Sandbox decides what an agent may do with files and processes. Applications can place that work on the host, in a container or VM, or behind a remote execution service without changing their tools.

class ContainerSandbox < LittleGhost::Sandbox
def initialize(workspace:, container:)
  super(workspace:)
  @container = container
end

def read(path, context: nil)
  context&.check!
  @container.read(path)
end

def execute_program(command, timeout:, context: nil, **)
  result = @container.run(
    command, timeout:, cancellation: context&.cancellation_token
  )
  Execution.new(**result)
end
end

Implementations confine paths to #workspace, honor RunContext cancellation, enforce time and output limits, and return Execution from process operations.

Direct Known Subclasses

UnrestrictedSandbox

Defined Under Namespace

Classes: Execution

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(workspace:) ⇒ Sandbox

Binds the sandbox to workspace.



76
77
78
# File 'lib/little_ghost/sandbox.rb', line 76

def initialize(workspace:)
  @workspace = workspace
end

Instance Attribute Details

#workspaceObject (readonly)

Workspace whose files and processes this sandbox governs.



81
82
83
# File 'lib/little_ghost/sandbox.rb', line 81

def workspace
  @workspace
end

Instance Method Details

#closeObject

Releases sandbox resources. Runs close the sandbox before its workspace.



134
135
136
# File 'lib/little_ghost/sandbox.rb', line 134

def close
  nil
end

#execute(command, timeout:, context: nil, max_output_bytes: 1_000_000, **options) ⇒ Object

Executes command through /bin/sh.

Prefer #execute_program for model-controlled arguments so shell syntax is not interpreted.



115
116
117
118
119
120
121
122
123
# File 'lib/little_ghost/sandbox.rb', line 115

def execute(command, timeout:, context: nil, max_output_bytes: 1_000_000, **options)
  execute_program(
    ["/bin/sh", "-c", String(command)],
    timeout:,
    context:,
    max_output_bytes:,
    **options
  )
end

#execute_program(command, timeout:, context: nil, max_output_bytes: 1_000_000, environment: {}, inherit_environment: false) ⇒ Object

Executes an argument vector without shell interpretation.

Implementations must enforce timeout and max_output_bytes. Environment inheritance is disabled by default to avoid leaking process credentials.

Raises:

  • (NotImplementedError)


129
130
131
# File 'lib/little_ghost/sandbox.rb', line 129

def execute_program(command, timeout:, context: nil, max_output_bytes: 1_000_000, environment: {}, inherit_environment: false)
  raise NotImplementedError, "#{self.class} does not support program execution"
end

#list(path = ".", context: nil) ⇒ Object

Lists entries at a workspace-relative directory path.

Raises:

  • (NotImplementedError)


97
98
99
# File 'lib/little_ghost/sandbox.rb', line 97

def list(path = ".", context: nil)
  raise NotImplementedError, "#{self.class} does not support filesystem listings"
end

#open(run: nil) ⇒ Object

Opens any run-scoped resources and makes the sandbox ready for tools.



84
85
86
# File 'lib/little_ghost/sandbox.rb', line 84

def open(run: nil)
  self
end

#read(path, context: nil) ⇒ Object

Reads UTF-8 text at a workspace-relative path.

Raises:

  • (NotImplementedError)


92
93
94
# File 'lib/little_ghost/sandbox.rb', line 92

def read(path, context: nil)
  raise NotImplementedError, "#{self.class} does not support filesystem reads"
end

#replace(path, old_text, new_text, context: nil) ⇒ Object

Replaces one exact old_text occurrence with new_text.

Raises:

  • (NotImplementedError)


107
108
109
# File 'lib/little_ghost/sandbox.rb', line 107

def replace(path, old_text, new_text, context: nil)
  raise NotImplementedError, "#{self.class} does not support filesystem edits"
end

#writable?Boolean

Indicates whether filesystem mutation is allowed.

Returns:

  • (Boolean)


89
# File 'lib/little_ghost/sandbox.rb', line 89

def writable? = false

#write(path, content, context: nil) ⇒ Object

Writes content to a workspace-relative path.

Raises:

  • (NotImplementedError)


102
103
104
# File 'lib/little_ghost/sandbox.rb', line 102

def write(path, content, context: nil)
  raise NotImplementedError, "#{self.class} does not support filesystem writes"
end