Skip to content

Commit e7dc3b9

Browse files
.NET: Add Microsoft.Agents.AI.Hyperlight package for CodeAct integration (.NET) (#5329)
* Add Microsoft.Agents.AI.Hyperlight package for CodeAct integration Introduces a new Microsoft.Agents.AI.Hyperlight package that enables CodeAct-style sandboxed code execution via Hyperlight (hyperlight-sandbox .NET SDK, PR #46) for .NET agents, following the docs/features/code_act/dotnet-implementation.md design and the Python agent_framework_hyperlight reference. Highlights: - HyperlightCodeActProvider (AIContextProvider): injects an execute_code tool and CodeAct guidance per invocation; single-instance-per-agent via a fixed StateKeys value; supports multiple provider-owned tools (exposed inside the sandbox via call_tool), file mounts, and an outbound domain allow-list; snapshot/restore per run. - HyperlightExecuteCodeFunction: standalone AIFunction for manual/static wiring when the sandbox configuration is fixed. - Approval model via CodeActApprovalMode (AlwaysRequire / NeverRequire) with propagation from ApprovalRequiredAIFunction-wrapped tools. - Unit tests (instruction builder, tool bridge, approval computation, provider CRUD, ProvideAIContextAsync snapshot isolation and approval wrapping). - Env-gated integration test (HYPERLIGHT_PYTHON_GUEST_PATH). - Three samples under samples/02-agents/AgentWithCodeAct (interpreter, tool-enabled, manual wiring). Build is not yet runnable: requires .NET SDK 10.0.200 and the not-yet-published HyperlightSandbox.Api 0.1.0-preview NuGet package. Package is marked IsPackable=false until the dependency is available. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR #5329 review feedback for Hyperlight CodeAct provider - A. Build-breakers: drop unused usings, override test TargetFrameworks off net472, drop redundant Microsoft.Extensions.AI.Abstractions PackageRef. - B. API: keep CRUD but rebuild sandbox when config fingerprint changes; add HyperlightCodeActProviderOptions.CreateForWasm/CreateForJavaScript factory methods (Backend/ModulePath now read-only); rename WorkspaceRoot to HostInputDirectory; convert AllowedDomain & FileMount from record to sealed class; drop ToolBridge.Unwrap (ApprovalRequiredAIFunction is invocable as-is). - C. ToolBridge: collapse SerializeResult switch; add comment explaining AOT-driven choice to keep JsonNode.Parse over typed Deserialize. - D. InstructionBuilder: drop language-specific 'Python code' phrasing; strip host filesystem paths from execute_code description. - E. Style polish: ternary expression-body for ComputeApprovalRequired, .Where(x is not null), .ToList() over .ToArray() in IReadOnlyList returns. - F. Samples: add guest-module / KVM-WHP build instructions to Step01; note future Excel-upload sample in Step02. Also adds SandboxExecutorTests covering the new RunSnapshot.ComputeFingerprint used for sandbox-rebuild detection. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Align Hyperlight package id and JS warm-up with merged upstream SDK The .NET SDK in hyperlight-dev/hyperlight-sandbox PR #46 has merged. The published package id is Hyperlight.HyperlightSandbox.Api (the bare HyperlightSandbox.Api remains the assembly/namespace) and the reference CodeExecutionTool uses 'void 0;' as the JavaScript warm-up no-op. Update the package reference, project comment, README, and SandboxExecutor warm-up accordingly. No functional change beyond that — all other public APIs we depend on (SandboxBuilder.With*, Sandbox.Run/RegisterToolAsync/AllowDomain/Snapshot/ Restore, ExecutionResult, SandboxBackend) match the merged shape. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Bump Hyperlight package to 0.4.0 and fix build/test issues Hyperlight.HyperlightSandbox.Api 0.4.0 is now published on nuget.org. Bump the version reference and address the analyzer/runtime issues that surfaced once restore could complete: - Add HyperlightJsonContext source-generated JsonSerializerContext for the execute_code result + tool error envelopes; route arbitrary AIFunction results through AIJsonUtilities.DefaultOptions to keep IsAotCompatible=true. - Replace explicit ObjectDisposedException throws with ObjectDisposedException.ThrowIf (CA1513). - Use HyperlightSandbox.Api.SandboxBackend in cref docs to disambiguate. - Update tests to match AIContext.Tools being IEnumerable<AITool>, drop ConfigureAwait(false) in xUnit test methods (xUnit1030), use collection expressions for AllowedDomain methods. - Add 'using OpenAI.Chat;' to all three samples so AsAIAgent resolves. - Verified: dotnet build of all four hyperlight projects + samples succeeds on net8/9/10; dotnet test for the unit tests passes 32/32 on net10.0. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix CI check failures: file encoding (UTF-8 BOM + LF) and broken markdown link - Convert all new .cs/.csproj files to UTF-8 with BOM and LF line endings to satisfy the dotnet/.editorconfig charset/end_of_line settings enforced by check-format. - Drop unused System.Collections.Generic using in HyperlightCodeActProviderTests. - Add missing using Microsoft.Extensions.AI in CodeActApprovalMode.cs and shorten ApprovalRequiredAIFunction cref (IDE0001). - Fix broken README link to docs/decisions/0024-codeact-integration.md. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR review: AIFunction inheritance, packaging, GetService approval check - HyperlightExecuteCodeFunction now inherits AIFunction directly. The AsAIFunction() indirection is gone; instances are accepted anywhere an AIFunction is. Approval requirement is surfaced via GetService<ApprovalRequiredAIFunction>() which lazily exposes a wrapping ApprovalRequiredAIFunction proxy when the effective ApprovalMode/tool stack requires it. - ComputeApprovalRequired now uses GetService<ApprovalRequiredAIFunction>() so approval-required tools nested anywhere in the AITool decorator stack are detected (not just the top-most class). - csproj: drop IsPackable=false (ready to release with the published Hyperlight.HyperlightSandbox.Api 0.4.0 dependency); add PackageReadmeFile and pack README.md at the package root, matching the pattern used by Aspire.Hosting.AgentFramework.DevUI / Microsoft.Agents.AI.DurableTask. - Update Step03 sample and README wording to reflect direct AIFunction usage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent d7ca9c8 commit e7dc3b9

35 files changed

Lines changed: 2287 additions & 0 deletions

dotnet/Directory.Packages.props

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@
109109
<PackageVersion Include="A2A.AspNetCore" Version="1.0.0-preview2" />
110110
<!-- MCP -->
111111
<PackageVersion Include="ModelContextProtocol" Version="1.1.0" />
112+
<!-- Hyperlight -->
113+
<PackageVersion Include="Hyperlight.HyperlightSandbox.Api" Version="0.4.0" />
112114
<!-- Inference SDKs -->
113115
<PackageVersion Include="Microsoft.ML.OnnxRuntimeGenAI" Version="0.10.0" />
114116
<PackageVersion Include="Microsoft.ML.Tokenizers" Version="2.0.0" />

dotnet/agent-framework-dotnet.slnx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,12 @@
175175
<Project Path="samples/02-agents/Evaluation/Evaluation_Multimodal/Evaluation_Multimodal.csproj" />
176176
<Project Path="samples/02-agents/Evaluation/Evaluation_SimpleEval/Evaluation_SimpleEval.csproj" />
177177
</Folder>
178+
<Folder Name="/Samples/02-agents/AgentWithCodeAct/">
179+
<File Path="samples/02-agents/AgentWithCodeAct/README.md" />
180+
<Project Path="samples/02-agents/AgentWithCodeAct/AgentWithCodeAct_Step01_Interpreter/AgentWithCodeAct_Step01_Interpreter.csproj" />
181+
<Project Path="samples/02-agents/AgentWithCodeAct/AgentWithCodeAct_Step02_ToolEnabled/AgentWithCodeAct_Step02_ToolEnabled.csproj" />
182+
<Project Path="samples/02-agents/AgentWithCodeAct/AgentWithCodeAct_Step03_ManualWiring/AgentWithCodeAct_Step03_ManualWiring.csproj" />
183+
</Folder>
178184
<Folder Name="/Samples/02-agents/AgentWithMemory/">
179185
<File Path="samples/02-agents/AgentWithMemory/README.md" />
180186
<Project Path="samples/02-agents/AgentWithMemory/AgentWithMemory_Step01_ChatHistoryMemory/AgentWithMemory_Step01_ChatHistoryMemory.csproj" />
@@ -560,6 +566,7 @@
560566
<Project Path="src/Microsoft.Agents.AI.Hosting.AzureFunctions/Microsoft.Agents.AI.Hosting.AzureFunctions.csproj" />
561567
<Project Path="src/Microsoft.Agents.AI.Hosting.OpenAI/Microsoft.Agents.AI.Hosting.OpenAI.csproj" />
562568
<Project Path="src/Microsoft.Agents.AI.Hosting/Microsoft.Agents.AI.Hosting.csproj" />
569+
<Project Path="src/Microsoft.Agents.AI.Hyperlight/Microsoft.Agents.AI.Hyperlight.csproj" />
563570
<Project Path="src/Microsoft.Agents.AI.Mem0/Microsoft.Agents.AI.Mem0.csproj" />
564571
<Project Path="src/Microsoft.Agents.AI.OpenAI/Microsoft.Agents.AI.OpenAI.csproj" />
565572
<Project Path="src/Microsoft.Agents.AI.Purview/Microsoft.Agents.AI.Purview.csproj" />
@@ -581,6 +588,7 @@
581588
<Project Path="tests/Microsoft.Agents.AI.GitHub.Copilot.IntegrationTests/Microsoft.Agents.AI.GitHub.Copilot.IntegrationTests.csproj" />
582589
<Project Path="tests/Microsoft.Agents.AI.Hosting.AGUI.AspNetCore.IntegrationTests/Microsoft.Agents.AI.Hosting.AGUI.AspNetCore.IntegrationTests.csproj" />
583590
<Project Path="tests/Microsoft.Agents.AI.Hosting.AzureFunctions.IntegrationTests/Microsoft.Agents.AI.Hosting.AzureFunctions.IntegrationTests.csproj" />
591+
<Project Path="tests/Microsoft.Agents.AI.Hyperlight.IntegrationTests/Microsoft.Agents.AI.Hyperlight.IntegrationTests.csproj" />
584592
<Project Path="tests/Microsoft.Agents.AI.Mem0.IntegrationTests/Microsoft.Agents.AI.Mem0.IntegrationTests.csproj" />
585593
<Project Path="tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests.csproj" />
586594
<Project Path="tests/OpenAIAssistant.IntegrationTests/OpenAIAssistant.IntegrationTests.csproj" />
@@ -606,6 +614,7 @@
606614
<Project Path="tests/Microsoft.Agents.AI.Hosting.AzureFunctions.UnitTests/Microsoft.Agents.AI.Hosting.AzureFunctions.UnitTests.csproj" />
607615
<Project Path="tests/Microsoft.Agents.AI.Hosting.OpenAI.UnitTests/Microsoft.Agents.AI.Hosting.OpenAI.UnitTests.csproj" />
608616
<Project Path="tests/Microsoft.Agents.AI.Hosting.UnitTests/Microsoft.Agents.AI.Hosting.UnitTests.csproj" />
617+
<Project Path="tests/Microsoft.Agents.AI.Hyperlight.UnitTests/Microsoft.Agents.AI.Hyperlight.UnitTests.csproj" />
609618
<Project Path="tests/Microsoft.Agents.AI.Mem0.UnitTests/Microsoft.Agents.AI.Mem0.UnitTests.csproj" />
610619
<Project Path="tests/Microsoft.Agents.AI.OpenAI.UnitTests/Microsoft.Agents.AI.OpenAI.UnitTests.csproj" />
611620
<Project Path="tests/Microsoft.Agents.AI.Purview.UnitTests/Microsoft.Agents.AI.Purview.UnitTests.csproj" />
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFrameworks>net10.0</TargetFrameworks>
6+
7+
<Nullable>enable</Nullable>
8+
<ImplicitUsings>enable</ImplicitUsings>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<PackageReference Include="Azure.AI.OpenAI" />
13+
<PackageReference Include="Azure.Identity" />
14+
<PackageReference Include="Microsoft.Extensions.AI.OpenAI" />
15+
</ItemGroup>
16+
17+
<ItemGroup>
18+
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
19+
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Hyperlight\Microsoft.Agents.AI.Hyperlight.csproj" />
20+
</ItemGroup>
21+
22+
</Project>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
3+
// This sample shows how to use HyperlightCodeActProvider as a sandboxed Python
4+
// code interpreter: the model can write and execute arbitrary Python code to
5+
// answer quantitative questions without calling any additional tools.
6+
7+
using Azure.AI.OpenAI;
8+
using Azure.Identity;
9+
using Microsoft.Agents.AI;
10+
using Microsoft.Agents.AI.Hyperlight;
11+
using OpenAI.Chat;
12+
13+
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
14+
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-5.4-mini";
15+
var guestPath = Environment.GetEnvironmentVariable("HYPERLIGHT_PYTHON_GUEST_PATH") ?? throw new InvalidOperationException("HYPERLIGHT_PYTHON_GUEST_PATH is not set.");
16+
17+
using var codeAct = new HyperlightCodeActProvider(HyperlightCodeActProviderOptions.CreateForWasm(guestPath));
18+
19+
AIAgent agent = new AzureOpenAIClient(
20+
new Uri(endpoint),
21+
new DefaultAzureCredential())
22+
.GetChatClient(deploymentName)
23+
.AsAIAgent(new ChatClientAgentOptions()
24+
{
25+
ChatOptions = new() { Instructions = "You are a helpful assistant. When the user asks something quantitative, write Python and call `execute_code` instead of guessing." },
26+
AIContextProviders = [codeAct],
27+
});
28+
29+
Console.WriteLine(await agent.RunAsync("What is the 20th Fibonacci number?"));
30+
Console.WriteLine(await agent.RunAsync("Compute the mean and standard deviation of [1, 4, 9, 16, 25, 36]."));
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# AgentWithCodeAct_Step01_Interpreter
2+
3+
A minimal CodeAct sample. The agent uses `HyperlightCodeActProvider` as a
4+
sandboxed Python interpreter: when the user asks something quantitative, the
5+
model writes Python and invokes the `execute_code` tool rather than answering
6+
from memory.
7+
8+
## Configuration
9+
10+
| Variable | Description |
11+
|--------------------------------|-------------------------------------------------------------------------------------------|
12+
| `AZURE_OPENAI_ENDPOINT` | Azure OpenAI endpoint. Required. |
13+
| `AZURE_OPENAI_DEPLOYMENT_NAME` | Azure OpenAI deployment. Defaults to `gpt-5.4-mini`. |
14+
| `HYPERLIGHT_PYTHON_GUEST_PATH` | Absolute path to the Hyperlight Python guest module (`.wasm` or `.aot` file). Required. |
15+
16+
Authentication uses `DefaultAzureCredential`.
17+
18+
## Getting the guest module
19+
20+
The Python guest module is built from the
21+
[hyperlight-dev/hyperlight-sandbox](https://github.com/hyperlight-dev/hyperlight-sandbox)
22+
repository — see its README for the exact `cargo`/`just` invocations and
23+
the location of the resulting `.wasm` / `.aot` file. Set
24+
`HYPERLIGHT_PYTHON_GUEST_PATH` to the absolute path of that artifact
25+
before running the sample.
26+
27+
Hyperlight requires a hardware virtualization back end on the host:
28+
KVM on Linux or WHP (Windows Hypervisor Platform) on Windows.
29+
30+
## Run
31+
32+
```shell
33+
cd AgentWithCodeAct_Step01_Interpreter
34+
dotnet run
35+
```
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFrameworks>net10.0</TargetFrameworks>
6+
7+
<Nullable>enable</Nullable>
8+
<ImplicitUsings>enable</ImplicitUsings>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<PackageReference Include="Azure.AI.OpenAI" />
13+
<PackageReference Include="Azure.Identity" />
14+
<PackageReference Include="Microsoft.Extensions.AI.OpenAI" />
15+
</ItemGroup>
16+
17+
<ItemGroup>
18+
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
19+
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Hyperlight\Microsoft.Agents.AI.Hyperlight.csproj" />
20+
</ItemGroup>
21+
22+
</Project>
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
3+
// This sample shows how to use HyperlightCodeActProvider with provider-owned
4+
// tools (exposed inside the sandbox via `call_tool(...)`). The model can
5+
// orchestrate those tools in a single Python block, reducing round-trips. A
6+
// sensitive tool (`send_email`) is additionally wrapped in
7+
// ApprovalRequiredAIFunction so any code that reaches it requires user approval
8+
// for the entire execute_code invocation.
9+
10+
using Azure.AI.OpenAI;
11+
using Azure.Identity;
12+
using Microsoft.Agents.AI;
13+
using Microsoft.Agents.AI.Hyperlight;
14+
using Microsoft.Extensions.AI;
15+
using OpenAI.Chat;
16+
17+
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
18+
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-5.4-mini";
19+
var guestPath = Environment.GetEnvironmentVariable("HYPERLIGHT_PYTHON_GUEST_PATH") ?? throw new InvalidOperationException("HYPERLIGHT_PYTHON_GUEST_PATH is not set.");
20+
21+
AIFunction fetchDocs = AIFunctionFactory.Create(
22+
(string topic) => $"Docs for {topic}: (...)",
23+
name: "fetch_docs",
24+
description: "Fetch documentation for a given topic.");
25+
26+
AIFunction queryData = AIFunctionFactory.Create(
27+
(string query) => $"Rows for `{query}`: []",
28+
name: "query_data",
29+
description: "Run a read-only SQL-like query against the sample store.");
30+
31+
AIFunction sendEmail = new ApprovalRequiredAIFunction(
32+
AIFunctionFactory.Create(
33+
(string to, string subject) => $"Sent '{subject}' to {to}.",
34+
name: "send_email",
35+
description: "Send an email on behalf of the user."));
36+
37+
var options = HyperlightCodeActProviderOptions.CreateForWasm(guestPath);
38+
options.Tools = [fetchDocs, queryData, sendEmail];
39+
40+
using var codeAct = new HyperlightCodeActProvider(options);
41+
42+
AIAgent agent = new AzureOpenAIClient(
43+
new Uri(endpoint),
44+
new DefaultAzureCredential())
45+
.GetChatClient(deploymentName)
46+
.AsAIAgent(new ChatClientAgentOptions()
47+
{
48+
ChatOptions = new() { Instructions = "You are a helpful assistant. Prefer orchestrating your work in a single `execute_code` block using `call_tool(...)` over issuing many direct tool calls." },
49+
AIContextProviders = [codeAct],
50+
});
51+
52+
Console.WriteLine(await agent.RunAsync("Look up docs on 'retries' and query the 'orders' table, then summarize."));
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# AgentWithCodeAct_Step02_ToolEnabled
2+
3+
Demonstrates adding provider-owned tools to `HyperlightCodeActProvider`. Those
4+
tools are **only** available to code running inside the sandbox via
5+
`call_tool("<name>", ...)` — they are never exposed to the model as direct
6+
tools. This lets the model orchestrate multiple tool calls in a single Python
7+
block.
8+
9+
One tool (`send_email`) is wrapped in `ApprovalRequiredAIFunction`, which causes
10+
the entire `execute_code` invocation to require user approval when that tool
11+
is configured.
12+
13+
## Configuration
14+
15+
| Variable | Description |
16+
|--------------------------------|-------------------------------------------------------------------------------------------|
17+
| `AZURE_OPENAI_ENDPOINT` | Azure OpenAI endpoint. Required. |
18+
| `AZURE_OPENAI_DEPLOYMENT_NAME` | Azure OpenAI deployment. Defaults to `gpt-5.4-mini`. |
19+
| `HYPERLIGHT_PYTHON_GUEST_PATH` | Absolute path to the Hyperlight Python guest module (`.wasm` or `.aot` file). Required. |
20+
21+
## Run
22+
23+
```shell
24+
cd AgentWithCodeAct_Step02_ToolEnabled
25+
dotnet run
26+
```
27+
28+
## Planned follow-up
29+
30+
A more realistic "upload a file (e.g. an Excel workbook), have the agent
31+
analyze it with code" sample is planned as a separate step that will use
32+
`HostInputDirectory` together with a guest tool capable of reading the
33+
uploaded file. It will be added in a follow-up PR once the corresponding
34+
guest module support is in place.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFrameworks>net10.0</TargetFrameworks>
6+
7+
<Nullable>enable</Nullable>
8+
<ImplicitUsings>enable</ImplicitUsings>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<PackageReference Include="Azure.AI.OpenAI" />
13+
<PackageReference Include="Azure.Identity" />
14+
<PackageReference Include="Microsoft.Extensions.AI.OpenAI" />
15+
</ItemGroup>
16+
17+
<ItemGroup>
18+
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
19+
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Hyperlight\Microsoft.Agents.AI.Hyperlight.csproj" />
20+
</ItemGroup>
21+
22+
</Project>
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
3+
// This sample shows how to wire up CodeAct manually using
4+
// HyperlightExecuteCodeFunction rather than the AIContextProvider. Use this
5+
// when you want a fixed tool surface for the agent's lifetime and don't need
6+
// the per-run snapshot/registry semantics of HyperlightCodeActProvider.
7+
8+
using Azure.AI.OpenAI;
9+
using Azure.Identity;
10+
using Microsoft.Agents.AI;
11+
using Microsoft.Agents.AI.Hyperlight;
12+
using Microsoft.Extensions.AI;
13+
using OpenAI.Chat;
14+
15+
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
16+
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-5.4-mini";
17+
var guestPath = Environment.GetEnvironmentVariable("HYPERLIGHT_PYTHON_GUEST_PATH") ?? throw new InvalidOperationException("HYPERLIGHT_PYTHON_GUEST_PATH is not set.");
18+
19+
AIFunction calculate = AIFunctionFactory.Create(
20+
(double a, double b) => a * b,
21+
name: "multiply",
22+
description: "Multiply two numbers.");
23+
24+
var options = HyperlightCodeActProviderOptions.CreateForWasm(guestPath);
25+
options.Tools = [calculate];
26+
27+
using var executeCode = new HyperlightExecuteCodeFunction(options);
28+
29+
var instructions =
30+
"You are a helpful assistant. When math is involved, solve it by writing Python "
31+
+ "and calling `execute_code` instead of computing values yourself.\n\n"
32+
+ executeCode.BuildInstructions(toolsVisibleToModel: false);
33+
34+
AIAgent agent = new AzureOpenAIClient(
35+
new Uri(endpoint),
36+
new DefaultAzureCredential())
37+
.GetChatClient(deploymentName)
38+
.AsAIAgent(instructions: instructions, tools: [executeCode]);
39+
40+
Console.WriteLine(await agent.RunAsync("What is 12.3 * 4.5? Use the multiply tool from within `execute_code`."));

0 commit comments

Comments
 (0)