<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Agents | The .NET Blog</title><link>https://thedotnetblog.com/tags/agents/</link><description>Articles, tutorials and insights from the .NET community.</description><generator>Hugo</generator><language>en</language><managingEditor>@thedotnetblog (The .NET Blog)</managingEditor><webMaster>@thedotnetblog</webMaster><lastBuildDate>Wed, 03 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://thedotnetblog.com/tags/agents/index.xml" rel="self" type="application/rss+xml"/><item><title>NL2SQL Is the SQL Injection of the Agentic Age</title><link>https://thedotnetblog.com/news/emiliano-montesdeoca/nl2sql-agentic-sql-injection-mcp-server/</link><pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/news/emiliano-montesdeoca/nl2sql-agentic-sql-injection-mcp-server/</guid><description>Before you let an agent query your database with natural language, read this. NL2SQL looks simple until you think through schema completeness, indeterminism, and what SQL MCP Server actually solves.</description><content:encoded>&lt;p&gt;There&amp;rsquo;s a version of the NL2SQL pitch that sounds perfect: users ask questions in natural language, agents generate SQL, data comes back. Fewer screens, fewer queries, less code. Simple.&lt;/p&gt;
&lt;p&gt;Then you think about it for five more minutes.&lt;/p&gt;
&lt;h2 id="the-problems-nobody-talks-about-in-the-demo"&gt;The Problems Nobody Talks About in the Demo&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Schemas weren&amp;rsquo;t designed to explain things.&lt;/strong&gt; Cryptic table names, inconsistent column names, technically valid relationships that are semantically invalid without additional predicates — these are normal for enterprise databases. They&amp;rsquo;re not bugs, they&amp;rsquo;re just the accumulated history of business changes. But when you ask a model to infer intent from a schema that wasn&amp;rsquo;t designed to communicate intent, the model will try anyway. It won&amp;rsquo;t give up. It&amp;rsquo;ll generate its best-effort query and return results with confidence.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Models are not deterministic.&lt;/strong&gt; Ask the same question about the same database twice and you might get different SQL. The model is calculating probabilities, and slight variations in context drive different outputs. You cannot test your way to a guarantee that the agent always generates the right query.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;User review doesn&amp;rsquo;t scale.&lt;/strong&gt; &amp;ldquo;Just review every query before execution&amp;rdquo; sounds safe. But it assumes users are experts in both the data model and SQL — exactly the people who didn&amp;rsquo;t need the natural language interface. It also introduces cognitive overload and a new class of confirmation bias, where users overwhelmed by query complexity approve invalid queries rather than investigate them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;And then there&amp;rsquo;s injection.&lt;/strong&gt; In traditional SQL development, parameterization solved injection because user input filled parameters, not SQL structure. With NL2SQL, the model is generating the SQL itself. The prompt, schema context, conversation history, and retrieved data all influence what gets executed. If someone crafts a prompt that changes what the model generates, that&amp;rsquo;s injection — not at the parameter level, but at the query generation level. And unlike dropping a table (obvious, recoverable), NL2SQL injection produces queries that return incorrect results with no visible error. Business decisions get made on wrong data.&lt;/p&gt;
&lt;h2 id="what-sql-mcp-server-actually-solves"&gt;What SQL MCP Server Actually Solves&lt;/h2&gt;
&lt;p&gt;This is where the article makes its most useful practical point. Instead of giving an agent arbitrary schema access and hoping for the best, SQL MCP Server exposes a &lt;strong&gt;curated API surface&lt;/strong&gt; built on top of &lt;a href="https://learn.microsoft.com/en-us/azure/data-api-builder/overview"&gt;Data API builder&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The difference matters: the agent doesn&amp;rsquo;t generate SQL. It calls named endpoints that return predefined result shapes. The SQL is written once, by a developer, and is deterministic. The agent&amp;rsquo;s nondeterminism is limited to choosing &lt;em&gt;which&lt;/em&gt; endpoint to call, not constructing arbitrary queries.&lt;/p&gt;
&lt;p&gt;This is analogous to what parameterization did for SQL injection in the traditional app model — you remove the ability to construct arbitrary queries from untrusted input.&lt;/p&gt;
&lt;h2 id="the-right-question"&gt;The Right Question&lt;/h2&gt;
&lt;p&gt;The article doesn&amp;rsquo;t say &amp;ldquo;never use NL2SQL.&amp;rdquo; It says: be deliberate about &lt;em&gt;where&lt;/em&gt; you apply it and &lt;em&gt;what&lt;/em&gt; you expose. For exploratory analysis in a controlled environment, with a scoped schema and read-only access, NL2SQL might be fine. For production systems where business decisions depend on the results, a curated API layer is significantly safer.&lt;/p&gt;
&lt;p&gt;Honesty: some problems are genuinely better solved with structured queries behind named endpoints than with natural language to SQL. SQL MCP Server gives you that option without abandoning the agentic interface entirely.&lt;/p&gt;
&lt;p&gt;Original post: &lt;a href="https://devblogs.microsoft.com/azure-sql/sql-mcp-server-nl2sql/"&gt;Considering NL2SQL? Should your database really be the prompt? How can SQL MCP Server help?&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>Your AI Agent Has an Identity Problem (And Here's the Template That Solves It)</title><link>https://thedotnetblog.com/news/emiliano-montesdeoca/azd-least-privilege-ai-agents-oauth-token-pattern/</link><pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/news/emiliano-montesdeoca/azd-least-privilege-ai-agents-oauth-token-pattern/</guid><description>A new azd template from Curity and Microsoft shows how to build AI agents that use short-lived OAuth tokens with fine-grained scopes — so agents can never see data they shouldn't.</description><content:encoded>&lt;p&gt;There&amp;rsquo;s a moment in every AI agent project that goes something like this: the demo works perfectly, the agent interprets natural language, calls the right APIs, returns the right data. Then you start thinking about real users.&lt;/p&gt;
&lt;p&gt;What stops one user&amp;rsquo;s agent session from seeing another user&amp;rsquo;s data? What if the agent is tricked through prompt injection? What if it calls a tool in an unexpected way?&lt;/p&gt;
&lt;p&gt;These aren&amp;rsquo;t edge cases. They&amp;rsquo;re design decisions you need to make before shipping.&lt;/p&gt;
&lt;p&gt;A new &lt;code&gt;azd&lt;/code&gt; template from Curity and Microsoft gives you a working reference for exactly this problem.&lt;/p&gt;
&lt;h2 id="the-core-problem-authentication--authorization"&gt;The Core Problem: Authentication ≠ Authorization&lt;/h2&gt;
&lt;p&gt;Most agent samples handle user authentication well. They handle authorization poorly. Knowing &lt;em&gt;who&lt;/em&gt; the user is doesn&amp;rsquo;t tell you &lt;em&gt;what data&lt;/em&gt; they should see.&lt;/p&gt;
&lt;p&gt;A traditional client app makes predictable API calls. An AI agent is nondeterministic — it interprets natural language and decides what to call. It can be creative. It can also be wrong. And if it&amp;rsquo;s manipulated through prompt injection, you need rules that don&amp;rsquo;t depend on the AI being well-behaved.&lt;/p&gt;
&lt;p&gt;The solution this template demonstrates: &lt;strong&gt;short-lived tokens that carry exactly the right information for each hop&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id="how-the-token-chain-works"&gt;How the Token Chain Works&lt;/h2&gt;
&lt;p&gt;The template uses OAuth 2.0 access tokens with token exchange to narrow permissions at each step. A user token gets exchanged twice before it reaches the MCP server:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;First exchange&lt;/strong&gt; — narrows the scope and converts the opaque token to a JWT&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Second exchange&lt;/strong&gt; — adds the agent identity and a new audience for the MCP server hop&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;What the MCP server token looks like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;scope&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;stocks/read&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;sub&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;62c839b8...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;aud&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://mcp.demo.example&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;customer_id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;178&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;region&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;USA&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;customer_id&lt;/code&gt; is baked into the token by the authorization server, not passed as a parameter the agent controls. The API checks the token, not the agent&amp;rsquo;s instructions.&lt;/p&gt;
&lt;p&gt;This means: even if someone tricks the agent into trying to fetch another customer&amp;rsquo;s data, the token won&amp;rsquo;t authorize it.&lt;/p&gt;
&lt;h2 id="what-the-template-deploys"&gt;What the Template Deploys&lt;/h2&gt;
&lt;p&gt;With a few &lt;code&gt;azd&lt;/code&gt; commands you get:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A backend agent on Microsoft Foundry (C#, Microsoft A2A and MCP SDKs)&lt;/li&gt;
&lt;li&gt;An MCP server exposing a sample portfolio API&lt;/li&gt;
&lt;li&gt;Curity Identity Server as the authorization server, alongside Entra ID for authentication&lt;/li&gt;
&lt;li&gt;External and internal API gateways handling token exchange and audit logging&lt;/li&gt;
&lt;li&gt;Bicep for all the Azure infrastructure: Container Apps, VNet, ACR, Azure AI Foundry, Key Vault, Azure SQL Database, storage&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The whole pattern is inspectable and customizable.&lt;/p&gt;
&lt;h2 id="the-design-principle-worth-borrowing"&gt;The Design Principle Worth Borrowing&lt;/h2&gt;
&lt;p&gt;Even if you don&amp;rsquo;t use Curity, the pattern is transferable: &lt;strong&gt;agents should never hold permanent API access&lt;/strong&gt;. Every action should use a short-lived token with the minimum scope needed for that specific call, issued to the specific agent identity, carrying the claims the API needs to make authorization decisions.&lt;/p&gt;
&lt;p&gt;This holds up against creative agents, mistakes, and prompt injection in ways that &amp;ldquo;just make sure the agent doesn&amp;rsquo;t do bad things&amp;rdquo; never will.&lt;/p&gt;
&lt;h2 id="wrapping-up"&gt;Wrapping Up&lt;/h2&gt;
&lt;p&gt;Security patterns for AI agents are still being worked out across the industry. This template is one of the more complete reference implementations I&amp;rsquo;ve seen — it covers the actual authorization flow, not just authentication.&lt;/p&gt;
&lt;p&gt;Original post: &lt;a href="https://devblogs.microsoft.com/azure-sdk/azd-curity-least-privilege-ai-agents/"&gt;Least privilege AI agents: A new azd template from Curity and Microsoft&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>CodeAct in Agent Framework: How to Cut Your Agent's Latency in Half</title><link>https://thedotnetblog.com/news/emiliano-montesdeoca/codeact-agent-framework-hyperlight-50-percent-faster/</link><pubDate>Sat, 25 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/news/emiliano-montesdeoca/codeact-agent-framework-hyperlight-50-percent-faster/</guid><description>CodeAct collapses multi-step tool chains into a single sandboxed code block — cutting latency by 52% and token usage by 64%. Here's what it means for your agents and when to reach for it.</description><content:encoded>&lt;p&gt;There&amp;rsquo;s a moment in every agent project where you look at the trace and think: &amp;ldquo;why is this taking so long?&amp;rdquo; The model is fine. The tools work. But there are seven round trips to get a result you could compute in one shot.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s exactly the problem CodeAct solves — and the &lt;a href="https://devblogs.microsoft.com/agent-framework/codeact-with-hyperlight/"&gt;Agent Framework team just shipped alpha support for it&lt;/a&gt; via a new &lt;code&gt;agent-framework-hyperlight&lt;/code&gt; package.&lt;/p&gt;
&lt;h2 id="what-is-codeact"&gt;What is CodeAct?&lt;/h2&gt;
&lt;p&gt;The &lt;a href="https://arxiv.org/abs/2402.01030"&gt;CodeAct pattern&lt;/a&gt; is elegantly simple: instead of giving the model a list of tools and letting it call them one by one, you give it a single &lt;code&gt;execute_code&lt;/code&gt; tool and let it express the &lt;em&gt;entire plan&lt;/em&gt; as a short Python program. The agent writes the code once, the sandbox runs it, and you get back a single consolidated result.&lt;/p&gt;
&lt;p&gt;A five-step plan that used to be five model turns becomes one &lt;code&gt;execute_code&lt;/code&gt; turn containing a Python script that calls your tools via &lt;code&gt;call_tool(...)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The benchmark in the repo makes this concrete. Eight users, dozens of orders, five tools (list users, get orders, discount rate, tax rate, compute line total). Same model, same tools, same prompt — just different wiring:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Wiring&lt;/th&gt;
&lt;th&gt;Time&lt;/th&gt;
&lt;th&gt;Tokens&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Traditional&lt;/td&gt;
&lt;td&gt;27.81s&lt;/td&gt;
&lt;td&gt;6,890&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodeAct&lt;/td&gt;
&lt;td&gt;13.23s&lt;/td&gt;
&lt;td&gt;2,489&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Improvement&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;52.4%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;63.9%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;That&amp;rsquo;s not a micro-benchmark. That&amp;rsquo;s a realistic workload with real orchestration overhead.&lt;/p&gt;
&lt;h2 id="the-safety-piece-hyperlight-micro-vms"&gt;The safety piece: Hyperlight micro-VMs&lt;/h2&gt;
&lt;p&gt;Here&amp;rsquo;s the thing that made me actually excited about this: safety has historically been CodeAct&amp;rsquo;s Achilles heel. If you&amp;rsquo;re running model-generated code, where exactly is it running? Against your process? In a shared container?&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;agent-framework-hyperlight&lt;/code&gt; package solves this with &lt;a href="https://github.com/hyperlight-dev/hyperlight"&gt;Hyperlight&lt;/a&gt; micro-VMs. Every single &lt;code&gt;execute_code&lt;/code&gt; call gets its own freshly created micro-VM — with its own memory, no host filesystem access beyond what you explicitly mount, and no network access beyond the domains you allow. Startup is measured in milliseconds. The isolation is basically free.&lt;/p&gt;
&lt;p&gt;Your tools still run on the host (they&amp;rsquo;re your code, with your access). The model-generated &lt;em&gt;glue&lt;/em&gt; — the Python that decides which tools to call and in what order — runs sandboxed. That&amp;rsquo;s the right split.&lt;/p&gt;
&lt;h2 id="wiring-it-up"&gt;Wiring it up&lt;/h2&gt;
&lt;p&gt;The minimal setup is straightforward:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;agent_framework&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;agent_framework_hyperlight&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HyperlightCodeActProvider&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;Return the current weather for a city.&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;city&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;temperature_c&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;21.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;conditions&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;partly cloudy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;codeact&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HyperlightCodeActProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;approval_mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;never_require&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;CodeActAgent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;instructions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;You are a helpful assistant.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;context_providers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;codeact&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Get the weather for Seattle and Amsterdam and compare them.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The provider registers &lt;code&gt;execute_code&lt;/code&gt; on every run and injects the CodeAct instructions into the system prompt automatically. You don&amp;rsquo;t need to write a custom prompt fragment.&lt;/p&gt;
&lt;h2 id="mixing-codeact-with-approval-gated-tools"&gt;Mixing CodeAct with approval-gated tools&lt;/h2&gt;
&lt;p&gt;This is where it gets interesting. Not every tool should run inside the sandbox without approval. You might want to gate &lt;code&gt;send_email&lt;/code&gt; or &lt;code&gt;charge_credit_card&lt;/code&gt; individually. The framework handles this cleanly:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;approval_mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;always_require&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;send_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;Send an email. Requires approval on every call.&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;MixedToolsAgent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;instructions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;You are a helpful assistant.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;context_providers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;codeact&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;send_email&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;# invoked directly, approval-gated&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Tools on the provider → the model reaches them via &lt;code&gt;call_tool(...)&lt;/code&gt; inside the sandbox, cheap and chainable.&lt;br&gt;
Tools on the agent directly → the model calls them as first-class tool calls, approval applies individually.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s a clean split: chainable data-lookup tools go through CodeAct, side-effect tools stay on the agent.&lt;/p&gt;
&lt;h2 id="when-to-use-codeact-and-when-not-to"&gt;When to use CodeAct (and when not to)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Reach for CodeAct when:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The task chains many small tool calls (lookups, joins, computations, formatting)&lt;/li&gt;
&lt;li&gt;You care about latency and token cost&lt;/li&gt;
&lt;li&gt;You want strong per-call isolation on model-generated code by default&lt;/li&gt;
&lt;li&gt;Tools are cheap and safe to invoke in sequence&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Stick with traditional tool-calling when:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The agent only makes one or two tool calls per turn&lt;/li&gt;
&lt;li&gt;Each tool has side effects you want approved individually&lt;/li&gt;
&lt;li&gt;Tool descriptions are sparse or ambiguous — CodeAct relies on good docstrings&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That last point matters. Because the model writes Python that calls your tools by name, docstrings and parameter annotations become part of the contract the model reasons about. Weak descriptions hurt CodeAct more than traditional tool-calling.&lt;/p&gt;
&lt;h2 id="try-it-now"&gt;Try it now&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pip install agent-framework-hyperlight --pre
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# or&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv add --prerelease&lt;span class="o"&gt;=&lt;/span&gt;allow agent-framework-hyperlight
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Samples are under &lt;a href="https://github.com/microsoft/agent-framework/tree/main/python/packages/hyperlight/samples"&gt;&lt;code&gt;python/packages/hyperlight/samples/&lt;/code&gt;&lt;/a&gt;. The &lt;a href="https://github.com/microsoft/agent-framework/blob/main/python/packages/hyperlight/samples/codeact_benchmark.py"&gt;benchmark sample&lt;/a&gt; is the best place to start — run it against your own tools to see if the wins apply to your workload.&lt;/p&gt;
&lt;p&gt;Worth noting: Linux and Windows are supported today. macOS support is on the way. A .NET counterpart is also coming, so if you&amp;rsquo;re on C#, keep an eye on the repo.&lt;/p&gt;
&lt;h2 id="wrapping-up"&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;CodeAct isn&amp;rsquo;t magic — it&amp;rsquo;s a sensible pattern that was just too risky to use without proper sandboxing. Hyperlight changes that equation. Per-call micro-VM isolation, millisecond startup, 50%+ latency improvement on the right workloads. That&amp;rsquo;s a combination worth experimenting with.&lt;/p&gt;
&lt;p&gt;Check the &lt;a href="https://devblogs.microsoft.com/agent-framework/codeact-with-hyperlight/"&gt;full post on the Agent Framework blog&lt;/a&gt; for deeper coverage on filesystem mounts, network policy, and the standalone &lt;code&gt;HyperlightExecuteCodeTool&lt;/code&gt; wiring.&lt;/p&gt;</content:encoded></item><item><title>Where Does Your Agent Remember Things? A Practical Guide to Chat History Storage</title><link>https://thedotnetblog.com/news/emiliano-montesdeoca/chat-history-storage-patterns-agent-framework/</link><pubDate>Sat, 25 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/news/emiliano-montesdeoca/chat-history-storage-patterns-agent-framework/</guid><description>Service-managed or client-managed? Linear or forking? The architectural decision that shapes what your AI agent can actually do — with code examples in C# and Python.</description><content:encoded>&lt;p&gt;When you build an AI agent, you spend most of your energy on the model, the tools, and the prompts. The question of &lt;em&gt;where the conversation history lives&lt;/em&gt; feels like an implementation detail — but it&amp;rsquo;s actually one of the most important architectural decisions you&amp;rsquo;ll make.&lt;/p&gt;
&lt;p&gt;It determines whether users can branch conversations, undo responses, resume sessions after a restart, and whether your data ever leaves your infrastructure. The &lt;a href="https://devblogs.microsoft.com/agent-framework/chat-history-storage-patterns-in-microsoft-agent-framework/"&gt;Agent Framework team published a deep dive on this&lt;/a&gt; and it&amp;rsquo;s worth understanding the full landscape.&lt;/p&gt;
&lt;h2 id="two-fundamental-patterns"&gt;Two fundamental patterns&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Service-managed&lt;/strong&gt;: the AI service stores the conversation state. Your app holds a reference (a thread ID, a response ID) and the service automatically includes relevant history on each request. Simpler to set up. Less control.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Client-managed&lt;/strong&gt;: your app maintains the full history and sends relevant messages with every request. The service is stateless. You control everything — what gets sent, how it&amp;rsquo;s compressed, where it lives.&lt;/p&gt;
&lt;p&gt;Neither is universally better. The right choice depends on what you&amp;rsquo;re building.&lt;/p&gt;
&lt;h2 id="service-managed-linear-vs-forking"&gt;Service-managed: linear vs forking&lt;/h2&gt;
&lt;p&gt;Not all service-managed storage is the same. There are two distinct models:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Linear (single-threaded)&lt;/strong&gt;: messages form an ordered sequence. You can append, but you can&amp;rsquo;t branch. This is the traditional chat model — used by Foundry Prompt Agents and the now-deprecated OpenAI Assistants API. Great for chatbots and support agents. Terrible if you want &amp;ldquo;try again&amp;rdquo; or parallel exploration.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Forking-capable&lt;/strong&gt;: each response has a unique ID, and new requests can reference &lt;em&gt;any&lt;/em&gt; previous response as the continuation point. This is what the Responses API (Microsoft Foundry, Azure OpenAI, OpenAI) supports. Users can branch conversations, build &amp;ldquo;undo&amp;rdquo; flows, explore multiple answer paths.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re building any kind of agentic workflow where multiple paths might be explored, forking is a capability you want.&lt;/p&gt;
&lt;h2 id="client-managed-you-own-the-complexity"&gt;Client-managed: you own the complexity&lt;/h2&gt;
&lt;p&gt;When the service doesn&amp;rsquo;t store history, your app does everything:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Context window management&lt;/strong&gt; — you can&amp;rsquo;t send unlimited history. You need truncation, sliding windows, summarization, or tool-call collapse strategies.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Persistence&lt;/strong&gt; — in-memory works for demos. Production needs a database, Redis, or blob storage.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Privacy&lt;/strong&gt; — conversation data never leaves your infrastructure unless you explicitly send it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The upside on privacy is real. For sensitive applications where you can&amp;rsquo;t have conversation history sitting on a third-party server, client-managed is the only option.&lt;/p&gt;
&lt;p&gt;Agent Framework ships built-in compaction strategies for all the common patterns, so you don&amp;rsquo;t have to build them from scratch. But you do need to choose and configure the right one.&lt;/p&gt;
&lt;h2 id="how-agent-framework-abstracts-this"&gt;How Agent Framework abstracts this&lt;/h2&gt;
&lt;p&gt;The beauty of the framework is that your agent invocation code stays the same regardless of which storage model you&amp;rsquo;re using. The &lt;code&gt;AgentSession&lt;/code&gt; handles the underlying differences.&lt;/p&gt;
&lt;p&gt;In C#:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Works with Chat Completions (client-managed)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// AND with Responses API (service-managed)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// The session handles the details.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;AgentSession&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateSessionAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RunAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;My name is Alice.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RunAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;What is my name?&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In Python:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_session&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;My name is Alice.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;What is my name?&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When you switch from OpenAI Chat Completions to the Responses API, you change the client configuration — not the agent invocation code.&lt;/p&gt;
&lt;h2 id="the-responses-api-is-uniquely-flexible"&gt;The Responses API is uniquely flexible&lt;/h2&gt;
&lt;p&gt;Most providers have a fixed storage model. The Responses API is the exception — it&amp;rsquo;s configurable via the &lt;code&gt;store&lt;/code&gt; parameter:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;store=true&lt;/code&gt; (default)&lt;/strong&gt;: service stores each response, supports forking via response IDs. Service handles compaction.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;store=false&lt;/code&gt;&lt;/strong&gt;: service is stateless, Agent Framework manages history client-side. You control compaction.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Conversations API&lt;/strong&gt;: linear thread model on top of Responses. Pass a conversation ID instead of a response ID.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here&amp;rsquo;s the client-managed mode in practice (C#):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;AIAgent&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;OpenAIClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&amp;lt;your_api_key&amp;gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetResponseClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;gpt-5.4-mini&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AsIChatClientWithStoredOutputDisabled&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AsAIAgent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ChatClientAgentOptions&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ChatOptions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Instructions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;You are a helpful assistant.&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ChatHistoryProvider&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;InMemoryChatHistoryProvider&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And in Python:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;OpenAIChatClient&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;StatelessAgent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;instructions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;You are a helpful assistant.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;default_options&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;store&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;context_providers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;InMemoryHistoryProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;memory&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;load_messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Swap &lt;code&gt;InMemoryHistoryProvider&lt;/code&gt; for your &lt;code&gt;DatabaseHistoryProvider&lt;/code&gt; when you&amp;rsquo;re ready for production persistence.&lt;/p&gt;
&lt;h2 id="provider-quick-reference"&gt;Provider quick reference&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Storage&lt;/th&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Compaction&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;OpenAI / Azure OpenAI Chat Completions&lt;/td&gt;
&lt;td&gt;Client&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;You&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Foundry Agent Service&lt;/td&gt;
&lt;td&gt;Service&lt;/td&gt;
&lt;td&gt;Linear&lt;/td&gt;
&lt;td&gt;Service&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Responses API (default)&lt;/td&gt;
&lt;td&gt;Service&lt;/td&gt;
&lt;td&gt;Forking&lt;/td&gt;
&lt;td&gt;Service&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Responses API (&lt;code&gt;store=false&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Client&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;You&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anthropic Claude, Ollama&lt;/td&gt;
&lt;td&gt;Client&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;You&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="how-to-choose"&gt;How to choose&lt;/h2&gt;
&lt;p&gt;Start with these questions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Do you need conversation branching or &amp;ldquo;undo&amp;rdquo;?&lt;/strong&gt; → Forking service-managed (Responses API)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Do you need full data sovereignty?&lt;/strong&gt; → Client-managed, with a database-backed provider&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Is this a simple chatbot or support flow?&lt;/strong&gt; → Service-managed linear is fine&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Do you need to migrate between providers later?&lt;/strong&gt; → Client-managed gives you portability&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The most important thing: don&amp;rsquo;t default to whatever is easiest to start with and forget to revisit it. Changing storage patterns after launch is painful.&lt;/p&gt;
&lt;h2 id="wrapping-up"&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;Chat history storage shapes what your agents can actually do — not just in demos but in production, under real user behavior. Agent Framework&amp;rsquo;s abstractions let you evolve your choice without rewriting your application logic, which is genuinely useful when you&amp;rsquo;re still figuring out the right model.&lt;/p&gt;
&lt;p&gt;Read the &lt;a href="https://devblogs.microsoft.com/agent-framework/chat-history-storage-patterns-in-microsoft-agent-framework/"&gt;full post&lt;/a&gt; for the complete decision tree, the Conversations API walkthrough, and the compaction strategy details.&lt;/p&gt;</content:encoded></item><item><title>Foundry Toolboxes: One Endpoint for All Your Agent Tools</title><link>https://thedotnetblog.com/news/emiliano-montesdeoca/foundry-toolboxes-curate-manage-tools-ai-agents/</link><pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/news/emiliano-montesdeoca/foundry-toolboxes-curate-manage-tools-ai-agents/</guid><description>Microsoft Foundry just launched Toolboxes in public preview — a way to curate, manage, and expose AI agent tools through a single MCP-compatible endpoint without re-wiring everything per agent.</description><content:encoded>&lt;p&gt;Here&amp;rsquo;s a problem that sounds boring until you&amp;rsquo;ve actually hit it: your organization is building multiple AI agents, each one needs tools, and every team is wiring those tools up from scratch. Same Web Search integration, same Azure AI Search config, same GitHub MCP server connection — just in a different repo, by a different team, with different credentials and no shared governance.&lt;/p&gt;
&lt;p&gt;Microsoft Foundry just shipped &lt;a href="https://devblogs.microsoft.com/foundry/introducing-toolboxes-in-foundry/"&gt;Toolboxes&lt;/a&gt; in public preview, and it&amp;rsquo;s a direct answer to that problem.&lt;/p&gt;
&lt;h2 id="whats-a-toolbox"&gt;What&amp;rsquo;s a Toolbox?&lt;/h2&gt;
&lt;p&gt;A Toolbox is a named, reusable bundle of tools that you define once in Foundry and expose through a single MCP-compatible endpoint. Any agent runtime that speaks MCP can consume it — you&amp;rsquo;re not locked to Foundry Agents.&lt;/p&gt;
&lt;p&gt;The pitch is simple: &lt;strong&gt;build once, consume anywhere&lt;/strong&gt;. Define the tools, configure auth centrally (OAuth passthrough, Entra managed identity), publish the endpoint. Every agent that needs those tools connects to the endpoint and gets them all.&lt;/p&gt;
&lt;p&gt;No per-tool wiring. No per-agent credential management.&lt;/p&gt;
&lt;h2 id="the-four-pillars-two-of-which-ship-today"&gt;The four pillars (two of which ship today)&lt;/h2&gt;
&lt;p&gt;The Toolbox feature is organized around four ideas:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pillar&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Discover&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Coming soon&lt;/td&gt;
&lt;td&gt;Find existing approved tools without hunting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Build&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Available now&lt;/td&gt;
&lt;td&gt;Curate tools into a named, reusable bundle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Consume&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Available now&lt;/td&gt;
&lt;td&gt;Single MCP endpoint exposes all tools&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Govern&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Coming soon&lt;/td&gt;
&lt;td&gt;Centralized auth + observability across all tool calls&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Today the focus is on Build and Consume. That&amp;rsquo;s enough to remove the most immediate friction.&lt;/p&gt;
&lt;h2 id="getting-started-in-practice"&gt;Getting started in practice&lt;/h2&gt;
&lt;p&gt;The SDK is Python-first for now. You start by creating an &lt;code&gt;AIProjectClient&lt;/code&gt; and then build a toolbox:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;azure.identity&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;DefaultAzureCredential&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;azure.ai.projects&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AIProjectClient&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AIProjectClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;endpoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;FOUNDRY_PROJECT_ENDPOINT&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;DefaultAzureCredential&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then you create a toolbox version with the tools you want to bundle:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;toolbox_version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;beta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toolboxes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_toolbox_version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;toolbox_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;customer-feedback-triaging-toolbox&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Search public and internal docs, then respond to GitHub issues.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;web_search&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Search approved public documentation&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;azure_ai_search&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;index_name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;internal-docs&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;mcp_server&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;server_url&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://your-github-mcp-server.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once published, Foundry gives you a unified endpoint:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;https://zava.services.ai.azure.com/api/projects/&amp;lt;project&amp;gt;/toolbox/&amp;lt;toolbox-name&amp;gt;/mcp?api-version=v1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Point any MCP-compatible agent runtime at that URL and it discovers all the tools in the bundle dynamically. One connection. All tools.&lt;/p&gt;
&lt;h2 id="not-locked-to-foundry-agents"&gt;Not locked to Foundry Agents&lt;/h2&gt;
&lt;p&gt;This is worth spelling out because it&amp;rsquo;s a common concern when Microsoft ships something under the Foundry brand.&lt;/p&gt;
&lt;p&gt;Toolboxes are &lt;strong&gt;created and governed&lt;/strong&gt; in Foundry, but the consumption surface is the open MCP protocol. That means you can use them from:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Custom agents&lt;/strong&gt; built with Microsoft Agent Framework, LangGraph, or your own code&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub Copilot&lt;/strong&gt; and other MCP-enabled IDEs&lt;/li&gt;
&lt;li&gt;Any other runtime that speaks MCP&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You&amp;rsquo;re not locked in. The toolbox is Foundry-homed (that&amp;rsquo;s where you manage it) but not Foundry-bound (you can consume it from anywhere).&lt;/p&gt;
&lt;h2 id="why-it-matters-now"&gt;Why it matters now&lt;/h2&gt;
&lt;p&gt;The multi-agent wave is hitting production. Teams are building 5, 10, 20 agents — and the tool-wiring problem compounds fast. Every new agent is a new surface for duplicated config, stale credentials, and inconsistent behavior.&lt;/p&gt;
&lt;p&gt;Toolboxes don&amp;rsquo;t solve governance and discovery yet (those are &amp;ldquo;coming soon&amp;rdquo;), but the Build + Consume foundation is enough to start centralizing. Once the Govern pillar ships, you&amp;rsquo;ll have a proper observable, centrally-controlled tool layer for your entire agent fleet.&lt;/p&gt;
&lt;h2 id="wrapping-up"&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;This is early — public preview, Python SDK first, with Discover and Govern still coming. But the model is sound, and the MCP-native design means it works with the tools you&amp;rsquo;re already building on. Take a look at the &lt;a href="https://devblogs.microsoft.com/foundry/introducing-toolboxes-in-foundry/"&gt;official announcement&lt;/a&gt; to get started.&lt;/p&gt;</content:encoded></item><item><title>VS Code 1.117: Agents Are Getting Their Own Git Branches and I'm Here For It</title><link>https://thedotnetblog.com/news/emiliano-montesdeoca/vscode-1-117-agents-autopilot-worktrees/</link><pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/news/emiliano-montesdeoca/vscode-1-117-agents-autopilot-worktrees/</guid><description>VS Code 1.117 ships worktree isolation for agent sessions, persistent Autopilot mode, and subagent support. The agentic coding workflow just got way more real.</description><content:encoded>&lt;p&gt;The line between &amp;ldquo;AI assistant&amp;rdquo; and &amp;ldquo;AI teammate&amp;rdquo; keeps getting thinner. VS Code 1.117 just dropped and the &lt;a href="https://code.visualstudio.com/updates/v1_117"&gt;full release notes&lt;/a&gt; are packed, but the story here is clear: agents are becoming first-class citizens in your dev workflow.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s what actually matters.&lt;/p&gt;
&lt;h2 id="autopilot-mode-finally-remembers-your-preference"&gt;Autopilot mode finally remembers your preference&lt;/h2&gt;
&lt;p&gt;Previously, you had to re-enable Autopilot every time you started a new session. Annoying. Now your permission mode persists across sessions, and you can configure the default.&lt;/p&gt;
&lt;p&gt;The Agent Host supports three session configs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Default&lt;/strong&gt; — tools ask for confirmation before running&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bypass&lt;/strong&gt; — auto-approves everything&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Autopilot&lt;/strong&gt; — fully autonomous, answers its own questions and keeps going&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you&amp;rsquo;re scaffolding a new .NET project with migrations, Docker, and CI — set it to Autopilot once and forget about it. That preference sticks.&lt;/p&gt;
&lt;h2 id="worktree-and-git-isolation-for-agent-sessions"&gt;Worktree and git isolation for agent sessions&lt;/h2&gt;
&lt;p&gt;This is the big one. Agent sessions now support full worktree and git isolation. That means when an agent works on a task, it gets its own branch and working directory. Your main branch stays untouched.&lt;/p&gt;
&lt;p&gt;Even better — Copilot CLI generates meaningful branch names for these worktree sessions. No more &lt;code&gt;agent-session-abc123&lt;/code&gt;. You get something that actually describes what the agent is doing.&lt;/p&gt;
&lt;p&gt;For .NET developers running multiple feature branches or fixing bugs while a long scaffolding task runs, this is a game changer. You can have an agent building out your API controllers in one worktree while you&amp;rsquo;re debugging a service layer issue in another. No conflicts. No stashing. No mess.&lt;/p&gt;
&lt;h2 id="subagents-and-agent-teams"&gt;Subagents and agent teams&lt;/h2&gt;
&lt;p&gt;The Agent Host Protocol now supports subagents. An agent can spin up other agents to handle parts of a task. Think of it as delegating — your main agent coordinates, and specialized agents handle the pieces.&lt;/p&gt;
&lt;p&gt;This is early, but the potential for .NET workflows is obvious. Imagine one agent handling your EF Core migrations while another sets up your integration tests. We&amp;rsquo;re not fully there yet, but the protocol support landing now means tooling will follow fast.&lt;/p&gt;
&lt;h2 id="terminal-output-auto-included-when-agents-send-input"&gt;Terminal output auto-included when agents send input&lt;/h2&gt;
&lt;p&gt;Small but meaningful. When an agent sends input to the terminal, the terminal output is now automatically included in the context. Before, the agent had to make an extra turn just to read what happened.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;ve ever watched an agent run &lt;code&gt;dotnet build&lt;/code&gt;, fail, and then take another round-trip just to see the error — that friction is gone. It sees the output immediately and reacts.&lt;/p&gt;
&lt;h2 id="self-updating-agents-app-on-macos"&gt;Self-updating Agents app on macOS&lt;/h2&gt;
&lt;p&gt;The standalone Agents app on macOS now self-updates. No more manually downloading new versions. It just stays current.&lt;/p&gt;
&lt;h2 id="the-smaller-stuff-worth-knowing"&gt;The smaller stuff worth knowing&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;package.json hovers&lt;/strong&gt; now show both the installed version and the latest available. Useful if you manage npm tooling alongside your .NET projects.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Images in JSDoc&lt;/strong&gt; comments render correctly in hovers and completions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Copilot CLI sessions&lt;/strong&gt; now indicate whether they were created by VS Code or externally — handy when you&amp;rsquo;re jumping between terminals.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Copilot CLI, Claude Code, and Gemini CLI&lt;/strong&gt; are recognized as shell types. The editor knows what you&amp;rsquo;re running.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="the-takeaway"&gt;The takeaway&lt;/h2&gt;
&lt;p&gt;VS Code 1.117 isn&amp;rsquo;t a flashy feature dump. It&amp;rsquo;s infrastructure. Worktree isolation, persistent permissions, subagent protocols — these are the building blocks for a workflow where agents handle real, parallel tasks without stepping on your code.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re building with .NET and haven&amp;rsquo;t leaned into the agentic workflow yet, honestly, now&amp;rsquo;s the time to start.&lt;/p&gt;</content:encoded></item><item><title>Where Should You Host Your AI Agents on Azure? A Practical Decision Guide</title><link>https://thedotnetblog.com/news/emiliano-montesdeoca/azure-ai-agent-hosting-options-guide/</link><pubDate>Wed, 15 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/news/emiliano-montesdeoca/azure-ai-agent-hosting-options-guide/</guid><description>Azure offers six ways to host AI agents — from raw containers to fully managed Foundry Hosted Agents. Here's how to pick the right one for your .NET workload.</description><content:encoded>&lt;p&gt;If you&amp;rsquo;re building AI agents with .NET right now, you&amp;rsquo;ve probably noticed something: there are a &lt;em&gt;lot&lt;/em&gt; of ways to host them on Azure. Container Apps, AKS, Functions, App Service, Foundry Agents, Foundry Hosted Agents — and they all sound reasonable until you actually need to pick one. Microsoft just published a &lt;a href="https://devblogs.microsoft.com/all-things-azure/hostedagent/"&gt;comprehensive guide to Azure AI agent hosting&lt;/a&gt; that clears this up, and I want to break it down from a practical .NET developer perspective.&lt;/p&gt;
&lt;h2 id="the-six-options-at-a-glance"&gt;The six options at a glance&lt;/h2&gt;
&lt;p&gt;Here&amp;rsquo;s how I&amp;rsquo;d summarize the landscape:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Best for&lt;/th&gt;
&lt;th&gt;You manage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Container Apps&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Full container control without K8s complexity&lt;/td&gt;
&lt;td&gt;Observability, state, lifecycle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AKS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Enterprise compliance, multi-cluster, custom networking&lt;/td&gt;
&lt;td&gt;Everything (that&amp;rsquo;s the point)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Azure Functions&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Event-driven, short-running agent tasks&lt;/td&gt;
&lt;td&gt;Not much — true serverless&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;App Service&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Simple HTTP agents, predictable traffic&lt;/td&gt;
&lt;td&gt;Deployment, scaling config&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Foundry Agents&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Code-optional agents via portal/SDK&lt;/td&gt;
&lt;td&gt;Almost nothing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Foundry Hosted Agents&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Custom framework agents with managed infra&lt;/td&gt;
&lt;td&gt;Your agent code only&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The first four are general-purpose compute — you &lt;em&gt;can&lt;/em&gt; run agents on them, but they weren&amp;rsquo;t designed for it. The last two are agent-native: they understand conversations, tool calls, and agent lifecycles as first-class concepts.&lt;/p&gt;
&lt;h2 id="foundry-hosted-agents--the-sweet-spot-for-net-agent-developers"&gt;Foundry Hosted Agents — the sweet spot for .NET agent developers&lt;/h2&gt;
&lt;p&gt;Here&amp;rsquo;s what caught my attention. Foundry Hosted Agents sit right in the middle: you get the flexibility of running your own code (Semantic Kernel, Agent Framework, LangGraph — whatever) but the platform handles infrastructure, observability, and conversation management.&lt;/p&gt;
&lt;p&gt;The key piece is the &lt;strong&gt;Hosting Adapter&lt;/strong&gt; — a thin abstraction layer that bridges your agent framework to the Foundry platform. For Microsoft Agent Framework, it looks like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;azure.ai.agentserver.agentframework&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;from_agent_framework&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatAgent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;chat_client&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;AzureAIAgentClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;instructions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;You are a helpful assistant.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;get_local_time&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vm"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;from_agent_framework&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That&amp;rsquo;s your entire hosting story. The adapter handles protocol translation, streaming via server-sent events, conversation history, and OpenTelemetry tracing — all automatically. No custom middleware, no manual plumbing.&lt;/p&gt;
&lt;h2 id="deploying-is-genuinely-simple"&gt;Deploying is genuinely simple&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve deployed agents to Container Apps before and it works, but you end up writing a lot of glue code for state management and observability. With Hosted Agents and &lt;code&gt;azd&lt;/code&gt;, the deployment is:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Install the AI agent extension&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;azd ext install azure.ai.agents
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Init from a template&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;azd ai agent init
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Build, push, deploy — done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;azd up
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That single &lt;code&gt;azd up&lt;/code&gt; builds your container, pushes it to ACR, provisions the Foundry project, deploys model endpoints, and starts your agent. Five steps collapsed into one command.&lt;/p&gt;
&lt;h2 id="built-in-conversation-management"&gt;Built-in conversation management&lt;/h2&gt;
&lt;p&gt;This is the part that saves the most time in production. Instead of building your own conversation state store, Hosted Agents handle it natively:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Create a persistent conversation&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;conversation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openai_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conversations&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# First turn&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;response1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openai_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;responses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;conversation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;conversation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;extra_body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;agent_reference&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;MyAgent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;agent_reference&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Remember: my favorite number is 42.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Second turn — context is preserved&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;response2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openai_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;responses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;conversation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;conversation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;extra_body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;agent_reference&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;MyAgent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;agent_reference&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Multiply my favorite number by 10.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;No Redis. No Cosmos DB session store. No custom middleware for message serialization. The platform just handles it.&lt;/p&gt;
&lt;h2 id="my-decision-framework"&gt;My decision framework&lt;/h2&gt;
&lt;p&gt;After going through all six options, here&amp;rsquo;s my quick mental model:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Do you need zero infrastructure?&lt;/strong&gt; → Foundry Agents (portal/SDK, no containers)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Do you have custom agent code but want managed hosting?&lt;/strong&gt; → Foundry Hosted Agents&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Do you need event-driven, short-lived agent tasks?&lt;/strong&gt; → Azure Functions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Do you need maximum container control without K8s?&lt;/strong&gt; → Container Apps&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Do you need strict compliance and multi-cluster?&lt;/strong&gt; → AKS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Do you have a simple HTTP agent with predictable traffic?&lt;/strong&gt; → App Service&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For most .NET developers building with Semantic Kernel or Microsoft Agent Framework, Hosted Agents is likely the right starting point. You get scale-to-zero, built-in OpenTelemetry, conversation management, and framework flexibility — without managing Kubernetes or wiring up your own observability stack.&lt;/p&gt;
&lt;h2 id="wrapping-up"&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;The agent hosting landscape on Azure is maturing fast. If you&amp;rsquo;re starting a new AI agent project today, I&amp;rsquo;d seriously consider Foundry Hosted Agents before reaching for Container Apps or AKS out of habit. The managed infrastructure saves real time, and the hosting adapter pattern lets you keep your framework choice.&lt;/p&gt;
&lt;p&gt;Check out the &lt;a href="https://devblogs.microsoft.com/all-things-azure/hostedagent/"&gt;full guide from Microsoft&lt;/a&gt; and the &lt;a href="https://github.com/microsoft-foundry/foundry-samples/tree/main/samples/python/hosted-agents"&gt;Foundry Samples repo&lt;/a&gt; for working examples.&lt;/p&gt;</content:encoded></item><item><title>Azure MCP Server 2.0 Just Dropped — Self-Hosted Agentic Cloud Automation Is Here</title><link>https://thedotnetblog.com/news/emiliano-montesdeoca/azure-mcp-server-2-self-hosted-agentic-cloud/</link><pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/news/emiliano-montesdeoca/azure-mcp-server-2-self-hosted-agentic-cloud/</guid><description>Azure MCP Server 2.0 goes stable with self-hosted remote deployments, 276 tools across 57 Azure services, and enterprise-grade security — here's what matters for .NET developers building agentic workflows.</description><content:encoded>&lt;p&gt;If you&amp;rsquo;ve been building anything with MCP and Azure lately, you probably already know the local experience works well. Plug in an MCP server, let your AI agent talk to Azure resources, move on. But the moment you need to share that setup across a team? That&amp;rsquo;s where things got complicated.&lt;/p&gt;
&lt;p&gt;Not anymore. Azure MCP Server &lt;a href="https://devblogs.microsoft.com/azure-sdk/announcing-azure-mcp-server-2-0-stable-release/"&gt;just hit 2.0 stable&lt;/a&gt;, and the headline feature is exactly what enterprise teams have been asking for: &lt;strong&gt;self-hosted remote MCP server support&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id="whats-azure-mcp-server"&gt;What&amp;rsquo;s Azure MCP Server?&lt;/h2&gt;
&lt;p&gt;Quick refresher. Azure MCP Server implements the &lt;a href="https://modelcontextprotocol.io/docs/getting-started/intro"&gt;Model Context Protocol&lt;/a&gt; specification and exposes Azure capabilities as structured, discoverable tools that AI agents can invoke. Think of it as a standardized bridge between your agent and Azure — provisioning, deployment, monitoring, diagnostics, all through one consistent interface.&lt;/p&gt;
&lt;p&gt;The numbers speak for themselves: &lt;strong&gt;276 MCP tools across 57 Azure services&lt;/strong&gt;. That&amp;rsquo;s serious coverage.&lt;/p&gt;
&lt;h2 id="the-big-deal-self-hosted-remote-deployments"&gt;The big deal: self-hosted remote deployments&lt;/h2&gt;
&lt;p&gt;Here&amp;rsquo;s the thing. Running MCP locally on your machine is fine for dev and experiments. But in a real team scenario, you need:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Shared access for developers and internal agent systems&lt;/li&gt;
&lt;li&gt;Centralized configuration (tenant context, subscription defaults, telemetry)&lt;/li&gt;
&lt;li&gt;Enterprise network and policy boundaries&lt;/li&gt;
&lt;li&gt;Integration into CI/CD pipelines&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Azure MCP Server 2.0 addresses all of this. You can deploy it as a centrally managed internal service with HTTP-based transport, proper authentication, and consistent governance.&lt;/p&gt;
&lt;p&gt;For auth, you get two solid options:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Managed Identity&lt;/strong&gt; — when running alongside &lt;a href="https://aka.ms/azmcp/self-host/foundry"&gt;Microsoft Foundry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;On-Behalf-Of (OBO) flow&lt;/strong&gt; — OpenID Connect delegation that calls Azure APIs using the signed-in user&amp;rsquo;s context&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That OBO flow is particularly interesting for us .NET developers. It means your agentic workflows can operate with the user&amp;rsquo;s actual permissions, not some over-privileged service account. Principle of least privilege, built right in.&lt;/p&gt;
&lt;h2 id="security-hardening"&gt;Security hardening&lt;/h2&gt;
&lt;p&gt;This isn&amp;rsquo;t just a feature release — it&amp;rsquo;s a security one too. The 2.0 release adds:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Stronger endpoint validation&lt;/li&gt;
&lt;li&gt;Protections against injection patterns in query-oriented tools&lt;/li&gt;
&lt;li&gt;Tighter isolation controls for dev environments&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you&amp;rsquo;re going to expose MCP as a shared service, these safeguards matter. A lot.&lt;/p&gt;
&lt;h2 id="where-can-you-use-it"&gt;Where can you use it?&lt;/h2&gt;
&lt;p&gt;The client compatibility story is broad. Azure MCP Server 2.0 works with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;IDEs&lt;/strong&gt;: VS Code, Visual Studio, IntelliJ, Eclipse, Cursor&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CLI agents&lt;/strong&gt;: GitHub Copilot CLI, Claude Code&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Standalone&lt;/strong&gt;: local server for simple setups&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Self-hosted remote&lt;/strong&gt;: the new star of 2.0&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Plus there&amp;rsquo;s sovereign cloud support for Azure US Government and Azure operated by 21Vianet, which is critical for regulated deployments.&lt;/p&gt;
&lt;h2 id="why-this-matters-for-net-developers"&gt;Why this matters for .NET developers&lt;/h2&gt;
&lt;p&gt;If you&amp;rsquo;re building agentic applications with .NET — whether that&amp;rsquo;s Semantic Kernel, Microsoft Agent Framework, or your own orchestration — Azure MCP Server 2.0 gives you a production-ready way to let your agents interact with Azure infrastructure. No custom REST wrappers. No service-specific integration patterns. Just MCP.&lt;/p&gt;
&lt;p&gt;Combined with the &lt;a href="https://devblogs.microsoft.com/azure-sdk/mcp-as-easy-as-1-2-3-introducing-the-fluent-api-for-mcp-apps/"&gt;fluent API for MCP Apps&lt;/a&gt; that dropped a few days ago, the .NET MCP ecosystem is maturing fast.&lt;/p&gt;
&lt;h2 id="getting-started"&gt;Getting started&lt;/h2&gt;
&lt;p&gt;Pick your path:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://aka.ms/azmcp"&gt;GitHub Repo&lt;/a&gt;&lt;/strong&gt; — source code, docs, everything&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://aka.ms/azmcp/download/docker"&gt;Docker Image&lt;/a&gt;&lt;/strong&gt; — containerized deployment&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://aka.ms/azmcp/download/vscode"&gt;VS Code Extension&lt;/a&gt;&lt;/strong&gt; — IDE integration&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://aka.ms/azmcp/self-host"&gt;Self-hosting guide&lt;/a&gt;&lt;/strong&gt; — the 2.0 flagship feature&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="wrapping-up"&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;Azure MCP Server 2.0 is exactly the kind of infrastructure upgrade that doesn&amp;rsquo;t look flashy in a demo but changes everything in practice. Self-hosted remote MCP with proper auth, security hardening, and sovereign cloud support means MCP is ready for real teams building real agentic workflows on Azure. If you&amp;rsquo;ve been waiting for the &amp;ldquo;enterprise-ready&amp;rdquo; signal — this is it.&lt;/p&gt;</content:encoded></item><item><title>Agentic Platform Engineering Is Getting Real — Git-APE Shows How</title><link>https://thedotnetblog.com/news/emiliano-montesdeoca/agentic-platform-engineering-git-ape/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/news/emiliano-montesdeoca/agentic-platform-engineering-git-ape/</guid><description>Microsoft's Git-APE project puts agentic platform engineering into practice — using GitHub Copilot agents and Azure MCP to turn natural-language requests into validated cloud infrastructure.</description><content:encoded>&lt;p&gt;Platform engineering has been one of those terms that sounds great in conference talks but usually means &amp;ldquo;we built an internal portal and a Terraform wrapper.&amp;rdquo; The real promise — self-service infrastructure that&amp;rsquo;s actually safe, governed, and fast — has always been a few steps away.&lt;/p&gt;
&lt;p&gt;The Azure team just published &lt;a href="https://devblogs.microsoft.com/all-things-azure/putting-agentic-platform-engineering-to-the-test/"&gt;Part 2 of their agentic platform engineering series&lt;/a&gt;, and this one is all about the hands-on implementation. They call it &lt;strong&gt;Git-APE&lt;/strong&gt; (yes, the acronym is intentional), and it&amp;rsquo;s an open-source project that uses GitHub Copilot agents plus Azure MCP servers to turn natural-language requests into validated, deployed infrastructure.&lt;/p&gt;
&lt;h2 id="what-git-ape-actually-does"&gt;What Git-APE actually does&lt;/h2&gt;
&lt;p&gt;The core idea: instead of developers learning Terraform modules, navigating portal UIs, or filing tickets to a platform team, they talk to a Copilot agent. The agent interprets the intent, generates Infrastructure-as-Code, validates it against policies, and deploys — all within VS Code.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the setup:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone https://github.com/Azure/git-ape
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; git-ape
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Open the workspace in VS Code, and the agent configuration files are auto-discovered by GitHub Copilot. You interact with the agent directly:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;@git-ape deploy a function app with storage in West Europe
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The agent uses Azure MCP Server under the hood to interact with Azure services. The MCP configuration in VS Code settings enables specific capabilities:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;azureMcp.serverMode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;namespace&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;azureMcp.enabledServices&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;deploy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;bestpractices&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;group&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;subscription&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;functionapp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;storage&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;sql&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;monitor&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;azureMcp.readOnly&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="why-this-matters"&gt;Why this matters&lt;/h2&gt;
&lt;p&gt;For those of us building on Azure, this shifts the platform engineering conversation from &amp;ldquo;how do we build a portal&amp;rdquo; to &amp;ldquo;how do we describe our guardrails as APIs.&amp;rdquo; When your platform&amp;rsquo;s interface is an AI agent, the quality of your constraints and policies becomes the product.&lt;/p&gt;
&lt;p&gt;The Part 1 blog laid out the theory: well-described APIs, control schemas, and explicit guardrails make platforms agent-ready. Part 2 proves it works by shipping actual tooling. The agent doesn&amp;rsquo;t just blindly generate resources — it validates against best practices, respects naming conventions, and applies your organization&amp;rsquo;s policies.&lt;/p&gt;
&lt;p&gt;Clean-up is just as easy:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;@git-ape destroy my-resource-group
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="my-take"&gt;My take&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ll be honest — this one is more about the pattern than the specific tool. Git-APE itself is a demo/reference architecture. But the underlying idea — agents as the interface to your platform, MCP as the protocol, GitHub Copilot as the host — is where enterprise developer experience is heading.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re a platform team looking at how to make your internal tooling agent-friendly, there&amp;rsquo;s no better starting point. And if you&amp;rsquo;re a .NET developer wondering how this connects to your world: the Azure MCP Server and GitHub Copilot agents work with any Azure workload. Your ASP.NET Core API, your .NET Aspire stack, your containerized microservices — all of it can be the target of an agentic deployment flow.&lt;/p&gt;
&lt;h2 id="wrapping-up"&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;Git-APE is an early but concrete look at agentic platform engineering in practice. Clone the &lt;a href="https://github.com/Azure/git-ape"&gt;repo&lt;/a&gt;, try the demo, and start thinking about how your platform&amp;rsquo;s APIs and policies would need to look for an agent to safely use them.&lt;/p&gt;
&lt;p&gt;Read the &lt;a href="https://devblogs.microsoft.com/all-things-azure/putting-agentic-platform-engineering-to-the-test/"&gt;full post&lt;/a&gt; for the walkthrough and video demos.&lt;/p&gt;</content:encoded></item><item><title>Microsoft Foundry March 2026 — GPT-5.4, Agent Service GA, and the SDK Refresh That Changes Everything</title><link>https://thedotnetblog.com/news/emiliano-montesdeoca/microsoft-foundry-march-2026-whats-new/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/news/emiliano-montesdeoca/microsoft-foundry-march-2026-whats-new/</guid><description>Microsoft Foundry's March 2026 update is massive: Agent Service hits GA, GPT-5.4 brings reliable reasoning, the azure-ai-projects SDK goes stable across all languages, and Fireworks AI brings open models to Azure.</description><content:encoded>&lt;p&gt;The monthly &amp;ldquo;What&amp;rsquo;s New in Microsoft Foundry&amp;rdquo; posts are usually a mix of incremental improvements and the occasional headline feature. The &lt;a href="https://devblogs.microsoft.com/foundry/whats-new-in-microsoft-foundry-mar-2026/"&gt;March 2026 edition&lt;/a&gt;? It&amp;rsquo;s basically all headline features. Foundry Agent Service goes GA, GPT-5.4 ships for production, the SDK gets a major stable release, and Fireworks AI brings open model inference to Azure. Let me break down what matters for .NET developers.&lt;/p&gt;
&lt;h2 id="foundry-agent-service-is-production-ready"&gt;Foundry Agent Service is production-ready&lt;/h2&gt;
&lt;p&gt;This is the big one. The next-gen agent runtime is generally available — built on the OpenAI Responses API, wire-compatible with OpenAI agents, and open to models from multiple providers. If you&amp;rsquo;re building with the Responses API today, migrating to Foundry adds enterprise security, private networking, Entra RBAC, full tracing, and evaluation on top of your existing agent logic.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;azure.ai.projects&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AIProjectClient&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;azure.ai.projects.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PromptAgentDefinition&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;project_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AIProjectClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;endpoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;AZURE_AI_PROJECT_ENDPOINT&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;DefaultAzureCredential&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;project_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agents&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;agent_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;my-enterprise-agent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;PromptAgentDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;AZURE_AI_MODEL_DEPLOYMENT_NAME&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;instructions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;You are a helpful assistant.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Key additions: end-to-end private networking, MCP auth expansion (including OAuth passthrough), Voice Live preview for speech-to-speech agents, and hosted agents in 6 new regions.&lt;/p&gt;
&lt;h2 id="gpt-54--reliability-over-raw-intelligence"&gt;GPT-5.4 — reliability over raw intelligence&lt;/h2&gt;
&lt;p&gt;GPT-5.4 isn&amp;rsquo;t about being smarter. It&amp;rsquo;s about being more reliable. Stronger reasoning over long interactions, better instruction adherence, fewer mid-workflow failures, and integrated computer use capabilities. For production agents, that reliability matters way more than benchmark scores.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Pricing (per M tokens)&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GPT-5.4 (≤272K)&lt;/td&gt;
&lt;td&gt;$2.50 / $15 output&lt;/td&gt;
&lt;td&gt;Production agents, coding, document workflows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-5.4 Pro&lt;/td&gt;
&lt;td&gt;$30 / $180 output&lt;/td&gt;
&lt;td&gt;Deep analysis, scientific reasoning&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-5.4 Mini&lt;/td&gt;
&lt;td&gt;Cost-effective&lt;/td&gt;
&lt;td&gt;Classification, extraction, lightweight tool calls&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The smart play is a routing strategy: GPT-5.4 Mini handles high-volume, low-latency work while GPT-5.4 takes the reasoning-heavy requests.&lt;/p&gt;
&lt;h2 id="the-sdk-is-finally-stable"&gt;The SDK is finally stable&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;azure-ai-projects&lt;/code&gt; SDK shipped stable releases across all languages — Python 2.0.0, JS/TS 2.0.0, Java 2.0.0, and .NET 2.0.0 (April 1). The &lt;code&gt;azure-ai-agents&lt;/code&gt; dependency is gone — everything lives under &lt;code&gt;AIProjectClient&lt;/code&gt;. Install with &lt;code&gt;pip install azure-ai-projects&lt;/code&gt; and the package bundles &lt;code&gt;openai&lt;/code&gt; and &lt;code&gt;azure-identity&lt;/code&gt; as direct dependencies.&lt;/p&gt;
&lt;p&gt;For .NET developers, this means a single NuGet package for the full Foundry surface. No more juggling separate agent SDKs.&lt;/p&gt;
&lt;h2 id="fireworks-ai-brings-open-models-to-azure"&gt;Fireworks AI brings open models to Azure&lt;/h2&gt;
&lt;p&gt;Perhaps the most architecturally interesting addition: Fireworks AI processing 13+ trillion tokens daily at ~180K requests/second, now available through Foundry. DeepSeek V3.2, gpt-oss-120b, Kimi K2.5, and MiniMax M2.5 at launch.&lt;/p&gt;
&lt;p&gt;The real story is &lt;strong&gt;bring-your-own-weights&lt;/strong&gt; — upload quantized or fine-tuned weights from anywhere without changing the serving stack. Deploy via serverless pay-per-token or provisioned throughput.&lt;/p&gt;
&lt;h2 id="other-highlights"&gt;Other highlights&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Phi-4 Reasoning Vision 15B&lt;/strong&gt; — multimodal reasoning for charts, diagrams, and document layouts&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Evaluations GA&lt;/strong&gt; — out-of-the-box evaluators with continuous production monitoring piped into Azure Monitor&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Priority Processing&lt;/strong&gt; (Preview) — dedicated compute lane for latency-sensitive workloads&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Voice Live&lt;/strong&gt; — speech-to-speech runtime that connects directly to Foundry agents&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tracing GA&lt;/strong&gt; — end-to-end agent trace inspection with sort and filter&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PromptFlow deprecation&lt;/strong&gt; — migration to Microsoft Framework Workflows by January 2027&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="wrapping-up"&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;March 2026 is a turning point for Foundry. The Agent Service GA, stable SDKs across all languages, GPT-5.4 for reliable production agents, and open model inference via Fireworks AI — the platform is ready for serious workloads.&lt;/p&gt;
&lt;p&gt;Read the &lt;a href="https://devblogs.microsoft.com/foundry/whats-new-in-microsoft-foundry-mar-2026/"&gt;full roundup&lt;/a&gt; and &lt;a href="https://learn.microsoft.com/azure/foundry/quickstarts/get-started-code"&gt;build your first agent&lt;/a&gt; to get started.&lt;/p&gt;</content:encoded></item><item><title>VS Code 1.116 — Agents App Gets Keyboard Navigation and File Context Completions</title><link>https://thedotnetblog.com/news/emiliano-montesdeoca/vscode-1-116-agents-app-updates/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/news/emiliano-montesdeoca/vscode-1-116-agents-app-updates/</guid><description>VS Code 1.116 focuses on Agents app polish — dedicated keybindings, accessibility improvements, file-context completions, and CSS @import link resolution.</description><content:encoded>&lt;p&gt;VS Code 1.116 is the April 2026 release, and while it&amp;rsquo;s lighter than some recent updates, the changes are focused and meaningful — especially if you&amp;rsquo;re using the Agents app daily.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s what landed, based on the &lt;a href="https://code.visualstudio.com/updates/v1_116"&gt;official release notes&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="agents-app-improvements"&gt;Agents app improvements&lt;/h2&gt;
&lt;p&gt;The Agents app continues to mature with usability polish that makes a real difference in daily workflows:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Dedicated keybindings&lt;/strong&gt; — you can now focus the Changes view, the files tree within Changes, and the Chat Customizations view with dedicated commands and keyboard shortcuts. If you&amp;rsquo;ve been clicking around the Agents app to navigate, this brings full keyboard-driven workflows.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Accessibility help dialog&lt;/strong&gt; — pressing &lt;code&gt;Alt+F1&lt;/code&gt; in the chat input box now opens an accessibility help dialog showing available commands and keybindings. Screen reader users can also control announcement verbosity. Good accessibility benefits everyone.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;File-context completions&lt;/strong&gt; — type &lt;code&gt;#&lt;/code&gt; in the Agents app chat to trigger file-context completions scoped to your current workspace. This is one of those small quality-of-life improvements that speeds up every interaction — no more typing full file paths when referencing code.&lt;/p&gt;
&lt;h2 id="css-import-link-resolution"&gt;CSS &lt;code&gt;@import&lt;/code&gt; link resolution&lt;/h2&gt;
&lt;p&gt;A nice one for frontend developers: VS Code now resolves CSS &lt;code&gt;@import&lt;/code&gt; references that use node_modules paths. You can &lt;code&gt;Ctrl+click&lt;/code&gt; through imports like &lt;code&gt;@import &amp;quot;some-module/style.css&amp;quot;&lt;/code&gt; when using bundlers. Small but eliminates a friction point in CSS workflows.&lt;/p&gt;
&lt;h2 id="wrapping-up"&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;VS Code 1.116 is about refinement — making the Agents app more navigable, more accessible, and more keyboard-friendly. If you&amp;rsquo;re spending significant time in the Agents app (and I suspect many of us are), these changes add up.&lt;/p&gt;
&lt;p&gt;Check the &lt;a href="https://code.visualstudio.com/updates/v1_116"&gt;full release notes&lt;/a&gt; for the complete list.&lt;/p&gt;</content:encoded></item><item><title>azd Now Lets You Run and Debug AI Agents Locally — Here's What Changed in March 2026</title><link>https://thedotnetblog.com/news/emiliano-montesdeoca/azd-march-2026-local-ai-agent-debugging/</link><pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/news/emiliano-montesdeoca/azd-march-2026-local-ai-agent-debugging/</guid><description>The Azure Developer CLI shipped seven releases in March 2026. The highlights: a local run-and-debug loop for AI agents, GitHub Copilot integration in project setup, and Container App Jobs support.</description><content:encoded>&lt;p&gt;Seven releases in one month. That&amp;rsquo;s what the Azure Developer CLI (&lt;code&gt;azd&lt;/code&gt;) team pushed in March 2026, and the headline feature is the one I&amp;rsquo;ve been waiting for: &lt;strong&gt;a local run-and-debug loop for AI agents&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;PC Chan &lt;a href="https://devblogs.microsoft.com/azure-sdk/azure-developer-cli-azd-march-2026/"&gt;published the full roundup&lt;/a&gt;, and while there&amp;rsquo;s a lot in there, let me filter it down to what actually matters for .NET developers building AI-powered apps.&lt;/p&gt;
&lt;h2 id="run-and-debug-ai-agents-without-deploying"&gt;Run and debug AI agents without deploying&lt;/h2&gt;
&lt;p&gt;This is the big one. The new &lt;code&gt;azure.ai.agents&lt;/code&gt; extension adds a set of commands that give you a proper inner-loop experience for AI agents:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;azd ai agent run&lt;/code&gt; — starts your agent locally&lt;/li&gt;
&lt;li&gt;&lt;code&gt;azd ai agent invoke&lt;/code&gt; — sends messages to it (local or deployed)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;azd ai agent show&lt;/code&gt; — displays container status and health&lt;/li&gt;
&lt;li&gt;&lt;code&gt;azd ai agent monitor&lt;/code&gt; — streams container logs in real time&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Before this, testing an AI agent meant deploying to Microsoft Foundry every time you made a change. Now you can iterate locally, test your agent&amp;rsquo;s behavior, and only deploy when you&amp;rsquo;re ready. If you&amp;rsquo;ve been building agents with the Microsoft Agent Framework or Semantic Kernel, this changes your daily workflow.&lt;/p&gt;
&lt;p&gt;The invoke command works against both local and deployed agents, which means you can use the same testing workflow regardless of where the agent is running. That&amp;rsquo;s the kind of detail that saves you from maintaining two sets of test scripts.&lt;/p&gt;
&lt;h2 id="github-copilot-scaffolds-your-azd-project"&gt;GitHub Copilot scaffolds your azd project&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;azd init&lt;/code&gt; now offers a &amp;ldquo;Set up with GitHub Copilot (Preview)&amp;rdquo; option. Instead of manually answering prompts about your project structure, a Copilot agent scaffolds the configuration for you. It checks for a dirty working directory before modifying anything and asks for MCP server tool consent upfront.&lt;/p&gt;
&lt;p&gt;When a command fails, &lt;code&gt;azd&lt;/code&gt; now offers AI-assisted troubleshooting: pick a category (explain, guidance, troubleshoot, or skip), let the agent suggest a fix, and retry — all without leaving the terminal. For complex infrastructure setups, that&amp;rsquo;s a real time saver.&lt;/p&gt;
&lt;h2 id="container-app-jobs-and-deployment-improvements"&gt;Container App Jobs and deployment improvements&lt;/h2&gt;
&lt;p&gt;A few deployment features worth noting:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Container App Jobs&lt;/strong&gt;: &lt;code&gt;azd&lt;/code&gt; now deploys &lt;code&gt;Microsoft.App/jobs&lt;/code&gt; through the existing &lt;code&gt;host: containerapp&lt;/code&gt; config. Your Bicep template determines whether the target is a Container App or a Job — no extra setup.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Configurable deployment timeouts&lt;/strong&gt;: New &lt;code&gt;--timeout&lt;/code&gt; flag on &lt;code&gt;azd deploy&lt;/code&gt; and a &lt;code&gt;deployTimeout&lt;/code&gt; field in &lt;code&gt;azure.yaml&lt;/code&gt;. No more guessing the default 1200-second limit.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Remote build fallback&lt;/strong&gt;: When remote ACR build fails, &lt;code&gt;azd&lt;/code&gt; falls back to local Docker/Podman build automatically.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Local preflight validation&lt;/strong&gt;: Bicep parameters get validated locally before deploying, catching missing params without a round-trip to Azure.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="developer-experience-polish"&gt;Developer experience polish&lt;/h2&gt;
&lt;p&gt;Some smaller improvements that add up:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Automatic pnpm/yarn detection&lt;/strong&gt; for JS/TS projects&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pyproject.toml support&lt;/strong&gt; for Python packaging&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Local template directories&lt;/strong&gt; — &lt;code&gt;azd init --template&lt;/code&gt; now accepts filesystem paths for offline iteration&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Better error messages&lt;/strong&gt; in &lt;code&gt;--no-prompt&lt;/code&gt; mode — all missing values reported at once with resolution commands&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build environment variables&lt;/strong&gt; injected into all framework build subprocesses (.NET, Node.js, Java, Python)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That last one is subtle but important: your .NET build now has access to &lt;code&gt;azd&lt;/code&gt; environment variables, which means you can do build-time configuration injection without extra scripting.&lt;/p&gt;
&lt;h2 id="wrapping-up"&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;The local AI agent debugging loop is the star of this release, but the accumulation of deployment improvements and DX polish makes &lt;code&gt;azd&lt;/code&gt; feel more mature than ever. If you&amp;rsquo;re deploying .NET apps to Azure — especially AI agents — this update is worth the install.&lt;/p&gt;
&lt;p&gt;Check the &lt;a href="https://devblogs.microsoft.com/azure-sdk/azure-developer-cli-azd-march-2026/"&gt;full release notes&lt;/a&gt; for every detail, or get started with &lt;a href="https://learn.microsoft.com/azure/developer/azure-developer-cli/install-azd"&gt;azd install&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>Foundry Agent Service is GA: What Actually Matters for .NET Agent Builders</title><link>https://thedotnetblog.com/news/emiliano-montesdeoca/foundry-agent-service-ga-what-matters/</link><pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/news/emiliano-montesdeoca/foundry-agent-service-ga-what-matters/</guid><description>Microsoft's Foundry Agent Service just hit GA with private networking, Voice Live, production evaluations, and an open multi-model runtime. Here's what you need to know.</description><content:encoded>&lt;p&gt;Let&amp;rsquo;s be honest — building an AI agent prototype is the easy part. The hard part is everything after: getting it into production with proper network isolation, running evaluations that actually mean something, handling compliance requirements, and not breaking things at 2 AM.&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://devblogs.microsoft.com/foundry/foundry-agent-service-ga/"&gt;Foundry Agent Service just went GA&lt;/a&gt;, and this release is laser-focused on that &amp;ldquo;everything after&amp;rdquo; gap.&lt;/p&gt;
&lt;h2 id="built-on-the-responses-api"&gt;Built on the Responses API&lt;/h2&gt;
&lt;p&gt;Here&amp;rsquo;s the headline: the next-gen Foundry Agent Service is built on the OpenAI Responses API. If you&amp;rsquo;re already building with that wire protocol, migrating to Foundry is minimal code changes. What you gain: enterprise security, private networking, Entra RBAC, full tracing, and evaluation — on top of your existing agent logic.&lt;/p&gt;
&lt;p&gt;The architecture is intentionally open. You&amp;rsquo;re not locked to one model provider or one orchestration framework. Use DeepSeek for planning, OpenAI for generation, LangGraph for orchestration — the runtime handles the consistency layer.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;azure.ai.projects&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AIProjectClient&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;azure.ai.projects.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PromptAgentDefinition&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;DefaultAzureCredential&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;AIProjectClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;endpoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;AZURE_AI_PROJECT_ENDPOINT&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;project_client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;project_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_openai_client&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;openai_client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;project_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agents&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;agent_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;my-enterprise-agent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;PromptAgentDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;AZURE_AI_MODEL_DEPLOYMENT_NAME&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;instructions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;You are a helpful assistant.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;conversation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openai_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conversations&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openai_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;responses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;conversation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;conversation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;What are best practices for building AI agents?&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;extra_body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;agent_reference&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;agent_reference&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output_text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;If you&amp;rsquo;re coming from the &lt;code&gt;azure-ai-agents&lt;/code&gt; package, agents are now first-class operations on &lt;code&gt;AIProjectClient&lt;/code&gt; in &lt;code&gt;azure-ai-projects&lt;/code&gt;. Drop the standalone pin and use &lt;code&gt;get_openai_client()&lt;/code&gt; to drive responses.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="private-networking-the-enterprise-blocker-removed"&gt;Private networking: the enterprise blocker removed&lt;/h2&gt;
&lt;p&gt;This is the feature that unblocks enterprise adoption. Foundry now supports full end-to-end private networking with BYO VNet:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;No public egress&lt;/strong&gt; — agent traffic never touches the public internet&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Container/subnet injection&lt;/strong&gt; into your network for local communication&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tool connectivity included&lt;/strong&gt; — MCP servers, Azure AI Search, Fabric data agents all operate over private paths&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That last point is critical. It&amp;rsquo;s not just inference calls that stay private — every tool invocation and retrieval call stays inside your network boundary too. For teams operating under data classification policies that prohibit external routing, this is what was missing.&lt;/p&gt;
&lt;h2 id="mcp-authentication-done-right"&gt;MCP authentication done right&lt;/h2&gt;
&lt;p&gt;MCP server connections now support the full spectrum of auth patterns:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Auth method&lt;/th&gt;
&lt;th&gt;When to use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Key-based&lt;/td&gt;
&lt;td&gt;Simple shared access for org-wide internal tools&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Entra Agent Identity&lt;/td&gt;
&lt;td&gt;Service-to-service; the agent authenticates as itself&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Entra Managed Identity&lt;/td&gt;
&lt;td&gt;Per-project isolation; no credential management&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OAuth Identity Passthrough&lt;/td&gt;
&lt;td&gt;User-delegated access; agent acts on behalf of users&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;OAuth Identity Passthrough is the interesting one. When users need to grant an agent access to their personal data — their OneDrive, their Salesforce org, a SaaS API scoped by user — the agent acts on their behalf with standard OAuth flows. No shared system identity pretending to be everyone.&lt;/p&gt;
&lt;h2 id="voice-live-speech-to-speech-without-the-plumbing"&gt;Voice Live: speech-to-speech without the plumbing&lt;/h2&gt;
&lt;p&gt;Adding voice to an agent used to mean stitching together STT, LLM, and TTS — three services, three latency hops, three billing surfaces, all synchronized by hand. &lt;strong&gt;Voice Live&lt;/strong&gt; collapses that into a single managed API with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Semantic voice activity and end-of-turn detection (understands meaning, not just silence)&lt;/li&gt;
&lt;li&gt;Server-side noise suppression and echo cancellation&lt;/li&gt;
&lt;li&gt;Barge-in support (users can interrupt mid-response)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Voice interactions go through the same agent runtime as text. Same evaluators, same traces, same cost visibility. For customer support, field service, or accessibility scenarios, this replaces what previously required a custom audio pipeline.&lt;/p&gt;
&lt;h2 id="evaluations-from-checkbox-to-continuous-monitoring"&gt;Evaluations: from checkbox to continuous monitoring&lt;/h2&gt;
&lt;p&gt;This is where Foundry gets serious about production quality. The evaluation system now has three layers:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Out-of-the-box evaluators&lt;/strong&gt; — coherence, relevance, groundedness, retrieval quality, safety. Connect to a dataset or live traffic and get scores back.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Custom evaluators&lt;/strong&gt; — encode your own business logic, tone standards, and domain-specific compliance rules.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Continuous evaluation&lt;/strong&gt; — Foundry samples live production traffic, runs your evaluator suite, and surfaces results through dashboards. Set Azure Monitor alerts for when groundedness drops or safety thresholds breach.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Everything publishes to Azure Monitor Application Insights. Agent quality, infrastructure health, cost, and app telemetry — all in one place.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;eval_object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openai_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;evals&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Agent Quality Evaluation&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;data_source_config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;DataSourceConfigCustom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;custom&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;item_schema&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;object&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;properties&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;query&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;required&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;query&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;include_sample_schema&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;testing_criteria&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;azure_ai_evaluator&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;fluency&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;evaluator_name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;builtin.fluency&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;initialization_parameters&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;deployment_name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;AZURE_AI_MODEL_DEPLOYMENT_NAME&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;data_mapping&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;query&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;{{item.query}}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;response&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;{{sample.output_text}}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="six-new-regions-for-hosted-agents"&gt;Six new regions for hosted agents&lt;/h2&gt;
&lt;p&gt;Hosted agents are now available in East US, North Central US, Sweden Central, Southeast Asia, Japan East, and more. This matters for data residency requirements and for compressing latency when your agent runs close to its data sources.&lt;/p&gt;
&lt;h2 id="why-this-matters-for-net-developers"&gt;Why this matters for .NET developers&lt;/h2&gt;
&lt;p&gt;Even though the code samples in the GA announcement are Python-first, the underlying infrastructure is language-agnostic — and the .NET SDK for &lt;code&gt;azure-ai-projects&lt;/code&gt; follows the same patterns. The Responses API, the evaluation framework, the private networking, the MCP auth — all of this is available from .NET.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;ve been waiting for AI agents to go from &amp;ldquo;cool demo&amp;rdquo; to &amp;ldquo;I can actually ship this at work,&amp;rdquo; this GA release is the signal. Private networking, proper auth, continuous evaluation, and production monitoring are the pieces that were missing.&lt;/p&gt;
&lt;h2 id="wrapping-up"&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;Foundry Agent Service is available now. Install the SDK, open &lt;a href="https://ai.azure.com"&gt;the portal&lt;/a&gt;, and start building. The &lt;a href="https://learn.microsoft.com/azure/foundry/quickstarts/get-started-code"&gt;quickstart guide&lt;/a&gt; takes you from zero to a running agent in minutes.&lt;/p&gt;
&lt;p&gt;For the full technical deep-dive with all code samples, check the &lt;a href="https://devblogs.microsoft.com/foundry/foundry-agent-service-ga/"&gt;GA announcement&lt;/a&gt;.&lt;/p&gt;</content:encoded></item></channel></rss>