.NET: [Breaking] RenameAgentRunResponse and AgentRunResponseUpdate classes (#3197)

* rename AgentRunResponse and AgentRunResponseUpdate classes - part1

* rename varialbles, parameters, methods and tests

* rollback unnecessary changes
This commit is contained in:
SergeyMenshykh
2026-01-14 10:27:41 +00:00
committed by GitHub
parent 8b1449024e
commit c70e594e6c
189 changed files with 1002 additions and 1002 deletions
@@ -19,7 +19,7 @@ AIAgent agent = agentCard.GetAIAgent();
AgentThread thread = await agent.GetNewThreadAsync();
// Start the initial run with a long-running task.
AgentRunResponse response = await agent.RunAsync("Conduct a comprehensive analysis of quantum computing applications in cryptography, including recent breakthroughs, implementation challenges, and future roadmap. Please include diagrams and visual representations to illustrate complex concepts.", thread);
AgentResponse response = await agent.RunAsync("Conduct a comprehensive analysis of quantum computing applications in cryptography, including recent breakthroughs, implementation challenges, and future roadmap. Please include diagrams and visual representations to illustrate complex concepts.", thread);
// Poll until the response is complete.
while (response.ContinuationToken is { } token)
+1 -1
View File
@@ -212,7 +212,7 @@ dotnet run
1. `AGUIAgent` sends HTTP POST request to server
2. Server responds with SSE stream
3. Client parses events into `AgentRunResponseUpdate` objects
3. Client parses events into `AgentResponseUpdate` objects
4. Updates are displayed based on content type
5. `ConversationId` maintains conversation context
@@ -51,7 +51,7 @@ try
bool isFirstUpdate = true;
string? threadId = null;
await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync(messages, thread))
await foreach (AgentResponseUpdate update in agent.RunStreamingAsync(messages, thread))
{
ChatResponseUpdate chatUpdate = update.AsChatResponseUpdate();
@@ -51,7 +51,7 @@ try
bool isFirstUpdate = true;
string? threadId = null;
await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync(messages, thread))
await foreach (AgentResponseUpdate update in agent.RunStreamingAsync(messages, thread))
{
ChatResponseUpdate chatUpdate = update.AsChatResponseUpdate();
@@ -64,7 +64,7 @@ try
bool isFirstUpdate = true;
string? threadId = null;
await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync(messages, thread))
await foreach (AgentResponseUpdate update in agent.RunStreamingAsync(messages, thread))
{
ChatResponseUpdate chatUpdate = update.AsChatResponseUpdate();
@@ -51,8 +51,8 @@ while ((input = Console.ReadLine()) != null && !input.Equals("exit", StringCompa
{
approvalResponses.Clear();
List<AgentRunResponseUpdate> chatResponseUpdates = [];
await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync(messages, thread, cancellationToken: default))
List<AgentResponseUpdate> chatResponseUpdates = [];
await foreach (AgentResponseUpdate update in agent.RunStreamingAsync(messages, thread, cancellationToken: default))
{
chatResponseUpdates.Add(update);
foreach (AIContent content in update.Contents)
@@ -111,7 +111,7 @@ while ((input = Console.ReadLine()) != null && !input.Equals("exit", StringCompa
}
}
AgentRunResponse response = chatResponseUpdates.ToAgentRunResponse();
AgentResponse response = chatResponseUpdates.ToAgentResponse();
messages.AddRange(response.Messages);
foreach (AIContent approvalResponse in approvalResponses)
{
@@ -22,17 +22,17 @@ internal sealed class ServerFunctionApprovalClientAgent : DelegatingAIAgent
this._jsonSerializerOptions = jsonSerializerOptions;
}
protected override Task<AgentRunResponse> RunCoreAsync(
protected override Task<AgentResponse> RunCoreAsync(
IEnumerable<ChatMessage> messages,
AgentThread? thread = null,
AgentRunOptions? options = null,
CancellationToken cancellationToken = default)
{
return this.RunCoreStreamingAsync(messages, thread, options, cancellationToken)
.ToAgentRunResponseAsync(cancellationToken);
.ToAgentResponseAsync(cancellationToken);
}
protected override async IAsyncEnumerable<AgentRunResponseUpdate> RunCoreStreamingAsync(
protected override async IAsyncEnumerable<AgentResponseUpdate> RunCoreStreamingAsync(
IEnumerable<ChatMessage> messages,
AgentThread? thread = null,
AgentRunOptions? options = null,
@@ -166,8 +166,8 @@ internal sealed class ServerFunctionApprovalClientAgent : DelegatingAIAgent
return result ?? messages;
}
private static AgentRunResponseUpdate ProcessIncomingServerApprovalRequests(
AgentRunResponseUpdate update,
private static AgentResponseUpdate ProcessIncomingServerApprovalRequests(
AgentResponseUpdate update,
JsonSerializerOptions jsonSerializerOptions)
{
IList<AIContent>? updatedContents = null;
@@ -215,7 +215,7 @@ internal sealed class ServerFunctionApprovalClientAgent : DelegatingAIAgent
if (updatedContents is not null)
{
var chatUpdate = update.AsChatResponseUpdate();
return new AgentRunResponseUpdate(new ChatResponseUpdate()
return new AgentResponseUpdate(new ChatResponseUpdate()
{
Role = chatUpdate.Role,
Contents = updatedContents,
@@ -22,17 +22,17 @@ internal sealed class ServerFunctionApprovalAgent : DelegatingAIAgent
this._jsonSerializerOptions = jsonSerializerOptions;
}
protected override Task<AgentRunResponse> RunCoreAsync(
protected override Task<AgentResponse> RunCoreAsync(
IEnumerable<ChatMessage> messages,
AgentThread? thread = null,
AgentRunOptions? options = null,
CancellationToken cancellationToken = default)
{
return this.RunCoreStreamingAsync(messages, thread, options, cancellationToken)
.ToAgentRunResponseAsync(cancellationToken);
.ToAgentResponseAsync(cancellationToken);
}
protected override async IAsyncEnumerable<AgentRunResponseUpdate> RunCoreStreamingAsync(
protected override async IAsyncEnumerable<AgentResponseUpdate> RunCoreStreamingAsync(
IEnumerable<ChatMessage> messages,
AgentThread? thread = null,
AgentRunOptions? options = null,
@@ -172,8 +172,8 @@ internal sealed class ServerFunctionApprovalAgent : DelegatingAIAgent
return result ?? messages;
}
private static AgentRunResponseUpdate ProcessOutgoingApprovalRequests(
AgentRunResponseUpdate update,
private static AgentResponseUpdate ProcessOutgoingApprovalRequests(
AgentResponseUpdate update,
JsonSerializerOptions jsonSerializerOptions)
{
IList<AIContent>? updatedContents = null;
@@ -207,7 +207,7 @@ internal sealed class ServerFunctionApprovalAgent : DelegatingAIAgent
{
var chatUpdate = update.AsChatResponseUpdate();
// Yield a tool call update that represents the approval request
return new AgentRunResponseUpdate(new ChatResponseUpdate()
return new AgentResponseUpdate(new ChatResponseUpdate()
{
Role = chatUpdate.Role,
Contents = updatedContents,
@@ -70,7 +70,7 @@ try
Console.WriteLine();
await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync(messages, thread))
await foreach (AgentResponseUpdate update in agent.RunStreamingAsync(messages, thread))
{
ChatResponseUpdate chatUpdate = update.AsChatResponseUpdate();
@@ -35,18 +35,18 @@ internal sealed class StatefulAgent<TState> : DelegatingAIAgent
}
/// <inheritdoc />
protected override Task<AgentRunResponse> RunCoreAsync(
protected override Task<AgentResponse> RunCoreAsync(
IEnumerable<ChatMessage> messages,
AgentThread? thread = null,
AgentRunOptions? options = null,
CancellationToken cancellationToken = default)
{
return this.RunCoreStreamingAsync(messages, thread, options, cancellationToken)
.ToAgentRunResponseAsync(cancellationToken);
.ToAgentResponseAsync(cancellationToken);
}
/// <inheritdoc />
protected override async IAsyncEnumerable<AgentRunResponseUpdate> RunCoreStreamingAsync(
protected override async IAsyncEnumerable<AgentResponseUpdate> RunCoreStreamingAsync(
IEnumerable<ChatMessage> messages,
AgentThread? thread = null,
AgentRunOptions? options = null,
@@ -64,7 +64,7 @@ internal sealed class StatefulAgent<TState> : DelegatingAIAgent
messagesWithState.Add(stateMessage);
// Stream the response and update state when received
await foreach (AgentRunResponseUpdate update in this.InnerAgent.RunStreamingAsync(messagesWithState, thread, options, cancellationToken))
await foreach (AgentResponseUpdate update in this.InnerAgent.RunStreamingAsync(messagesWithState, thread, options, cancellationToken))
{
// Check if this update contains a state snapshot
foreach (AIContent content in update.Contents)
@@ -17,17 +17,17 @@ internal sealed class SharedStateAgent : DelegatingAIAgent
this._jsonSerializerOptions = jsonSerializerOptions;
}
protected override Task<AgentRunResponse> RunCoreAsync(
protected override Task<AgentResponse> RunCoreAsync(
IEnumerable<ChatMessage> messages,
AgentThread? thread = null,
AgentRunOptions? options = null,
CancellationToken cancellationToken = default)
{
return this.RunCoreStreamingAsync(messages, thread, options, cancellationToken)
.ToAgentRunResponseAsync(cancellationToken);
.ToAgentResponseAsync(cancellationToken);
}
protected override async IAsyncEnumerable<AgentRunResponseUpdate> RunCoreStreamingAsync(
protected override async IAsyncEnumerable<AgentResponseUpdate> RunCoreStreamingAsync(
IEnumerable<ChatMessage> messages,
AgentThread? thread = null,
AgentRunOptions? options = null,
@@ -91,7 +91,7 @@ internal sealed class SharedStateAgent : DelegatingAIAgent
var firstRunMessages = messages.Append(stateUpdateMessage);
// Collect all updates from first run
var allUpdates = new List<AgentRunResponseUpdate>();
var allUpdates = new List<AgentResponseUpdate>();
await foreach (var update in this.InnerAgent.RunStreamingAsync(firstRunMessages, thread, firstRunOptions, cancellationToken).ConfigureAwait(false))
{
allUpdates.Add(update);
@@ -104,7 +104,7 @@ internal sealed class SharedStateAgent : DelegatingAIAgent
}
}
var response = allUpdates.ToAgentRunResponse();
var response = allUpdates.ToAgentResponse();
// Try to deserialize the structured state response
if (response.TryDeserialize(this._jsonSerializerOptions, out JsonElement stateSnapshot))
@@ -113,7 +113,7 @@ internal sealed class SharedStateAgent : DelegatingAIAgent
byte[] stateBytes = JsonSerializer.SerializeToUtf8Bytes(
stateSnapshot,
this._jsonSerializerOptions.GetTypeInfo(typeof(JsonElement)));
yield return new AgentRunResponseUpdate
yield return new AgentResponseUpdate
{
Contents = [new DataContent(stateBytes, "application/json")]
};
@@ -14,5 +14,5 @@ A2ACardResolver agentCardResolver = new(new Uri(a2aAgentHost));
AIAgent agent = await agentCardResolver.GetAIAgentAsync();
// Invoke the agent and output the text result.
AgentRunResponse response = await agent.RunAsync("Tell me a joke about a pirate.");
AgentResponse response = await agent.RunAsync("Tell me a joke about a pirate.");
Console.WriteLine(response);
@@ -29,6 +29,6 @@ A2AClient a2aClient = new(new Uri("https://your-a2a-agent-host/echo"));
AIAgent agent = a2aClient.GetAIAgent();
// Run the agent
AgentRunResponse response = await agent.RunAsync("Tell me a joke about a pirate.");
AgentResponse response = await agent.RunAsync("Tell me a joke about a pirate.");
Console.WriteLine(response);
```
@@ -34,7 +34,7 @@ namespace SampleApp
public override ValueTask<AgentThread> DeserializeThreadAsync(JsonElement serializedThread, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
=> new(new CustomAgentThread(serializedThread, jsonSerializerOptions));
protected override async Task<AgentRunResponse> RunCoreAsync(IEnumerable<ChatMessage> messages, AgentThread? thread = null, AgentRunOptions? options = null, CancellationToken cancellationToken = default)
protected override async Task<AgentResponse> RunCoreAsync(IEnumerable<ChatMessage> messages, AgentThread? thread = null, AgentRunOptions? options = null, CancellationToken cancellationToken = default)
{
// Create a thread if the user didn't supply one.
thread ??= await this.GetNewThreadAsync(cancellationToken);
@@ -58,7 +58,7 @@ namespace SampleApp
};
await typedThread.MessageStore.InvokedAsync(invokedContext, cancellationToken);
return new AgentRunResponse
return new AgentResponse
{
AgentId = this.Id,
ResponseId = Guid.NewGuid().ToString("N"),
@@ -66,7 +66,7 @@ namespace SampleApp
};
}
protected override async IAsyncEnumerable<AgentRunResponseUpdate> RunCoreStreamingAsync(IEnumerable<ChatMessage> messages, AgentThread? thread = null, AgentRunOptions? options = null, [EnumeratorCancellation] CancellationToken cancellationToken = default)
protected override async IAsyncEnumerable<AgentResponseUpdate> RunCoreStreamingAsync(IEnumerable<ChatMessage> messages, AgentThread? thread = null, AgentRunOptions? options = null, [EnumeratorCancellation] CancellationToken cancellationToken = default)
{
// Create a thread if the user didn't supply one.
thread ??= await this.GetNewThreadAsync(cancellationToken);
@@ -92,7 +92,7 @@ namespace SampleApp
foreach (var message in responseMessages)
{
yield return new AgentRunResponseUpdate
yield return new AgentResponseUpdate
{
AgentId = this.Id,
AuthorName = message.AuthorName,
@@ -22,7 +22,7 @@ ChatClientAgent agentGenAI = new(
name: JokerName,
instructions: JokerInstructions);
AgentRunResponse response = await agentGenAI.RunAsync("Tell me a joke about a pirate.");
AgentResponse response = await agentGenAI.RunAsync("Tell me a joke about a pirate.");
Console.WriteLine($"Google GenAI client based agent response:\n{response}");
// Using a community driven Mscc.GenerativeAI.Microsoft package
@@ -31,7 +31,7 @@ Console.WriteLine(await agent.RunAsync("What is the weather like in Amsterdam?",
// Streaming agent interaction with function tools.
thread = await agent.GetNewThreadAsync();
await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync("What is the weather like in Amsterdam?", thread))
await foreach (AgentResponseUpdate update in agent.RunStreamingAsync("What is the weather like in Amsterdam?", thread))
{
Console.WriteLine(update);
}
@@ -87,10 +87,10 @@ public class OpenAIChatClientAgent : DelegatingAIAgent
}
/// <inheritdoc/>
protected sealed override Task<AgentRunResponse> RunCoreAsync(IEnumerable<Microsoft.Extensions.AI.ChatMessage> messages, AgentThread? thread = null, AgentRunOptions? options = null, CancellationToken cancellationToken = default) =>
protected sealed override Task<AgentResponse> RunCoreAsync(IEnumerable<Microsoft.Extensions.AI.ChatMessage> messages, AgentThread? thread = null, AgentRunOptions? options = null, CancellationToken cancellationToken = default) =>
base.RunCoreAsync(messages, thread, options, cancellationToken);
/// <inheritdoc/>
protected override IAsyncEnumerable<AgentRunResponseUpdate> RunCoreStreamingAsync(IEnumerable<Microsoft.Extensions.AI.ChatMessage> messages, AgentThread? thread = null, AgentRunOptions? options = null, CancellationToken cancellationToken = default) =>
protected override IAsyncEnumerable<AgentResponseUpdate> RunCoreStreamingAsync(IEnumerable<Microsoft.Extensions.AI.ChatMessage> messages, AgentThread? thread = null, AgentRunOptions? options = null, CancellationToken cancellationToken = default) =>
base.RunCoreStreamingAsync(messages, thread, options, cancellationToken);
}
@@ -105,10 +105,10 @@ public class OpenAIResponseClientAgent : DelegatingAIAgent
}
/// <inheritdoc/>
protected sealed override Task<AgentRunResponse> RunCoreAsync(IEnumerable<ChatMessage> messages, AgentThread? thread = null, AgentRunOptions? options = null, CancellationToken cancellationToken = default) =>
protected sealed override Task<AgentResponse> RunCoreAsync(IEnumerable<ChatMessage> messages, AgentThread? thread = null, AgentRunOptions? options = null, CancellationToken cancellationToken = default) =>
base.RunCoreAsync(messages, thread, options, cancellationToken);
/// <inheritdoc/>
protected sealed override IAsyncEnumerable<AgentRunResponseUpdate> RunCoreStreamingAsync(IEnumerable<ChatMessage> messages, AgentThread? thread = null, AgentRunOptions? options = null, CancellationToken cancellationToken = default) =>
protected sealed override IAsyncEnumerable<AgentResponseUpdate> RunCoreStreamingAsync(IEnumerable<ChatMessage> messages, AgentThread? thread = null, AgentRunOptions? options = null, CancellationToken cancellationToken = default) =>
base.RunCoreStreamingAsync(messages, thread, options, cancellationToken);
}
@@ -64,4 +64,4 @@ while (userInputRequests.Count > 0)
Console.WriteLine($"\nAgent: {response}");
// For streaming use:
// Console.WriteLine($"\nAgent: {updates.ToAgentRunResponse()}");
// Console.WriteLine($"\nAgent: {updates.ToAgentResponse()}");
@@ -24,7 +24,7 @@ ChatClient chatClient = new AzureOpenAIClient(
ChatClientAgent agent = chatClient.CreateAIAgent(name: "HelpfulAssistant", instructions: "You are a helpful assistant.");
// Set PersonInfo as the type parameter of RunAsync method to specify the expected structured output from the agent and invoke the agent with some unstructured input.
AgentRunResponse<PersonInfo> response = await agent.RunAsync<PersonInfo>("Please provide information about John Smith, who is a 35-year-old software engineer.");
AgentResponse<PersonInfo> response = await agent.RunAsync<PersonInfo>("Please provide information about John Smith, who is a 35-year-old software engineer.");
// Access the structured output via the Result property of the agent response.
Console.WriteLine("Assistant Output:");
@@ -44,7 +44,7 @@ var updates = agentWithPersonInfo.RunStreamingAsync("Please provide information
// Assemble all the parts of the streamed output, since we can only deserialize once we have the full json,
// then deserialize the response into the PersonInfo class.
PersonInfo personInfo = (await updates.ToAgentRunResponseAsync()).Deserialize<PersonInfo>(JsonSerializerOptions.Web);
PersonInfo personInfo = (await updates.ToAgentResponseAsync()).Deserialize<PersonInfo>(JsonSerializerOptions.Web);
Console.WriteLine("Assistant Output:");
Console.WriteLine($"Name: {personInfo.Name}");
@@ -35,7 +35,7 @@ AgentRunOptions options = new() { AllowBackgroundResponses = true };
AgentThread thread = await agent.GetNewThreadAsync();
// Start the initial run.
AgentRunResponse response = await agent.RunAsync("Write a very long novel about a team of astronauts exploring an uncharted galaxy.", thread, options);
AgentResponse response = await agent.RunAsync("Write a very long novel about a team of astronauts exploring an uncharted galaxy.", thread, options);
// Poll for background responses until complete.
while (response.ContinuationToken is not null)
@@ -131,7 +131,7 @@ async ValueTask<object?> PerRequestFunctionCallingMiddleware(AIAgent agent, Func
}
// This middleware redacts PII information from input and output messages.
async Task<AgentRunResponse> PIIMiddleware(IEnumerable<ChatMessage> messages, AgentThread? thread, AgentRunOptions? options, AIAgent innerAgent, CancellationToken cancellationToken)
async Task<AgentResponse> PIIMiddleware(IEnumerable<ChatMessage> messages, AgentThread? thread, AgentRunOptions? options, AIAgent innerAgent, CancellationToken cancellationToken)
{
// Redact PII information from input messages
var filteredMessages = FilterMessages(messages);
@@ -171,7 +171,7 @@ async Task<AgentRunResponse> PIIMiddleware(IEnumerable<ChatMessage> messages, Ag
}
// This middleware enforces guardrails by redacting certain keywords from input and output messages.
async Task<AgentRunResponse> GuardrailMiddleware(IEnumerable<ChatMessage> messages, AgentThread? thread, AgentRunOptions? options, AIAgent innerAgent, CancellationToken cancellationToken)
async Task<AgentResponse> GuardrailMiddleware(IEnumerable<ChatMessage> messages, AgentThread? thread, AgentRunOptions? options, AIAgent innerAgent, CancellationToken cancellationToken)
{
// Redact keywords from input messages
var filteredMessages = FilterMessages(messages);
@@ -208,7 +208,7 @@ async Task<AgentRunResponse> GuardrailMiddleware(IEnumerable<ChatMessage> messag
}
// This middleware handles Human in the loop console interaction for any user approval required during function calling.
async Task<AgentRunResponse> ConsolePromptingApprovalMiddleware(IEnumerable<ChatMessage> messages, AgentThread? thread, AgentRunOptions? options, AIAgent innerAgent, CancellationToken cancellationToken)
async Task<AgentResponse> ConsolePromptingApprovalMiddleware(IEnumerable<ChatMessage> messages, AgentThread? thread, AgentRunOptions? options, AIAgent innerAgent, CancellationToken cancellationToken)
{
var response = await innerAgent.RunAsync(messages, thread, options, cancellationToken);
@@ -22,7 +22,7 @@ AgentRunOptions options = new() { AllowBackgroundResponses = true };
AgentThread thread = await agent.GetNewThreadAsync();
// Start the initial run.
AgentRunResponse response = await agent.RunAsync("Write a very long novel about otters in space.", thread, options);
AgentResponse response = await agent.RunAsync("Write a very long novel about otters in space.", thread, options);
// Poll until the response is complete.
while (response.ContinuationToken is { } token)
@@ -43,9 +43,9 @@ Console.WriteLine(response.Text);
options = new() { AllowBackgroundResponses = true };
thread = await agent.GetNewThreadAsync();
AgentRunResponseUpdate? lastReceivedUpdate = null;
AgentResponseUpdate? lastReceivedUpdate = null;
// Start streaming.
await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync("Write a very long novel about otters in space.", thread, options))
await foreach (AgentResponseUpdate update in agent.RunStreamingAsync("Write a very long novel about otters in space.", thread, options))
{
// Output each update.
Console.Write(update.Text);
@@ -63,7 +63,7 @@ await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync("Write a
// Resume from interruption point.
options.ContinuationToken = lastReceivedUpdate?.ContinuationToken;
await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync(thread, options))
await foreach (AgentResponseUpdate update in agent.RunStreamingAsync(thread, options))
{
// Output each update.
Console.Write(update.Text);
@@ -27,7 +27,7 @@ AgentVersion agentVersion = aiProjectClient.Agents.CreateAgentVersion(agentName:
AIAgent jokerAgent = aiProjectClient.GetAIAgent(agentVersion);
// Invoke the agent with streaming support.
await foreach (AgentRunResponseUpdate update in jokerAgent.RunStreamingAsync("Tell me a joke about a pirate."))
await foreach (AgentResponseUpdate update in jokerAgent.RunStreamingAsync("Tell me a joke about a pirate."))
{
Console.WriteLine(update);
}
@@ -32,11 +32,11 @@ Console.WriteLine(await jokerAgent.RunAsync("Now add some emojis to the joke and
// Invoke the agent with a multi-turn conversation and streaming, where the context is preserved in the thread object.
thread = await jokerAgent.GetNewThreadAsync();
await foreach (AgentRunResponseUpdate update in jokerAgent.RunStreamingAsync("Tell me a joke about a pirate.", thread))
await foreach (AgentResponseUpdate update in jokerAgent.RunStreamingAsync("Tell me a joke about a pirate.", thread))
{
Console.WriteLine(update);
}
await foreach (AgentRunResponseUpdate update in jokerAgent.RunStreamingAsync("Now add some emojis to the joke and tell it in the voice of a pirate's parrot.", thread))
await foreach (AgentResponseUpdate update in jokerAgent.RunStreamingAsync("Now add some emojis to the joke and tell it in the voice of a pirate's parrot.", thread))
{
Console.WriteLine(update);
}
@@ -42,7 +42,7 @@ Console.WriteLine(await existingAgent.RunAsync("What is the weather like in Amst
// Streaming agent interaction with function tools.
thread = await existingAgent.GetNewThreadAsync();
await foreach (AgentRunResponseUpdate update in existingAgent.RunStreamingAsync("What is the weather like in Amsterdam?", thread))
await foreach (AgentResponseUpdate update in existingAgent.RunStreamingAsync("What is the weather like in Amsterdam?", thread))
{
Console.WriteLine(update);
}
@@ -33,7 +33,7 @@ AIAgent agent = await aiProjectClient.CreateAIAgentAsync(name: AssistantName, mo
// Call the agent with approval-required function tools.
// The agent will request approval before invoking the function.
AgentThread thread = await agent.GetNewThreadAsync();
AgentRunResponse response = await agent.RunAsync("What is the weather like in Amsterdam?", thread);
AgentResponse response = await agent.RunAsync("What is the weather like in Amsterdam?", thread);
// Check if there are any user input requests (approvals needed).
List<UserInputRequestContent> userInputRequests = response.UserInputRequests.ToList();
@@ -35,7 +35,7 @@ ChatClientAgent agent = await aiProjectClient.CreateAIAgentAsync(
});
// Set PersonInfo as the type parameter of RunAsync method to specify the expected structured output from the agent and invoke the agent with some unstructured input.
AgentRunResponse<PersonInfo> response = await agent.RunAsync<PersonInfo>("Please provide information about John Smith, who is a 35-year-old software engineer.");
AgentResponse<PersonInfo> response = await agent.RunAsync<PersonInfo>("Please provide information about John Smith, who is a 35-year-old software engineer.");
// Access the structured output via the Result property of the agent response.
Console.WriteLine("Assistant Output:");
@@ -57,11 +57,11 @@ ChatClientAgent agentWithPersonInfo = aiProjectClient.CreateAIAgent(
});
// Invoke the agent with some unstructured input while streaming, to extract the structured information from.
IAsyncEnumerable<AgentRunResponseUpdate> updates = agentWithPersonInfo.RunStreamingAsync("Please provide information about John Smith, who is a 35-year-old software engineer.");
IAsyncEnumerable<AgentResponseUpdate> updates = agentWithPersonInfo.RunStreamingAsync("Please provide information about John Smith, who is a 35-year-old software engineer.");
// Assemble all the parts of the streamed output, since we can only deserialize once we have the full json,
// then deserialize the response into the PersonInfo class.
PersonInfo personInfo = (await updates.ToAgentRunResponseAsync()).Deserialize<PersonInfo>(JsonSerializerOptions.Web);
PersonInfo personInfo = (await updates.ToAgentResponseAsync()).Deserialize<PersonInfo>(JsonSerializerOptions.Web);
Console.WriteLine("Assistant Output:");
Console.WriteLine($"Name: {personInfo.Name}");
@@ -43,7 +43,7 @@ Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate.", thread)
// Invoke the agent with streaming support.
thread = await agent.GetNewThreadAsync();
await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync("Tell me a joke about a pirate.", thread))
await foreach (AgentResponseUpdate update in agent.RunStreamingAsync("Tell me a joke about a pirate.", thread))
{
Console.WriteLine(update);
}
@@ -65,7 +65,7 @@ internal sealed class SampleService(AIProjectClient client, AIAgent agent, IHost
}
// Stream the output to the console as it is generated.
await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync(input, this._thread, cancellationToken: cancellationToken))
await foreach (AgentResponseUpdate update in agent.RunStreamingAsync(input, this._thread, cancellationToken: cancellationToken))
{
Console.Write(update);
}
@@ -26,7 +26,7 @@ ChatMessage message = new(ChatRole.User, [
AgentThread thread = await agent.GetNewThreadAsync();
await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync(message, thread))
await foreach (AgentResponseUpdate update in agent.RunStreamingAsync(message, thread))
{
Console.WriteLine(update);
}
@@ -52,18 +52,18 @@ AIAgent middlewareEnabledAgent = originalAgent
AgentThread thread = await middlewareEnabledAgent.GetNewThreadAsync();
Console.WriteLine("\n\n=== Example 1: Wording Guardrail ===");
AgentRunResponse guardRailedResponse = await middlewareEnabledAgent.RunAsync("Tell me something harmful.");
AgentResponse guardRailedResponse = await middlewareEnabledAgent.RunAsync("Tell me something harmful.");
Console.WriteLine($"Guard railed response: {guardRailedResponse}");
Console.WriteLine("\n\n=== Example 2: PII detection ===");
AgentRunResponse piiResponse = await middlewareEnabledAgent.RunAsync("My name is John Doe, call me at 123-456-7890 or email me at john@something.com");
AgentResponse piiResponse = await middlewareEnabledAgent.RunAsync("My name is John Doe, call me at 123-456-7890 or email me at john@something.com");
Console.WriteLine($"Pii filtered response: {piiResponse}");
Console.WriteLine("\n\n=== Example 3: Agent function middleware ===");
// Agent function middleware support is limited to agents that wraps a upstream ChatClientAgent or derived from it.
AgentRunResponse functionCallResponse = await middlewareEnabledAgent.RunAsync("What's the current time and the weather in Seattle?", thread);
AgentResponse functionCallResponse = await middlewareEnabledAgent.RunAsync("What's the current time and the weather in Seattle?", thread);
Console.WriteLine($"Function calling response: {functionCallResponse}");
// Special per-request middleware agent.
@@ -78,7 +78,7 @@ AIAgent humanInTheLoopAgent = aiProjectClient.CreateAIAgent(
tools: [new ApprovalRequiredAIFunction(AIFunctionFactory.Create(GetWeather, name: nameof(GetWeather)))]);
// Using the ConsolePromptingApprovalMiddleware for a specific request to handle user approval during function calls.
AgentRunResponse response = await humanInTheLoopAgent
AgentResponse response = await humanInTheLoopAgent
.AsBuilder()
.Use(ConsolePromptingApprovalMiddleware, null)
.Build()
@@ -113,7 +113,7 @@ async ValueTask<object?> FunctionCallOverrideWeather(AIAgent agent, FunctionInvo
}
// This middleware redacts PII information from input and output messages.
async Task<AgentRunResponse> PIIMiddleware(IEnumerable<ChatMessage> messages, AgentThread? thread, AgentRunOptions? options, AIAgent innerAgent, CancellationToken cancellationToken)
async Task<AgentResponse> PIIMiddleware(IEnumerable<ChatMessage> messages, AgentThread? thread, AgentRunOptions? options, AIAgent innerAgent, CancellationToken cancellationToken)
{
// Redact PII information from input messages
var filteredMessages = FilterMessages(messages);
@@ -152,7 +152,7 @@ async Task<AgentRunResponse> PIIMiddleware(IEnumerable<ChatMessage> messages, Ag
}
// This middleware enforces guardrails by redacting certain keywords from input and output messages.
async Task<AgentRunResponse> GuardrailMiddleware(IEnumerable<ChatMessage> messages, AgentThread? thread, AgentRunOptions? options, AIAgent innerAgent, CancellationToken cancellationToken)
async Task<AgentResponse> GuardrailMiddleware(IEnumerable<ChatMessage> messages, AgentThread? thread, AgentRunOptions? options, AIAgent innerAgent, CancellationToken cancellationToken)
{
// Redact keywords from input messages
var filteredMessages = FilterMessages(messages);
@@ -189,9 +189,9 @@ async Task<AgentRunResponse> GuardrailMiddleware(IEnumerable<ChatMessage> messag
}
// This middleware handles Human in the loop console interaction for any user approval required during function calling.
async Task<AgentRunResponse> ConsolePromptingApprovalMiddleware(IEnumerable<ChatMessage> messages, AgentThread? thread, AgentRunOptions? options, AIAgent innerAgent, CancellationToken cancellationToken)
async Task<AgentResponse> ConsolePromptingApprovalMiddleware(IEnumerable<ChatMessage> messages, AgentThread? thread, AgentRunOptions? options, AIAgent innerAgent, CancellationToken cancellationToken)
{
AgentRunResponse response = await innerAgent.RunAsync(messages, thread, options, cancellationToken);
AgentResponse response = await innerAgent.RunAsync(messages, thread, options, cancellationToken);
List<UserInputRequestContent> userInputRequests = response.UserInputRequests.ToList();
@@ -49,10 +49,10 @@ AIAgent agentOption2 = await aiProjectClient.CreateAIAgentAsync(
// Either invoke option1 or option2 agent, should have same result
// Option 1
AgentRunResponse response = await agentOption1.RunAsync("I need to solve the equation sin(x) + x^2 = 42");
AgentResponse response = await agentOption1.RunAsync("I need to solve the equation sin(x) + x^2 = 42");
// Option 2
// AgentRunResponse response = await agentOption2.RunAsync("I need to solve the equation sin(x) + x^2 = 42");
// AgentResponse response = await agentOption2.RunAsync("I need to solve the equation sin(x) + x^2 = 42");
// Get the CodeInterpreterToolCallContent
CodeInterpreterToolCallContent? toolCallContent = response.Messages.SelectMany(m => m.Contents).OfType<CodeInterpreterToolCallContent>().FirstOrDefault();
@@ -93,7 +93,7 @@ internal sealed class Program
// Initial request with screenshot - start with Bing search page
Console.WriteLine("Starting computer automation session (initial screenshot: cua_browser_search.png)...");
AgentRunResponse runResponse = await agent.RunAsync(message, thread: thread, options: runOptions);
AgentResponse response = await agent.RunAsync(message, thread: thread, options: runOptions);
// Main interaction loop
const int MaxIterations = 10;
@@ -105,7 +105,7 @@ internal sealed class Program
while (true)
{
// Poll until the response is complete.
while (runResponse.ContinuationToken is { } token)
while (response.ContinuationToken is { } token)
{
// Wait before polling again.
await Task.Delay(TimeSpan.FromSeconds(2));
@@ -113,10 +113,10 @@ internal sealed class Program
// Continue with the token.
runOptions.ContinuationToken = token;
runResponse = await agent.RunAsync(thread, runOptions);
response = await agent.RunAsync(thread, runOptions);
}
Console.WriteLine($"Agent response received (ID: {runResponse.ResponseId})");
Console.WriteLine($"Agent response received (ID: {response.ResponseId})");
if (iteration >= MaxIterations)
{
@@ -128,7 +128,7 @@ internal sealed class Program
Console.WriteLine($"\n--- Iteration {iteration} ---");
// Check for computer calls in the response
IEnumerable<ComputerCallResponseItem> computerCallResponseItems = runResponse.Messages
IEnumerable<ComputerCallResponseItem> computerCallResponseItems = response.Messages
.SelectMany(x => x.Contents)
.Where(c => c.RawRepresentation is ComputerCallResponseItem and not null)
.Select(c => (ComputerCallResponseItem)c.RawRepresentation!);
@@ -137,7 +137,7 @@ internal sealed class Program
if (firstComputerCall is null)
{
Console.WriteLine("No computer call actions found. Ending interaction.");
Console.WriteLine($"Final Response: {runResponse}");
Console.WriteLine($"Final Response: {response}");
break;
}
@@ -168,7 +168,7 @@ internal sealed class Program
// Follow-up message with action result and new screenshot
message = new(ChatRole.User, [content]);
runResponse = await agent.RunAsync(message, thread: thread, options: runOptions);
response = await agent.RunAsync(message, thread: thread, options: runOptions);
}
}
}
@@ -58,8 +58,8 @@ public static class Program
// re-render all messages on each update.
static async Task ProcessInputAsync(AIAgent agent, AgentThread thread, string input)
{
Dictionary<string, List<AgentRunResponseUpdate>> buffer = [];
await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync(input, thread))
Dictionary<string, List<AgentResponseUpdate>> buffer = [];
await foreach (AgentResponseUpdate update in agent.RunStreamingAsync(input, thread))
{
if (update.MessageId is null || string.IsNullOrEmpty(update.Text))
{
@@ -68,7 +68,7 @@ public static class Program
}
Console.Clear();
if (!buffer.TryGetValue(update.MessageId, out List<AgentRunResponseUpdate>? value))
if (!buffer.TryGetValue(update.MessageId, out List<AgentResponseUpdate>? value))
{
value = [];
buffer[update.MessageId] = value;
@@ -65,7 +65,7 @@ public static class SampleWorkflowProvider
bool autoSend = true;
IList<ChatMessage>? inputMessages = null;
AgentRunResponse agentResponse =
AgentResponse agentResponse =
await InvokeAgentAsync(
context,
agentName,
@@ -102,7 +102,7 @@ public static class SampleWorkflowProvider
bool autoSend = false;
IList<ChatMessage>? inputMessages = null;
AgentRunResponse agentResponse =
AgentResponse agentResponse =
await InvokeAgentAsync(
context,
agentName,
@@ -175,7 +175,7 @@ public static class SampleWorkflowProvider
GOLD STAR!
"""
);
AgentRunResponse response = new([new ChatMessage(ChatRole.Assistant, activityText)]);
AgentResponse response = new([new ChatMessage(ChatRole.Assistant, activityText)]);
await context.AddEventAsync(new AgentRunResponseEvent(this.Id, response)).ConfigureAwait(false);
return default;
@@ -196,7 +196,7 @@ public static class SampleWorkflowProvider
Let's try again later...
"""
);
AgentRunResponse response = new([new ChatMessage(ChatRole.Assistant, activityText)]);
AgentResponse response = new([new ChatMessage(ChatRole.Assistant, activityText)]);
await context.AddEventAsync(new AgentRunResponseEvent(this.Id, response)).ConfigureAwait(false);
return default;
@@ -65,10 +65,10 @@ internal sealed class Program
};
ChatClientAgentRunOptions runOptions = new(chatOptions);
IAsyncEnumerable<AgentRunResponseUpdate> agentResponseUpdates = agent.RunStreamingAsync(workflowInput, thread, runOptions);
IAsyncEnumerable<AgentResponseUpdate> agentResponseUpdates = agent.RunStreamingAsync(workflowInput, thread, runOptions);
string? lastMessageId = null;
await foreach (AgentRunResponseUpdate responseUpdate in agentResponseUpdates)
await foreach (AgentResponseUpdate responseUpdate in agentResponseUpdates)
{
if (responseUpdate.MessageId != lastMessageId)
{
@@ -111,8 +111,8 @@ public static class Program
// re-render all messages on each update.
static async Task ProcessInputAsync(AIAgent agent, AgentThread thread, string input)
{
Dictionary<string, List<AgentRunResponseUpdate>> buffer = [];
await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync(input, thread))
Dictionary<string, List<AgentResponseUpdate>> buffer = [];
await foreach (AgentResponseUpdate update in agent.RunStreamingAsync(input, thread))
{
if (update.MessageId is null || string.IsNullOrEmpty(update.Text))
{
@@ -121,7 +121,7 @@ public static class Program
}
Console.Clear();
if (!buffer.TryGetValue(update.MessageId, out List<AgentRunResponseUpdate>? value))
if (!buffer.TryGetValue(update.MessageId, out List<AgentResponseUpdate>? value))
{
value = [];
buffer[update.MessageId] = value;
@@ -254,7 +254,7 @@ internal sealed class WriterExecutor : Executor
Console.WriteLine($"\n=== Writer (Iteration {state.Iteration}) ===\n");
StringBuilder sb = new();
await foreach (AgentRunResponseUpdate update in this._agent.RunStreamingAsync(message, cancellationToken: cancellationToken))
await foreach (AgentResponseUpdate update in this._agent.RunStreamingAsync(message, cancellationToken: cancellationToken))
{
if (!string.IsNullOrEmpty(update.Text))
{
@@ -313,10 +313,10 @@ internal sealed class CriticExecutor : Executor<ChatMessage, CriticDecision>
Console.WriteLine($"=== Critic (Iteration {state.Iteration}) ===\n");
// Use RunStreamingAsync to get streaming updates, then deserialize at the end
IAsyncEnumerable<AgentRunResponseUpdate> updates = this._agent.RunStreamingAsync(message, cancellationToken: cancellationToken);
IAsyncEnumerable<AgentResponseUpdate> updates = this._agent.RunStreamingAsync(message, cancellationToken: cancellationToken);
// Stream the output in real-time (for any rationale/explanation)
await foreach (AgentRunResponseUpdate update in updates)
await foreach (AgentResponseUpdate update in updates)
{
if (!string.IsNullOrEmpty(update.Text))
{
@@ -326,7 +326,7 @@ internal sealed class CriticExecutor : Executor<ChatMessage, CriticDecision>
Console.WriteLine("\n");
// Convert the stream to a response and deserialize the structured output
AgentRunResponse response = await updates.ToAgentRunResponseAsync(cancellationToken);
AgentResponse response = await updates.ToAgentResponseAsync(cancellationToken);
CriticDecision decision = response.Deserialize<CriticDecision>(JsonSerializerOptions.Web);
Console.WriteLine($"Decision: {(decision.Approved ? " APPROVED" : " NEEDS REVISION")}");
@@ -394,7 +394,7 @@ internal sealed class SummaryExecutor : Executor<CriticDecision, ChatMessage>
string prompt = $"Present this approved content:\n\n{message.Content}";
StringBuilder sb = new();
await foreach (AgentRunResponseUpdate update in this._agent.RunStreamingAsync(new ChatMessage(ChatRole.User, prompt), cancellationToken: cancellationToken))
await foreach (AgentResponseUpdate update in this._agent.RunStreamingAsync(new ChatMessage(ChatRole.User, prompt), cancellationToken: cancellationToken))
{
if (!string.IsNullOrEmpty(update.Text))
{