chore: import upstream snapshot with attribution
SDK Tests / changes (push) Successful in 2m29s
Real E2E Tests / changes (push) Successful in 2m29s
Deploy Docs Pages / build (push) Has been cancelled
Deploy Docs Pages / deploy (push) Has been cancelled
Real E2E Tests / JavaScript E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / Python E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / Java E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / C# E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / Go E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / Real E2E CI (push) Has been cancelled
SDK Tests / SDK CI (push) Has been cancelled
SDK Tests / CLI Tests (push) Has been cancelled
SDK Tests / Python SDK Quality (code-interpreter) (push) Has been cancelled
SDK Tests / Python SDK Quality (sandbox) (push) Has been cancelled
SDK Tests / Python SDK Tests (code-interpreter) (push) Has been cancelled
SDK Tests / JavaScript SDK Quality And Tests (code-interpreter) (push) Has been cancelled
SDK Tests / JavaScript SDK Quality And Tests (sandbox) (push) Has been cancelled
SDK Tests / Python SDK Tests (sandbox) (push) Has been cancelled
SDK Tests / CLI Quality (push) Has been cancelled
SDK Tests / Kotlin SDK Quality And Tests (sandbox) (push) Has been cancelled
SDK Tests / Kotlin SDK Quality And Tests (code-interpreter) (push) Has been cancelled
SDK Tests / C# SDK Quality And Tests (code-interpreter) (push) Has been cancelled
SDK Tests / C# SDK Quality And Tests (sandbox) (push) Has been cancelled
SDK Tests / Go SDK Quality And Tests (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:39:33 +08:00
commit e0e362d700
1949 changed files with 375388 additions and 0 deletions
@@ -0,0 +1,230 @@
// Copyright 2026 Alibaba Group Holding Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.Json;
using OpenSandbox.Adapters;
using OpenSandbox.CodeInterpreter.Models;
using OpenSandbox.CodeInterpreter.Services;
using OpenSandbox.Core;
using OpenSandbox.Internal;
using OpenSandbox.Models;
using Microsoft.Extensions.Logging;
namespace OpenSandbox.CodeInterpreter.Adapters;
/// <summary>
/// Adapter implementation for the codes service.
/// </summary>
internal sealed class CodesAdapter : ICodes
{
private readonly HttpClientWrapper _client;
private readonly HttpClient _sseHttpClient;
private readonly string _baseUrl;
private readonly IReadOnlyDictionary<string, string> _headers;
private readonly ILogger _logger;
private static readonly JsonSerializerOptions JsonOptions = new()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
PropertyNameCaseInsensitive = true,
DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull
};
public CodesAdapter(
HttpClientWrapper client,
HttpClient sseHttpClient,
string baseUrl,
IReadOnlyDictionary<string, string> headers,
ILogger logger)
{
_client = client ?? throw new ArgumentNullException(nameof(client));
_sseHttpClient = sseHttpClient ?? throw new ArgumentNullException(nameof(sseHttpClient));
_baseUrl = baseUrl?.TrimEnd('/') ?? throw new ArgumentNullException(nameof(baseUrl));
_headers = headers ?? new Dictionary<string, string>();
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public async Task<CodeContext> CreateContextAsync(string language, CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(language))
{
throw new InvalidArgumentException("Language cannot be empty");
}
var request = new CreateContextRequest { Language = language };
_logger.LogDebug("Creating code context (language={Language})", language);
var response = await _client.PostAsync<CodeContext>("/code/context", request, cancellationToken).ConfigureAwait(false);
if (response == null || string.IsNullOrEmpty(response.Language))
{
throw new SandboxApiException(
message: "Create code context failed: unexpected response shape",
error: new SandboxError(SandboxErrorCodes.UnexpectedResponse, "Create code context failed: unexpected response shape"));
}
return response;
}
public async Task<CodeContext> GetContextAsync(string contextId, CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(contextId))
{
throw new InvalidArgumentException("contextId cannot be empty");
}
_logger.LogDebug("Fetching code context: {ContextId}", contextId);
var response = await _client.GetAsync<CodeContext>($"/code/contexts/{Uri.EscapeDataString(contextId)}", cancellationToken: cancellationToken).ConfigureAwait(false);
if (response == null || string.IsNullOrEmpty(response.Language))
{
throw new SandboxApiException(
message: "Get code context failed: unexpected response shape",
error: new SandboxError(SandboxErrorCodes.UnexpectedResponse, "Get code context failed: unexpected response shape"));
}
return response;
}
public async Task<IReadOnlyList<CodeContext>> ListContextsAsync(string language, CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(language))
{
throw new InvalidArgumentException("Language cannot be empty");
}
_logger.LogDebug("Listing code contexts (language={Language})", language);
var queryParams = new Dictionary<string, string?> { ["language"] = language };
var response = await _client.GetAsync<List<CodeContext>>("/code/contexts", queryParams, cancellationToken).ConfigureAwait(false);
if (response == null)
{
throw new SandboxApiException(
message: "List code contexts failed: unexpected response shape",
error: new SandboxError(SandboxErrorCodes.UnexpectedResponse, "List code contexts failed: unexpected response shape"));
}
return response;
}
public async Task DeleteContextAsync(string contextId, CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(contextId))
{
throw new InvalidArgumentException("contextId cannot be empty");
}
_logger.LogInformation("Deleting code context: {ContextId}", contextId);
await _client.DeleteAsync($"/code/contexts/{Uri.EscapeDataString(contextId)}", cancellationToken: cancellationToken).ConfigureAwait(false);
}
public async Task DeleteContextsAsync(string language, CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(language))
{
throw new InvalidArgumentException("Language cannot be empty");
}
_logger.LogInformation("Deleting code contexts (language={Language})", language);
var queryParams = new Dictionary<string, string?> { ["language"] = language };
await _client.DeleteAsync("/code/contexts", queryParams, cancellationToken).ConfigureAwait(false);
}
public async Task InterruptAsync(string executionId, CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(executionId))
{
throw new InvalidArgumentException("executionId cannot be empty");
}
_logger.LogInformation("Interrupting code execution: {ExecutionId}", executionId);
var queryParams = new Dictionary<string, string?> { ["id"] = executionId };
await _client.DeleteAsync("/code", queryParams, cancellationToken).ConfigureAwait(false);
}
public async IAsyncEnumerable<ServerStreamEvent> RunStreamAsync(
RunCodeRequest request,
[EnumeratorCancellation] CancellationToken cancellationToken = default)
{
if (request == null)
{
throw new InvalidArgumentException("request cannot be null");
}
if (string.IsNullOrWhiteSpace(request.Code))
{
throw new InvalidArgumentException("Code cannot be empty");
}
var url = $"{_baseUrl}/code";
_logger.LogDebug("Running code stream (codeLength={CodeLength})", request.Code.Length);
var json = JsonSerializer.Serialize(request, JsonOptions);
using var httpRequest = new HttpRequestMessage(HttpMethod.Post, url)
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
httpRequest.Headers.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("text/event-stream"));
foreach (var header in _headers)
{
httpRequest.Headers.TryAddWithoutValidation(header.Key, header.Value);
}
using var response = await _sseHttpClient.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
await foreach (var ev in SseParser.ParseJsonEventStreamAsync<ServerStreamEvent>(response, "Run code failed", cancellationToken).ConfigureAwait(false))
{
yield return ev;
}
}
public async Task<Execution> RunAsync(string code, RunCodeOptions? options = null, CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(code))
{
throw new InvalidArgumentException("Code cannot be empty");
}
if (options?.Context != null && options.Language != null)
{
throw new InvalidArgumentException("Provide either options.Context or options.Language, not both");
}
var context = options?.Context
?? (options?.Language != null
? new CodeContext { Language = options.Language }
: new CodeContext { Language = SupportedLanguage.Python });
var request = new RunCodeRequest
{
Code = code,
Context = context
};
var execution = new Execution();
_logger.LogDebug("Running code (codeLength={CodeLength})", code.Length);
var dispatcher = new ExecutionEventDispatcher(execution, options?.Handlers);
await foreach (var ev in RunStreamAsync(request, cancellationToken).ConfigureAwait(false))
{
await dispatcher.DispatchAsync(ev).ConfigureAwait(false);
}
return execution;
}
}
@@ -0,0 +1,149 @@
// Copyright 2026 Alibaba Group Holding Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using OpenSandbox.CodeInterpreter.Factory;
using OpenSandbox.CodeInterpreter.Services;
using OpenSandbox.Config;
using OpenSandbox.Core;
using OpenSandbox.Services;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
namespace OpenSandbox.CodeInterpreter;
/// <summary>
/// Options for creating a code interpreter.
/// </summary>
public class CodeInterpreterCreateOptions
{
/// <summary>
/// Gets or sets the adapter factory. If not provided, a default factory is used.
/// </summary>
public ICodeInterpreterAdapterFactory? AdapterFactory { get; set; }
/// <summary>
/// Gets or sets diagnostics options such as logging.
/// </summary>
public SdkDiagnosticsOptions? Diagnostics { get; set; }
}
/// <summary>
/// Code interpreter facade for executing code in multiple languages.
/// </summary>
/// <remarks>
/// This class wraps an existing <see cref="Sandbox"/> and provides a high-level API for code execution.
/// Use <see cref="Codes"/> to create contexts and run code.
/// <see cref="Files"/>, <see cref="Commands"/>, and <see cref="Metrics"/> are exposed for convenience
/// and are the same instances as on the underlying <see cref="Sandbox"/>.
/// This type does not own the remote sandbox lifecycle. Call <see cref="Sandbox.KillAsync"/> when you want to terminate
/// the remote instance. Dispose the wrapped <see cref="Sandbox"/> to release local SDK resources.
/// </remarks>
public sealed class CodeInterpreter
{
/// <summary>
/// Gets the underlying sandbox instance.
/// </summary>
public Sandbox Sandbox { get; }
/// <summary>
/// Gets the codes service for code execution operations.
/// </summary>
public ICodes Codes { get; }
/// <summary>
/// Gets the sandbox ID.
/// </summary>
public string Id => Sandbox.Id;
/// <summary>
/// Gets the filesystem service.
/// </summary>
public ISandboxFiles Files => Sandbox.Files;
/// <summary>
/// Gets the command execution service.
/// </summary>
public IExecdCommands Commands => Sandbox.Commands;
/// <summary>
/// Gets the metrics service.
/// </summary>
public IExecdMetrics Metrics => Sandbox.Metrics;
private readonly ILogger _logger;
private CodeInterpreter(Sandbox sandbox, ICodes codes, ILogger logger)
{
Sandbox = sandbox ?? throw new ArgumentNullException(nameof(sandbox));
Codes = codes ?? throw new ArgumentNullException(nameof(codes));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_logger.LogDebug("Code interpreter initialized for sandbox: {SandboxId}", sandbox.Id);
}
/// <summary>
/// Creates a new code interpreter from an existing sandbox.
/// </summary>
/// <param name="sandbox">The sandbox to wrap.</param>
/// <param name="options">Optional creation options.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>A new code interpreter instance.</returns>
/// <exception cref="InvalidArgumentException">Thrown when <paramref name="sandbox"/> is null.</exception>
/// <exception cref="SandboxException">Thrown when endpoint discovery or adapter initialization fails.</exception>
public static async Task<CodeInterpreter> CreateAsync(
Sandbox sandbox,
CodeInterpreterCreateOptions? options = null,
CancellationToken cancellationToken = default)
{
if (sandbox == null)
{
throw new InvalidArgumentException("sandbox cannot be null");
}
var loggerFactory = options?.Diagnostics?.LoggerFactory ?? sandbox.SharedLoggerFactory ?? NullLoggerFactory.Instance;
var logger = loggerFactory.CreateLogger("OpenSandbox.CodeInterpreter.CodeInterpreter");
var endpoint = await sandbox.GetEndpointAsync(Constants.DefaultExecdPort, cancellationToken).ConfigureAwait(false);
logger.LogInformation("Creating code interpreter for sandbox: {SandboxId}", sandbox.Id);
var protocol = sandbox.ConnectionConfig.Protocol == ConnectionProtocol.Https ? "https" : "http";
var execdBaseUrl = $"{protocol}://{endpoint.EndpointAddress}";
var execdHeaders = MergeHeaders(sandbox.ConnectionConfig.Headers, endpoint.Headers);
var adapterFactory = options?.AdapterFactory ?? DefaultCodeInterpreterAdapterFactory.Create();
var codes = adapterFactory.CreateCodes(new CreateCodesStackOptions
{
ConnectionConfig = sandbox.ConnectionConfig,
ExecdBaseUrl = execdBaseUrl,
ExecdHeaders = execdHeaders,
HttpClientProvider = sandbox.SharedHttpClientProvider,
LoggerFactory = loggerFactory
});
return new CodeInterpreter(sandbox, codes, logger);
}
private static IReadOnlyDictionary<string, string> MergeHeaders(
IReadOnlyDictionary<string, string> baseHeaders,
IReadOnlyDictionary<string, string>? overrideHeaders)
{
var merged = baseHeaders.ToDictionary(header => header.Key, header => header.Value);
if (overrideHeaders != null)
{
foreach (var header in overrideHeaders)
{
merged[header.Key] = header.Value;
}
}
return merged;
}
}
@@ -0,0 +1,80 @@
// Copyright 2026 Alibaba Group Holding Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using OpenSandbox.CodeInterpreter.Adapters;
using OpenSandbox.CodeInterpreter.Services;
using OpenSandbox.Core;
using OpenSandbox.Internal;
using Microsoft.Extensions.Logging;
namespace OpenSandbox.CodeInterpreter.Factory;
/// <summary>
/// Default implementation of the code interpreter adapter factory.
/// </summary>
public class DefaultCodeInterpreterAdapterFactory : ICodeInterpreterAdapterFactory
{
/// <summary>
/// Creates a new instance of the default adapter factory.
/// </summary>
/// <returns>A new factory instance.</returns>
public static DefaultCodeInterpreterAdapterFactory Create() => new();
/// <inheritdoc />
public ICodes CreateCodes(CreateCodesStackOptions options)
{
if (options == null)
{
throw new InvalidArgumentException("options cannot be null");
}
if (options.ConnectionConfig == null)
{
throw new InvalidArgumentException("options.ConnectionConfig cannot be null");
}
if (string.IsNullOrWhiteSpace(options.ExecdBaseUrl))
{
throw new InvalidArgumentException("options.ExecdBaseUrl cannot be null or empty");
}
if (options.ExecdHeaders == null)
{
throw new InvalidArgumentException("options.ExecdHeaders cannot be null");
}
if (options.HttpClientProvider == null)
{
throw new InvalidArgumentException("options.HttpClientProvider cannot be null");
}
if (options.LoggerFactory == null)
{
throw new InvalidArgumentException("options.LoggerFactory cannot be null");
}
var client = new HttpClientWrapper(
options.HttpClientProvider.HttpClient,
options.ExecdBaseUrl,
options.ExecdHeaders,
options.LoggerFactory.CreateLogger("OpenSandbox.HttpClientWrapper"));
return new CodesAdapter(
client,
options.HttpClientProvider.SseHttpClient,
options.ExecdBaseUrl,
options.ExecdHeaders,
options.LoggerFactory.CreateLogger("OpenSandbox.CodeInterpreter.CodesAdapter"));
}
}
@@ -0,0 +1,64 @@
// Copyright 2026 Alibaba Group Holding Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using OpenSandbox.CodeInterpreter.Services;
using OpenSandbox.Config;
using OpenSandbox;
using Microsoft.Extensions.Logging;
namespace OpenSandbox.CodeInterpreter.Factory;
/// <summary>
/// Options for creating a codes service stack.
/// </summary>
public class CreateCodesStackOptions
{
/// <summary>
/// Gets or sets the connection configuration.
/// </summary>
public required ConnectionConfig ConnectionConfig { get; set; }
/// <summary>
/// Gets or sets the execd API base URL.
/// </summary>
public required string ExecdBaseUrl { get; set; }
/// <summary>
/// Gets or sets headers to apply to execd requests.
/// </summary>
public required IReadOnlyDictionary<string, string> ExecdHeaders { get; set; }
/// <summary>
/// Gets or sets the HTTP client provider for this SDK instance.
/// </summary>
public required HttpClientProvider HttpClientProvider { get; set; }
/// <summary>
/// Gets or sets the logger factory for this SDK instance.
/// </summary>
public required ILoggerFactory LoggerFactory { get; set; }
}
/// <summary>
/// Factory interface for creating code interpreter adapters.
/// </summary>
public interface ICodeInterpreterAdapterFactory
{
/// <summary>
/// Creates a codes service instance.
/// </summary>
/// <param name="options">The creation options.</param>
/// <returns>The codes service.</returns>
ICodes CreateCodes(CreateCodesStackOptions options);
}
@@ -0,0 +1,127 @@
// Copyright 2026 Alibaba Group Holding Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.Text.Json.Serialization;
namespace OpenSandbox.CodeInterpreter.Models;
/// <summary>
/// Supported programming languages for code execution.
/// </summary>
public static class SupportedLanguage
{
/// <summary>
/// Python language.
/// </summary>
public const string Python = "python";
/// <summary>
/// Java language.
/// </summary>
public const string Java = "java";
/// <summary>
/// Go language.
/// </summary>
public const string Go = "go";
/// <summary>
/// TypeScript language.
/// </summary>
public const string TypeScript = "typescript";
/// <summary>
/// JavaScript language.
/// </summary>
public const string JavaScript = "javascript";
/// <summary>
/// Bash shell.
/// </summary>
public const string Bash = "bash";
}
/// <summary>
/// Represents a code execution context.
/// </summary>
public class CodeContext
{
/// <summary>
/// Gets or sets the context ID.
/// </summary>
[JsonPropertyName("id")]
public string? Id { get; set; }
/// <summary>
/// Gets or sets the programming language.
/// </summary>
[JsonPropertyName("language")]
public required string Language { get; set; }
}
/// <summary>
/// Request to run code.
/// </summary>
public class RunCodeRequest
{
/// <summary>
/// Gets or sets the code to execute.
/// </summary>
[JsonPropertyName("code")]
public required string Code { get; set; }
/// <summary>
/// Gets or sets the execution context.
/// </summary>
[JsonPropertyName("context")]
public required CodeContext Context { get; set; }
}
/// <summary>
/// Options for running code.
/// </summary>
public class RunCodeOptions
{
/// <summary>
/// Gets or sets the execution context. If provided, code runs in this context.
/// </summary>
public CodeContext? Context { get; set; }
/// <summary>
/// Gets or sets the language for a new ephemeral context.
/// Cannot be used together with Context.
/// </summary>
/// <remarks>
/// When only <see cref="Language"/> is provided and <see cref="Context"/> is null, execd creates or reuses
/// a default session for that language, so state can persist across runs.
/// </remarks>
public string? Language { get; set; }
/// <summary>
/// Gets or sets the execution event handlers.
/// </summary>
public OpenSandbox.Models.ExecutionHandlers? Handlers { get; set; }
}
/// <summary>
/// Request to create a code context.
/// </summary>
internal class CreateContextRequest
{
/// <summary>
/// Gets or sets the programming language.
/// </summary>
[JsonPropertyName("language")]
public required string Language { get; set; }
}
@@ -0,0 +1,74 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1;net6.0;net7.0;net8.0;net9.0;net10.0</TargetFrameworks>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>OpenSandbox.CodeInterpreter</RootNamespace>
<AssemblyName>OpenSandbox.CodeInterpreter</AssemblyName>
<!-- Package Information -->
<PackageId>Alibaba.OpenSandbox.CodeInterpreter</PackageId>
<Version>$(OpenSandboxCodeInterpreterPackageVersion)</Version>
<Authors>Alibaba Group</Authors>
<Company>Alibaba Group Holding Ltd.</Company>
<Product>OpenSandbox Code Interpreter SDK</Product>
<Description>A C# SDK for code interpretation with OpenSandbox. Provides high-level APIs for executing code in multiple languages (Python, JavaScript, TypeScript, Go, Java, Bash) within secure sandbox environments.</Description>
<Copyright>Copyright 2026 Alibaba Group Holding Ltd.</Copyright>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<PackageProjectUrl>https://open-sandbox.ai</PackageProjectUrl>
<RepositoryUrl>https://github.com/opensandbox-group/OpenSandbox.git</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>sandbox;code-interpreter;execution;opensandbox;alibaba;python;javascript</PackageTags>
<PackageReadmeFile>README.md</PackageReadmeFile>
<!-- Build Settings -->
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<TreatWarningsAsErrors Condition="'$(Configuration)' == 'Release'">true</TreatWarningsAsErrors>
<!--
Default to local source reference for development.
For release packing with NuGet version range, run:
dotnet pack -c Release -p:UseLocalOpenSandboxProjectReference=false
-->
<UseLocalOpenSandboxProjectReference Condition="'$(UseLocalOpenSandboxProjectReference)' == ''">true</UseLocalOpenSandboxProjectReference>
</PropertyGroup>
<!-- Expose internals to test project -->
<ItemGroup>
<InternalsVisibleTo Include="OpenSandbox.CodeInterpreter.Tests" />
</ItemGroup>
<!-- Use local project reference for day-to-day development -->
<ItemGroup Condition="'$(UseLocalOpenSandboxProjectReference)' == 'true'">
<ProjectReference Include="..\..\..\..\sandbox\csharp\src\OpenSandbox\OpenSandbox.csproj" />
</ItemGroup>
<!-- Use NuGet dependency range for release packaging -->
<ItemGroup Condition="'$(UseLocalOpenSandboxProjectReference)' != 'true'">
<PackageReference Include="Alibaba.OpenSandbox" Version="$(OpenSandboxDependencyVersionRange)" />
</ItemGroup>
<!-- Common Dependencies -->
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.2" />
<PackageReference Include="System.Text.Json" Version="8.0.5" />
<PackageReference Include="PolySharp" Version="1.14.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<!-- .NET Standard 2.0 specific dependencies -->
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" />
</ItemGroup>
<!-- Package files -->
<ItemGroup>
<None Include="..\..\README.md" Pack="true" PackagePath="\" />
</ItemGroup>
</Project>
@@ -0,0 +1,105 @@
// Copyright 2026 Alibaba Group Holding Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using OpenSandbox.CodeInterpreter.Models;
using OpenSandbox.Core;
using OpenSandbox.Models;
namespace OpenSandbox.CodeInterpreter.Services;
/// <summary>
/// Service interface for code execution operations.
/// </summary>
public interface ICodes
{
/// <summary>
/// Creates a new code execution context for the specified language.
/// </summary>
/// <param name="language">The programming language (use <see cref="SupportedLanguage"/> constants).</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>The created context.</returns>
/// <exception cref="InvalidArgumentException">Thrown when <paramref name="language"/> is null or empty.</exception>
/// <exception cref="SandboxException">Thrown when the sandbox service request fails.</exception>
Task<CodeContext> CreateContextAsync(string language, CancellationToken cancellationToken = default);
/// <summary>
/// Gets an existing context by ID.
/// </summary>
/// <param name="contextId">The context ID.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>The context.</returns>
/// <exception cref="InvalidArgumentException">Thrown when <paramref name="contextId"/> is null or empty.</exception>
/// <exception cref="SandboxException">Thrown when the sandbox service request fails.</exception>
Task<CodeContext> GetContextAsync(string contextId, CancellationToken cancellationToken = default);
/// <summary>
/// Lists active contexts for the specified language.
/// </summary>
/// <param name="language">Required language filter.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>List of contexts.</returns>
/// <exception cref="InvalidArgumentException">Thrown when <paramref name="language"/> is null or empty.</exception>
/// <exception cref="SandboxException">Thrown when the sandbox service request fails.</exception>
Task<IReadOnlyList<CodeContext>> ListContextsAsync(string language, CancellationToken cancellationToken = default);
/// <summary>
/// Deletes a context by ID.
/// </summary>
/// <param name="contextId">The context ID.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <exception cref="InvalidArgumentException">Thrown when <paramref name="contextId"/> is null or empty.</exception>
/// <exception cref="SandboxException">Thrown when the sandbox service request fails.</exception>
Task DeleteContextAsync(string contextId, CancellationToken cancellationToken = default);
/// <summary>
/// Deletes all contexts for the specified language.
/// </summary>
/// <param name="language">The programming language.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <exception cref="InvalidArgumentException">Thrown when <paramref name="language"/> is null or empty.</exception>
/// <exception cref="SandboxException">Thrown when the sandbox service request fails.</exception>
Task DeleteContextsAsync(string language, CancellationToken cancellationToken = default);
/// <summary>
/// Runs code and returns the execution result.
/// </summary>
/// <param name="code">The code to execute.</param>
/// <param name="options">Optional execution options.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>The execution result.</returns>
/// <exception cref="InvalidArgumentException">Thrown when required request fields are missing.</exception>
/// <exception cref="SandboxException">Thrown when the sandbox service request fails.</exception>
Task<Execution> RunAsync(string code, RunCodeOptions? options = null, CancellationToken cancellationToken = default);
/// <summary>
/// Runs code and streams execution events.
/// </summary>
/// <param name="request">The run code request.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>An async enumerable of server stream events.</returns>
/// <exception cref="InvalidArgumentException">Thrown when the request is invalid.</exception>
/// <exception cref="SandboxException">Thrown when the sandbox service request fails.</exception>
IAsyncEnumerable<ServerStreamEvent> RunStreamAsync(RunCodeRequest request, CancellationToken cancellationToken = default);
/// <summary>
/// Interrupts a running code execution.
/// </summary>
/// <param name="executionId">
/// The execution ID to interrupt, typically obtained from the run result or the <c>init</c> event.
/// </param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <exception cref="InvalidArgumentException">Thrown when <paramref name="executionId"/> is null or empty.</exception>
/// <exception cref="SandboxException">Thrown when the sandbox service request fails.</exception>
Task InterruptAsync(string executionId, CancellationToken cancellationToken = default);
}