-
Notifications
You must be signed in to change notification settings - Fork 4k
.NET Agent - Add AIContext to OpenAIResponseAgent
#12456
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
markwallace-microsoft
merged 17 commits into
main
from
update-agents-response-aicontext
Jun 19, 2025
Merged
Changes from 8 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
7b70ee3
Updated
crickman ca5dd85
Null check
crickman 27d4796
Conformance tests
crickman c456b93
Merge branch 'main' into update-agents-response-aicontext
crickman 47e1035
Typo
crickman a61d743
Fix
crickman df829c4
Enable working test
crickman 40b9bd4
Merge branch 'main' into update-agents-response-aicontext
crickman 03fe7b1
Update dotnet/samples/Concepts/Agents/OpenAIResponseAgent_Whiteboard.cs
crickman 6556355
Update "WithoutMessage" test
crickman 70f78b5
Merge branch 'main' into update-agents-response-aicontext
crickman 1c98451
Cleanup
crickman 63fa69a
Revert empty string / request
crickman 8a5a324
Merge branch 'main' into update-agents-response-aicontext
crickman 4c13b26
Update conformance test
crickman 2524060
Merge branch 'update-agents-response-aicontext' of https://github.com…
crickman f9f01dd
Merge branch 'main' into update-agents-response-aicontext
crickman File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
135 changes: 135 additions & 0 deletions
135
dotnet/samples/Concepts/Agents/OpenAIResponseAgent_Whiteboard.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
// Copyright (c) Microsoft. All rights reserved. | ||
|
||
using Azure.AI.OpenAI; | ||
using Azure.Identity; | ||
using Microsoft.Extensions.AI; | ||
using Microsoft.SemanticKernel; | ||
using Microsoft.SemanticKernel.Agents; | ||
using Microsoft.SemanticKernel.Agents.OpenAI; | ||
using Microsoft.SemanticKernel.ChatCompletion; | ||
using Microsoft.SemanticKernel.Memory; | ||
|
||
namespace Agents; | ||
|
||
#pragma warning disable SKEXP0130 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. | ||
|
||
/// <summary> | ||
/// Demonstrate creation of <see cref="ChatCompletionAgent"/> and | ||
/// adding whiteboarding capabilities, where the most relevant information from the conversation is captured on a whiteboard. | ||
/// This is useful for long running conversations where the conversation history may need to be truncated | ||
/// over time, but you do not want to agent to lose context. | ||
/// </summary> | ||
public class OpenAIResponseAgent_Whiteboard(ITestOutputHelper output) : BaseResponsesAgentTest(output) | ||
{ | ||
private const string AgentName = "FriendlyAssistant"; | ||
private const string AgentInstructions = "You are a friendly assistant"; | ||
|
||
/// <summary> | ||
/// Shows how to allow an agent to use a whiteboard for storing the most important information | ||
/// from a long running, truncated conversation. | ||
/// </summary> | ||
[Fact] | ||
private async Task UseWhiteboardForShortTermMemory() | ||
{ | ||
IChatClient chatClient = new AzureOpenAIClient(new Uri(TestConfiguration.AzureOpenAI.Endpoint), new AzureCliCredential()) | ||
.GetChatClient(TestConfiguration.AzureOpenAI.ChatDeploymentName) | ||
.AsIChatClient(); | ||
|
||
// Create the whiteboard. | ||
WhiteboardProvider whiteboardProvider = new(chatClient); | ||
|
||
OpenAIResponseAgent agent = new(this.Client) | ||
{ | ||
Name = AgentName, | ||
Instructions = AgentInstructions, | ||
Arguments = new KernelArguments(new PromptExecutionSettings { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() }), | ||
StoreEnabled = false, | ||
}; | ||
|
||
// Create the agent with our sample plugin. | ||
agent.Kernel.Plugins.AddFromType<VMPlugin>(); | ||
|
||
// Create a chat history reducer that we can use to truncate the chat history | ||
// when it goes over 3 items. | ||
ChatHistoryTruncationReducer chatHistoryReducer = new(3, 3); | ||
|
||
// Create a thread for the agent and add the whiteboard to it. | ||
ChatHistoryAgentThread agentThread = new(); | ||
agentThread.AIContextProviders.Add(whiteboardProvider); | ||
|
||
// Simulate a conversation with the agent. | ||
// We will also truncate the conversation once it goes over a few items. | ||
await InvokeWithConsoleWriteLine("Hello"); | ||
await InvokeWithConsoleWriteLine("I'd like to create a VM?"); | ||
await InvokeWithConsoleWriteLine("I want it to have 3 cores."); | ||
await InvokeWithConsoleWriteLine("I want it to have 48GB of RAM."); | ||
await InvokeWithConsoleWriteLine("I want it to have a 500GB Harddrive."); | ||
await InvokeWithConsoleWriteLine("I want it in Europe."); | ||
await InvokeWithConsoleWriteLine("Can you make it Linux and call it 'ContosoVM'."); | ||
await InvokeWithConsoleWriteLine("OK, let's call it `ContosoFinanceVM_Europe` instead."); | ||
await InvokeWithConsoleWriteLine("Thanks, now I want to create another VM."); | ||
await InvokeWithConsoleWriteLine("Make all the options the same as the last one, except for the region, which should be North America, and the name, which should be 'ContosoFinanceVM_NorthAmerica'."); | ||
|
||
async Task InvokeWithConsoleWriteLine(string message) | ||
{ | ||
// Print the user input. | ||
Console.WriteLine($"User: {message}"); | ||
|
||
// Invoke the agent. | ||
ChatMessageContent response = await agent.InvokeAsync(message, agentThread).FirstAsync(); | ||
|
||
// Print the response. | ||
this.WriteAgentChatMessage(response); | ||
|
||
// Make sure any async whiteboard processing is complete before we print out its contents. | ||
await whiteboardProvider.WhenProcessingCompleteAsync(); | ||
|
||
// Print out the whiteboard contents. | ||
Console.WriteLine("Whiteboard contents:"); | ||
foreach (var item in whiteboardProvider.CurrentWhiteboardContent) | ||
{ | ||
Console.WriteLine($"- {item}"); | ||
} | ||
Console.WriteLine(); | ||
|
||
// Truncate the chat history if it gets too big. | ||
await agentThread.ChatHistory.ReduceInPlaceAsync(chatHistoryReducer, CancellationToken.None); | ||
} | ||
} | ||
|
||
private sealed class VMPlugin | ||
{ | ||
[KernelFunction] | ||
public Task<VMCreateResult> CreateVM(Region region, OperatingSystem os, string name, int numberOfCores, int memorySizeInGB, int hddSizeInGB) | ||
{ | ||
if (name == "ContosoVM") | ||
{ | ||
throw new Exception("VM name already exists"); | ||
} | ||
|
||
return Task.FromResult(new VMCreateResult { VMId = Guid.NewGuid().ToString() }); | ||
} | ||
} | ||
|
||
public class VMCreateResult | ||
{ | ||
public string VMId { get; set; } = string.Empty; | ||
} | ||
|
||
private enum Region | ||
{ | ||
NorthAmerica, | ||
SouthAmerica, | ||
Europe, | ||
Asia, | ||
Africa, | ||
Australia | ||
} | ||
|
||
private enum OperatingSystem | ||
{ | ||
Windows, | ||
Linux, | ||
MacOS | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
dotnet/src/Agents/Abstractions/Extensions/AgentInvokeOptionsExtensions.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// Copyright (c) Microsoft. All rights reserved. | ||
|
||
namespace Microsoft.SemanticKernel.Agents.Extensions; | ||
|
||
/// <summary> | ||
/// Extension methods for <see cref="AgentInvokeOptions"/> | ||
/// </summary> | ||
public static class AgentInvokeOptionsExtensions | ||
crickman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
/// <summary> | ||
/// Gets the kernel scoped to the current invocation. | ||
/// </summary> | ||
/// <param name="options">The <see cref="AgentInvokeOptions"/> instance containing invocation-specific options. May be <c>null</c>.</param> | ||
/// <param name="agent">The <see cref="Agent"/> whose kernel is used as a fallback if <paramref name="options"/> does not specify one.</param> | ||
/// <returns> | ||
/// The <see cref="Kernel"/> instance to use for the current invocation. Returns the kernel from <paramref name="options"/> if specified; otherwise, returns the kernel from <paramref name="agent"/>. | ||
/// </returns> | ||
public static Kernel GetKernel(this AgentInvokeOptions? options, Agent agent) => options?.Kernel ?? agent.Kernel; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.