OpenSandbox C# SDK 实战指南:创建、管理与交互安全沙箱环境
【免费下载链接】OpenSandboxSecure, Fast, and Extensible Sandbox runtime for AI agents.项目地址: https://gitcode.com/GitHub_Trending/ope/OpenSandbox
本文以 OpenSandbox 仓库中的 C# SDK 官方文档为主体,系统讲解如何通过Alibaba.OpenSandboxNuGet 包创建、连接、管理沙箱环境,覆盖生命周期管理(续期/暂停/恢复/手动清理)、命令执行与流式输出、文件操作、端点访问、出站网络策略热更新与 Credential Vault 凭据注入等核心能力,并结合 SDK 源码剖析ConnectionConfig默认值、就绪等待与异常体系等实现细节。读完后,你可以在 .NET 6.0–10.0 或 .NET Framework 4.6.1+ 环境中独立编写生产级沙箱集成代码。
安装
C# SDK 以 NuGet 包Alibaba.OpenSandbox形式发布,打包信息定义在 OpenSandbox.csproj(<PackageId>Alibaba.OpenSandbox</PackageId>、PackageLicenseExpression为 Apache-2.0)。
NuGet CLI
dotnet add package Alibaba.OpenSandboxPackage Manager
Install-Package Alibaba.OpenSandboxSDK 依赖面很窄:核心仅依赖Microsoft.Extensions.Logging.Abstractions8.0.2、System.Text.Json8.0.5 与PolySharp(源码编译 polyfill 工具,不参与运行时),netstandard2.0 目标框架额外引入Microsoft.Bcl.AsyncInterfaces。
快速开始
下面的示例展示如何创建沙箱并执行一条 shell 命令。
提示:运行此示例前,请确保 OpenSandbox 服务已启动。参见 安装指南 中的启动说明。
using OpenSandbox; using OpenSandbox.Config; using OpenSandbox.Core; var config = new ConnectionConfig(new ConnectionConfigOptions { Domain = "api.opensandbox.io", ApiKey = "your-api-key", // Protocol = ConnectionProtocol.Https, // RequestTimeoutSeconds = 60, }); try { await using var sandbox = await Sandbox.CreateAsync(new SandboxCreateOptions { ConnectionConfig = config, Image = "ubuntu", TimeoutSeconds = 10 * 60, }); var execution = await sandbox.Commands.RunAsync("echo 'Hello Sandbox!'"); Console.WriteLine(execution.Logs.Stdout.FirstOrDefault()?.Text); // Optional but recommended: terminate the remote instance when you are done. await sandbox.KillAsync(); } catch (SandboxException ex) { Console.Error.WriteLine($"Sandbox Error: [{ex.Error.Code}] {ex.Error.Message}"); Console.Error.WriteLine($"Request ID: {ex.RequestId}"); }从源码看,CreateAsync并非一次简单的 HTTP 调用:在 Sandbox.cs 中,完整链路依次为——
- 构造请求(
Image/SnapshotId二选一,Entrypoint缺省为["tail","-f","/dev/null"],资源限额缺省为cpu=1, memory=2Gi,均由 Constants.cs 定义); - 调用沙箱 API 创建实例并获取沙箱 ID;
- 分别解析 execd 端口(
44772)与 egress 端口(18080)的端点,构建 execd 与 egress 两条 HTTP 通道; - 若未设置
SkipHealthCheck,则以ReadyTimeoutSeconds(默认 30 秒)、HealthCheckPollingInterval(默认 200 毫秒)轮询就绪状态; - 最后上报 best-effort 的创建耗时遥测事件(可用
DisableMetrics关闭)。
创建过程中若已产生沙箱 ID 但后续步骤失败,SDK 会尝试自动删除该实例以避免资源泄漏(见 Sandbox.cs 的清理逻辑)。
生命周期钩子(Lifecycle Hooks)
在SandboxCreateOptions中设置Lifecycle即可配置创建期钩子。PreStart在容器 entrypoint 启动之前完成,而Periodic钩子在沙箱启动后按各自的调度计划运行。
using OpenSandbox.Models; await using var sandbox = await Sandbox.CreateAsync(new SandboxCreateOptions { ConnectionConfig = config, Image = "ubuntu:24.04", Lifecycle = new SandboxLifecycle { PreStart = new LifecycleHook { Command = new[] { "sh", "-c", "echo ready > /tmp/prestart.done" }, TimeoutSeconds = 120, }, Periodic = new[] { new PeriodicLifecycleHook { Name = "checkpoint", Schedule = "@every 5m", Command = new[] { "sh", "-c", "date -u >> /tmp/checkpoints.log" }, TimeoutSeconds = 120, }, }, }, });服务端会对TimeoutSeconds做校验:PreStart接受 1–10800 秒,Periodic接受 1–300 秒;省略时两者均默认为 60 秒。关于触发时机、失败行为与各 provider 的差异,参见 Lifecycle Hooks 指南。
使用示例
1. 生命周期管理
管理沙箱生命周期,包括续期、暂停与恢复:
var info = await sandbox.GetInfoAsync(); Console.WriteLine($"State: {info.Status.State}"); Console.WriteLine($"Created: {info.CreatedAt}"); Console.WriteLine($"Expires: {info.ExpiresAt}"); // null when manual cleanup mode is used await sandbox.PauseAsync(); // Resume returns a fresh, connected Sandbox instance. var resumed = await sandbox.ResumeAsync(); // Renew: expiresAt = now + timeoutSeconds await resumed.RenewAsync(30 * 60);对应 SDK 侧的方法签名见 Sandbox.cs:GetInfoAsync、PauseAsync、ResumeAsync、KillAsync、RenewAsync,均为Task形式且支持CancellationToken。
手动清理模式(不自动过期):设置ManualCleanup = true:
var manual = await Sandbox.CreateAsync(new SandboxCreateOptions { ConnectionConfig = config, Image = "ubuntu", ManualCleanup = true, });说明:与 Python、JavaScript、Kotlin SDK 不同,C# SDK 使用显式的
ManualCleanup标志位,而不是TimeoutSeconds = null。这是有意为之:当前 options 模型中的int?无法可靠区分“未设置,使用默认 TTL”与“显式请求手动清理”,若用null表达二者会使默认创建路径变得含糊。源码中可印证这一点:Sandbox.cs 的构造逻辑为Timeout = options.ManualCleanup ? null : options.TimeoutSeconds ?? Constants.DefaultTimeoutSeconds——只有ManualCleanup = true才会把请求体的 TTL 置为null。
连接已有沙箱
当你已经拥有沙箱 ID 并需要一个新的绑定到该实例的 SDK 对象时,使用ConnectAsync:
var connected = await Sandbox.ConnectAsync(new SandboxConnectOptions { SandboxId = "existing-sandbox-id", ConnectionConfig = config });SandboxConnectOptions(定义于 Options.cs)还支持SkipHealthCheck、自定义HealthCheck以及ReadyTimeoutSeconds/HealthCheckPollingInterval:对ConnectAsync/ResumeAsync而言,端点发现与健康检查共享ReadyTimeoutSeconds这一总预算,自定义检查中的阻塞代码可能拖延超时上报——这一点在 options 的 XML 文档注释中有明确提示。
2. 自定义健康检查
自定义判定沙箱是否就绪/健康的逻辑:
var sandbox = await Sandbox.CreateAsync(new SandboxCreateOptions { ConnectionConfig = config, Image = "nginx:latest", HealthCheck = async (sbx) => { // Example: consider the sandbox healthy when port 80 endpoint becomes available var ep = await sbx.GetEndpointAsync(80); return !string.IsNullOrEmpty(ep.EndpointAddress); }, });HealthCheck的类型是Func<Sandbox, Task<bool>>(见 Options.cs),轮询间隔由HealthCheckPollingInterval(毫秒)控制,总等待时间由ReadyTimeoutSeconds控制;超时未就绪将抛出SandboxReadyTimeoutException。
3. 命令执行与流式输出
执行命令并实时处理输出流:
using OpenSandbox.Models; var handlers = new ExecutionHandlers { OnStdout = msg => { Console.WriteLine($"STDOUT: {msg.Text}"); return Task.CompletedTask; }, OnStderr = msg => { Console.Error.WriteLine($"STDERR: {msg.Text}"); return Task.CompletedTask; }, OnExecutionComplete = c => { Console.WriteLine($"Finished in {c.ExecutionTimeMs}ms"); return Task.CompletedTask; }, }; await sandbox.Commands.RunAsync( "for i in 1 2 3; do echo \"Count $i\"; sleep 0.2; done", handlers: handlers );流式输出由 SSE(Server-Sent Events)承载:ConnectionConfig提供了专门的无超时 SSE 客户端 CreateSseHttpClient(Timeout = Timeout.InfiniteTimeSpan),事件解析在 SseParser.cs 中完成。
原生 argv 执行:为避免 shell 解析,传入参数数组即可。在 Linux 上,下面的示例会原样打印字面量$HOME,并保留hello world作为单个参数:
await sandbox.Commands.RunAsync(new[] { "printf", "%s\n", "$HOME", "hello world" });原生 argv 执行模式需要较新版本的 execd,可执行文件查找与平台行为详见 execd 命令执行模式说明。
后台命令:以Background = true运行命令后,可轮询状态与增量日志:
var execution = await sandbox.Commands.RunAsync( "python /app/server.py", options: new RunCommandOptions { Background = true, TimeoutSeconds = 120, }); var status = await sandbox.Commands.GetCommandStatusAsync(execution.Id!); var logs = await sandbox.Commands.GetBackgroundCommandLogsAsync(execution.Id!, cursor: 0); Console.WriteLine($"running={status.Running}, cursor={logs.Cursor}");日志通过cursor游标实现增量拉取:GetBackgroundCommandLogsAsync返回新的 cursor,下次请求传入即可只取新增部分。
4. 全面的文件操作
管理沙箱内的文件与目录:创建目录、读写、搜索、删除。
await sandbox.Files.CreateDirectoriesAsync(new[] { new CreateDirectoryEntry { Path = "/tmp/demo", Mode = 755 } }); await sandbox.Files.WriteFilesAsync(new[] { new WriteEntry { Path = "/tmp/demo/hello.txt", Data = "Hello World", Mode = 644 } }); var content = await sandbox.Files.ReadFileAsync("/tmp/demo/hello.txt"); Console.WriteLine($"Content: {content}"); var files = await sandbox.Files.SearchAsync(new SearchEntry { Path = "/tmp/demo", Pattern = "*.txt" }); foreach (var file in files) { Console.WriteLine(file.Path); } await sandbox.Files.DeleteDirectoriesAsync(new[] { "/tmp/demo" }); // Delete one or more files directly. await sandbox.Files.DeleteFilesAsync(new[] { "/tmp/demo/hello.txt" });文件操作的底层实现在 FilesystemAdapter.cs,接口定义于 ISandboxFiles.cs,测试覆盖见 FilesystemAdapterTests.cs。
5. 端点(Endpoints)
GetEndpointAsync()返回不带 scheme的端点(例如"localhost:44772");如需可直接使用的绝对 URL,使用GetEndpointUrlAsync():
var endpoint = await sandbox.GetEndpointAsync(44772); Console.WriteLine(endpoint.EndpointAddress); var url = await sandbox.GetEndpointUrlAsync(44772); Console.WriteLine(url); // e.g., "http://localhost:44772"注意 URL 的 scheme 由ConnectionConfig.Protocol决定(见 Sandbox.cs 中protocol == ConnectionProtocol.Https ? "https" : "http"的拼接逻辑)。此外 SDK 还支持GetSignedEndpointAsync(port, expires)获取带签名的临时端点,用于安全访问场景;端点解析结果会进入本地缓存(EndpointCacheTtlSeconds默认 600 秒、EndpointCacheSize默认 1024,见 ConnectionConfig.cs)。
6. 沙箱管理(Admin)
使用SandboxManager执行管理任务、查找已有沙箱:
await using var manager = SandboxManager.Create(new SandboxManagerOptions { ConnectionConfig = config }); var list = await manager.ListSandboxInfosAsync(new SandboxFilter { States = new[] { SandboxStates.Running }, PageSize = 10 }); foreach (var s in list.Items) { Console.WriteLine(s.Id); }SandboxFilter(Options.cs)除States、PageSize外还支持Metadata(按元数据过滤)与Page(1 起始的页码),可组合实现“按标签分页扫描”类运维查询。
配置
1. 连接配置
ConnectionConfig类管理到 API 服务器的连接设置。
| 参数 | 说明 | 默认值 | 环境变量 |
|---|---|---|---|
ApiKey | 认证用 API key | 可选 | OPEN_SANDBOX_API_KEY |
Domain | 沙箱服务域名(host[:port]) | localhost:8080 | OPEN_SANDBOX_DOMAIN |
Protocol | HTTP 协议(Http/Https) | Http | - |
RequestTimeoutSeconds | 应用于 SDK HTTP 调用的请求超时 | 30 | - |
UseServerProxy | 请求服务端代理的沙箱端点 URL | false | - |
Headers | 附加到每个请求的额外请求头 | {} | - |
DisableMetrics | 禁用 SDK 创建耗时遥测(见 SDK Telemetry) | false | OPENSANDBOX_DISABLE_METRICS |
using OpenSandbox.Config; // 1. Basic configuration var config = new ConnectionConfig(new ConnectionConfigOptions { Domain = "api.opensandbox.io", ApiKey = "your-key", RequestTimeoutSeconds = 60, // UseServerProxy = true, // Useful when the client cannot access sandbox endpoint directly }); // 2. Advanced: custom headers var config2 = new ConnectionConfig(new ConnectionConfigOptions { Domain = "api.opensandbox.io", ApiKey = "your-key", Headers = new Dictionary<string, string> { ["X-Custom-Header"] = "value" }, });源码层面还有几个值得了解的细节(ConnectionConfig.cs):
- 优先级:显式 options > 环境变量 > 内置默认值,例如
Domain的解析顺序为options.Domain ?? envDomain ?? "localhost:8080"; - URL 归一化:
Domain既可写host[:port],也可直接传完整 URL(http://localhost:8080、https://api.example.com),SDK 会自动解析出协议与路径前缀,并剥掉尾部多余的/v1(GetBaseUrl()统一补上/v1前缀); - API key 注入:
ApiKey非空时自动以请求头OPEN-SANDBOX-API-KEY的形式写入(除非Headers中已显式提供同名头); - 客户端自报 IP:每个客户端(普通与 SSE)都会自动附加
OPEN-SANDBOX-CLIENT-IP头,刻意使用非标准头名是因为X-Forwarded-For等标准转发头会被中间设备改写或剥离; - 线程安全:
HttpClient按ConnectionConfig实例惰性创建并共享,构造加锁保证并发安全。
提示(SDK Telemetry):
Sandbox.CreateAsync默认会向POST /v1/metrics/events上报创建耗时。设置ConnectionConfigOptions.DisableMetrics = true,或导出环境变量OPENSANDBOX_DISABLE_METRICS=1即可关闭。详见 SDK Telemetry 指南。
2. 诊断与日志
SDK 基于Microsoft.Extensions.Logging抽象输出日志,可接入任何兼容 provider(控制台、文件、Serilog 等):
using Microsoft.Extensions.Logging; using OpenSandbox.Config; using var loggerFactory = LoggerFactory.Create(builder => { builder.SetMinimumLevel(LogLevel.Debug); builder.AddConsole(); }); var sandbox = await Sandbox.CreateAsync(new SandboxCreateOptions { Image = "python:3.11", ConnectionConfig = new ConnectionConfig(), Diagnostics = new SdkDiagnosticsOptions { LoggerFactory = loggerFactory } });未提供LoggerFactory时回退到NullLoggerFactory(见 Options.cs 与 Sandbox.cs 中的options.Diagnostics?.LoggerFactory ?? NullLoggerFactory.Instance),生产环境建议注入结构化日志以便排查就绪等待与请求失败问题。
3. 沙箱创建配置
Sandbox.CreateAsync()允许配置沙箱运行环境。
| 参数 | 说明 | 默认值 |
|---|---|---|
Image | 使用的 Docker 镜像 | 必填 |
TimeoutSeconds | 自动终止超时(服务端 TTL) | 10 分钟 |
Entrypoint | 容器入口命令 | ["tail","-f","/dev/null"] |
Resource | CPU 与内存限额(字符串映射) | {"cpu":"1","memory":"2Gi"} |
Env | 环境变量 | {} |
Metadata | 自定义元数据标签 | {} |
NetworkPolicy | 可选的出站网络策略(egress) | - |
CredentialProxy | 可选的 Credential Vault 代理启动配置 | - |
Volumes | 可选存储挂载(Host/PVC,支持ReadOnly与SubPath) | - |
Extensions | 额外服务端定义的字段 | {} |
SkipHealthCheck | 跳过就绪检查(Running+ 健康检查) | false |
HealthCheck | 自定义就绪检查 | - |
ReadyTimeoutSeconds | 等待就绪的最长时间 | 30 秒 |
HealthCheckPollingInterval | 等待期间的轮询间隔(毫秒) | 200 毫秒 |
警告:
opensandbox.io/前缀的 metadata key 为系统保留标签,会被服务端拒绝。
除上表外,SandboxCreateOptions在源码中还暴露了若干文档表格未列出的能力(见 Options.cs):SnapshotId(从快照恢复,与Image二选一)、ImageAuth(私有镜像仓库认证)、SecureAccess(端点安全访问)、Platform(运行时平台约束)、ResourceRequests(Kubernetes Burstable QoS 的 requests)等。
var sandbox = await Sandbox.CreateAsync(new SandboxCreateOptions { ConnectionConfig = config, Image = "python:3.11", NetworkPolicy = new NetworkPolicy { DefaultAction = NetworkRuleAction.Deny, Egress = new List<NetworkRule> { new() { Action = NetworkRuleAction.Allow, Target = "pypi.org" } } }, Volumes = new[] { new Volume { Name = "workspace", Host = new Host { Path = "/tmp/opensandbox-e2e/host-volume-test" }, MountPath = "/workspace", ReadOnly = false } } });源码中还有一个容易忽略的行为:当设置了NetworkPolicy但未指定DefaultAction时,SDK 会将其补全为Deny(见 Sandbox.cs),即默认“拒绝所有出站、白名单放行”的零信任基线。另外,CreateAsync在发送请求前会校验Volumes的宿主路径合法性(ValidateHostPaths),非法路径直接抛出InvalidArgumentException。
4. 运行时出站策略热更新
运行时的出站策略读取与补丁更新直接发给沙箱内的 egress sidecar:SDK 先解析沙箱18080端口的端点,再调用 sidecar 的/policyAPI(实现见 EgressAdapter.cs:GET /policy读取、PATCH /policy打补丁、DELETE /policy按 target 删除)。
Patch 采用合并(merge)语义:
- 传入规则对相同
Target的既有规则优先; - 其他 target 的既有规则保持不变;
- 单次 patch 载荷内,同一
Target的第一条规则生效; - 当前
DefaultAction保持不变。
var policy = await sandbox.GetEgressPolicyAsync(); await sandbox.PatchEgressRulesAsync(new[] { new NetworkRule { Action = NetworkRuleAction.Allow, Target = "www.github.com" }, new NetworkRule { Action = NetworkRuleAction.Deny, Target = "pypi.org" } });Sandbox类还提供了DeleteEgressRulesAsync用于按 target 精确移除规则(Sandbox.cs),与 patch 合并语义形成完整的运行时策略管理闭环。
5. Credential Vault(凭据保险库)
Credential Vault 让 egress sidecar 在出站流量中注入凭据,同时让真实密钥不出现在沙箱的环境变量、命令、文件与日志中。步骤:创建沙箱时启用CredentialProxy,随后通过sandbox.CredentialVault或沙箱辅助方法写入凭据与绑定。
var sandbox = await Sandbox.CreateAsync(new SandboxCreateOptions { ConnectionConfig = config, Image = "python:3.11", NetworkPolicy = new NetworkPolicy { DefaultAction = NetworkRuleAction.Deny, Egress = new List<NetworkRule> { new() { Action = NetworkRuleAction.Allow, Target = "api.example.com" } } }, CredentialProxy = new CredentialProxyConfig { Enabled = true } }); await sandbox.CreateCredentialVaultAsync( new[] { new Credential { Name = "api-token", Source = new InlineCredentialSource { Value = "<token>" } } }, new[] { new CredentialBinding { Name = "api-token", Match = new CredentialMatch { Schemes = new[] { "https" }, Ports = new[] { 443 }, Hosts = new[] { "api.example.com" }, Paths = new[] { "/v1/*" } }, Auth = new CredentialAuth { Type = "apiKey", Name = "x-api-key", Credential = "api-token" } } });绑定的匹配条件(scheme/端口/host/路径 glob)决定哪些出站请求会被注入凭据;Auth.Type = "apiKey"表示以x-api-key请求头形式注入。Sandbox.CredentialVault暴露完整的 CRUD:CreateAsync、GetAsync、PatchAsync、DeleteAsync、ListCredentialsAsync、GetCredentialAsync、ListBindingsAsync、GetBindingAsync(Sandbox.cs),并有专门的测试 EgressAdapterCredentialVaultTests.cs 覆盖。若未启用CredentialProxy,CredentialVault回退到UnavailableCredentialVault实现,调用会明确失败而非静默。认证类型、绑定建议以及 Git/curl 的完整示例参见 Credential Vault 指南。
6. 超时与重试行为
ConnectionConfig.RequestTimeoutSeconds:SDK 普通 HTTP 调用的超时(默认 30 秒);SSE 流式客户端不受此限制,无超时;RunCommandOptions.TimeoutSeconds:单次命令执行超时;RunInSessionOptions.TimeoutSeconds:隔离会话(session)内命令执行超时;SandboxCreateOptions.TimeoutSeconds:沙箱服务端 TTL(默认 600 秒);ReadyTimeoutSeconds:就绪等待总预算。对ConnectAsync/ResumeAsync,端点发现与健康检查共享该超时;阻塞式自定义代码可能拖延超时上报;- SDK不会自动重试失败的 API 请求,需要重试时请在调用方代码中实现。
7. 资源清理
Sandbox与SandboxManager都实现了IAsyncDisposable,用完请用await using或显式调用DisposeAsync():
await using var sandbox = await Sandbox.CreateAsync(options); // ... use sandbox ... // Automatically disposed when leaving scope错误处理
操作失败时 SDK 抛出SandboxException及其派生异常:SandboxApiException(API 返回错误,携带StatusCode/RawBody)、SandboxReadyTimeoutException(就绪等待超时)、InvalidArgumentException(参数校验失败)、SandboxUnhealthyException、SandboxInternalException(完整定义见 Exceptions.cs)。所有异常都携带结构化SandboxError(稳定错误码 + 可选消息)与服务端RequestId。
SDK 内置的稳定错误码(SandboxErrorCodes):INTERNAL_UNKNOWN_ERROR、READY_TIMEOUT、UNHEALTHY、INVALID_ARGUMENT、UNEXPECTED_RESPONSE,便于程序化分支处理。
try { var execution = await sandbox.Commands.RunAsync("echo 'Hello Sandbox!'"); Console.WriteLine(execution.Logs.Stdout.FirstOrDefault()?.Text); } catch (SandboxReadyTimeoutException) { Console.Error.WriteLine("Sandbox did not become ready before the configured timeout."); } catch (SandboxApiException ex) { Console.Error.WriteLine($"API Error: status={ex.StatusCode}, requestId={ex.RequestId}, message={ex.Message}"); } catch (SandboxException ex) { Console.Error.WriteLine($"Sandbox Error: [{ex.Error.Code}] {ex.Error.Message}"); }支持的 .NET 框架
TargetFrameworks定义于 OpenSandbox.csproj,Release 构建开启TreatWarningsAsErrors:
- .NET Standard 2.0(兼容 .NET Framework 4.6.1+、.NET Core 2.0+、Mono、Xamarin 等)
- .NET Standard 2.1
- .NET 6.0 (LTS)
- .NET 7.0
- .NET 8.0 (LTS)
- .NET 9.0
- .NET 10.0
源码结构与延伸阅读
C# SDK 的源码组织(sdks/sandbox/csharp/src/OpenSandbox/)值得开发者参考:
- 门面层:Sandbox.cs(沙箱实例)、SandboxManager.cs(管理端);
- 配置层:Config/ConnectionConfig.cs、Config/DiagnosticsOptions.cs;
- 适配器层(接口实现):Adapters/ 下的
CommandsAdapter、FilesystemAdapter、EgressAdapter、MetricsAdapter、IsolatedSessionsAdapter、SseParser等,接口定义在 Services/;IAdapterFactory允许替换整套适配实现; - 内部机制:Internal/ 中的
HttpClientWrapper(请求封装)、ExecutionEventDispatcher(执行事件分发)、ReadinessBudget(就绪等待预算)、LifecycleMetricsReporter(创建遥测); - 测试:tests/OpenSandbox.Tests/ 提供连接配置、端点缓存、就绪诊断、egress/凭据、命令适配器等 20 余个测试文件,可作为行为契约的参照。
本文涉及的仓库文档延伸阅读:C# SDK 官方文档、生命周期钩子指南、凭据保险库指南、SDK 遥测指南、execd 组件文档。
License
Apache License 2.0。
【免费下载链接】OpenSandboxSecure, Fast, and Extensible Sandbox runtime for AI agents.项目地址: https://gitcode.com/GitHub_Trending/ope/OpenSandbox
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考