Skip to content

[BREAKING] .NET: fix(hyperlight): propagate cancellation and limit execution - #10066

Draft
Vincent Biret (baywet) wants to merge 2 commits into
mainfrom
fix/hyperlight-execution-limits
Draft

Vincent Biret (baywet) wants to merge 2 commits into
mainfrom
fix/hyperlight-execution-limits

Conversation

@baywet

@baywet Vincent Biret (baywet) commented Nov 3, 2026 •

Copy link
Copy Markdown
Member

Motivation & Context

Propagate caller cancellation into running Hyperlight guest execution and apply a finite execution limit. Preserve snapshot restoration and executor reuse after cancellation or timeout.

This maintainer-directed draft depends on hyperlight-dev/hyperlight-sandbox#275 and publication of an SDK package containing its cancellation-aware Run overload. Keep this PR in draft; the current released-package dependency does not compile the new calls.

Description & Review Guide

  • What are the major changes? Forward a linked cancellation token into SDK warm-up and execution. Add a validated, snapshot-captured ExecutionTimeoutSeconds option with a 30-second default. Preserve caller cancellation, return an unsuccessful result for the configured timeout, and restore the warm snapshot before subsequent use. Bound recovery assertions and provide an explicit reflection-enabled KVM guest-test configuration while retaining ordinary reflection-disabled settings.
  • What is the impact of these changes? Guest execution is now finite by default. Migration: applications that intentionally run longer than 30 seconds must set HyperlightCodeActProviderOptions.ExecutionTimeoutSeconds to an appropriate larger positive value; an unlimited setting is not supported. Native execution and interruption callbacks finish before the execution semaphore is released. Runtime initialization and host tool callbacks cannot be interrupted, so host tools must enforce their own limits.
  • What do you want reviewers to focus on? Token and timeout precedence, per-run option capture, snapshot recovery, and the upstream package dependency. Both native JavaScript and Python/Wasm paths were validated against a locally built SDK through a temporary source-project reference; no machine-specific reference or unpublished package version is committed.

Recorded commands and results, from dotnet inside Ubuntu x64 SDK containers:

dotnet build tests/Microsoft.Agents.AI.Hyperlight.UnitTests -f net10.0 --tl:off \
  -p:CustomAfterMicrosoftCommonTargets=/linked-sdk.targets -p:HyperlightGuestTests=true

Passed, zero warnings/errors. The temporary targets replace the NuGet SDK reference with the locally built upstream API project for validation only.

dotnet test --project tests/Microsoft.Agents.AI.Hyperlight.UnitTests -f net10.0 --no-build --no-restore \
  -p:CustomAfterMicrosoftCommonTargets=/linked-sdk.targets -p:HyperlightGuestTests=true

Passed, all 62 tests, no skips. HYPERLIGHT_RUN_GUEST_TESTS=true and the built Python guest path were set; /dev/kvm was passed through to a resource-limited, network-disabled container. This includes caller cancellation and recovery, the 30-second default, and captured one-second limits with recovery for JavaScript and Python/Wasm.

dotnet build tests/Microsoft.Agents.AI.Hyperlight.IntegrationTests -f net10.0 --tl:off \
  -p:CustomAfterMicrosoftCommonTargets=/linked-sdk.targets -p:JsonSerializerIsReflectionEnabledByDefault=true
dotnet test --project tests/Microsoft.Agents.AI.Hyperlight.IntegrationTests -f net10.0 --no-build --no-restore \
  -p:CustomAfterMicrosoftCommonTargets=/linked-sdk.targets -p:JsonSerializerIsReflectionEnabledByDefault=true

Both passed: zero build warnings/errors, all 5 real Python/Wasm integration tests, no skips.

Ordinary reflection-disabled unit configuration, without KVM or guest opt-in:

dotnet build tests/Microsoft.Agents.AI.Hyperlight.UnitTests -f net10.0 --tl:off \
  -p:CustomAfterMicrosoftCommonTargets=/linked-sdk.targets
dotnet test --project tests/Microsoft.Agents.AI.Hyperlight.UnitTests -f net10.0 --no-build --no-restore \
  -p:CustomAfterMicrosoftCommonTargets=/linked-sdk.targets

Both passed: zero build warnings/errors, 58 passed, 4 explicitly gated guest cases skipped.

Formatting with the temporary SDK targets supplied through the CustomAfterMicrosoftCommonTargets environment property:

dotnet format src/Microsoft.Agents.AI.Hyperlight --no-restore
dotnet format tests/Microsoft.Agents.AI.Hyperlight.UnitTests --no-restore
dotnet format src/Microsoft.Agents.AI.Hyperlight --no-restore --verify-no-changes
dotnet format tests/Microsoft.Agents.AI.Hyperlight.UnitTests --no-restore --verify-no-changes

All passed. Formatter output is included in the submitted changes.

Before implementation, the linked-SDK regression run failed for both intended behaviors: cancellation threw no exception, and the 32-second guest returned success instead of timing out. Guest warm-up succeeded. The same original regressions now pass.

dotnet build src/Microsoft.Agents.AI.Hyperlight -f net10.0 --tl:off

Blocked with the current released SDK: CS1501 at both cancellation-aware Run calls. This remains a draft pending the upstream SDK package release and dependency update. The full Agent Framework solution, Windows execution, and other target frameworks were not run.

Related Issue

Related to hyperlight-dev/hyperlight-sandbox#9 and dependent on hyperlight-dev/hyperlight-sandbox#275. This maintainer-directed integration does not close the upstream tracker or duplicate the SDK implementation.

AI Assistance

  • No material AI assistance was used.
  • This is an AI-assisted contribution. I reviewed, understood, and verified all submitted content and accept responsibility for it.

AI assistance details: Copilot assisted with implementation, tests, documentation, validation, and this PR description.

Contribution Checklist

  • The code builds clean without any errors or warnings
  • All unit tests pass, and I have added new tests where possible
  • The PR follows the Contribution Guidelines
  • This PR links to an agreed issue with no competing open PR, or the Related Issue section documents a trivial-change or repository-automation exception.
  • This is not a breaking change. If it is a breaking change, add the breaking change label (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3d6807e7-70a6-4c43-8dc1-7bab20376cd4
Copilot AI balanced review requested due to automatic review settings November 3, 2026 20:28
@agent-framework-automation agent-framework-automation Bot added the .NET Usage: [Issues, PRs], Target: .Net label Nov 3, 2026
@github-actions github-actions Bot changed the title fix(hyperlight): add cancellation regression coverage .NET: fix(hyperlight): add cancellation regression coverage Nov 3, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The cancellation regression test fails during warm-up under the checked-in serialization configuration, and its unbounded recovery call can hang the test runner if the execution lock leaks.

2 open issues
What changed in this PR

This test-only draft adds regression coverage for cancellation during Hyperlight guest execution and subsequent executor reuse. Production behavior is unchanged; the recorded run currently fails at the cancellation assertion.

Changes:

  • Warms up a real JavaScript guest and verifies successful execution.
  • Cancels the caller token from a registered host callback and expects cancellation to propagate.
  • Adds a follow-up invocation to check executor reuse after cancellation.
File Description
dotnet/​tests/​Microsoft.Agents.AI.Hyperlight.UnitTests/​SandboxExecutorTests.cs Adds the guest-execution cancellation and executor-reuse regression test.

Review effort: Balanced

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MAF Automated Review — Iteration 1

Result: Findings reported
Scope: full PR (1 commit(s)): 2005a2f87b09
Model: gpt-5.6-sol

Overview

The PR adds a real-sandbox regression test that proves guest entry, triggers caller cancellation from a host callback, and attempts to reuse the executor. Existing finally-based lock release and warm-snapshot restoration are strong lifecycle guards, but the current executor does not observe cancellation after guest execution starts, so the new enabled test deterministically fails. In addition, the test's tool-bearing warm-up requires serialization behavior disabled by the project's normal configuration, which can prevent the intended scenario from being reached at all.

Reviewed the supplied pull-request change set across correctness, security/reliability, architecture, and failure behavior.
2 verified findings remained after source verification (1 high, 1 medium) across 1 file. Details are attached to the affected lines below.

Affected areas: dotnet/tests/Microsoft.Agents.AI.Hyperlight.UnitTests/SandboxExecutorTests.cs

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3d6807e7-70a6-4c43-8dc1-7bab20376cd4
@baywet Vincent Biret (baywet) changed the title .NET: fix(hyperlight): add cancellation regression coverage [BREAKING] .NET: fix(hyperlight): propagate cancellation and limit execution Nov 4, 2026
@baywet
Vincent Biret (baywet) requested a balanced review from Copilot November 4, 2026 00:31
@agent-framework-automation agent-framework-automation Bot added documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs breaking change Usage: [PRs], Target: all PRs that introduce changes that are not backward compatible labels Nov 4, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The cancellation test can pass through the SDK’s post-execution cancellation check without verifying that cancellation promptly interrupts running guest code.

1 open issue
2 resolved since last review

Review effort: Balanced

Comment on lines +90 to +91
await Assert.ThrowsAnyAsync<OperationCanceledException>(
() => executor.ExecuteAsync(snapshot, "call_tool('cancel_run', {});", cancellation.Token));

This branch was previously deployed

2 inactive deployments
github-app-auth — 8c08448e Deployed Nov 4, 2026 by baywet via add_label #27031
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking change Usage: [PRs], Target: all PRs that introduce changes that are not backward compatible documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs .NET Usage: [Issues, PRs], Target: .Net

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants