Demonstrates basic AI agent setup allowing users to configure instructions and messages, with Submit and Stream buttons for synchronous and real-time responses using OpenAI GPT-4.1-nano via OpenRouter.
-
-
-
-
-
-
-
-
-
-
-
-
+
+
π€ Agent 01 β Basic Agent
+
Demonstrates basic AI agent setup allowing users to configure instructions and messages, with Submit and Stream buttons for synchronous and real-time responses using OpenAI GPT-4.1-nano via OpenRouter.
@code {
private string message = "Tell me a long joke about a pirate. It should be at least two pargraphs.";
@@ -44,8 +84,8 @@
protected override Task OnInitializedAsync()
{
- var apiKey = Configuration["OPEN_ROUTER_API_KEY"] ??
- throw new InvalidOperationException("OPEN_ROUTER_API_KEY is not set in.");
+ var apiKey = Configuration["OpenRouter:ApiKey"] ?? Configuration["OPEN_ROUTER_API_KEY"] ??
+ throw new InvalidOperationException("OpenRouter:ApiKey (or OPEN_ROUTER_API_KEY) is not configured.");
var openAIClientOptions = new OpenAIClientOptions
{
diff --git a/0-Agents/AgentsWebUI/Components/Pages/Agent02.razor b/0-Agents/AgentsWebUI/Components/Pages/Agent02.razor
index c1c2956..5f5804f 100644
--- a/0-Agents/AgentsWebUI/Components/Pages/Agent02.razor
+++ b/0-Agents/AgentsWebUI/Components/Pages/Agent02.razor
@@ -1,41 +1,118 @@
ο»Ώ@page "/agent02"
@inject IConfiguration Configuration
-Agent 02
-
Agent 02 - Agent with Thread (Multi-conversation)
+Agent 02 β Agent with Thread
-
Showcases multi-turn conversations with threads, where the agent maintains context across sequential messages using GetNewThread() for continued interaction.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
π§΅ Agent 02 β Agent with Thread
+
Showcases multi-turn conversations with threads, where the agent maintains context across sequential messages using GetNewThread() for continued interaction.
@code {
private string instructions = "You are good at telling jokes.";
@@ -53,8 +130,8 @@
protected override Task OnInitializedAsync()
{
- var apiKey = Configuration["OPEN_ROUTER_API_KEY"] ??
- throw new InvalidOperationException("OPEN_ROUTER_API_KEY is not set in.");
+ var apiKey = Configuration["OpenRouter:ApiKey"] ?? Configuration["OPEN_ROUTER_API_KEY"] ??
+ throw new InvalidOperationException("OpenRouter:ApiKey (or OPEN_ROUTER_API_KEY) is not configured.");
var openAIClientOptions = new OpenAIClientOptions
{
diff --git a/0-Agents/AgentsWebUI/Components/Pages/Agent03.razor b/0-Agents/AgentsWebUI/Components/Pages/Agent03.razor
index ca1ea41..0424cc6 100644
--- a/0-Agents/AgentsWebUI/Components/Pages/Agent03.razor
+++ b/0-Agents/AgentsWebUI/Components/Pages/Agent03.razor
@@ -1,43 +1,85 @@
ο»Ώ@page "/agent03"
@inject IConfiguration Configuration
-Agent 03
+Agent 03 β Agent with Function/Tool
-
Agent 03 - Agent with Function/Tool
-
-
Demonstrates function calling with AIFunctionFactory-created tools (Add and Multiply), logging function executions and enabling agents to perform calculations.
-
-
-
-
-
-
-
-
-
-
-
-
+
+
π§ Agent 03 β Agent with Function/Tool
+
Demonstrates function calling with AIFunctionFactory-created tools (Add and Multiply), logging function executions and enabling agents to perform calculations.
@code {
private string message = "I have purchased 2 apples for $5. I purchased 10 more apples $4 each. How much is the value of my apples?";
@@ -52,8 +94,8 @@
protected override Task OnInitializedAsync()
{
- var apiKey = Configuration["OPEN_ROUTER_API_KEY"] ??
- throw new InvalidOperationException("OPEN_ROUTER_API_KEY is not set in.");
+ var apiKey = Configuration["OpenRouter:ApiKey"] ?? Configuration["OPEN_ROUTER_API_KEY"] ??
+ throw new InvalidOperationException("OpenRouter:ApiKey (or OPEN_ROUTER_API_KEY) is not configured.");
var openAIClientOptions = new OpenAIClientOptions
{
diff --git a/0-Agents/AgentsWebUI/Components/Pages/Agent04.razor b/0-Agents/AgentsWebUI/Components/Pages/Agent04.razor
index 3200f55..4f2eeda 100644
--- a/0-Agents/AgentsWebUI/Components/Pages/Agent04.razor
+++ b/0-Agents/AgentsWebUI/Components/Pages/Agent04.razor
@@ -2,43 +2,88 @@
@inject IConfiguration Configuration
@inject IJSRuntime JsRuntime
-Agent 04
+Agent 04 β Functions with User Approval
-
Agent 0 - Functions with User Approval
-
-
Features user approval for function calls using ApprovalRequiredAIFunction, prompting confirmations via JavaScript dialog before executing math operations.
-
-
-
-
-
-
-
-
-
-
-
-
+
+
β Agent 04 β Functions with User Approval
+
Features user approval for function calls using ApprovalRequiredAIFunction, prompting confirmations via JavaScript dialog before executing math operations.
-@if (!string.IsNullOrEmpty(response))
-{
+
+
+
-
+
+
βοΈ Configuration
-
Response
-
@response
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
Log
-
@((MarkupString)log)
-
+
+ β οΈ This page requires browser approval dialogs. Make sure pop-ups are not blocked for this site.
@code {
private string message = "Please provide information about John Smith, who is a 35-year-old software engineer.";
@@ -45,8 +80,8 @@
protected override Task OnInitializedAsync()
{
- var apiKey = Configuration["OPEN_ROUTER_API_KEY"] ??
- throw new InvalidOperationException("OPEN_ROUTER_API_KEY is not set in.");
+ var apiKey = Configuration["OpenRouter:ApiKey"] ?? Configuration["OPEN_ROUTER_API_KEY"] ??
+ throw new InvalidOperationException("OpenRouter:ApiKey (or OPEN_ROUTER_API_KEY) is not configured.");
var openAIClientOptions = new OpenAIClientOptions
{
diff --git a/0-Agents/AgentsWebUI/Components/Pages/Agent06.razor b/0-Agents/AgentsWebUI/Components/Pages/Agent06.razor
index 7d89482..613de4a 100644
--- a/0-Agents/AgentsWebUI/Components/Pages/Agent06.razor
+++ b/0-Agents/AgentsWebUI/Components/Pages/Agent06.razor
@@ -1,50 +1,94 @@
ο»Ώ@page "/agent06"
@inject IConfiguration Configuration
-Agent 06
+Agent 06 β Persisted Conversation
-
Agent 06 - Persisted Conversation
-
-
Shows thread persistence through serialization and deserialization, saving conversation state to temporary files and resuming multi-turn dialogues.
-
-
-
-
-
-
-
-
-
-
-
-
+
+
πΎ Agent 06 β Persisted Conversation
+
Shows thread persistence through serialization and deserialization, saving conversation state to temporary files and resuming multi-turn dialogues.
@code {
private string message = "Tell me a short joke about a pirate.";
@@ -60,8 +104,8 @@
protected override Task OnInitializedAsync()
{
- var apiKey = Configuration["OPEN_ROUTER_API_KEY"] ??
- throw new InvalidOperationException("OPEN_ROUTER_API_KEY is not set in.");
+ var apiKey = Configuration["OpenRouter:ApiKey"] ?? Configuration["OPEN_ROUTER_API_KEY"] ??
+ throw new InvalidOperationException("OpenRouter:ApiKey (or OPEN_ROUTER_API_KEY) is not configured.");
var openAIClientOptions = new OpenAIClientOptions
{
diff --git a/0-Agents/AgentsWebUI/Components/Pages/Agent07.razor b/0-Agents/AgentsWebUI/Components/Pages/Agent07.razor
index e606ca3..75f5184 100644
--- a/0-Agents/AgentsWebUI/Components/Pages/Agent07.razor
+++ b/0-Agents/AgentsWebUI/Components/Pages/Agent07.razor
@@ -2,50 +2,97 @@
@inject IConfiguration Configuration
@using Microsoft.Extensions.VectorData
-Agent 07
+Agent 07 β Custom Thread Storage
-
Agent 07 - Custom Thread Storage
-
-
Demonstrates custom thread storage with VectorChatMessageStore, persisting conversation history in an in-memory vector store for scalable context management.
-
-
-
-
-
-
-
-
-
-
-
-
+
+
ποΈ Agent 07 β Custom Thread Storage
+
Demonstrates custom thread storage with VectorChatMessageStore, persisting conversation history in an in-memory vector store for scalable context management.
-@if (!string.IsNullOrEmpty(response))
-{
-
-
+
+
+
+
+
+
βοΈ Configuration
-
Response
-
@((MarkupString)@response)
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
Log
-
@((MarkupString)log)
-
+
+ π§ Uses an in-memory vector store as a custom ChatHistoryProvider for session storage.
@code {
private string message = "What do you see in this image?";
@@ -44,8 +91,8 @@
protected override Task OnInitializedAsync()
{
- var apiKey = Configuration["OPEN_ROUTER_API_KEY"] ??
- throw new InvalidOperationException("OPEN_ROUTER_API_KEY is not set in.");
+ var apiKey = Configuration["OpenRouter:ApiKey"] ?? Configuration["OPEN_ROUTER_API_KEY"] ??
+ throw new InvalidOperationException("OpenRouter:ApiKey (or OPEN_ROUTER_API_KEY) is not configured.");
var openAIClientOptions = new OpenAIClientOptions
{
@@ -63,11 +110,15 @@
{
response = string.Empty;
isLoading = true;
+ // Load image binary from local image file at wwwroot/image.jpg
+
+ var imageData = await File.ReadAllBytesAsync(Path.Combine(WebHostEnvironment.WebRootPath, "image.jpg"));
+ var imageContent = new DataContent(imageData, "image/jpeg");
var chatMessage = new Microsoft.Extensions.AI.ChatMessage(ChatRole.User,
[
new TextContent(message),
- new UriContent("https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg", "image/jpeg")
+ imageContent
]);
var thread = await agent.CreateSessionAsync();
diff --git a/0-Agents/AgentsWebUI/Components/Pages/Agent09.razor b/0-Agents/AgentsWebUI/Components/Pages/Agent09.razor
index b9ea936..a777c39 100644
--- a/0-Agents/AgentsWebUI/Components/Pages/Agent09.razor
+++ b/0-Agents/AgentsWebUI/Components/Pages/Agent09.razor
@@ -1,42 +1,88 @@
ο»Ώ@page "/agent09"
@inject IConfiguration Configuration
-Agent 09
+Agent 09 β Using Remote MCP Server
-
Agent 09 - Using Remote MCP Server
-
-
Integrates remote MCP server for Microsoft Learn documentation search, allowing agents to query and fetch official docs using HttpClientTransport.
-
-
-
-
-
-
-
-
-
-
-
-
+
+
π Agent 09 β Using Remote MCP Server
+
Integrates remote MCP server for Microsoft Learn documentation search, allowing agents to query and fetch official docs using HttpClientTransport.
-@if (!string.IsNullOrEmpty(response))
-{
+
+
+
-
+
+
βοΈ Configuration
-
Response
-
@((MarkupString)RenderMarkdown(response))
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
Log
-
@((MarkupString)log)
-
+
+ π Connects to the Microsoft Learn MCP at learn.microsoft.com/api/mcp via HttpClientTransport.
@code {
#pragma warning disable MEAI001
@@ -81,8 +125,8 @@
protected override async Task OnInitializedAsync()
{
- var apiKey = Configuration["OPEN_ROUTER_API_KEY"] ??
- throw new InvalidOperationException("OPEN_ROUTER_API_KEY is not set in.");
+ var apiKey = Configuration["OpenRouter:ApiKey"] ?? Configuration["OPEN_ROUTER_API_KEY"] ??
+ throw new InvalidOperationException("OpenRouter:ApiKey (or OPEN_ROUTER_API_KEY) is not configured.");
var openAIClientOptions = new OpenAIClientOptions
{
diff --git a/0-Agents/AgentsWebUI/Components/Pages/Agent12.razor b/0-Agents/AgentsWebUI/Components/Pages/Agent12.razor
index 4720fe8..a6dfbe5 100644
--- a/0-Agents/AgentsWebUI/Components/Pages/Agent12.razor
+++ b/0-Agents/AgentsWebUI/Components/Pages/Agent12.razor
@@ -1,38 +1,79 @@
ο»Ώ@page "/agent12"
@inject IConfiguration Configuration
-Agent 12
+Agent 12 β Background Responses
-
Agent 12 - Backgroud Responses
-
-
Explores background responses with continuation tokens for handling long-running processes and resumable streaming (note: Azure-only feature).
-
-
This example won't work: it only works with Azure and they don't support other yet.
-
-
-
-
-
-
-
-
-
-
-
-
+
+
β³ Agent 12 β Background Responses
+
Explores background responses with continuation tokens for handling long-running processes and resumable streaming (note: Azure-only feature).
-@if (!string.IsNullOrEmpty(response))
-{
+
+
+
-
+
+
βοΈ Configuration
-
Response
-
@((MarkupString)RenderMarkdown(@response))
+
+
+
+
+
+
+
+
+
+
+
+
+
+ β οΈ Azure-only feature. This example requires Azure OpenAI and will not work with other providers. Background responses use AllowBackgroundResponses = true and ContinuationToken for resumable streaming.
+
@code {
@@ -51,8 +92,8 @@
protected override async Task OnInitializedAsync()
{
- var apiKey = Configuration["OPEN_ROUTER_API_KEY"] ??
- throw new InvalidOperationException("OPEN_ROUTER_API_KEY is not set in.");
+ var apiKey = Configuration["OpenRouter:ApiKey"] ?? Configuration["OPEN_ROUTER_API_KEY"] ??
+ throw new InvalidOperationException("OpenRouter:ApiKey (or OPEN_ROUTER_API_KEY) is not configured.");
var openAIClientOptions = new OpenAIClientOptions
{
diff --git a/0-Agents/AgentsWebUI/Components/Pages/Agent13.razor b/0-Agents/AgentsWebUI/Components/Pages/Agent13.razor
index c764223..18b71a9 100644
--- a/0-Agents/AgentsWebUI/Components/Pages/Agent13.razor
+++ b/0-Agents/AgentsWebUI/Components/Pages/Agent13.razor
@@ -1,37 +1,79 @@
ο»Ώ@page "/agent13"
@inject IConfiguration Configuration
-Agent 13
+Agent 13 β Plugins
-
Agent 13 - Plugins
-
-
Showcases plugins with dependency injection, exposing weather and time providers as AI tools in a service collection architecture.
-
-
-
-
-
-
-
-
-
-
-
-
+
+
π§ Agent 13 β Plugins
+
Showcases plugins with dependency injection, exposing weather and time providers as AI tools in a service collection architecture.
-@if (!string.IsNullOrEmpty(response))
-{
+
+
+
-
+
+ π‘ Plugins via DI: This agent registers WeatherProvider and CurrentTimeProvider in a ServiceCollection, then exposes them as AI tools through an AgentPlugin class.
+
@code {
#pragma warning disable MEAI001
@@ -53,8 +103,8 @@
protected override Task OnInitializedAsync()
{
- var apiKey = Configuration["OPEN_ROUTER_API_KEY"] ??
- throw new InvalidOperationException("OPEN_ROUTER_API_KEY is not set in.");
+ var apiKey = Configuration["OpenRouter:ApiKey"] ?? Configuration["OPEN_ROUTER_API_KEY"] ??
+ throw new InvalidOperationException("OpenRouter:ApiKey (or OPEN_ROUTER_API_KEY) is not configured.");
var openAIClientOptions = new OpenAIClientOptions
{
diff --git a/0-Agents/AgentsWebUI/Components/Pages/Agent15.razor b/0-Agents/AgentsWebUI/Components/Pages/Agent15.razor
index bb03dce..2913eab 100644
--- a/0-Agents/AgentsWebUI/Components/Pages/Agent15.razor
+++ b/0-Agents/AgentsWebUI/Components/Pages/Agent15.razor
@@ -1,32 +1,94 @@
ο»Ώ@page "/agent15"
@inject IConfiguration Configuration
-Agent 15
+Agent 15 β Declarative Agent
-
Agent 15 - Declartive Agent
-
-
Uses declarative agent configuration via YAML, defining output schema for structured responses with specified temperature and model options.
-
-
-
-
-
-
-
-
+
+
β οΈ Agent 15 β Declarative Agent
+
Uses declarative agent configuration via YAML, defining output schema for structured responses with specified temperature and model options.
-@if (!string.IsNullOrEmpty(response))
-{
+
+
+
-
+
+
βοΈ YAML Agent Definition
-
Response
-
@response
+
+
+
kind: Prompt
+name: Assistant
+description: Helpful assistant
+instructions: You are a helpful assistant.
+ You answer questions in the language
+ specified by the user. You return your
+ answers in a JSON format.
+model:
+ options:
+ temperature: 0.9
+ topP: 0.95
+outputSchema:
+ properties:
+ language:
+ type: string
+ required: true
+ answer:
+ type: string
+ required: true
@code {
private string message = "Tell me a long joke about a pirate. It should be at least two pargraphs.";
@@ -62,8 +124,8 @@
protected override Task OnInitializedAsync()
{
- var apiKey = Configuration["OPEN_ROUTER_API_KEY"] ??
- throw new InvalidOperationException("OPEN_ROUTER_API_KEY is not set in.");
+ var apiKey = Configuration["OpenRouter:ApiKey"] ?? Configuration["OPEN_ROUTER_API_KEY"] ??
+ throw new InvalidOperationException("OpenRouter:ApiKey (or OPEN_ROUTER_API_KEY) is not configured.");
var openAIClientOptions = new OpenAIClientOptions
{
diff --git a/0-Agents/AgentsWebUI/Components/Pages/Agent16.razor b/0-Agents/AgentsWebUI/Components/Pages/Agent16.razor
index 971c872..cba19a8 100644
--- a/0-Agents/AgentsWebUI/Components/Pages/Agent16.razor
+++ b/0-Agents/AgentsWebUI/Components/Pages/Agent16.razor
@@ -1,38 +1,85 @@
ο»Ώ@page "/agent16"
@inject IConfiguration Configuration
-Agent 16
+Agent 16 β Reasoning
-
Agent 16 - Reasoning
-
-
Demonstrates advanced reasoning capabilities using OpenAI's o4-mini model through OpenRouter, allowing users to see both the final response and the step-by-step reasoning process.
-
-
-
-
-
-
-
-
+
+
β οΈ Agent 16 β Reasoning
+
Demonstrates advanced reasoning capabilities using OpenAI's o4-mini model through OpenRouter, allowing users to see both the final response and the step-by-step reasoning process.
Guides the model to reason step-by-step before arriving at a final answer, improving accuracy on complex problems.
+
+
+
+ π‘ Chain-of-Thought (CoT): A prompting strategy where the model is instructed to break down its reasoning into explicit steps before reaching a conclusion. This improves accuracy on math, logic, and multi-step problems by externalising the reasoning process.
+
@code {
private string message = "A farmer has 17 sheep. All but 9 run away. How many sheep does the farmer have left? Show your reasoning.";
@@ -70,8 +106,8 @@
protected override Task OnInitializedAsync()
{
- var apiKey = Configuration["OPEN_ROUTER_API_KEY"] ??
- throw new InvalidOperationException("OPEN_ROUTER_API_KEY is not set.");
+ var apiKey = Configuration["OpenRouter:ApiKey"] ?? Configuration["OPEN_ROUTER_API_KEY"] ??
+ throw new InvalidOperationException("OpenRouter:ApiKey (or OPEN_ROUTER_API_KEY) is not configured.");
var openAIClientOptions = new OpenAIClientOptions { Endpoint = new Uri(endpoint) };
var credential = new ApiKeyCredential(apiKey);
var chatClient = new ChatClient(modelName, credential, openAIClientOptions);
diff --git a/0-Agents/AgentsWebUI/Components/Pages/Agent18.razor b/0-Agents/AgentsWebUI/Components/Pages/Agent18.razor
index 345375c..492c0e7 100644
--- a/0-Agents/AgentsWebUI/Components/Pages/Agent18.razor
+++ b/0-Agents/AgentsWebUI/Components/Pages/Agent18.razor
@@ -2,81 +2,107 @@
@using Markdig
@inject IConfiguration Configuration
-Agent 18
-
Agent 18 - Tree of Thoughts
-
Explores multiple reasoning branches simultaneously, evaluates each path, and selects the most promising solution.
Explores multiple reasoning branches simultaneously, evaluates each path, and selects the most promising solution.
-@if (logMessages.Count > 0)
-{
-
-
Log
-
-
- @foreach (var log in logMessages)
- {
-
@log
- }
-
-
-
-}
+
+ π‘ Tree of Thoughts (ToT): A prompting strategy that creates a tree-shaped reasoning structure by spawning multiple independent thought branches. Each branch explores a different perspective or approach, and an evaluator agent synthesises the best elements into a final solution.
+
@code {
private string message = "How would you approach building a sustainable city transportation system?";
@@ -101,8 +127,8 @@
protected override Task OnInitializedAsync()
{
- var apiKey = Configuration["OPEN_ROUTER_API_KEY"] ??
- throw new InvalidOperationException("OPEN_ROUTER_API_KEY is not set.");
+ var apiKey = Configuration["OpenRouter:ApiKey"] ?? Configuration["OPEN_ROUTER_API_KEY"] ??
+ throw new InvalidOperationException("OpenRouter:ApiKey (or OPEN_ROUTER_API_KEY) is not configured.");
var openAIClientOptions = new OpenAIClientOptions { Endpoint = new Uri(endpoint) };
var credential = new ApiKeyCredential(apiKey);
diff --git a/0-Agents/AgentsWebUI/Components/Pages/Agent19.razor b/0-Agents/AgentsWebUI/Components/Pages/Agent19.razor
index 6d5ab47..4bae726 100644
--- a/0-Agents/AgentsWebUI/Components/Pages/Agent19.razor
+++ b/0-Agents/AgentsWebUI/Components/Pages/Agent19.razor
@@ -2,81 +2,107 @@
@using Markdig
@inject IConfiguration Configuration
-Agent 19
-
Agent 19 - Graph of Thoughts
-
Builds a non-linear reasoning graph where thoughts can merge, branch, and reference each other to solve complex problems.
Builds a non-linear reasoning graph where thoughts can merge, branch, and reference each other to solve complex problems.
-@if (logMessages.Count > 0)
-{
-
-
Log β Graph Edges
-
-
- @foreach (var log in logMessages)
- {
-
@log
- }
-
-
-
-}
+
+ π‘ Graph of Thoughts (GoT): A prompting strategy that models reasoning as a directed graph. A decomposer breaks the problem into sub-problems (nodes), specialist agents solve each node in parallel, and a synthesizer merges the solutions along graph edges into a final answer.
+
@code {
private string message = "Design an AI system that can both understand medical images and explain its diagnoses to patients.";
@@ -101,8 +127,8 @@
protected override Task OnInitializedAsync()
{
- var apiKey = Configuration["OPEN_ROUTER_API_KEY"] ??
- throw new InvalidOperationException("OPEN_ROUTER_API_KEY is not set.");
+ var apiKey = Configuration["OpenRouter:ApiKey"] ?? Configuration["OPEN_ROUTER_API_KEY"] ??
+ throw new InvalidOperationException("OpenRouter:ApiKey (or OPEN_ROUTER_API_KEY) is not configured.");
var openAIClientOptions = new OpenAIClientOptions { Endpoint = new Uri(endpoint) };
var credential = new ApiKeyCredential(apiKey);
diff --git a/0-Agents/AgentsWebUI/Components/Pages/Agent20.razor b/0-Agents/AgentsWebUI/Components/Pages/Agent20.razor
index a4afc5f..8d9ca09 100644
--- a/0-Agents/AgentsWebUI/Components/Pages/Agent20.razor
+++ b/0-Agents/AgentsWebUI/Components/Pages/Agent20.razor
@@ -2,61 +2,89 @@
@using Markdig
@inject IConfiguration Configuration
-Agent 20
-
Agent 20 - Program of Thoughts (PoT)
-
Generates executable pseudocode or step-by-step algorithmic logic to solve problems, separating computation from reasoning.
Generates executable pseudocode or step-by-step algorithmic logic to solve problems, separating computation from reasoning.
+
+
+
+ π‘ Program of Thoughts (PoT): A prompting strategy that separates reasoning from computation. The model writes a pseudocode program to solve the problem (the "program"), then a separate interpreter agent traces through each step to execute it and derive the final result.
+
@code {
private string message = "Calculate the sum of all even numbers between 1 and 20, then multiply by the count of odd numbers in the same range.";
@@ -77,8 +105,8 @@
protected override Task OnInitializedAsync()
{
- var apiKey = Configuration["OPEN_ROUTER_API_KEY"] ??
- throw new InvalidOperationException("OPEN_ROUTER_API_KEY is not set.");
+ var apiKey = Configuration["OpenRouter:ApiKey"] ?? Configuration["OPEN_ROUTER_API_KEY"] ??
+ throw new InvalidOperationException("OpenRouter:ApiKey (or OPEN_ROUTER_API_KEY) is not configured.");
var openAIClientOptions = new OpenAIClientOptions { Endpoint = new Uri(endpoint) };
var credential = new ApiKeyCredential(apiKey);
diff --git a/0-Agents/AgentsWebUI/Components/Pages/Agent21.razor b/0-Agents/AgentsWebUI/Components/Pages/Agent21.razor
index 92302c6..41f1ab4 100644
--- a/0-Agents/AgentsWebUI/Components/Pages/Agent21.razor
+++ b/0-Agents/AgentsWebUI/Components/Pages/Agent21.razor
@@ -3,54 +3,93 @@
@using System.ComponentModel
@inject IConfiguration Configuration
-Agent 21
-
Agent 21 - ReAct (Reason + Act)
-
Interleaves reasoning traces with action execution, allowing the agent to think, act, observe, and iterate toward a solution.
Interleaves reasoning traces with action execution, allowing the agent to think, act, observe, and iterate toward a solution.
+
+
+
+ π‘ ReAct (Reason + Act): A prompting strategy that interleaves reasoning traces with tool-use actions. The agent cycles through: Thought (what to do and why) β Action (calling a tool) β Observation (what the tool returned), repeating until it reaches a Final Answer.
+
The agent generates an initial response, then critically evaluates its own output for errors, gaps, and improvements.
+
+
+
+ π‘ Reflection: A prompting strategy where a second "critic" agent evaluates the initial response from a "responder" agent. The critic identifies errors, missing points, and rates quality β producing a structured self-critique that highlights areas for improvement.
+
Iteratively improves its own output through multiple refinement rounds, each time incorporating feedback from its own critique.
+
+
+
+ π‘ Self-Refine: A prompting strategy that iterates through a Generate β Critique β Refine loop. A generator produces an initial draft, a critic provides targeted feedback, and a refiner incorporates that feedback. This repeats for multiple rounds, progressively improving quality.
+
@code {
private string message = "Write a brief explanation of machine learning for a high school student.";
@@ -89,8 +116,8 @@
protected override Task OnInitializedAsync()
{
- var apiKey = Configuration["OPEN_ROUTER_API_KEY"] ??
- throw new InvalidOperationException("OPEN_ROUTER_API_KEY is not set.");
+ var apiKey = Configuration["OpenRouter:ApiKey"] ?? Configuration["OPEN_ROUTER_API_KEY"] ??
+ throw new InvalidOperationException("OpenRouter:ApiKey (or OPEN_ROUTER_API_KEY) is not configured.");
var openAIClientOptions = new OpenAIClientOptions { Endpoint = new Uri(endpoint) };
var credential = new ApiKeyCredential(apiKey);
diff --git a/0-Agents/AgentsWebUI/Components/Pages/Error.razor b/0-Agents/AgentsWebUI/Components/Pages/Error.razor
index 576cc2d..4630df2 100644
--- a/0-Agents/AgentsWebUI/Components/Pages/Error.razor
+++ b/0-Agents/AgentsWebUI/Components/Pages/Error.razor
@@ -3,26 +3,37 @@
Error
-
Error.
-
An error occurred while processing your request.
-
-@if (ShowRequestId)
-{
-
- Request ID:@RequestId
-
-}
+
+
β οΈ An Error Occurred
+
An error occurred while processing your request.
+
+
+
+
π΄ Error Details
+
+ @if (ShowRequestId)
+ {
+
+ Request ID:@RequestId
+
+ }
+
+
+ Something went wrong. If this problem persists, please try reloading the page.
+
-
Development Mode
-
- Swapping to Development environment will display more detailed information about the error that occurred.
-
-
- The Development environment shouldn't be enabled for deployed applications.
- It can result in displaying sensitive information from exceptions to end users.
- For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development
- and restarting the app.
-
+
Development Mode
+
+ Swapping to Development environment will display more detailed information about the error that occurred.
+
+
+ The Development environment shouldn't be enabled for deployed applications.
+ It can result in displaying sensitive information from exceptions to end users.
+ For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development
+ and restarting the app.
+
+```
+
+Panel headers inherit Bootstrap `.card-header` and get overridden by the `.panel-*` modifier. The headers are styled with uppercased small text, a subtle background, and a border-bottom that matches the panel type colour.
+
+---
+
+### Page Header
+
+Every agent page should have a consistent header block above the panels.
+
+```html
+
+
Agent 01 - Basic Agent
+
+ Demonstrates basic AI agent setup allowing users to configure instructions and messages,
+ with Submit and Stream buttons for synchronous and real-time responses.
+
+
+```
+
+- `.page-title` β 1.5rem bold, line-height tight
+- `.page-subtitle` β 1.0625rem muted gray, max-width 720px
+
+---
+
+### Form Controls
+
+Use Bootstrap classes augmented by the design system overrides:
+
+```html
+
+}
+```
+
+---
+
+## Home Page Structure
+
+The Home page structure uses these classes:
+
+```html
+
+
+
+ π€
+
Microsoft Agent Framework Samples
+
+
...
+
+ .NET 10
+ Blazor
+
+
+
+
+
+
+ π
+
Basics
+ 3 samples
+
+
+
+
+
+
+
Basic Agent
+ Basic
+
+
Description...
+
+
+
+
+
+
+```
+
+The `.cat-basics`, `.cat-functions`, `.cat-storage`, `.cat-multimodal`, `.cat-advanced`, and `.cat-prompting` wrapper classes automatically apply the correct border, badge background, and button colour to all child elements.
+
+---
+
+## Navigation Menu
+
+The navigation menu in `NavMenu.razor` uses these classes (already in place):
+
+| Class | Purpose |
+|-------|---------|
+| `.nav-category-header` | Uppercase section label |
+| `.nav-divider` | `` separator between groups |
+| `.nav-icon` | Emoji icon wrapper with fixed width |
+| `.nav-scrollable` | Scrollable nav container |
+| `.navbar-brand` | App name in top left |
+
+Category header colours are set inline with `style="color: var(--color-cat-*)"` in the Razor file. This is acceptable since NavMenu.razor.css is a scoped file.
+
+---
+
+## Per-Category Theme System
+
+The theme system uses a BEM-like modifier pattern:
+
+```
+.agent-category.cat-[name]
+ βββ .category-header β 2px bottom border in category colour
+ βββ .cat-count-badge β background in category colour
+ βββ .agent-card β 4px top border in category colour
+ βββ .agent-badge β background in category colour
+ βββ .btn-cat β filled button in category colour (optional)
+```
+
+No JavaScript is needed. The CSS cascade handles all theming through the parent wrapper class.
+
+---
+
+## Files to Update After CSS is Applied
+
+Once `app.css` is complete, the following per-page CSS files can be **deleted**:
+
+| File | Can delete? | Reason |
+|------|-------------|--------|
+| `Home.razor.css` | β Yes | All classes migrated to `app.css` |
+| `NavMenu.razor.css` | β οΈ Keep | Contains scoped `::deep` selectors for Blazor component isolation |
+| `MainLayout.razor.css` | β οΈ Keep | Contains scoped layout media queries |
+| `ReconnectModal.razor.css` | β οΈ Keep | Scoped modal overlay styles |
+
+Agent pages (`Agent01.razor` through `Agent23.razor`) do not have individual `.razor.css` files currently, so no files need deletion for those β only the inline `style=""` attributes and the basic Bootstrap class usage need updating per the page structure pattern above.
+
+### Inline styles to migrate
+
+Several pages use inline style attributes that should be replaced with classes:
+
+- `style="height:200px;"` on `