AgentSandbox.Core
5.1.0
dotnet add package AgentSandbox.Core --version 5.1.0
NuGet\Install-Package AgentSandbox.Core -Version 5.1.0
<PackageReference Include="AgentSandbox.Core" Version="5.1.0" />
<PackageVersion Include="AgentSandbox.Core" Version="5.1.0" />
<PackageReference Include="AgentSandbox.Core" />
paket add AgentSandbox.Core --version 5.1.0
#r "nuget: AgentSandbox.Core, 5.1.0"
#:package AgentSandbox.Core@5.1.0
#addin nuget:?package=AgentSandbox.Core&version=5.1.0
#tool nuget:?package=AgentSandbox.Core&version=5.1.0
AgentSandbox.Core
A lightweight, in-memory virtual filesystem and shell for AI agents. Zero external dependencies.
Foundational Principles
- Only 4 core agent APIs:
Execute(command)for shell executionReadFileLines(path, startLine?, endLine?)for structured line-range readsWriteFile(path, content)for atomic full-file writesApplyPatch(path, patch)for incremental context-aware edits
- One agent-session = one sandbox instance:
- Single-owner model by design
- Phase 2 baseline allows concurrent file reads while serializing file writes
- Phase 3 adds optional isolated parallel command execution via
SandboxOptions.EnableIsolatedParallelCommandExecution
- Cross-session state transition via snapshots:
- Session handoff and recovery are done through snapshot create/restore
- Filesystem, working directory, and environment state are portable checkpoint data
Current Scope vs Direction
- Direction: keep the agent-facing contract centered on the 4 core APIs above.
- Current scope: implementation also includes orchestration and integration surfaces (e.g.,
SandboxManager, REST endpoints, DI, observability, skills/importing).
Snapshot Semantics
- Snapshot/restore is the required cross-session state transition mechanism.
- Snapshot captures filesystem, working directory, and environment.
Non-goals / Constraints
- Shell intentionally does not support pipes, command chaining (
||), or stdin redirection. - Parallel command execution is off by default and remains opt-in.
Integration Invariant: Single Owner, Controlled Multi-Thread Access
- A sandbox instance is a single-agent execution lane.
- Public integrations can dispatch from multiple threads, but should respect lane semantics:
ReadFileLinescan run concurrently with other reads.WriteFileandApplyPatchserialize against reads/writes.Executeis exclusive by default; whenEnableIsolatedParallelCommandExecutionis enabled, isolated command executions can overlap.RestoreSnapshotremains exclusive.CreateSnapshotruns as a file-read operation (concurrent with reads, serialized with writes).
- For high parallel throughput with persistent mutations, allocate separate sandbox instances via
SandboxManager. - Conflicting command-lane overlaps fail fast with deterministic errors; file-lane overlaps are serialized.
Phase 3 Optional Isolated Parallel Execute
- Enable with
SandboxOptions.EnableIsolatedParallelCommandExecution = true. - In this mode,
Executeruns commands in isolated shell contexts with filesystem snapshots. - Command-local cwd/environment/session cache mutations are isolated and are not written back to the primary sandbox shell context.
- Filesystem mutations made by isolated commands are confined to throwaway filesystem copies and do not affect the primary sandbox filesystem.
- Shell extensions must implement
IParallelSafeShellCommand; otherwise execution fails fast with actionable diagnostics. - Timed-out isolated commands are tracked and quarantined until completion to preserve lifecycle safety.
RestoreSnapshotand disposal still take exclusive coordination locks to preserve deterministic lifecycle behavior.
Design Outcome
The system optimizes for simplicity, correctness, and reproducibility over broad API surface area: agents get just enough primitives to work effectively, and orchestration-level continuity is handled explicitly via snapshot-based state transfer.
Installation
dotnet add package AgentSandbox.Core
Quick Start
using AgentSandbox.Core;
// Create a sandbox
var sandbox = new Sandbox();
// Execute shell commands
var result = sandbox.Execute("echo 'Hello, Agent!'");
Console.WriteLine(result.Stdout); // Hello, Agent!
// File operations
sandbox.Execute("mkdir -p /workspace/src");
sandbox.Execute("echo 'console.log(1)' > /workspace/src/app.js");
sandbox.Execute("cat /workspace/src/app.js");
Configuration
var options = new SandboxOptions
{
WorkingDirectory = "/workspace",
MaxTotalSize = 1024 * 1024, // 1MB total storage
MaxFileSize = 64 * 1024, // 64KB per file
MaxCommandLength = 8 * 1024, // 8KB command input max
MaxWritePayloadBytes = 64 * 1024, // 64KB WriteFile payload max
MaxNodeCount = 5000,
Environment = new() { ["HOME"] = "/home/agent" }
};
var sandbox = new Sandbox("agent-1", options);
ReadFileLines, WriteFile, and ApplyPatch reject path inputs that contain .. traversal segments.
Secret Policy Model
You can constrain secret usage for network-enabled commands (for example curl) using SecretBroker and SecretPolicy:
var options = new SandboxOptions
{
SecretBroker = mySecretBroker,
SecretPolicy = new SecretResolutionPolicy
{
AllowedRefs = new HashSet<string>(StringComparer.Ordinal) { "api-token", "service-token" },
MaxSecretAge = TimeSpan.FromMinutes(10),
EgressHostAllowlistHook = context => context.DestinationUri.Host.EndsWith(".example.com", StringComparison.OrdinalIgnoreCase)
}
};
curl also supports per-command allowlists with repeatable --allowed-ref flags.
For custom shell extensions, always resolve secretRef:<ref> placeholders via IShellContext.TryResolveSecretReferences(...) rather than ad hoc parsing so secret policy checks are applied uniformly; for network/egress operations, ensure SecretAccessRequest.CommandName and SecretAccessRequest.DestinationUri are populated so destination-aware egress policy is evaluated.
Capabilities Extension Pattern
ISandboxCapability allows extension packages to configure SandboxOptions without adding dependencies to core:
using AgentSandbox.Core;
using AgentSandbox.Extensions;
using AgentSandbox.Core.Shell.Extensions;
var options = new SandboxOptions
{
Capabilities =
[
new ShellCommandsCapability([
new CurlCommand(),
new JqCommand(),
new GitCommand()
])
]
};
var sandbox = new Sandbox(options: options);
Importing Files
var options = new SandboxOptions
{
Imports = [
new FileImportOptions { Path = "/data", Source = new FileSystemSource("C:/my-data") },
new FileImportOptions { Path = "/config", Source = new InMemorySource()
.AddFile("settings.json", """{"debug": true}""") }
]
};
Agent Skills
Load agentskills.io compatible skill packages. Skills are discovered by scanning the skill base path for SKILL.md files after imports:
var options = new SandboxOptions
{
Imports = [
// Import skill files from filesystem
new FileImportOptions("/skills/python-dev", new FileSystemSource("C:/skills/python-dev")),
// Or import from in-memory sources
new FileImportOptions("/skills/custom", new InMemorySource()
.AddFile("SKILL.md", "---\nname: my-skill\ndescription: Custom skill\n---\n# Instructions...")
.AddFile("scripts/setup.sh", "#!/bin/bash\necho 'Setting up'"))
],
AgentSkills = new AgentSkillOptions
{
BasePath = "/skills" // Where to discover skills in sandbox file system
}
};
var sandbox = new Sandbox(options: options);
// Skills are automatically discovered from BasePath
var skills = sandbox.GetSkills();
Console.WriteLine(skills[0].Metadata.Instructions);
// Execute skill scripts
sandbox.Execute("sh /skills/python-dev/scripts/setup.sh");
Built-in Commands
| Command | Description |
|---|---|
ls, cd, pwd |
Directory navigation |
cat, head, tail |
File viewing |
mkdir, touch, rm, cp, mv |
File management |
echo, grep, find, wc |
Text processing |
which, date |
Utilities |
env, export |
Environment variables |
clear |
Clear screen |
sh |
Script execution |
help |
List commands (<cmd> -h for details) |
Grep Features:
- Basic:
-i(case insensitive),-n(line numbers),-r(recursive) - Output:
-l(files only),-c(count),-o(only matching) - Filtering:
-v(invert),-w(word match),-m N(max count) - Context:
-A N(after),-B N(before),-C N(around)
Shell Features:
- Output redirection:
>(write) and>>(append) - Environment variables:
$VAR,$HOME - Glob patterns:
*.txt,src/**/*.cs - Shell scripts:
sh script.shor./script.sh
Not Supported:
- Pipelines (
|) - use file arguments instead:grep pattern file.txt - Command chaining with
||- run fallback commands separately or use scripts - Input redirection (
<,<<) - pass files as arguments - Background jobs (
&) - returns an error if used - Command substitution (
`cmd`or$(cmd)) - returns an error if used
Common Commands Not Available (examples):
sed,awk,sort,uniq,cut,tr,xargs,teeless,more,diff,chmod,chown,lndu,df,ps,kill,whoami,uname,whereis,man
Snapshots
// Save state
var snapshot = sandbox.CreateSnapshot();
// Snapshot metadata (schema-versioned)
var metadata = snapshot.Metadata;
// metadata.SchemaVersion, metadata.SnapshotSizeBytes, metadata.FileCount,
// metadata.CreatedAt, metadata.SourceSandboxId, metadata.SourceSessionId
// Restore later
sandbox.RestoreSnapshot(snapshot);
Manager-level persistence via configurable store:
var manager = new SandboxManager(
defaultOptions: null,
managerOptions: new SandboxManagerOptions
{
SnapshotStore = new InMemorySnapshotStore()
});
var sandbox = manager.Get();
var snapshotId = manager.SaveSnapshot(sandbox.Id);
var snapshotMetadata = manager.GetSnapshotMetadata(snapshotId);
var restoredSandbox = manager.RestoreSnapshot(snapshotId); // new sandbox ID
// Persist and release in one lifecycle call
var releasedSnapshotId = manager.Release(restoredSandbox.Id);
History and Observability
// Inspect command history
var history = sandbox.GetHistory();
// Build an AI tool description for the sandbox
var toolDescription = sandbox.GetToolDescription();
// Subscribe to sandbox events (commands, files, lifecycle)
using var subscription = sandbox.Subscribe(myObserver);
Telemetry hooks live in AgentSandbox.Core.Telemetry and are configured via SandboxOptions.Telemetry.
Lifecycle telemetry includes sandbox Created, Executed, SnapshotRestored, and Disposed events. Integrators can attach host correlation metadata (for example: tenantId, sessionId, requestId) through SandboxTelemetryOptions.HostCorrelationMetadata.
For compliance retention, persist emitted lifecycle events in your host logging/telemetry backend with policy driven by your regulatory requirements. Keep retention windows and archival controls in the host system rather than in sandbox memory.
GetHistory() and GetStats() are projection views over a centralized metadata journal that tracks shell and capability operations. Journal retention is configurable through SandboxOptions.Journal.
See Also
- AgentSandbox.Extensions - Shell extensions (curl, git, jq) and Semantic Kernel integration
- Agent Skills Specification
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- No dependencies.
NuGet packages (2)
Showing the top 2 NuGet packages that depend on AgentSandbox.Core:
| Package | Downloads |
|---|---|
|
AgentSandbox.Extensions
Package Description |
|
|
AgentSandbox.SemanticKernel
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.