Skip to content

[BREAKING] Python: fix(hyperlight): interrupt guest execution and enforce time limits - #10152

Merged
Eduard van Valkenburg (eavanvalkenburg) merged 7 commits into
mainfrom
fix/python-hyperlight-execution-limits
Nov 11, 2026
Merged

Eduard van Valkenburg (eavanvalkenburg) merged 7 commits into
mainfrom
fix/python-hyperlight-execution-limits

Conversation

@baywet

Copy link
Copy Markdown
Member

Motivation & Context

Cancelling an asynchronous Hyperlight invocation should stop its guest execution before the sandbox can be reused. Python guest execution also needs a finite default budget, consistent with the .NET work in #10066.

Description & Review Guide

  • What are the major changes? Add a positive finite execution_timeout_seconds option to the tool and provider, defaulting to 30 seconds. Forward cancellation through an independently owned SDK interruption handle, wait for the native worker and interruption monitor to finish, and restore the warm snapshot before reuse. Capture the setting in provider run snapshots and serialized state. Add focused unit and real-guest regressions and update consumer guidance.
  • What is the impact of these changes? Guest execution is no longer unlimited by default; applications that intentionally run longer must configure a larger budget. Timeout returns error content, while caller cancellation remains asyncio.CancelledError. Runtime initialization and host tool callbacks cannot be interrupted and must enforce their own limits.
  • What do you want reviewers to focus on? Native owner-thread confinement, cancellation during host callbacks and queued work, repeated cancellation, budget capture, and recovery after interruption.

Dependency prerequisite: This draft requires the Python Sandbox.interrupt_handle() API from hyperlight-dev/hyperlight-sandbox#275. The declared released dependency does not yet provide it. A compatible SDK release and dependency-floor update are required before shipping; no local source paths are committed.

Validation used temporary Linux x64 Azure KVM containers linked to SDK revision 530672881443ac26973688191a18f180dc373efd. The three original real-guest regressions failed for the intended behavior before implementation changes.

Commands below ran from python/packages/hyperlight with that source-linked environment:

  • python -m pytest tests/hyperlight/test_execution_limits.py tests/hyperlight/test_execution_control.py -v --tb=short with HYPERLIGHT_RUN_GUEST_TESTS=true: 8 passed, covering Python/Wasm and native JavaScript.
  • python -m pytest tests -k "not pings_bing" --tb=short with HYPERLIGHT_RUN_GUEST_TESTS=true: 267 passed, 6 platform skips, 1 deselected, with the pre-existing warning described below.
  • python -m pytest tests -k pings_bing --tb=short with networking enabled: 1 passed.
  • python -m pytest -m 'not integration' --cov=agent_framework_hyperlight --cov-report=term-missing:skip-covered --cov-fail-under=85 tests --tb=short: 247 passed, 6 platform skips, 21 deselected; 88.31% coverage, above the 85% gate.
  • ruff check --no-fix . and ruff format --check .: passed with the repository-pinned Ruff.
  • pyright --pythonpath /src/.venv/bin/python: passed, 0 errors for source.

The configured test-typing profiles ran from python:

  • mypy --config-file pyproject.toml --explicit-package-bases --namespace-packages --python-executable /src/.venv/bin/python packages/hyperlight/tests: passed.
  • pyrefly check -c pyrefly.toml packages/hyperlight/tests: passed.
  • ty check packages/hyperlight/tests: passed.
  • zuban mypy --config-file pyproject.toml packages/hyperlight/tests: passed.
  • pyright -p pyrightconfig.tests.json --pythonpath /src/.venv/bin/python packages/hyperlight/tests: passed.

The full package run reports a native WasmSandbox cross-thread finalization warning. Repeating the existing host-error and owner-thread tests with unchanged production code from main and the same SDK reproduces it: python -m pytest tests/hyperlight/test_hyperlight_codeact.py -k 'host_error_policy_with_real_sandbox or sandbox_run_result_is_finalized_on_owner_thread' --tb=short -W error::pytest.PytestUnraisableExceptionWarning produced 4 passed, 1 failed because the warning was promoted to an error. This draft does not claim that existing warning is fixed.

Cross-language checks used the same updated SDK and the unchanged #10066 source. /src was the SDK checkout and /linked-sdk.targets replaced the .NET package reference with its local project:

  • From the SDK root, python -m unittest discover -s src/sdk/python/core/tests -p test_interruption.py -v: 4 passed, each exercising both backends.
  • dotnet vstest /src/src/sdk/dotnet/core/Tests/HyperlightSandbox.Tests/bin/Debug/net8.0/HyperlightSandbox.Tests.dll --Logger:"console;verbosity=normal": 152 passed.
  • From the Agent Framework dotnet directory, dotnet test --project tests/Microsoft.Agents.AI.Hyperlight.UnitTests -f net10.0 --no-build --no-restore -p:CustomAfterMicrosoftCommonTargets=/linked-sdk.targets -p:HyperlightGuestTests=true: 62 passed, 0 skipped.
  • From that same directory, dotnet test --project tests/Microsoft.Agents.AI.Hyperlight.IntegrationTests -f net10.0 --no-build --no-restore -p:CustomAfterMicrosoftCommonTargets=/linked-sdk.targets -p:JsonSerializerIsReflectionEnabledByDefault=true: 5 passed, 0 skipped.

Temporary Azure resources were deleted and their absence verified.

Related Issue

Related to #10066, which implements the .NET counterpart. This PR implements the Python integration rather than duplicating that work.

Depends on hyperlight-dev/hyperlight-sandbox#275. No separate Agent Framework issue is linked.

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: GitHub Copilot assisted with implementation, regression 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.

Copilot AI balanced review requested due to automatic review settings November 6, 2026 15:33
@agent-framework-automation agent-framework-automation Bot added documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs python Usage: [Issues, PRs], Target: Python breaking change Usage: [PRs], Target: all PRs that introduce changes that are not backward compatible labels Nov 6, 2026
@github-code-quality

github-code-quality Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Code coverage overview

Languages: Python

Python / code-coverage/python

main 7bfd07b fix/python-hyperligh... e29c10c +/-
92% 92% 0%

ℹ️ Calculations represent line coverage. Results may change as calculations are updated.


Updated November 10, 2026 16:50 UTC

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

A cold invocation can incorrectly exhaust its budget while waiting behind another execution, and deterministic tests are missing for timeout and cancellation cleanup during initialization and warm-up.

2 open issues
What changed in this PR

Adds cancellation propagation and finite execution budgets to Python Hyperlight, aligning with the .NET work in #10066. Shipping still requires a compatible SDK release and dependency-floor update.

Changes:

  • Adds a validated, configurable 30-second default budget, captured in run snapshots and serialized state.
  • Interrupts guest execution on cancellation or timeout and waits for worker cleanup before reuse.
  • Adds interruption and recovery tests and documents execution limits and migration requirements.
File Description
skills/​agent-framework-builder-python/​references/​integrations.md Documents execution budgets, cancellation, and SDK requirements.
python/​packages/​hyperlight/​tests/​hyperlight/​test_hyperlight_codeact.py Tests timeout validation and provider capture; updates sandbox fakes.
python/​packages/​hyperlight/​tests/​hyperlight/​test_execution_limits.py Adds real-guest cancellation, timeout, and recovery regressions.
python/​packages/​hyperlight/​tests/​hyperlight/​test_execution_control.py Tests timeout recovery, repeated cancellation, and queued cancellation.
python/​packages/​hyperlight/​tests/​hyperlight/​conftest.py Adds a controllable interruption fixture and updates lifecycle fakes.
python/​packages/​hyperlight/​README.md Explains limits, migration, SDK prerequisites, and native test setup.
python/​packages/​hyperlight/​agent_framework_hyperlight/​_provider.py Exposes and forwards the execution timeout option.
python/​packages/​hyperlight/​agent_framework_hyperlight/​_execute_code_tool.py Implements budget enforcement, interruption, cancellation cleanup, and setting capture.

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)): 858c047f5ade
Model: gpt-5.6-sol

Overview

The PR introduces per-invocation execution controls that preserve sandbox owner-thread confinement, wait through repeated cancellation, and restore cached sandboxes after interruption; focused tests cover cancellation, queued work, timeout, and reuse. Timeout validation, provider forwarding, and serialized state capture are coherent. The remaining risk is that the implementation unconditionally requires an SDK API absent from the declared and locked dependency, so standard installations fail before guest execution.

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

Affected areas: python/packages/hyperlight/agent_framework_hyperlight/_execute_code_tool.py

@baywet
Vincent Biret (baywet) force-pushed the fix/python-hyperlight-execution-limits branch from 858c047 to 53f6526 Compare November 9, 2026 17:16
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Exclude worker queue delays while retaining initialization costs, and cover timeout and cancellation cleanup during initialization.

Co-authored-by: Copilot <[email protected]>
Copilot-Session: 69b80046-564c-406d-8a7a-85c3f7bd7f5d

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 integration guidance conflicts with the consumer-skill maintenance contract by duplicating configuration and SDK interruption details instead of linking to the package README.

1 open issue
2 resolved since last review

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 2

Result: Findings reported
Scope: full PR (4 commit(s)): 5360db5873f7, 53f6526768b1, 9a487570e3f8, 6e8ce9b01df0
Model: gpt-5.6-sol

Overview

The PR adds a finite host-controlled guest budget, owner-thread-safe SDK interruption, cancellation cleanup, cold-start budget accounting, provider-state propagation, and the required dependency floor. Validation and lifecycle guards cover initialization failure, queued sandbox work, repeated cancellation, owner-thread disposal, and post-interruption reuse. Two residual races remain: a final host callback can complete successfully after the deadline, and cancellation can wait indefinitely when the invocation has not yet started in the shared default executor.

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

Affected areas: python/packages/hyperlight/agent_framework_hyperlight/_execute_code_tool.py

Recheck execution controls after guest completion and cancel queued default-executor invocations without waiting for unrelated work. Add regressions for both cases and sandbox recovery.

Co-authored-by: Copilot <[email protected]>
Copilot-Session: 69b80046-564c-406d-8a7a-85c3f7bd7f5d
Cancel queued worker futures without waiting for another invocation's host callback, while retaining owner-thread cleanup once work starts. Verify cancellation finishes before the active callback is released and the sandbox remains reusable.

Co-authored-by: Copilot <[email protected]>
Copilot-Session: 69b80046-564c-406d-8a7a-85c3f7bd7f5d
Merged via the queue into main with commit 9dd1cbb Nov 11, 2026
57 checks passed
@eavanvalkenburg
Eduard van Valkenburg (eavanvalkenburg) deleted the fix/python-hyperlight-execution-limits branch November 11, 2026 09:18

This branch was successfully deployed

1 active deployment
github-app-auth — e29c10c4 Deployed Nov 10, 2026 by baywet via add_label #27512
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 python Usage: [Issues, PRs], Target: Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants