Files
Eduard van Valkenburg fcc5576b04 .NET: feat(dotnet): Add LocalCodeAct package for local Python execution (#6105)
* feat(dotnet): Add LocalCodeAct package scaffold

Create Microsoft.Agents.AI.LocalCodeAct package with:
- Project file with embedded Python resources
- ExecutionMode enum (Subprocess only)
- ProcessExecutionLimits record
- FileMount record and FileMountMode enum
- README.md documentation
- Embedded Python runner and validator scripts

This is the .NET equivalent of the Python agent-framework-local-codeact
package. Next: Implement process bridge and tool integration.

* feat(dotnet): Add embedded Python runner and validator

Copy Python runner and validator scripts from the Python implementation
as embedded resources for the .NET package.

* feat(dotnet): Add CodeValidator wrapper

Implement CodeValidator.cs that:
- Extracts embedded Python validator script to temp file
- Invokes Python validator with JSON request
- Passes custom allow/block lists
- Throws CodeValidationException on failures
- Cleans up temp files

Uses the embedded Resources/validator.py for AST validation.

* feat(dotnet): Add LocalExecuteCodeFunction

Implement LocalExecuteCodeFunction as AIFunction:
- Accepts Python executable path (required)
- Registers host tools for code to call
- Validates code via CodeValidator if custom lists provided
- Executes via ProcessBridge
- Converts result dict to ChatMessage list
- Builds dynamic description including available tools

Matches Python LocalExecuteCodeTool functionality.

* feat(dotnet): Add LocalCodeActProvider

Implement AIContextProvider that:
- Injects execute_code tool into context
- Adds CodeAct instructions
- Enforces single-provider-per-agent via StateKeys
- Wraps LocalExecuteCodeFunction lifecycle

Minimal provider implementation matching Python LocalCodeActProvider.

* feat(dotnet): Add tests and sample for LocalCodeAct

Add unit tests:
- LocalExecuteCodeFunctionTests (4 tests)
- ProcessExecutionLimitsTests (2 tests)
- FileMountTests (2 tests)

Add sample:
- LocalCodeAct/Program.cs - Demonstrates provider and function usage
- LocalCodeAct/README.md - Documentation and safety warnings

Tests verify basic construction, metadata, and disposal.
Sample shows provider creation, function setup, and configuration.

Note: Build requires .NET 10 SDK per global.json.

* feat(dotnet): Add LocalCodeAct sample project

Add sample demonstrating:
- LocalCodeActProvider creation and configuration
- LocalExecuteCodeFunction direct usage
- Execution modes and file mount configuration
- Safety warnings and prerequisites

Includes project file and README with security guidance.

* feat(dotnet): Add file mount support and integration tests

- Added FileMountHelper.cs for file mount normalization, snapshot, and capture
- Updated LocalExecuteCodeFunction to support file mounts parameter
- Added file snapshot before/after execution with capture logic
- Updated LocalCodeActProvider to pass file mounts through
- Created comprehensive IntegrationTests.cs with 10 test cases:
  - Simple code execution
  - Timeout handling
  - Syntax error handling
  - Blocked import validation
  - Blocked builtin validation
  - Custom allowed imports
  - File mount read/write with capture
  - Stdout capture
  - Provider tool injection

All features from Python implementation now ported to .NET.

* Rewrite .NET LocalCodeAct to address all PR review comments

Complete rewrite that follows the Hyperlight package conventions
(see Microsoft.Agents.AI.Hyperlight) and addresses all 24 review
comments on PR #6105:

Architectural fixes:
* LocalCodeActProvider now uses options-class constructor pattern
  matching HyperlightCodeActProvider.
* Override of ProvideAIContextAsync uses the correct
  (InvokingContext, CancellationToken) signature returning
  ValueTask<AIContext>.
* ExecuteCodeFunction follows the AIFunction Name/Description/JsonSchema
  property pattern with InvokeCoreAsync override.
* Provider exposes AddTools/GetTools/RemoveTools/ClearTools and
  AddFileMounts/GetFileMounts/RemoveFileMounts/ClearFileMounts CRUD
  methods, with snapshot-at-invocation semantics under a lock.

Runtime/security fixes:
* Subprocess IPC uses JsonObject/JsonNode end-to-end (no
  Dictionary<string, object?> casts that broke under JsonElement
  deserialization).
* Validator runs in its own subprocess with a dedicated timeout
  (ProcessExecutionLimits.ValidationTimeoutSeconds), never reuses
  the runner script.
* Validation enabled by default; can be opt-ed out via
  ValidationEnabled = false.
* validator.py has a __main__ entrypoint that reads JSON from
  stdin and exits with structured errors.
* validator.py is now compatible with Python 3.9+ (Match nodes
  added conditionally).
* call_id parsed as long to match Python id(kwargs) range.

Other:
* README rewritten with valid C# syntax (options-class, FileMount
  constructor) and accurate descriptions of validator and file
  capture behavior.
* Added integration tests that exercise the real subprocess and
  validator (skipped gracefully when python3 is not on PATH).
* All 18 tests pass (15 unit + 3 integration) across net8/net9/net10.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Sync embedded validator.py with Python package allow-list enforcement

The embedded Python validator script used by the .NET LocalCodeAct
package now enforces the builtin allow-list, matching the latest
behavior of agent_framework_local_codeact._validator. Names that are
real Python builtins must appear in the allow-list, while unknown names
(user-defined functions, registered tools) remain allowed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add Hosted-LocalCodeAct foundry hosted-agent sample

Mirrors the Python foundry_hosted_agent.py sample for the local-codeact
package: registers compute and fetch_data as sandbox-only host tools on
LocalCodeActProvider so the model only sees execute_code and reaches them
via await call_tool(...). Includes the standard hosted-agent supporting
files (agent.yaml, agent.manifest.yaml, Dockerfile, Dockerfile.contributor,
.env.example, README.md) and installs python3 in the container images so
the embedded runner and validator can execute.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(local-codeact-dotnet): sync validator os.* allow-list with Python

Mirror the Python package change: the embedded validator.py invoked by the
.NET ProcessBridge replaces the os.* deny-list with an allow-list of
{environ, path}. Add allowed_os_attrs parameter to validate_code and
_CodeValidator, and surface it via the stdin JSON request schema so the
.NET host can opt in to a broader allow-list when needed.

Default behavior tightens to match the documented contract: any os.*
attribute outside {environ, path} (for example os.listdir, os.open,
os.getcwd) is rejected.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(local-codeact-dotnet): address review + tighten validator

- validator.py: enforce os.* allow-list on `from os import X` so names like
  `system`, `getcwd` cannot bypass the visit_Attribute restriction.
- ProcessBridge.ConfigureEnvironment: document that null Environment inherits
  the parent env (matching real behavior) and update the public
  LocalCodeActProviderOptions.Environment doc to describe the explicit
  empty-dictionary opt-in for a scrubbed environment.
- Tests:
  * FileMountHelperTests covers per-file, per-mount, and total
    capture-limit branches that return TextContent omissions.
  * Integration tests cover unknown-tool dispatch error, tool throwing
    exception, and CodeValidator timeout that kills the process and
    raises CodeValidationException.
- Sample: drop unused `Microsoft.Agents.AI.Foundry` using in
  Hosted-LocalCodeAct/Program.cs to satisfy IDE0005 check-format.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* chore(local-codeact-dotnet): remove stale orphan sample

The dotnet/samples/LocalCodeAct/ scaffolding sample referenced APIs
that don't exist in the current package (`ExecutionMode`, FileMount
object-initializer syntax, the old LocalExecuteCodeFunction
constructor signature, function.Metadata.*), produced a long list of
check-format violations (CHARSET, IMPORTS, IDE0073 header, IDE0005
unused using, IDE1006 Async suffix, RCS1037 trailing whitespace), and
did not match any of the documented sample layouts.

The hosted-agent example at
dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-LocalCodeAct
is the supported entry-point sample for this package.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* style(local-codeact-dotnet): satisfy check-format rules

- Add UTF-8 BOM to source files (CHARSET)
- Remove unused using directives (IDE0005)
- Simplify type names (IDE0001/IDE0002/IDE0090)
- Rename static field JsonOptions -> s_jsonOptions (IDE1006)
- Rename static field SyncRoot -> s_syncRoot (IDE1006)
- Add missing this. qualifications in ProcessBridge (IDE0009)
- Remove unused _options field from LocalCodeActProvider (IDE0052)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(local-codeact-dotnet): wire hosted sample into solution

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(local-codeact-dotnet): sync embedded Python scripts

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(local-codeact-dotnet): exercise Python integration on Windows

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* .NET: Address LocalCodeAct API review feedback

Move the required Python executable path to LocalCodeAct constructors, invert the validation flag default, and apply small project/file mount cleanup suggestions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* .NET: Address LocalCodeAct concurrency review

Surface unauthorized mount traversal errors and use concurrent provider registries for LocalCodeAct tool and file mount CRUD operations.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* .NET: Simplify LocalCodeAct function wrappers

Use AIFunctionFactory-created inner functions for LocalCodeAct execute_code wrappers and remove redundant script cache and JsonNode cloning logic.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* .NET: Update LocalCodeAct factory result tests

Handle JsonElement result values produced by AIFunctionFactory delegation in LocalCodeAct execute_code integration tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-17 15:30:52 +00:00
..

Agent Framework Samples

The agent framework samples are designed to help you get started with building AI-powered agents from various providers.

The Agent Framework supports building agents using various inference and inference-style services. All these are supported using the single ChatClientAgent class.

The Agent Framework also supports creating proxy agents, that allow accessing remote agents as if they were local agents. These are supported using various AIAgent subclasses.

Sample Structure

Folder Description
01-get-started/ Progressive tutorial: hello agent → hosting
02-agents/ Deep-dive by concept: tools, middleware, providers, orchestrations
03-workflows/ Workflow patterns: sequential, concurrent, state, declarative
04-hosting/ Deployment: Azure Functions, Durable Tasks
05-end-to-end/ Full applications, evaluation, demos

Getting Started

Start with 01-get-started/ and work through the numbered files:

  1. 01_hello_agent — Create and run your first agent
  2. 02_add_tools — Add function tools
  3. 03_multi_turn — Multi-turn conversations with AgentSession
  4. 04_memory — Agent memory with AIContextProvider
  5. 05_first_workflow — Build a workflow with executors and edges
  6. 06_host_your_agent — Host your agent via Azure Functions

Additional Samples

Some additional samples of note include:

  • Agents: Basic steps to get started with the agent framework. These samples demonstrate the fundamental concepts and functionalities of the agent framework when using the AIAgent and can be used with any underlying service that provides an AIAgent implementation.
  • Agent Providers: Shows how to create an AIAgent instance for a selection of providers.
  • Agent Telemetry: Demo which showcases the integration of OpenTelemetry with the Microsoft Agent Framework using Azure OpenAI and .NET Aspire Dashboard for telemetry visualization.
  • Durable Agents - Azure Functions: Samples for using the Microsoft Agent Framework with Azure Functions via the durable task extension.
  • Durable Agents - Console Apps: Samples demonstrating durable agents in console applications.

Migration from Semantic Kernel

If you are migrating from Semantic Kernel to the Microsoft Agent Framework, the following resources provide guidance and side-by-side examples to help you transition your existing agents, tools, and orchestration patterns. The migration samples map Semantic Kernel primitives (such as ChatCompletionAgent and Team orchestrations) to their Agent Framework equivalents (such as ChatClientAgent and workflow builders).

For an in-depth migration guide, see the official migration documentation.

Prerequisites

For prerequisites see each set of samples for their specific requirements.