Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ All other workspace member crates inherit the version automatically.

- `src/wasm_sandbox/guests/javascript/package.json`

### .NET (Directory.Build.props)

- `src/sdk/dotnet/Directory.Build.props`

## 2. Verify the Build

```sh
Expand Down
17 changes: 14 additions & 3 deletions src/sdk/dotnet/Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ build-rust target=default-target:
build-dotnet target=default-target:
dotnet build {{repo-root}}/src/sdk/dotnet/core/HyperlightSandbox.sln --configuration {{ if target == "release" { "Release" } else { "Debug" } }}

# Build guest modules that are embedded into guest NuGet packages
build-guests target=default-target:
cd {{repo-root}} && just -f src/wasm_sandbox/Justfile guest-build {{target}}
cd {{repo-root}} && just -f src/wasm_sandbox/Justfile js-guest-build

#### FORMAT ####

# Apply all formatting (Rust + .NET)
Expand Down Expand Up @@ -82,8 +87,8 @@ test-dotnet target=default-target: (build target)

#### EXAMPLES ####

# Run the core examples (requires guest module: just wasm guest-build)
examples:
# Run the core examples
examples target=default-target: (build-guests target)
dotnet run --project {{repo-root}}/src/sdk/dotnet/core/Examples/BasicExample/BasicExample.csproj
dotnet run --project {{repo-root}}/src/sdk/dotnet/core/Examples/ToolRegistrationExample/ToolRegistrationExample.csproj
dotnet run --project {{repo-root}}/src/sdk/dotnet/core/Examples/SnapshotExample/SnapshotExample.csproj
Expand All @@ -99,11 +104,13 @@ copilot-sdk-example:
#### DIST / PUBLISH ####

# Build NuGet packages
dist target="release": (build target)
dist target="release": (build-guests target) (build target)
{{mkdirp}} {{repo-root}}/dist/dotnetsdk
dotnet pack {{repo-root}}/src/sdk/dotnet/core/PInvoke/HyperlightSandbox.PInvoke.csproj --configuration {{ if target == "release" { "Release" } else { "Debug" } }} --no-build --output {{repo-root}}/dist/dotnetsdk
dotnet pack {{repo-root}}/src/sdk/dotnet/core/Api/HyperlightSandbox.Api.csproj --configuration {{ if target == "release" { "Release" } else { "Debug" } }} --no-build --output {{repo-root}}/dist/dotnetsdk
dotnet pack {{repo-root}}/src/sdk/dotnet/core/Extensions.AI/HyperlightSandbox.Extensions.AI.csproj --configuration {{ if target == "release" { "Release" } else { "Debug" } }} --no-build --output {{repo-root}}/dist/dotnetsdk
dotnet pack {{repo-root}}/src/sdk/dotnet/core/Guest.Python/HyperlightSandbox.Guest.Python.csproj --configuration {{ if target == "release" { "Release" } else { "Debug" } }} --no-build --output {{repo-root}}/dist/dotnetsdk
dotnet pack {{repo-root}}/src/sdk/dotnet/core/Guest.JavaScript/HyperlightSandbox.Guest.JavaScript.csproj --configuration {{ if target == "release" { "Release" } else { "Debug" } }} --no-build --output {{repo-root}}/dist/dotnetsdk
@echo "✅ NuGet packages created in dist/dotnetsdk/"

# Publish NuGet packages to nuget.org (requires NUGET_API_KEY env var)
Expand Down Expand Up @@ -157,4 +164,8 @@ clean:
-{{rmrf}} {{repo-root}}/src/sdk/dotnet/core/Api/obj
-{{rmrf}} {{repo-root}}/src/sdk/dotnet/core/Extensions.AI/bin
-{{rmrf}} {{repo-root}}/src/sdk/dotnet/core/Extensions.AI/obj
-{{rmrf}} {{repo-root}}/src/sdk/dotnet/core/Guest.Python/bin
-{{rmrf}} {{repo-root}}/src/sdk/dotnet/core/Guest.Python/obj
-{{rmrf}} {{repo-root}}/src/sdk/dotnet/core/Guest.JavaScript/bin
-{{rmrf}} {{repo-root}}/src/sdk/dotnet/core/Guest.JavaScript/obj
-{{rmrf}} {{repo-root}}/dist/dotnetsdk
30 changes: 23 additions & 7 deletions src/sdk/dotnet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,18 @@ A .NET 8.0 SDK for running code in secure, sandboxed environments using [hyperli

```bash
# Prerequisites
just wasm guest-build # Build the Python guest module
just dotnet build # Build the .NET SDK + Rust FFI
```

### Basic Usage

```csharp
using HyperlightSandbox.Api;
using HyperlightSandbox.Guest.Python;

// Create a sandbox with the Python guest
using var sandbox = new SandboxBuilder()
.WithModulePath("path/to/python-sandbox.aot")
.WithPythonModule()
.Build();

// Execute code
Expand All @@ -50,7 +50,7 @@ Register .NET functions that guest code can call:

```csharp
using var sandbox = new SandboxBuilder()
.WithModulePath("python-sandbox.aot")
.WithPythonModule()
.Build();

// Typed tool — auto-serializes args and result
Expand Down Expand Up @@ -87,13 +87,24 @@ using var sandbox = new SandboxBuilder()
var result = sandbox.Run("console.log('Hello from JS!');");
```

To run JavaScript through the Wasm guest module package instead, reference
`Hyperlight.HyperlightSandbox.Guest.JavaScript` and call:

```csharp
using HyperlightSandbox.Guest.JavaScript;

using var sandbox = new SandboxBuilder()
.WithJavaScriptModule()
.Build();
```

### Snapshot/Restore

Checkpoint sandbox state for fast resets between executions:

```csharp
using var sandbox = new SandboxBuilder()
.WithModulePath("python-sandbox.aot")
.WithPythonModule()
.Build();

// Cold start (~2.5s)
Expand All @@ -114,7 +125,7 @@ sandbox.Run("print(x)"); // NameError: x is not defined

```csharp
using var sandbox = new SandboxBuilder()
.WithModulePath("python-sandbox.aot")
.WithPythonModule()
.WithInputDir("/path/to/input") // Read-only /input in guest
.WithTempOutput() // Writable /output in guest
.Build();
Expand Down Expand Up @@ -149,11 +160,12 @@ Use with GitHub Copilot SDK or Microsoft Agent Framework:
```csharp
using HyperlightSandbox.Api;
using HyperlightSandbox.Extensions.AI;
using HyperlightSandbox.Guest.Python;

// Create a code execution tool with snapshot/restore for clean state
using var codeTool = new CodeExecutionTool(
new SandboxBuilder()
.WithModulePath("python-sandbox.aot")
.WithPythonModule()
.WithTempOutput());

codeTool.RegisterTool<MathArgs, double>("compute",
Expand Down Expand Up @@ -229,6 +241,8 @@ just dotnet copilot-sdk-example # Run Copilot SDK example
| `Hyperlight.HyperlightSandbox.PInvoke` | P/Invoke bindings + native library |
| `Hyperlight.HyperlightSandbox.Api` | High-level API (Sandbox, tools, snapshots) |
| `Hyperlight.HyperlightSandbox.Extensions.AI` | AI agent integration (CodeExecutionTool, AIFunction) |
| `Hyperlight.HyperlightSandbox.Guest.Python` | Bundled Python Wasm/AOT guest module + `WithPythonModule()` |
| `Hyperlight.HyperlightSandbox.Guest.JavaScript` | Bundled JavaScript Wasm/AOT guest module + `WithJavaScriptModule()` |

## API Reference

Expand All @@ -237,6 +251,8 @@ just dotnet copilot-sdk-example # Run Copilot SDK example
| Method | Description |
|--------|-------------|
| `WithModulePath(string)` | Path to `.wasm`/`.aot` guest (required for Wasm) |
| `WithPythonModule()` | Use the bundled Python guest from `Hyperlight.HyperlightSandbox.Guest.Python` |
| `WithJavaScriptModule()` | Use the bundled JavaScript Wasm guest from `Hyperlight.HyperlightSandbox.Guest.JavaScript` |
Comment thread
jsturtevant marked this conversation as resolved.
Outdated
| `WithBackend(SandboxBackend)` | `Wasm` (default) or `JavaScript` |
| `WithHeapSize(string\|ulong)` | Guest heap size (e.g. `"50Mi"`, default: platform-dependent) |
| `WithStackSize(string\|ulong)` | Guest stack size (e.g. `"35Mi"`, default: platform-dependent) |
Expand Down Expand Up @@ -299,7 +315,7 @@ sandbox.Run("...");
- .NET 8.0 SDK or later
- Rust 1.89+ (for building the FFI crate)
- Linux (Windows support coming via hyperlight)
- `just wasm guest-build` for Wasm backend examples
- `just dotnet dist` builds the Python and JavaScript guest modules before packing their NuGet packages

## Contributing

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Api\HyperlightSandbox.Api.csproj" />
<ProjectReference Include="..\Common\Common.csproj" />
<ProjectReference Include="..\..\Guest.Python\HyperlightSandbox.Guest.Python.csproj" />
</ItemGroup>
</Project>
10 changes: 3 additions & 7 deletions src/sdk/dotnet/core/Examples/BasicExample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,15 @@
// Mirrors: src/wasm_sandbox/examples/python_basics.rs
//
// Prerequisites:
// just wasm guest-build # builds python-sandbox.aot
// just dotnet build # builds the .NET SDK + FFI
// just dotnet build # builds the .NET SDK + bundled guest package
Comment thread
jsturtevant marked this conversation as resolved.

using HyperlightSandbox.Api;
using HyperlightSandbox.Examples.Common;

var guestPath = ExampleHelper.RequirePythonGuest();
using HyperlightSandbox.Guest.Python;

Console.WriteLine("=== Hyperlight Sandbox .NET — Basic Example ===\n");
Console.WriteLine($"Guest module: {guestPath}\n");

using var sandbox = new SandboxBuilder()
.WithModulePath(guestPath)
.WithPythonModule()
.Build();

// --- Test 1: Basic code execution ---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Api\HyperlightSandbox.Api.csproj" />
<ProjectReference Include="..\Common\Common.csproj" />
<ProjectReference Include="..\..\Guest.Python\HyperlightSandbox.Guest.Python.csproj" />
</ItemGroup>
</Project>
8 changes: 3 additions & 5 deletions src/sdk/dotnet/core/Examples/FilesystemExample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,14 @@
// Mirrors: src/wasm_sandbox/examples/python_filesystem_demo.rs

using HyperlightSandbox.Api;
using HyperlightSandbox.Examples.Common;

var guestPath = ExampleHelper.RequirePythonGuest();
using HyperlightSandbox.Guest.Python;

Console.WriteLine("=== Hyperlight Sandbox .NET — Filesystem Example ===\n");

// --- Test 1: Temp output ---
Console.WriteLine("═══ Test 1: Temp output directory ═══");
using (var sandbox = new SandboxBuilder()
.WithModulePath(guestPath)
.WithPythonModule()
.WithTempOutput()
.Build())
{
Expand All @@ -38,7 +36,7 @@ with open("/output/hello.txt", "w") as f:
try
{
using var sandbox = new SandboxBuilder()
.WithModulePath(guestPath)
.WithPythonModule()
.WithInputDir(inputDir)
.WithTempOutput()
.Build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Api\HyperlightSandbox.Api.csproj" />
<ProjectReference Include="..\Common\Common.csproj" />
<ProjectReference Include="..\..\Guest.Python\HyperlightSandbox.Guest.Python.csproj" />
</ItemGroup>
</Project>
8 changes: 3 additions & 5 deletions src/sdk/dotnet/core/Examples/NetworkExample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,14 @@
// Mirrors: src/wasm_sandbox/examples/python_network_demo.rs

using HyperlightSandbox.Api;
using HyperlightSandbox.Examples.Common;

var guestPath = ExampleHelper.RequirePythonGuest();
using HyperlightSandbox.Guest.Python;

Console.WriteLine("=== Hyperlight Sandbox .NET — Network Example ===\n");

// --- Test 1: Allow a domain with all methods ---
Console.WriteLine("═══ Test 1: HTTP GET with allowlisted domain ═══");
using (var sandbox = new SandboxBuilder()
.WithModulePath(guestPath)
.WithPythonModule()
.Build())
{
sandbox.AllowDomain("https://httpbin.org");
Expand All @@ -30,7 +28,7 @@
// --- Test 2: Method-filtered access ---
Console.WriteLine("\n═══ Test 2: Method-filtered access (GET only) ═══");
using (var sandbox = new SandboxBuilder()
.WithModulePath(guestPath)
.WithPythonModule()
.Build())
{
// Only allow GET requests to httpbin.org.
Expand Down
6 changes: 2 additions & 4 deletions src/sdk/dotnet/core/Examples/SnapshotExample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,12 @@

using System.Diagnostics;
using HyperlightSandbox.Api;
using HyperlightSandbox.Examples.Common;

var guestPath = ExampleHelper.RequirePythonGuest();
using HyperlightSandbox.Guest.Python;

Console.WriteLine("=== Hyperlight Sandbox .NET — Snapshot Example ===\n");

using var sandbox = new SandboxBuilder()
.WithModulePath(guestPath)
.WithPythonModule()
.WithTempOutput()
.Build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Api\HyperlightSandbox.Api.csproj" />
<ProjectReference Include="..\Common\Common.csproj" />
<ProjectReference Include="..\..\Guest.Python\HyperlightSandbox.Guest.Python.csproj" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@

using System.Text.Json.Serialization;
using HyperlightSandbox.Api;
using HyperlightSandbox.Examples.Common;

var guestPath = ExampleHelper.RequirePythonGuest();
using HyperlightSandbox.Guest.Python;

Console.WriteLine("=== Hyperlight Sandbox .NET — Tool Registration Example ===\n");

using var sandbox = new SandboxBuilder()
.WithModulePath(guestPath)
.WithPythonModule()
.Build();

// --- Register typed tools ---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Api\HyperlightSandbox.Api.csproj" />
<ProjectReference Include="..\Common\Common.csproj" />
<ProjectReference Include="..\..\Guest.Python\HyperlightSandbox.Guest.Python.csproj" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AnalysisMode>All</AnalysisMode>
<AnalysisLevel>latest</AnalysisLevel>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<RootNamespace>HyperlightSandbox.Guest.JavaScript</RootNamespace>

<!-- NuGet Package Metadata -->
<PackageId>Hyperlight.HyperlightSandbox.Guest.JavaScript</PackageId>
<Description>JavaScript guest module package for hyperlight-sandbox. Bundles the prebuilt JavaScript AOT guest and provides SandboxBuilder.WithJavaScriptModule().</Description>
<PackageTags>hyperlight;sandbox;javascript;guest;module</PackageTags>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/hyperlight-dev/hyperlight-sandbox</PackageProjectUrl>
<RepositoryUrl>https://github.com/hyperlight-dev/hyperlight-sandbox</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
</PropertyGroup>

<PropertyGroup>
<WorkspaceRoot>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)../../../../..'))</WorkspaceRoot>
<JavaScriptGuestDir>$(WorkspaceRoot)\src\wasm_sandbox\guests\javascript</JavaScriptGuestDir>
</PropertyGroup>
Comment thread
jsturtevant marked this conversation as resolved.

<ItemGroup>
<ProjectReference Include="..\Api\HyperlightSandbox.Api.csproj" />
</ItemGroup>

<!--
Native assets following the NuGet runtimes/{rid}/native/ convention (same as PInvoke).
The .aot file is Hyperlight/Cranelift AOT output: architecture-specific but NOT OS-specific,
so the same binary serves both linux-x64 and win-x64. Include it under both RID folders so
NuGet selects the right entry for each consumer platform from a single package build.
-->
<ItemGroup>
<None Include="$(JavaScriptGuestDir)\js-sandbox.aot"
Condition="Exists('$(JavaScriptGuestDir)\js-sandbox.aot')">
<Pack>true</Pack>
<PackagePath>runtimes/linux-x64/native/</PackagePath>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Link>runtimes/linux-x64/native/js-sandbox.aot</Link>
</None>
<None Include="$(JavaScriptGuestDir)\js-sandbox.aot"
Condition="Exists('$(JavaScriptGuestDir)\js-sandbox.aot')">
<Pack>true</Pack>
<PackagePath>runtimes/win-x64/native/</PackagePath>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Link>runtimes/win-x64/native/js-sandbox.aot</Link>
</None>
</ItemGroup>

<Target Name="ValidateJavaScriptGuestResources" BeforeTargets="Pack">
<Error Condition="!Exists('$(JavaScriptGuestDir)\js-sandbox.aot')"
Text="JavaScript guest AOT binary is missing. Run 'just wasm js-guest-build' before packing Hyperlight.HyperlightSandbox.Guest.JavaScript." />
</Target>

</Project>
Loading
Loading