mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
96d242fa7f
* Move token params from HarnessAgent constructor to options Remove the required maxContextWindowTokens and maxOutputTokens constructor parameters from HarnessAgent and AsHarnessAgent, replacing them with optional MaxContextWindowTokens and MaxOutputTokens properties on HarnessAgentOptions. When both values are provided, compaction is enabled as before (in-loop CompactionProvider and chat reducer on the default InMemoryChatHistory Provider). When either is null, compaction is disabled entirely, making it opt-in. New constructor: HarnessAgent(IChatClient, HarnessAgentOptions?, ILoggerFactory?, IServiceProvider?) Closes #6333 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Improving comments. * feat: Add custom CompactionStrategy and DisableCompaction to HarnessAgentOptions Allow users to provide their own CompactionStrategy via options, with a clear priority system: 1. DisableCompaction=true: no compaction regardless of other settings 2. Custom CompactionStrategy provided: use it (token params ignored) 3. Both MaxContextWindowTokens and MaxOutputTokens set: default strategy 4. Otherwise: no compaction Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: Address PR review comments on compaction opt-in - Update chatClient param XML doc to reflect compaction is opt-in - Strengthen compaction tests to assert ChatReducer is null/not-null rather than just asserting construction succeeds Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
125 lines
5.5 KiB
C#
125 lines
5.5 KiB
C#
// Copyright (c) Microsoft. All rights reserved.
|
|
|
|
// This sample demonstrates a HarnessAgent with ALL features enabled, plus:
|
|
// - Hyperlight CodeAct (HyperlightCodeActProvider) for sandboxed Python code execution
|
|
// - Skills (AgentSkillsProvider) discovering a local "regex-tester" skill
|
|
//
|
|
// The agent can plan tasks with todos, manage modes, store memories, read/write files,
|
|
// search the web, approve sensitive tools, discover and use skills, and execute arbitrary
|
|
// Python code in a Hyperlight sandbox — all pre-configured by the HarnessAgent.
|
|
//
|
|
// Try asking: "Help me write a regex that matches valid email addresses, then test it."
|
|
//
|
|
// Special commands:
|
|
// /todos — Display the current todo list without invoking the agent.
|
|
// /mode — Get or set the current agent mode.
|
|
// /exit — End the session.
|
|
|
|
#pragma warning disable OPENAI001 // Suppress experimental API warnings for Responses API usage.
|
|
#pragma warning disable MAAI001 // Suppress experimental API warnings for Agents AI experiments.
|
|
|
|
using System.ClientModel.Primitives;
|
|
using Azure.AI.Projects;
|
|
using Azure.Identity;
|
|
using Harness.Shared.Console;
|
|
using HyperlightSandbox.Guest.Python;
|
|
using Microsoft.Agents.AI;
|
|
using Microsoft.Agents.AI.Hyperlight;
|
|
using Microsoft.Extensions.AI;
|
|
|
|
var endpoint = Environment.GetEnvironmentVariable("AZURE_AI_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_AI_PROJECT_ENDPOINT is not set.");
|
|
var deploymentName = Environment.GetEnvironmentVariable("AZURE_AI_MODEL_DEPLOYMENT_NAME") ?? "gpt-5.4";
|
|
|
|
const int MaxContextWindowTokens = 1_050_000;
|
|
const int MaxOutputTokens = 128_000;
|
|
const string TracingSourceName = "Harness.CodeExecution";
|
|
|
|
// Set up OpenTelemetry tracing that writes spans to a text file.
|
|
using var tracerProvider = HarnessTracing.CreateFileTracerProvider(TracingSourceName);
|
|
|
|
// Create the HyperlightCodeActProvider with the Python/Wasm backend.
|
|
// The guest module path is resolved automatically from the Hyperlight.HyperlightSandbox.Guest.Python NuGet package.
|
|
using var codeAct = new HyperlightCodeActProvider(
|
|
HyperlightCodeActProviderOptions.CreateForWasm(PythonGuestModule.GetModulePath()));
|
|
|
|
var instructions =
|
|
"""
|
|
## Technical Assistant Instructions
|
|
|
|
You are a code-powered technical assistant. You can execute Python code in a sandboxed environment
|
|
to solve problems precisely rather than guessing. You also have access to skills that provide
|
|
structured workflows for specific technical tasks.
|
|
|
|
### Code Execution
|
|
|
|
When a problem requires computation, validation, or testing:
|
|
- Write Python code and use `execute_code` to run it in the sandbox.
|
|
- Always verify results by running the code rather than reasoning about what would happen.
|
|
- If code fails, read the error message carefully, fix the issue, and retry.
|
|
|
|
### Skills
|
|
|
|
You have access to discoverable skills. When a task matches a skill's description:
|
|
- Follow the skill's instructions carefully.
|
|
- Use the skill's reference materials for context.
|
|
- Combine the skill's workflow with code execution when appropriate.
|
|
|
|
### Planning and Research
|
|
|
|
For complex tasks:
|
|
- Break the problem into steps using your todo list.
|
|
- Research background information using web search when needed.
|
|
- Save important findings to file memory for later reference.
|
|
|
|
### Presenting Results
|
|
|
|
- Show your work: include the code you ran and its output.
|
|
- Explain what each part of your solution does.
|
|
- If applicable, save final results to file memory.
|
|
""";
|
|
|
|
// Create the agent with ALL HarnessAgent features enabled plus Hyperlight CodeAct.
|
|
// No Disable* flags are set — TodoProvider, AgentModeProvider, FileMemory, FileAccess,
|
|
// ToolApproval, WebSearch, and AgentSkillsProvider are all active.
|
|
AIAgent agent =
|
|
new AIProjectClient(
|
|
new Uri(endpoint),
|
|
new DefaultAzureCredential(),
|
|
new AIProjectClientOptions { RetryPolicy = new ClientRetryPolicy(3) })
|
|
.GetProjectOpenAIClient()
|
|
.GetResponsesClient()
|
|
.AsIChatClient(deploymentName)
|
|
.AsHarnessAgent(new HarnessAgentOptions
|
|
{
|
|
MaxContextWindowTokens = MaxContextWindowTokens,
|
|
MaxOutputTokens = MaxOutputTokens,
|
|
Name = "CodeExecutionAgent",
|
|
Description = "A technical assistant with sandboxed code execution and skill-based workflows.",
|
|
OpenTelemetrySourceName = TracingSourceName,
|
|
// Point the file memory at a local folder for persistent memory across sessions.
|
|
FileMemoryStore = new FileSystemAgentFileStore(Path.Combine(AppContext.BaseDirectory, "agent-files")),
|
|
// Add the HyperlightCodeActProvider so the agent can execute Python code in a sandbox.
|
|
AIContextProviders = [codeAct],
|
|
ChatOptions = new ChatOptions
|
|
{
|
|
Instructions = instructions,
|
|
MaxOutputTokens = MaxOutputTokens,
|
|
Reasoning = new() { Effort = ReasoningEffort.Medium },
|
|
},
|
|
});
|
|
|
|
// Run the interactive console session using the shared HarnessConsole helper.
|
|
await HarnessConsole.RunAgentAsync(
|
|
agent,
|
|
userPrompt: "Ask me a technical question, or try: \"Help me write a regex that matches valid email addresses.\"",
|
|
new HarnessConsoleOptions
|
|
{
|
|
Observers = HarnessConsoleOptions.BuildObserversWithPlanning(
|
|
agent,
|
|
planModeName: "plan",
|
|
executionModeName: "execute",
|
|
maxContextWindowTokens: MaxContextWindowTokens,
|
|
maxOutputTokens: MaxOutputTokens),
|
|
CommandHandlers = HarnessConsoleOptions.BuildDefaultCommandHandlers(agent),
|
|
});
|