ChatClientAgent working

This commit is contained in:
Roger Barreto
2026-04-11 13:03:55 +01:00
Unverified
parent eb7f8617c1
commit a82c1ede09
5 changed files with 60 additions and 5 deletions
@@ -32,4 +32,11 @@ builder.Services.AddFoundryResponses(agent);
var app = builder.Build();
app.MapFoundryResponses();
// In Development, also map the OpenAI-compatible route that AIProjectClient uses.
if (app.Environment.IsDevelopment())
{
app.MapFoundryResponses("openai/v1");
}
app.Run();
@@ -29,4 +29,11 @@ builder.Services.AddFoundryResponses(agent);
var app = builder.Build();
app.MapFoundryResponses();
// In Development, also map the OpenAI-compatible route that AIProjectClient uses.
if (app.Environment.IsDevelopment())
{
app.MapFoundryResponses("openai/v1");
}
app.Run();
@@ -1,5 +1,6 @@
// Copyright (c) Microsoft. All rights reserved.
using System.ClientModel.Primitives;
using Azure.AI.Projects;
using Azure.Identity;
using DotNetEnv;
@@ -11,9 +12,21 @@ Env.TraversePath().Load();
string agentEndpoint = Environment.GetEnvironmentVariable("AGENT_ENDPOINT") ?? "http://localhost:8088";
// ── Create an agent-framework agent backed by the remote agent endpoint ──────
// The Foundry Agent SDK's AIProjectClient can target any OpenAI-compatible endpoint.
var aiProjectClient = new AIProjectClient(new Uri(agentEndpoint), new AzureCliCredential());
var endpointUri = new Uri(agentEndpoint);
var options = new AIProjectClientOptions();
// For local HTTP dev: tell AIProjectClient the endpoint is HTTPS (to satisfy
// BearerTokenPolicy's TLS check), then swap the scheme back to HTTP right
// before the request hits the wire.
Uri clientEndpoint = endpointUri;
if (endpointUri.Scheme == "http")
{
clientEndpoint = new UriBuilder(endpointUri) { Scheme = "https" }.Uri;
options.AddPolicy(new HttpSchemeRewritePolicy(), PipelinePosition.BeforeTransport);
}
var aiProjectClient = new AIProjectClient(clientEndpoint, new AzureCliCredential(), options);
var agent = aiProjectClient.AsAIAgent();
AgentSession session = await agent.CreateSessionAsync();
@@ -66,3 +79,31 @@ while (true)
}
Console.WriteLine("Goodbye!");
/// <summary>
/// Rewrites HTTPS URIs to HTTP right before transport, allowing AIProjectClient
/// to target a local HTTP dev server while satisfying BearerTokenPolicy's TLS check.
/// </summary>
internal sealed class HttpSchemeRewritePolicy : PipelinePolicy
{
public override void Process(PipelineMessage message, IReadOnlyList<PipelinePolicy> pipeline, int currentIndex)
{
RewriteScheme(message);
ProcessNext(message, pipeline, currentIndex);
}
public override async ValueTask ProcessAsync(PipelineMessage message, IReadOnlyList<PipelinePolicy> pipeline, int currentIndex)
{
RewriteScheme(message);
await ProcessNextAsync(message, pipeline, currentIndex).ConfigureAwait(false);
}
private static void RewriteScheme(PipelineMessage message)
{
var uri = message.Request.Uri!;
if (uri.Scheme == Uri.UriSchemeHttps)
{
message.Request.Uri = new UriBuilder(uri) { Scheme = "http" }.Uri;
}
}
}
@@ -12,6 +12,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.AI.Projects" />
<PackageReference Include="Azure.Identity" />
<PackageReference Include="DotNetEnv" />
</ItemGroup>
@@ -13,7 +13,6 @@ using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Foundry;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Shared.DiagnosticIds;
using Microsoft.Shared.Diagnostics;
using OpenAI.Responses;
@@ -230,8 +229,7 @@ public static partial class AzureAIProjectChatClientExtensions
{
Throw.IfNull(aiProjectClient);
Throw.IfNull(agentOptions);
Throw.IfNull(agentOptions.ChatOptions);
Throw.IfNullOrWhitespace(agentOptions.ChatOptions.ModelId);
agentOptions.ChatOptions ??= new();
IChatClient chatClient = aiProjectClient
.GetProjectOpenAIClient()