Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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