Microsoft Agent Framework is Microsoft's open-source SDK for building AI agents and multi-agent workflows in .NET and Python, and the direct successor to both Semantic Kernel and AutoGen. This guide is for C# developers who want to build agents that call tools, keep conversation state, collaborate in workflows and run safely in production. You will learn the core abstractions, sessions, tools and MCP integration, orchestration patterns, human-in-the-loop approvals, hosting, observability and how to migrate existing Semantic Kernel or AutoGen code.

What Is Microsoft Agent Framework?#

Semantic Kernel and AutoGen pioneered agents and multi-agent orchestration at Microsoft, but they overlapped and diverged. Agent Framework, built by the same teams, merges AutoGen's simple agent abstractions with Semantic Kernel's enterprise features, such as session-based state, type safety, middleware and telemetry, and adds graph-based workflows for explicit control over multi-agent execution. Microsoft now describes it as the next generation of both projects, and the Semantic Kernel repository itself points new users to it.

The .NET packages reached a release candidate in February 2026 and 1.0 in April 2026, with stable APIs and a long-term support commitment. Stable releases have continued at a fast cadence since; version 1.22.0 shipped in September 2026. Not every package is stable, so check before you depend on one:

PackagePurposeStatus (Sept 2026)
Microsoft.Agents.AI / .AbstractionsAIAgent, ChatClientAgent, sessions, middleware, context providersStable
Microsoft.Agents.AI.OpenAIAsAIAgent extensions for OpenAI chat and Responses clientsStable
Microsoft.Agents.AI.WorkflowsWorkflows and built-in orchestrationsStable
Microsoft.Agents.AI.HarnessBatteries-included agent for long, multi-step tasksStable
Microsoft.Agents.AI.FoundryMicrosoft Foundry project integrationPrerelease
Microsoft.Agents.AI.Hosting*, .A2A, .DevUIHosting helpers, Agent-to-Agent protocol, developer UIPrerelease

The framework is organized into four areas: agents that use a model, tools and memory to respond; the Harness Agent, an opinionated agent with planning, todo tracking, context compaction, file memory and approval policies built in; workflows that connect agents and functions through explicit execution paths; and integrations for model providers, agent services, context providers and UI protocols.

How Agent Framework Works#

Everything starts with the abstract AIAgent class. It exposes RunAsync for a complete AgentResponse and RunStreamingAsync for a stream of AgentResponseUpdate objects, plus CreateSessionAsync for conversation state. Messages and content use the Microsoft.Extensions.AI types, so a ChatMessage in an agent is the same type you already use with IChatClient.

The workhorse implementation is ChatClientAgent, which wraps any IChatClient. When you run it, a request flows through a predictable pipeline:

  1. Agent middleware can inspect or modify the input messages and the final response.
  2. Context providers (AIContextProvider) add instructions, messages or tools for this run, for example retrieved documents or long-term memories.
  3. Chat history is loaded from the session or a history provider.
  4. The IChatClient pipeline runs, including FunctionInvokingChatClient, which executes tool calls and loops until the model returns a final answer.
  5. New messages are stored back into the session, and context providers get a chance to persist what they learned.

Because the model layer is plain Microsoft.Extensions.AI, every provider that has an IChatClient, including OpenAI, Azure OpenAI in Microsoft Foundry, Anthropic, Ollama and ONNX models, works with Agent Framework.

A useful rule from the official guidance: use an agent when the task is open-ended or conversational and needs autonomous tool use; use a workflow when the process has well-defined steps or several agents and functions must coordinate. And if a plain function can do the job, write the function.

Getting Started: Your First Agent in C#

Add the core package and the OpenAI integration. The same code works against Azure OpenAI in Microsoft Foundry by pointing the OpenAI client at your resource's /openai/v1/ endpoint:

Bash
dotnet add package Microsoft.Agents.AI
dotnet add package Microsoft.Agents.AI.OpenAI
dotnet add package Azure.Identity

The AsAIAgent extension turns an OpenAI ChatClient into a ChatClientAgent. Tools are ordinary methods described with [Description] attributes:

C#
using System.ComponentModel;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using OpenAI.Chat;

var chatClient = new ChatClient("gpt-5-mini",
    Environment.GetEnvironmentVariable("OPENAI_API_KEY")!);

AIAgent agent = chatClient.AsAIAgent(
    name: "TravelAssistant",
    instructions: "You help employees plan business trips. Be brief and factual.",
    tools: [AIFunctionFactory.Create(GetTravelPolicy)]);

// Non-streaming
AgentResponse response = await agent.RunAsync("What is the hotel limit in Munich?");
Console.WriteLine(response.Text);

// Streaming
await foreach (AgentResponseUpdate update in agent.RunStreamingAsync(
    "Summarize the meal allowance rules in one sentence."))
{
    Console.Write(update.Text);
}

[Description("Returns the company travel policy for a city.")]
static string GetTravelPolicy([Description("City name.")] string city) =>
    city == "Munich" ? "Hotel limit: 180 EUR per night. Meals: 50 EUR per day." : "Standard policy.";

If you already have an IChatClient, for example one registered through dependency injection with caching and telemetry middleware, call chatClient.AsAIAgent(...) on it or construct new ChatClientAgent(chatClient, instructions, name) directly. For Microsoft Foundry projects, the prerelease Microsoft.Agents.AI.Foundry package adds AIProjectClient.AsAIAgent(model, instructions).

Sessions and Conversation State#

Agents are stateless by default: two RunAsync calls without a session are independent. An AgentSession holds the conversation so later turns can refer to earlier ones. Sessions can be serialized, which is how you survive process restarts or move a conversation between servers:

C#
AgentSession session = await agent.CreateSessionAsync();

await agent.RunAsync("I'm flying to Munich on October 12 for three nights.", session);
AgentResponse followUp = await agent.RunAsync("What will the hotel cost at most?", session);
Console.WriteLine(followUp.Text);

// Persist the session, for example in a database row keyed by user and conversation.
JsonElement state = await agent.SerializeSessionAsync(session);
await store.SaveAsync(userId, conversationId, state.GetRawText(), cancellationToken);

// Later, possibly on another server instance:
string json = await store.LoadAsync(userId, conversationId, cancellationToken);
AgentSession restored = await agent.DeserializeSessionAsync(
    JsonSerializer.Deserialize<JsonElement>(json));

Where the history lives depends on the provider. With chat completions, the session holds the messages locally. With service-managed conversations, such as the OpenAI Responses API or Foundry, the session may hold only a service-side conversation ID. The documentation stresses an important security point here: those IDs are scoped to the API key or project, not to your end users. In a multi-user application, store them server-side, map them to your own conversation identifiers and verify the authenticated user or tenant before resuming. Also note that sessions are specific to an agent configuration; do not reuse a session with a different agent or provider.

For long conversations, Agent Framework supports chat history providers for external storage and compaction strategies that keep the context window under control.

Tools and Human-in-the-Loop Approvals#

Function tools are AIFunction instances, usually created with AIFunctionFactory.Create, and the agent's underlying FunctionInvokingChatClient runs them automatically. For tools with side effects, such as refunds, deployments or emails, wrap the function in ApprovalRequiredAIFunction. The run then ends with a ToolApprovalRequestContent instead of executing the tool, and your application decides:

C#
AIFunction refund = AIFunctionFactory.Create(IssueRefundAsync);

AIAgent supportAgent = chatClient.AsAIAgent(
    instructions: "You resolve billing issues. Refunds need approval.",
    tools: [new ApprovalRequiredAIFunction(refund)]);

AgentSession session = await supportAgent.CreateSessionAsync();
AgentResponse response = await supportAgent.RunAsync(
    "I was charged twice for order 7781, please refund one charge.", session);

List<ToolApprovalRequestContent> approvals = response.Messages
    .SelectMany(m => m.Contents)
    .OfType<ToolApprovalRequestContent>()
    .ToList();

while (approvals.Count > 0)
{
    List<AIContent> decisions = [];
    foreach (ToolApprovalRequestContent request in approvals)
    {
        var call = (FunctionCallContent)request.ToolCall;
        bool approved = await approvalService.AskAsync(call.Name, call.Arguments);
        decisions.Add(request.CreateResponse(approved));
    }

    response = await supportAgent.RunAsync(new ChatMessage(ChatRole.User, decisions), session);
    approvals = [.. response.Messages.SelectMany(m => m.Contents)
        .OfType<ToolApprovalRequestContent>()];
}

Console.WriteLine(response.Text);

Keep approval decisions tied to the exact request that was surfaced; Agent Framework binds each response to the model-originated request by default so an approved call runs exactly as shown to the user. The Harness Agent adds standing approval rules and optional auto-approval heuristics on top of this mechanism.

Using MCP Tools with Agents#

Agent Framework uses the official MCP C# SDK to consume Model Context Protocol servers. Tools returned by an MCP client are AIFunction instances, so they drop into the agent's tool list next to your own functions:

C#
using ModelContextProtocol.Client;

await using McpClient mcp = await McpClient.CreateAsync(new HttpClientTransport(
    new HttpClientTransportOptions
    {
        Endpoint = new Uri("https://tools.contoso.internal/mcp"),
    }));

IList<McpClientTool> mcpTools = await mcp.ListToolsAsync();

AIAgent opsAgent = chatClient.AsAIAgent(
    instructions: "You answer questions about our deployments using the available tools.",
    tools: [.. mcpTools]); // McpClientTool derives from AIFunction

Console.WriteLine(await opsAgent.RunAsync("Which services deployed to production today?"));

For local servers, use StdioClientTransport with a command and arguments instead. Treat MCP servers like any third-party dependency: review what data you send, prefer servers operated by the service owner, pass credentials through headers deliberately, and limit the tool list to what the agent needs. Providers with hosted tool support, such as the OpenAI Responses API and Foundry, can also call remote MCP servers on the service side through HostedMcpServerTool.

Context Providers, Memory and RAG#

Context providers are the extension point for memory and retrieval. An AIContextProvider runs before each model invocation to contribute instructions, messages or tools, and after it to store anything worth remembering. Session-specific state belongs in the session, not in the provider instance, because one provider instance serves every session of an agent.

The built-in TextSearchProvider implements retrieval-augmented generation with a search delegate that you supply, so it works with Azure AI Search, a vector store or any search API:

C#
AIAgent kbAgent = chatClient.AsAIAgent(new ChatClientAgentOptions
{
    Name = "PolicyAgent",
    ChatOptions = new()
    {
        Instructions = "Answer from the provided policy excerpts and cite the source.",
    },
    AIContextProviders =
    [
        new TextSearchProvider(SearchPoliciesAsync, new TextSearchProviderOptions
        {
            SearchTime = TextSearchProviderOptions.TextSearchBehavior.BeforeAIInvoke,
            RecentMessageMemoryLimit = 6,
        }),
    ],
});

async Task<IEnumerable<TextSearchProvider.TextSearchResult>> SearchPoliciesAsync(
    string query, CancellationToken cancellationToken)
{
    var hits = policyCollection.SearchAsync(query, top: 4, cancellationToken: cancellationToken);
    List<TextSearchProvider.TextSearchResult> results = [];
    await foreach (var hit in hits)
    {
        results.Add(new() { Text = hit.Record.Text, SourceName = hit.Record.Title,
            SourceLink = hit.Record.Url });
    }
    return results;
}

BeforeAIInvoke searches on every run using recent messages; the alternative on-demand mode exposes search as a tool the model calls when it decides it needs information. The end-to-end retrieval pipeline behind policyCollection, including chunking, hybrid search and evaluation, is covered in the RAG in .NET guide.

Agent Middleware#

Agent middleware wraps runs the way DelegatingChatClient wraps model calls. There are three layers: agent run middleware, function-calling middleware and IChatClient middleware. Use them for guardrails, auditing, redaction and metrics:

C#
AIAgent guarded = agent
    .AsBuilder()
    .Use(runFunc: AuditRunAsync, runStreamingFunc: null)
    .Use(BlockDangerousToolsAsync)
    .Build();

async Task<AgentResponse> AuditRunAsync(IEnumerable<ChatMessage> messages,
    AgentSession? session, AgentRunOptions? options, AIAgent inner,
    CancellationToken cancellationToken)
{
    var started = Stopwatch.GetTimestamp();
    AgentResponse result = await inner.RunAsync(messages, session, options, cancellationToken);
    logger.LogInformation("Agent {Agent} answered in {Elapsed} ms with {Count} messages",
        inner.Name, Stopwatch.GetElapsedTime(started).TotalMilliseconds, result.Messages.Count);
    return result;
}

async ValueTask<object?> BlockDangerousToolsAsync(AIAgent owner,
    FunctionInvocationContext context,
    Func<FunctionInvocationContext, CancellationToken, ValueTask<object?>> next,
    CancellationToken cancellationToken)
{
    if (context.Function.Name.StartsWith("delete_", StringComparison.Ordinal))
    {
        return "This operation is not allowed from chat.";
    }
    return await next(context, cancellationToken);
}

When you pass only non-streaming run middleware, streaming calls still work but run in non-streaming mode behind the scenes, so provide both delegates for chat UIs. Function middleware applies to agents built on FunctionInvokingChatClient, which includes every ChatClientAgent.

Workflows: Sequential, Concurrent, Handoff and Group Chat#

Workflows give you explicit, testable control flow. A workflow is a graph of executors, which can be agents or plain functions, connected by edges and run in supersteps. For common multi-agent shapes, AgentWorkflowBuilder provides ready-made orchestrations:

OrchestrationBuilderUse it for
SequentialBuildSequential(agents)Pipelines where each agent refines the previous output
ConcurrentBuildConcurrent(agents)Independent perspectives run in parallel, results aggregated
HandoffCreateHandoffBuilderWith(triage)Routing a conversation to the right specialist
Group chatCreateGroupChatBuilderWith(manager)Agents iterating together, such as writer and reviewer
MagenticMagentic builderA manager agent that plans and delegates dynamically

A triage agent that hands customer questions to specialists looks like this:

C#
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Workflows;
using Microsoft.Extensions.AI;

IChatClient model = chatClient.AsIChatClient(); // any IChatClient works here

ChatClientAgent Specialist(string id, string description, string instructions) =>
    new(model, new ChatClientAgentOptions
    {
        Id = id,        // stable IDs keep checkpoints compatible across restarts
        Name = id,
        Description = description,
        ChatOptions = new() { Instructions = instructions },
    });

var triage = Specialist("triage", "Routes requests",
    "Decide who should answer. Always hand off to a specialist.");
var billing = Specialist("billing", "Invoices, refunds and payments",
    "Answer billing questions only.");
var technical = Specialist("technical", "Errors, outages and configuration",
    "Answer technical questions only.");

Workflow workflow = AgentWorkflowBuilder.CreateHandoffBuilderWith(triage)
    .WithHandoffs(triage, [billing, technical])
    .WithHandoffs([billing, technical], triage)
    .Build();

List<ChatMessage> conversation = [new(ChatRole.User, "Why did my invoice double this month?")];

await using StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow, conversation);
await run.TrySendMessageAsync(new TurnToken(emitEvents: true));

await foreach (WorkflowEvent evt in run.WatchStreamAsync())
{
    if (evt is AgentResponseUpdateEvent update)
    {
        Console.Write(update.Update.Text); // update.ExecutorId tells you who is speaking
    }
    else if (evt is WorkflowOutputEvent output)
    {
        conversation = output.As<List<ChatMessage>>()!; // full history for the next turn
        break;
    }
}

The TurnToken starts agent processing, and AgentResponseUpdateEvent lets you stream tokens with the ExecutorId of whichever agent is speaking. Handoff is interactive by default: when a specialist answers without handing off, control returns to you for the next user message. A group chat uses a manager such as RoundRobinGroupChatManager with a MaximumIterationCount to bound the conversation. Beyond the built-in orchestrations, WorkflowBuilder lets you connect custom executors with conditional edges, fan-out and fan-in, and sub-workflows, and any workflow can itself be exposed as an agent.

Human-in-the-Loop and Checkpoints in Workflows#

Workflows pause for people in two ways. Agents that call ApprovalRequiredAIFunction tools emit a RequestInfoEvent carrying a ToolApprovalRequestContent; custom workflows can use a typed RequestPort to ask for any input. Checkpoints capture the complete workflow state at the end of each superstep, so a paused workflow can wait hours for a human and resume in another process:

C#
CheckpointManager checkpoints = CheckpointManager.CreateInMemory(); // use durable storage in production

await using StreamingRun run = await InProcessExecution.RunStreamingAsync(
    workflow, conversation, checkpoints);
await run.TrySendMessageAsync(new TurnToken(emitEvents: true));

await foreach (WorkflowEvent evt in run.WatchStreamAsync())
{
    if (evt is RequestInfoEvent request &&
        request.Request.TryGetDataAs(out ToolApprovalRequestContent? approval))
    {
        var call = (FunctionCallContent)approval.ToolCall;
        bool approved = await approvalService.AskAsync(call.Name, call.Arguments);
        await run.SendResponseAsync(
            request.Request.CreateResponse(approval.CreateResponse(approved)));
    }
    else if (evt is SuperStepCompletedEvent step &&
             step.CompletionInfo?.Checkpoint is CheckpointInfo checkpoint)
    {
        await checkpointIndex.RecordAsync(run.SessionId, checkpoint);
    }
}

To continue later, call InProcessExecution.ResumeStreamingAsync with the same workflow shape, the saved CheckpointInfo and the checkpoint manager. The workflow must have the same structure and executor identities as the one that created the checkpoint, which is why the specialists above use stable Id values.

Hosting and Observability#

For self-hosting in ASP.NET Core, the prerelease Microsoft.Agents.AI.Hosting packages register named agents with dependency injection and map protocol endpoints. The OpenAI hosting package exposes an agent through an OpenAI Responses-compatible endpoint, and other packages add the Agent-to-Agent (A2A) protocol and AG-UI for web front ends:

C#
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Hosting;
using Microsoft.Extensions.AI;
using OpenAI.Chat;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddChatClient(
    new ChatClient("gpt-5-mini", builder.Configuration["OpenAI:ApiKey"]!).AsIChatClient());

var travel = builder.AddAIAgent("travel", (sp, name) =>
    sp.GetRequiredService<IChatClient>()
      .AsAIAgent(name: name, instructions: "You help employees plan business trips.")
      .AsBuilder()
      .UseOpenTelemetry(sourceName: "Contoso.Agents")
      .Build());

builder.Services.AddOpenTelemetry().WithTracing(t => t
    .AddSource("Contoso.Agents")
    .AddOtlpExporter());

var app = builder.Build();
app.MapOpenAIResponses(travel);   // OpenAI Responses-compatible endpoint for the agent
app.Run();

Hosted endpoints can persist sessions through an AgentSessionStore you implement over durable storage; the framework does not ship a production store, and it scopes stored sessions by an isolation key, such as the authenticated user's claims, so one user cannot resume another's conversation. If you prefer not to operate the infrastructure, Microsoft Foundry Hosted Agents run your Agent Framework code as a managed container with scaling, identity and observability, and that service is generally available.

Agent Framework emits traces, metrics and logs that follow the OpenTelemetry semantic conventions for generative AI. You can instrument the chat client, the agent or both; instrumenting both duplicates prompt content when sensitive data capture is on, so pick one layer in production. If you do not pass a source name, spans use Experimental.Microsoft.Agents.AI, which your tracer provider must subscribe to. The Aspire dashboard is a convenient local viewer.

Migrating from Semantic Kernel and AutoGen#

Official migration guides exist for both predecessors. For Semantic Kernel, the changes are mostly mechanical:

Semantic KernelAgent Framework
Kernel required by every agentNo kernel; agents wrap an IChatClient
ChatCompletionAgent, OpenAIAssistantAgent, AzureAIAgentOne ChatClientAgent, or provider AsAIAgent extensions
AgentThread subclasses created by the callerAgentSession created by agent.CreateSessionAsync()
InvokeAsync / InvokeStreamingAsyncRunAsync / RunStreamingAsync
[KernelFunction] plugins added to the kernelPlain methods with [Description], passed as tools
PromptExecutionSettings in KernelArgumentsChatClientAgentRunOptions wrapping ChatOptions
Filters (IFunctionInvocationFilter and others)Agent, function and chat client middleware
Agent orchestration (sequential, concurrent, handoff, group chat)Workflows via AgentWorkflowBuilder

AutoGen users map AssistantAgent to ChatClientAgent, team patterns such as round-robin and Magentic-One group chats to the corresponding workflow orchestrations, and graph flows to WorkflowBuilder. One behavioral difference matters: Agent Framework agents keep invoking tools until they have a final answer, whereas AutoGen's assistant is single-turn unless configured otherwise. For a feature-by-feature view of Semantic Kernel's position today, see the Semantic Kernel guide.

Best Practices#

  • Start with one agent and few tools. Add orchestration only when a single agent with good instructions demonstrably fails.
  • Make tools narrow and safe. Validate arguments, enforce authorization inside each tool and require approval for anything irreversible.
  • Give agents stable identities. Set Id and Name explicitly so checkpoints and handoff routing survive restarts.
  • Own your session storage. Persist serialized sessions or implement AgentSessionStore, and scope every lookup by the authenticated user.
  • Bound every loop. Cap tool iterations, group chat turns and autonomous handoff turns to control cost and runaway behavior.
  • Instrument one layer consistently. Trace the agent or the chat client, keep sensitive data capture off in production, and watch token usage per agent.
  • Test deterministically, evaluate statistically. Unit test tools and workflow wiring with fake chat clients, and use evaluation datasets for answer quality.

Common Pitfalls#

  • Reusing preview-era samples. Several names changed before 1.0. In 1.x, conversation state is an AgentSession from CreateSessionAsync, results are AgentResponse objects, and MCP clients come from McpClient.CreateAsync.
  • Storing session state in a context provider. Provider instances are shared across sessions; keep per-conversation data in the session.
  • Treating service conversation IDs as authorization. Anyone holding a response or conversation ID can resume it under your API key unless your application checks ownership.
  • Forgetting the turn token. Workflows that contain agents need a TurnToken to start processing, or the run appears to hang.
  • Changing agent IDs between deployments. Rebuilt workflows with different executor identities cannot resume old checkpoints.
  • Depending on prerelease packages unknowingly. Hosting, A2A, DevUI and Foundry integration packages are still prerelease; pin versions and read release notes.

When to Use Microsoft Agent Framework#

ScenarioBest choiceWhy
Single model call, summarization, extractionMicrosoft.Extensions.AINo orchestration needed
Conversational assistant with tools and memoryAgent Framework ChatClientAgentSessions, tools, middleware and context providers
Long-running research or coding tasksAgent Framework Harness AgentPlanning, compaction, file memory and approvals built in
Multi-agent routing, review loops, fan-outAgent Framework workflowsExplicit, checkpointable control flow
No-code agent managed by the platformFoundry Agent Service prompt agentConfiguration only, Foundry runs it
Existing Semantic Kernel production appKeep SK, plan migrationMaintained, but new features land in Agent Framework

Frequently Asked Questions#

Is Microsoft Agent Framework production-ready?#

Yes. The core .NET packages have been stable since the 1.0 release in April 2026 and ship frequent updates with stable APIs. Some integration packages, including hosting, A2A, DevUI and the Foundry integration, are still prerelease, so check each package's status before relying on it.

What is the difference between an agent and a workflow?#

An agent lets the model decide which tools to call and when it is done, which suits open-ended tasks. A workflow defines the execution path explicitly as a graph of agents and functions, which suits processes with known steps, multiple participants, approvals and checkpoints.

Can I use Agent Framework with models other than OpenAI?#

Yes. ChatClientAgent works with any IChatClient, so Azure OpenAI in Microsoft Foundry, Anthropic, Amazon Bedrock, Google Gemini, Ollama and ONNX models are all options through their Microsoft.Extensions.AI implementations. Hosted tools, such as code interpreter or web search, depend on provider support.

Should I migrate from Semantic Kernel now?#

For new projects, start with Agent Framework. For stable Semantic Kernel applications, plan a migration rather than rushing one: the official guide shows that most changes are mechanical, and Semantic Kernel continues to receive releases while new capabilities arrive only in Agent Framework.

How do I keep agents from taking dangerous actions?#

Combine several controls: narrow tools with their own authorization checks, ApprovalRequiredAIFunction for irreversible operations, function middleware that blocks disallowed calls, bounded iteration counts and platform guardrails in Microsoft Foundry. Never rely on instructions alone to prevent misuse.

Summary#

  • Microsoft Agent Framework 1.x is the successor to Semantic Kernel and AutoGen, built on Microsoft.Extensions.AI types.
  • ChatClientAgent turns any IChatClient into an agent with tools, sessions, middleware and context providers.
  • AgentSession holds conversation state and serializes for persistence; scope service-side conversation IDs to your users.
  • ApprovalRequiredAIFunction and workflow RequestInfoEvent handling implement human-in-the-loop control.
  • AgentWorkflowBuilder provides sequential, concurrent, handoff, group chat and Magentic orchestrations, with checkpointing for long-running processes.
  • Host agents yourself with the prerelease hosting packages or use Foundry Hosted Agents, and instrument them with OpenTelemetry.

Further Reading#