Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dotnet/samples/A2AClientServer/A2AClient/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ private static async Task HandleCommandsAsync(CancellationToken cancellationToke
// Create the Host agent
var hostAgent = new HostClientAgent(loggerFactory);
await hostAgent.InitializeAgentAsync(modelId, apiKey, agentUrls!.Split(";"));
AgentThread thread = hostAgent.Agent!.GetNewThread();
AgentThread thread = await hostAgent.Agent!.GetNewThreadAsync(cancellationToken);
try
{
while (true)
Expand Down
2 changes: 1 addition & 1 deletion dotnet/samples/AGUIClientServer/AGUIClient/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ private static async Task HandleCommandsAsync(CancellationToken cancellationToke
description: "AG-UI Client Agent",
tools: [changeBackground, readClientClimateSensors]);

AgentThread thread = agent.GetNewThread();
AgentThread thread = await agent.GetNewThreadAsync(cancellationToken);
List<ChatMessage> messages = [new(ChatRole.System, "You are a helpful assistant.")];
try
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public sealed record TextResponse(string Text);
public static async Task<string> RunOrchestrationAsync([OrchestrationTrigger] TaskOrchestrationContext context)
{
DurableAIAgent writer = context.GetAgent("WriterAgent");
AgentThread writerThread = writer.GetNewThread();
AgentThread writerThread = await writer.GetNewThreadAsync();

AgentRunResponse<TextResponse> initial = await writer.RunAsync<TextResponse>(
message: "Write a concise inspirational sentence about learning.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public static async Task<string> RunOrchestrationAsync([OrchestrationTrigger] Ta

// Get the spam detection agent
DurableAIAgent spamDetectionAgent = context.GetAgent("SpamDetectionAgent");
AgentThread spamThread = spamDetectionAgent.GetNewThread();
AgentThread spamThread = await spamDetectionAgent.GetNewThreadAsync();

// Step 1: Check if the email is spam
AgentRunResponse<DetectionResult> spamDetectionResponse = await spamDetectionAgent.RunAsync<DetectionResult>(
Expand All @@ -43,7 +43,7 @@ public static async Task<string> RunOrchestrationAsync([OrchestrationTrigger] Ta

// Generate and send response for legitimate email
DurableAIAgent emailAssistantAgent = context.GetAgent("EmailAssistantAgent");
AgentThread emailThread = emailAssistantAgent.GetNewThread();
AgentThread emailThread = await emailAssistantAgent.GetNewThreadAsync();

AgentRunResponse<EmailResponse> emailAssistantResponse = await emailAssistantAgent.RunAsync<EmailResponse>(
message:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public static async Task<object> RunOrchestrationAsync(

// Get the writer agent
DurableAIAgent writerAgent = context.GetAgent("WriterAgent");
AgentThread writerThread = writerAgent.GetNewThread();
AgentThread writerThread = await writerAgent.GetNewThreadAsync();

// Set initial status
context.SetCustomStatus($"Starting content generation for topic: {input.Topic}");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public static async Task<object> RunOrchestrationAsync(

// Get the writer agent
DurableAIAgent writerAgent = context.GetAgent("Writer");
AgentThread writerThread = writerAgent.GetNewThread();
AgentThread writerThread = await writerAgent.GetNewThreadAsync();

// Set initial status
context.SetCustomStatus($"Starting content generation for topic: {input.Topic}");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public async Task<IActionResult> CreateAsync(
AIAgent agentProxy = durableClient.AsDurableAgentProxy(context, "TravelPlanner");

// Create a new agent thread
AgentThread thread = agentProxy.GetNewThread();
AgentThread thread = await agentProxy.GetNewThreadAsync(cancellationToken);
string agentSessionId = thread.GetService<AgentSessionId>().ToString();

this._logger.LogInformation("Creating new agent session: {AgentSessionId}", agentSessionId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
// Create an instance of the AIAgent for an existing A2A agent specified by the agent card.
AIAgent agent = agentCard.GetAIAgent();

AgentThread thread = agent.GetNewThread();
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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
name: "agui-client",
description: "AG-UI Client Agent");

AgentThread thread = agent.GetNewThread();
AgentThread thread = await agent.GetNewThreadAsync();
List<ChatMessage> messages =
[
new(ChatRole.System, "You are a helpful assistant.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
name: "agui-client",
description: "AG-UI Client Agent");

AgentThread thread = agent.GetNewThread();
AgentThread thread = await agent.GetNewThreadAsync();
List<ChatMessage> messages =
[
new(ChatRole.System, "You are a helpful assistant.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ static string GetUserLocation()
description: "AG-UI Client Agent",
tools: frontendTools);

AgentThread thread = agent.GetNewThread();
AgentThread thread = await agent.GetNewThreadAsync();
List<ChatMessage> messages =
[
new(ChatRole.System, "You are a helpful assistant.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
};
StatefulAgent<AgentState> agent = new(baseAgent, jsonOptions, new AgentState());

AgentThread thread = agent.GetNewThread();
AgentThread thread = await agent.GetNewThreadAsync();
List<ChatMessage> messages =
[
new(ChatRole.System, "You are a helpful recipe assistant.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ static async Task<string> GetWeatherAsync([Description("The location to get the
.UseOpenTelemetry(SourceName, configure: (cfg) => cfg.EnableSensitiveData = true) // enable telemetry at the agent level
.Build();

var thread = agent.GetNewThread();
var thread = await agent.GetNewThreadAsync();

appLogger.LogInformation("Agent created successfully with ID: {AgentId}", agent.Id);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
instructions: JokerInstructions);

// You can then invoke the agent like any other AIAgent.
AgentThread thread = agent1.GetNewThread();
AgentThread thread = await agent1.GetNewThreadAsync();
Console.WriteLine(await agent1.RunAsync("Tell me a joke about a pirate.", thread));

// Cleanup for sample purposes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
Console.WriteLine($"Latest agent version id: {latestAgentVersion.Id}");

// Once you have the AIAgent, you can invoke it like any other AIAgent.
AgentThread thread = jokerAgentLatest.GetNewThread();
AgentThread thread = await jokerAgentLatest.GetNewThreadAsync();
Console.WriteLine(await jokerAgentLatest.RunAsync("Tell me a joke about a pirate.", thread));

// This will use the same thread to continue the conversation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,16 @@ internal sealed class UpperCaseParrotAgent : AIAgent
{
public override string? Name => "UpperCaseParrotAgent";

public override AgentThread GetNewThread()
=> new CustomAgentThread();
public override ValueTask<AgentThread> GetNewThreadAsync(CancellationToken cancellationToken = default)
=> new(new CustomAgentThread());

public override AgentThread DeserializeThread(JsonElement serializedThread, JsonSerializerOptions? jsonSerializerOptions = null)
=> new CustomAgentThread(serializedThread, jsonSerializerOptions);
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)
{
// Create a thread if the user didn't supply one.
thread ??= this.GetNewThread();
thread ??= await this.GetNewThreadAsync(cancellationToken);

if (thread is not CustomAgentThread typedThread)
{
Expand Down Expand Up @@ -69,7 +69,7 @@ protected override async Task<AgentRunResponse> RunCoreAsync(IEnumerable<ChatMes
protected override async IAsyncEnumerable<AgentRunResponseUpdate> 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 ??= this.GetNewThread();
thread ??= await this.GetNewThreadAsync(cancellationToken);

if (thread is not CustomAgentThread typedThread)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
instructions: JokerInstructions);

// You can invoke the agent like any other AIAgent.
AgentThread thread = agent1.GetNewThread();
AgentThread thread = await agent1.GetNewThreadAsync();
Console.WriteLine(await agent1.RunAsync("Tell me a joke about a pirate.", thread));

// Cleanup for sample purposes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ static string GetWeather([Description("The location to get the weather for.")] s
.CreateAIAgent(model: model, instructions: AssistantInstructions, name: AssistantName, tools: [tool]);

// Non-streaming agent interaction with function tools.
AgentThread thread = agent.GetNewThread();
AgentThread thread = await agent.GetNewThreadAsync();
Console.WriteLine(await agent.RunAsync("What is the weather like in Amsterdam?", thread));

// Streaming agent interaction with function tools.
thread = agent.GetNewThread();
thread = await agent.GetNewThreadAsync();
await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync("What is the weather like in Amsterdam?", thread))
{
Console.WriteLine(update);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
{
ChatOptions = new() { Instructions = "You are good at telling jokes." },
Name = "Joker",
AIContextProviderFactory = (ctx) => new ChatHistoryMemoryProvider(
AIContextProviderFactory = (ctx, ct) => new ValueTask<AIContextProvider>(new ChatHistoryMemoryProvider(
vectorStore,
collectionName: "chathistory",
vectorDimensions: 3072,
Expand All @@ -43,18 +43,18 @@
storageScope: new() { UserId = "UID1", ThreadId = new Guid().ToString() },
// Configure the scope which would be used to search for relevant prior messages.
// In this case, we are searching for any messages for the user across all threads.
searchScope: new() { UserId = "UID1" })
searchScope: new() { UserId = "UID1" }))
});

// Start a new thread for the agent conversation.
AgentThread thread = agent.GetNewThread();
AgentThread thread = await agent.GetNewThreadAsync();

// Run the agent with the thread that stores conversation history in the vector store.
Console.WriteLine(await agent.RunAsync("I like jokes about Pirates. Tell me a joke about a pirate.", thread));

// Start a second thread. Since we configured the search scope to be across all threads for the user,
// the agent should remember that the user likes pirate jokes.
AgentThread thread2 = agent.GetNewThread();
AgentThread thread2 = await agent.GetNewThreadAsync();

// Run the agent with the second thread.
Console.WriteLine(await agent.RunAsync("Tell me a joke that I might like.", thread2));
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,16 @@
.CreateAIAgent(new ChatClientAgentOptions()
{
ChatOptions = new() { Instructions = "You are a friendly travel assistant. Use known memories about the user when responding, and do not invent details." },
AIContextProviderFactory = ctx => ctx.SerializedState.ValueKind is not JsonValueKind.Null and not JsonValueKind.Undefined
AIContextProviderFactory = (ctx, ct) => new ValueTask<AIContextProvider>(ctx.SerializedState.ValueKind is not JsonValueKind.Null and not JsonValueKind.Undefined
// If each thread should have its own Mem0 scope, you can create a new id per thread here:
// ? new Mem0Provider(mem0HttpClient, new Mem0ProviderScope() { ThreadId = Guid.NewGuid().ToString() })
// In this case we are storing memories scoped by application and user instead so that memories are retained across threads.
? new Mem0Provider(mem0HttpClient, new Mem0ProviderScope() { ApplicationId = "getting-started-agents", UserId = "sample-user" })
// For cases where we are restoring from serialized state:
: new Mem0Provider(mem0HttpClient, ctx.SerializedState, ctx.JsonSerializerOptions)
: new Mem0Provider(mem0HttpClient, ctx.SerializedState, ctx.JsonSerializerOptions))
});

AgentThread thread = agent.GetNewThread();
AgentThread thread = await agent.GetNewThreadAsync();

// Clear any existing memories for this scope to demonstrate fresh behavior.
Mem0Provider mem0Provider = thread.GetService<Mem0Provider>()!;
Expand All @@ -56,9 +56,9 @@

Console.WriteLine("\n>> Serialize and deserialize the thread to demonstrate persisted state\n");
JsonElement serializedThread = thread.Serialize();
AgentThread restoredThread = agent.DeserializeThread(serializedThread);
AgentThread restoredThread = await agent.DeserializeThreadAsync(serializedThread);
Console.WriteLine(await agent.RunAsync("Can you recap the personal details you remember?", restoredThread));

Console.WriteLine("\n>> Start a new thread that shares the same Mem0 scope\n");
AgentThread newThread = agent.GetNewThread();
AgentThread newThread = await agent.GetNewThreadAsync();
Console.WriteLine(await agent.RunAsync("Summarize what you already know about me.", newThread));
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@
AIAgent agent = chatClient.CreateAIAgent(new ChatClientAgentOptions()
{
ChatOptions = new() { Instructions = "You are a friendly assistant. Always address the user by their name." },
AIContextProviderFactory = ctx => new UserInfoMemory(chatClient.AsIChatClient(), ctx.SerializedState, ctx.JsonSerializerOptions)
AIContextProviderFactory = (ctx, ct) => new ValueTask<AIContextProvider>(new UserInfoMemory(chatClient.AsIChatClient(), ctx.SerializedState, ctx.JsonSerializerOptions))
});

// Create a new thread for the conversation.
AgentThread thread = agent.GetNewThread();
AgentThread thread = await agent.GetNewThreadAsync();

Console.WriteLine(">> Use thread with blank memory\n");

Expand All @@ -52,7 +52,7 @@
Console.WriteLine("\n>> Use deserialized thread with previously created memories\n");

// Later we can deserialize the thread and continue the conversation with the previous memory component state.
var deserializedThread = agent.DeserializeThread(threadElement);
var deserializedThread = await agent.DeserializeThreadAsync(threadElement);
Console.WriteLine(await agent.RunAsync("What is my name and age?", deserializedThread));

Console.WriteLine("\n>> Read memories from memory component\n");
Expand All @@ -68,7 +68,7 @@

// It is also possible to set the memories in a memory component on an individual thread.
// This is useful if we want to start a new thread, but have it share the same memories as a previous thread.
var newThread = agent.GetNewThread();
var newThread = await agent.GetNewThreadAsync();
if (userInfo is not null && newThread.GetService<UserInfoMemory>() is UserInfoMemory newThreadMemory)
{
newThreadMemory.UserInfo = userInfo;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
string conversationId = createConversationResultAsJson.RootElement.GetProperty("id"u8)!.GetString()!;

// Create a thread for the conversation - this enables conversation state management for subsequent turns
AgentThread thread = agent.GetNewThread(conversationId);
AgentThread thread = await agent.GetNewThreadAsync(conversationId);

Console.WriteLine("=== Multi-turn Conversation Demo ===\n");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ The `AgentThread` works with `ChatClientAgentRunOptions` to link the agent to a
ChatClientAgentRunOptions agentRunOptions = new() { ChatOptions = new ChatOptions() { ConversationId = conversationId } };

// Create a thread for the conversation
AgentThread thread = agent.GetNewThread();
AgentThread thread = await agent.GetNewThreadAsync();

// First call links the thread to the conversation
ChatCompletion firstResponse = await agent.RunAsync([firstMessage], thread, agentRunOptions);
Expand All @@ -59,7 +59,7 @@ foreach (ClientResult result in getConversationItemsResults.GetRawPages())
1. **Create an OpenAI Client**: Initialize an `OpenAIClient` with your API key
2. **Create a Conversation**: Use `ConversationClient` to create a server-side conversation
3. **Create an Agent**: Initialize an `OpenAIResponseClientAgent` with the desired model and instructions
4. **Create a Thread**: Call `agent.GetNewThread()` to create a new conversation thread
4. **Create a Thread**: Call `agent.GetNewThreadAsync()` to create a new conversation thread
5. **Link Thread to Conversation**: Pass `ChatClientAgentRunOptions` with the `ConversationId` on the first call
6. **Send Messages**: Subsequent calls to `agent.RunAsync()` only need the thread - context is maintained
7. **Cleanup**: Delete the conversation when done using `conversationClient.DeleteConversation()`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,15 @@
.CreateAIAgent(new ChatClientAgentOptions
{
ChatOptions = new() { Instructions = "You are a helpful support specialist for Contoso Outdoors. Answer questions using the provided context and cite the source document when available." },
AIContextProviderFactory = ctx => new TextSearchProvider(SearchAdapter, ctx.SerializedState, ctx.JsonSerializerOptions, textSearchOptions),
AIContextProviderFactory = (ctx, ct) => new ValueTask<AIContextProvider>(new TextSearchProvider(SearchAdapter, ctx.SerializedState, ctx.JsonSerializerOptions, textSearchOptions)),
// Since we are using ChatCompletion which stores chat history locally, we can also add a message removal policy
// that removes messages produced by the TextSearchProvider before they are added to the chat history, so that
// we don't bloat chat history with all the search result messages.
ChatMessageStoreFactory = ctx => new InMemoryChatMessageStore(ctx.SerializedState, ctx.JsonSerializerOptions)
.WithAIContextProviderMessageRemoval(),
ChatMessageStoreFactory = (ctx, ct) => new ValueTask<ChatMessageStore>(new InMemoryChatMessageStore(ctx.SerializedState, ctx.JsonSerializerOptions)
.WithAIContextProviderMessageRemoval()),
});

AgentThread thread = agent.GetNewThread();
AgentThread thread = await agent.GetNewThreadAsync();

Console.WriteLine(">> Asking about returns\n");
Console.WriteLine(await agent.RunAsync("Hi! I need help understanding the return policy.", thread));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,10 @@
.CreateAIAgent(new ChatClientAgentOptions
{
ChatOptions = new() { Instructions = "You are a helpful support specialist for the Microsoft Agent Framework. Answer questions using the provided context and cite the source document when available. Keep responses brief." },
AIContextProviderFactory = ctx => new TextSearchProvider(SearchAdapter, ctx.SerializedState, ctx.JsonSerializerOptions, textSearchOptions)
AIContextProviderFactory = (ctx, ct) => new ValueTask<AIContextProvider>(new TextSearchProvider(SearchAdapter, ctx.SerializedState, ctx.JsonSerializerOptions, textSearchOptions))
});

AgentThread thread = agent.GetNewThread();
AgentThread thread = await agent.GetNewThreadAsync();

Console.WriteLine(">> Asking about SK threads\n");
Console.WriteLine(await agent.RunAsync("Hi! How do I create a thread in Semantic Kernel?", thread));
Expand Down
Loading
Loading