Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
5c88cb6
Point AgentOptions.Instructions to ChatOptions
rogerbarreto Oct 16, 2025
368d606
Update tests and checks
rogerbarreto Oct 16, 2025
bae09b8
Update xml docs
rogerbarreto Oct 16, 2025
2396240
Removal of agentOptions.Instructions in favor of chatOptions.Instruct…
rogerbarreto Oct 17, 2025
489b8e9
Address Merge Conflicts
rogerbarreto Oct 17, 2025
1a58888
Instructions and tool check consistency
rogerbarreto Oct 17, 2025
d425bdd
Instructions and tool check consistency
rogerbarreto Oct 17, 2025
acbe378
Merge branch 'main' into issues/1453-simplify-chatclientagentoptions-…
rogerbarreto Oct 20, 2025
866150b
Address comment
rogerbarreto Oct 20, 2025
6d3768d
Update .github/upgrades/prompts/SemanticKernelToAgentFramework.md
rogerbarreto Oct 20, 2025
defdeb1
Address PR Comment
rogerbarreto Oct 20, 2025
2346e4e
Merge branch 'main' of https://github.com/microsoft/agent-framework i…
rogerbarreto Nov 26, 2025
865849f
Update latest changes to comply with the PR proposal
rogerbarreto Nov 26, 2025
8d4c201
Merge branch 'main' into issues/1453-simplify-chatclientagentoptions-…
rogerbarreto Nov 26, 2025
5f07cde
Address feedback
rogerbarreto Nov 26, 2025
90ccf99
Merge branch 'main' into issues/1453-simplify-chatclientagentoptions-…
markwallace-microsoft Nov 27, 2025
0bb440d
Update dotnet/tests/Microsoft.Agents.AI.UnitTests/ChatClient/ChatClie…
rogerbarreto Nov 27, 2025
bda75af
Merge branch 'main' into issues/1453-simplify-chatclientagentoptions-…
rogerbarreto Dec 2, 2025
59796c4
Address instructions
rogerbarreto Dec 2, 2025
7f7ea4d
Update declarative to use promptAgent.Instrucitons with chatOptions.I…
rogerbarreto Dec 2, 2025
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 .github/upgrades/prompts/SemanticKernelToAgentFramework.md
Original file line number Diff line number Diff line change
Expand Up @@ -1636,4 +1636,4 @@ The property mapping guide from a `AutoFunctionInvocationContext` to a `Function
| Result | Use `return` from the delegate |
| Terminate | Terminate |
| CancellationToken | provided via argument to middleware delegate |
| Arguments | Arguments |
| Arguments | Arguments |
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
.GetChatClient(deploymentName)
.CreateAIAgent(new ChatClientAgentOptions
{
Instructions = "You are good at telling jokes.",
ChatOptions = new() { Instructions = "You are good at telling jokes." },
Name = "Joker",
AIContextProviderFactory = (ctx) => new ChatHistoryMemoryProvider(
vectorStore,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
.GetChatClient(deploymentName)
.CreateAIAgent(new ChatClientAgentOptions()
{
Instructions = "You are a friendly travel assistant. Use known memories about the user when responding, and do not invent details.",
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
// 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() })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
// and its storage to that user id.
AIAgent agent = chatClient.CreateAIAgent(new ChatClientAgentOptions()
{
Instructions = "You are a friendly assistant. Always address the user by their name.",
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)
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
.GetChatClient(deploymentName)
.CreateAIAgent(new ChatClientAgentOptions
{
Instructions = "You are a helpful support specialist for Contoso Outdoors. Answer questions using the provided context and cite the source document when available.",
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)
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
.GetChatClient(deploymentName)
.CreateAIAgent(new ChatClientAgentOptions
{
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.",
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)
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
.GetChatClient(deploymentName)
.CreateAIAgent(new ChatClientAgentOptions
{
Instructions = "You are a helpful support specialist for Contoso Outdoors. Answer questions using the provided context and cite the source document when available.",
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(MockSearchAsync, ctx.SerializedState, ctx.JsonSerializerOptions, textSearchOptions)
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
.GetChatClient(deploymentName);

// Create the ChatClientAgent with the specified name and instructions.
ChatClientAgent agent = chatClient.CreateAIAgent(new ChatClientAgentOptions(name: "HelpfulAssistant", instructions: "You are a helpful assistant."));
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.");
Expand All @@ -34,12 +34,10 @@
Console.WriteLine($"Occupation: {response.Result.Occupation}");

// Create the ChatClientAgent with the specified name, instructions, and expected structured output the agent should produce.
ChatClientAgent agentWithPersonInfo = chatClient.CreateAIAgent(new ChatClientAgentOptions(name: "HelpfulAssistant", instructions: "You are a helpful assistant.")
ChatClientAgent agentWithPersonInfo = chatClient.CreateAIAgent(new ChatClientAgentOptions()
{
ChatOptions = new()
{
ResponseFormat = Microsoft.Extensions.AI.ChatResponseFormat.ForJsonSchema<PersonInfo>()
}
Name = "HelpfulAssistant",
ChatOptions = new() { Instructions = "You are a helpful assistant.", ResponseFormat = Microsoft.Extensions.AI.ChatResponseFormat.ForJsonSchema<PersonInfo>() }
});

// Invoke the agent with some unstructured input while streaming, to extract the structured information from.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
.GetChatClient(deploymentName)
.CreateAIAgent(new ChatClientAgentOptions
{
Instructions = "You are good at telling jokes.",
ChatOptions = new() { Instructions = "You are good at telling jokes." },
Name = "Joker",
ChatMessageStoreFactory = ctx =>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

// Add agent options to the service collection.
builder.Services.AddSingleton(
new ChatClientAgentOptions(instructions: "You are good at telling jokes.", name: "Joker"));
builder.Services.AddSingleton(new ChatClientAgentOptions() { Name = "Joker", ChatOptions = new() { Instructions = "You are good at telling jokes." } });

// Add a chat client to the service collection.
builder.Services.AddKeyedChatClient("AzureOpenAI", (sp) => new AzureOpenAIClient(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
.GetChatClient(deploymentName)
.CreateAIAgent(new ChatClientAgentOptions
{
Instructions = "You are good at telling jokes.",
ChatOptions = new() { Instructions = "You are good at telling jokes." },
Name = "Joker",
ChatMessageStoreFactory = ctx => new InMemoryChatMessageStore(new MessageCountingChatReducer(2), ctx.SerializedState, ctx.JsonSerializerOptions)
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@
// Create ChatClientAgent directly
ChatClientAgent agent = await aiProjectClient.CreateAIAgentAsync(
model: deploymentName,
new ChatClientAgentOptions(name: AssistantName, instructions: AssistantInstructions)
new ChatClientAgentOptions()
{
Name = AssistantName,
ChatOptions = new()
{
Instructions = AssistantInstructions,
ResponseFormat = Microsoft.Extensions.AI.ChatResponseFormat.ForJsonSchema<PersonInfo>()
}
});
Expand All @@ -44,10 +46,12 @@
// Create the ChatClientAgent with the specified name, instructions, and expected structured output the agent should produce.
ChatClientAgent agentWithPersonInfo = aiProjectClient.CreateAIAgent(
model: deploymentName,
new ChatClientAgentOptions(name: AssistantName, instructions: AssistantInstructions)
new ChatClientAgentOptions()
{
Name = AssistantName,
ChatOptions = new()
{
Instructions = AssistantInstructions,
ResponseFormat = Microsoft.Extensions.AI.ChatResponseFormat.ForJsonSchema<PersonInfo>()
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@
options: new()
{
Name = "MicrosoftLearnAgent",
Instructions = "You answer questions by searching the Microsoft Learn content only.",
ChatOptions = new()
{
Instructions = "You answer questions by searching the Microsoft Learn content only.",
Tools = [mcpTool]
},
});
Expand Down Expand Up @@ -67,9 +67,9 @@
options: new()
{
Name = "MicrosoftLearnAgentWithApproval",
Instructions = "You answer questions by searching the Microsoft Learn content only.",
ChatOptions = new()
{
Instructions = "You answer questions by searching the Microsoft Learn content only.",
Tools = [mcpToolWithApproval]
},
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,11 @@ internal sealed class SloganWriterExecutor : Executor
/// <param name="chatClient">The chat client to use for the AI agent.</param>
public SloganWriterExecutor(string id, IChatClient chatClient) : base(id)
{
ChatClientAgentOptions agentOptions = new(instructions: "You are a professional slogan writer. You will be given a task to create a slogan.")
ChatClientAgentOptions agentOptions = new()
{
ChatOptions = new()
{
Instructions = "You are a professional slogan writer. You will be given a task to create a slogan.",
ResponseFormat = ChatResponseFormat.ForJsonSchema<SloganResult>()
}
};
Expand Down Expand Up @@ -193,10 +194,11 @@ internal sealed class FeedbackExecutor : Executor<SloganResult>
/// <param name="chatClient">The chat client to use for the AI agent.</param>
public FeedbackExecutor(string id, IChatClient chatClient) : base(id)
{
ChatClientAgentOptions agentOptions = new(instructions: "You are a professional editor. You will be given a slogan and the task it is meant to accomplish.")
ChatClientAgentOptions agentOptions = new()
{
ChatOptions = new()
{
Instructions = "You are a professional editor. You will be given a slogan and the task it is meant to accomplish.",
ResponseFormat = ChatResponseFormat.ForJsonSchema<FeedbackResult>()
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,11 @@ private static async Task Main()
/// </summary>
/// <returns>A ChatClientAgent configured for spam detection</returns>
private static ChatClientAgent GetSpamDetectionAgent(IChatClient chatClient) =>
new(chatClient, new ChatClientAgentOptions(instructions: "You are a spam detection assistant that identifies spam emails.")
new(chatClient, new ChatClientAgentOptions()
{
ChatOptions = new()
{
Instructions = "You are a spam detection assistant that identifies spam emails.",
ResponseFormat = ChatResponseFormat.ForJsonSchema<DetectionResult>()
}
});
Expand All @@ -98,10 +99,11 @@ private static ChatClientAgent GetSpamDetectionAgent(IChatClient chatClient) =>
/// </summary>
/// <returns>A ChatClientAgent configured for email assistance</returns>
private static ChatClientAgent GetEmailAssistantAgent(IChatClient chatClient) =>
new(chatClient, new ChatClientAgentOptions(instructions: "You are an email assistant that helps users draft responses to emails with professionalism.")
new(chatClient, new ChatClientAgentOptions()
{
ChatOptions = new()
{
Instructions = "You are an email assistant that helps users draft responses to emails with professionalism.",
ResponseFormat = ChatResponseFormat.ForJsonSchema<EmailResponse>()
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,11 @@ private static async Task Main()
/// </summary>
/// <returns>A ChatClientAgent configured for spam detection</returns>
private static ChatClientAgent GetSpamDetectionAgent(IChatClient chatClient) =>
new(chatClient, new ChatClientAgentOptions(instructions: "You are a spam detection assistant that identifies spam emails. Be less confident in your assessments.")
new(chatClient, new ChatClientAgentOptions()
{
ChatOptions = new()
{
Instructions = "You are a spam detection assistant that identifies spam emails. Be less confident in your assessments.",
ResponseFormat = ChatResponseFormat.ForJsonSchema<DetectionResult>()
}
});
Expand All @@ -113,10 +114,11 @@ private static ChatClientAgent GetSpamDetectionAgent(IChatClient chatClient) =>
/// </summary>
/// <returns>A ChatClientAgent configured for email assistance</returns>
private static ChatClientAgent GetEmailAssistantAgent(IChatClient chatClient) =>
new(chatClient, new ChatClientAgentOptions(instructions: "You are an email assistant that helps users draft responses to emails with professionalism.")
new(chatClient, new ChatClientAgentOptions()
{
ChatOptions = new()
{
Instructions = "You are an email assistant that helps users draft responses to emails with professionalism.",
ResponseFormat = ChatResponseFormat.ForJsonSchema<EmailResponse>()
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,11 @@ private static async Task Main()
/// </summary>
/// <returns>A ChatClientAgent configured for email analysis</returns>
private static ChatClientAgent GetEmailAnalysisAgent(IChatClient chatClient) =>
new(chatClient, new ChatClientAgentOptions(instructions: "You are a spam detection assistant that identifies spam emails.")
new(chatClient, new ChatClientAgentOptions()
{
ChatOptions = new()
{
Instructions = "You are a spam detection assistant that identifies spam emails.",
ResponseFormat = ChatResponseFormat.ForJsonSchema<AnalysisResult>()
}
});
Expand All @@ -153,10 +154,11 @@ private static ChatClientAgent GetEmailAnalysisAgent(IChatClient chatClient) =>
/// </summary>
/// <returns>A ChatClientAgent configured for email assistance</returns>
private static ChatClientAgent GetEmailAssistantAgent(IChatClient chatClient) =>
new(chatClient, new ChatClientAgentOptions(instructions: "You are an email assistant that helps users draft responses to emails with professionalism.")
new(chatClient, new ChatClientAgentOptions()
{
ChatOptions = new()
{
Instructions = "You are an email assistant that helps users draft responses to emails with professionalism.",
ResponseFormat = ChatResponseFormat.ForJsonSchema<EmailResponse>()
}
});
Expand All @@ -166,10 +168,11 @@ private static ChatClientAgent GetEmailAssistantAgent(IChatClient chatClient) =>
/// </summary>
/// <returns>A ChatClientAgent configured for email summarization</returns>
private static ChatClientAgent GetEmailSummaryAgent(IChatClient chatClient) =>
new(chatClient, new ChatClientAgentOptions(instructions: "You are an assistant that helps users summarize emails.")
new(chatClient, new ChatClientAgentOptions()
{
ChatOptions = new()
{
Instructions = "You are an assistant that helps users summarize emails.",
ResponseFormat = ChatResponseFormat.ForJsonSchema<EmailSummary>()
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,19 +285,19 @@ public CriticExecutor(IChatClient chatClient) : base("Critic")
this._agent = new ChatClientAgent(chatClient, new ChatClientAgentOptions
{
Name = "Critic",
Instructions = """
You are a constructive critic. Review the content and provide specific feedback.
Always try to provide actionable suggestions for improvement and strive to identify improvement points.
Only approve if the content is high quality, clear, and meets the original requirements and you see no improvement points.

Provide your decision as structured output with:
- approved: true if content is good, false if revisions needed
- feedback: specific improvements needed (empty if approved)

Be concise but specific in your feedback.
""",
ChatOptions = new()
{
Instructions = """
You are a constructive critic. Review the content and provide specific feedback.
Always try to provide actionable suggestions for improvement and strive to identify improvement points.
Only approve if the content is high quality, clear, and meets the original requirements and you see no improvement points.

Provide your decision as structured output with:
- approved: true if content is good, false if revisions needed
- feedback: specific improvements needed (empty if approved)

Be concise but specific in your feedback.
""",
ResponseFormat = ChatResponseFormat.ForJsonSchema<CriticDecision>()
}
});
Expand Down
2 changes: 1 addition & 1 deletion dotnet/samples/M365Agent/Agents/WeatherForecastAgent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ public WeatherForecastAgent(IChatClient chatClient)
new ChatClientAgentOptions()
{
Name = AgentName,
Instructions = AgentInstructions,
ChatOptions = new ChatOptions()
{
Instructions = AgentInstructions,
Tools = [new ApprovalRequiredAIFunction(AIFunctionFactory.Create(GetWeather))],
// We want the agent to return structured output in a known format
// so that we can easily create adaptive cards from the response.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,20 @@ public static ChatClientAgent CreateAIAgent(
{
var options = new ChatClientAgentOptions
{
Instructions = instructions,
Name = name,
Description = description,
};

if (!string.IsNullOrWhiteSpace(instructions))
{
options.ChatOptions ??= new();
options.ChatOptions.Instructions = instructions;
}

if (tools is { Count: > 0 })
{
options.ChatOptions = new ChatOptions { Tools = tools };
options.ChatOptions ??= new();
options.ChatOptions.Tools = tools;
}

var chatClient = betaService.AsIChatClient(model, defaultMaxTokens ?? DefaultMaxTokens);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,20 @@ public static ChatClientAgent CreateAIAgent(
{
var options = new ChatClientAgentOptions
{
Instructions = instructions,
Name = name,
Description = description,
};

if (!string.IsNullOrWhiteSpace(instructions))
{
options.ChatOptions ??= new();
options.ChatOptions.Instructions = instructions;
}

if (tools is { Count: > 0 })
{
options.ChatOptions = new ChatOptions { Tools = tools };
options.ChatOptions ??= new();
options.ChatOptions.Tools = tools;
}

var chatClient = client.AsIChatClient(model, defaultMaxTokens ?? DefaultMaxTokens);
Expand Down
Loading
Loading