A Blazor Web App playground for quickly testing agents built with Microsoft Agent Framework. The project provides a ready-to-use chat UI, session handling, streaming responses, reasoning display, function-call visibility, and token-usage details, so you can focus on defining and experimenting with your agent.
- Overview
- Screenshots
- Prerequisites
- Project Structure
- Setup
- Supported Features
- How to Use
- Limitations & FAQ
- Contributing
- License
This application allows you to:
- Define a Microsoft Agent Framework agent in one place:
Program.cs - Test the agent immediately through a Blazor chat interface
- Stream answers as they are generated
- Show reasoning output when the model provides it
- Show function/tool calls made by the agent
- Display token usage for each completed answer
- Keep conversation history through an
AgentSessionStore
The goal is to provide a lightweight playground for local agent experiments. Instead of rebuilding a chat UI and streaming pipeline for every test, you can configure the PlaygroundAgent and start interacting with it from the browser.
The default agent is registered in Program.cs with the name PlaygroundAgent. The AgentService is already wired to that agent and its session store, and exposes a streaming method that the Blazor UI consumes.
- .NET 10 SDK
- An AI provider account and API key
- A chat model supported by Microsoft Agent Framework or exposed through an
IChatClientintegration
AgentPlayground/- Main Blazor Web AppComponents/- Blazor UI components and the chat pageModels/- Request and response models used by the chat pipelineServices/- Agent execution and session-store servicesSettings/- Configuration classesTools/- Example tools/functions that can be exposed to the agentTracing/- HTTP tracing utilities for inspecting requests sent to the configured AI provider
-
Clone the repository
git clone https://github.com/marcominerva/AgentPlayground.git
-
Configure the AI provider
The default sample uses Azure OpenAI. Edit
AgentPlayground/appsettings.jsonand set the corresponding values:{ "AzureOpenAI": { "Endpoint": "https://<your-resource>.openai.azure.com/openai/v1/", "Deployment": "<your-chat-deployment>", "ApiKey": "<your-api-key>" }, "AppSettings": { "MessageExpiration": "00:05:00", "MessageLimit": 20 } }The playground is not tied to Azure OpenAI. You can use any provider supported by Microsoft Agent Framework, or any provider that can expose an
IChatClient: add the corresponding settings toappsettings.json, reference the required Agent Framework/provider packages, and configure the chat client accordingly inProgram.cs.For example, to use Anthropic, add a configuration section like this:
{ "Anthropic": { "ModelId": "claude-sonnet-4-5", "ApiKey": "<your-api-key>" }, "AppSettings": { "MessageExpiration": "00:05:00", "MessageLimit": 20 } }Then add the
Microsoft.Agents.AI.Anthropicpackage, create the Anthropic client, and convert it toIChatClientwithAsIChatClient(modelId):var anthropicSettings = builder.Configuration.GetSection("Anthropic"); builder.Services.AddChatClient(_ => { var apiKey = anthropicSettings["ApiKey"]!; var modelId = anthropicSettings["ModelId"]!; var anthropicClient = new AnthropicClient { ApiKey = apiKey }; return anthropicClient.AsIChatClient(modelId); });
The
PlaygroundAgentregistration remains the same as shown in the next step: it only needs anIChatClientfrom dependency injection (see below). -
Configure the agent
Open
Program.csand update thePlaygroundAgentregistration:builder.Services.AddAIAgent("PlaygroundAgent", (services, key) => { var chatClient = services.GetRequiredService<IChatClient>(); return chatClient.AsAIAgent(new ChatClientAgentOptions { Id = key.ToLowerInvariant(), Name = key, ChatOptions = new() { Instructions = """ You are a helpful assistant. Answer the user's questions in the same language as the question. """, Reasoning = new() { Effort = ReasoningEffort.Low, Output = ReasoningOutput.Summary }, Tools = [new HostedWebSearchTool(), AIFunctionFactory.Create(DateTimeTools.GetCurrentDateTime)] } }, loggerFactory: services.GetRequiredService<ILoggerFactory>(), services: services); }, ServiceLifetime.Scoped) .WithSessionStore((services, _) => services.GetRequiredService<HybridCacheSessionStoreService>(), withIsolation: false);
You can change the instructions, model options, reasoning options, and tools without touching the UI.
-
Run the application
dotnet run --project AgentPlayground/AgentPlayground.csproj
-
Access the Web App
- Navigate to the HTTPS URL shown in the console.
- Ready-to-use Blazor chat UI: The home page contains the chat experience, including message streaming, copy-to-clipboard, conversation reset, and Markdown rendering.
- Single agent configuration point: Configure
PlaygroundAgentinProgram.cs, then test it directly from the browser. - Microsoft Agent Framework integration: The app uses
AddAIAgent,ChatClientAgentOptions,AIAgent, andAgentSessionStorefrom Microsoft Agent Framework. - Conversation history: Sessions are stored with
HybridCacheSessionStoreService, so follow-up questions can use prior context. - Response streaming:
AgentServiceexposesAskStreamingAsync, which streams answer chunks to the UI as they arrive. - Reasoning visibility: Reasoning text emitted by the agent is surfaced separately in the stream.
- Function-call visibility: Tool/function calls are displayed while the answer is being generated.
- Token usage details: The final stream message includes token usage for the completed response.
- HTTP tracing: The configured
TraceHttpClientHandlercan print raw requests sent to Azure OpenAI to help debug agent behavior.
- Configure your agent: Edit the
PlaygroundAgentdefinition inProgram.cs. - Add or remove tools: Add function tools through
AIFunctionFactory.Create(...), hosted tools such asHostedWebSearchTool, or your own Microsoft Agent Framework-compatible tools. - Run the app: Start the Blazor app and open the chat page.
- Ask questions: The UI sends each question to
AgentService, which invokes the configured agent and streams the response back. - Inspect behavior: Watch the answer, reasoning, function calls, and token usage in the UI. Use console tracing when you need to inspect the raw OpenAI request payload.
- The Blazor home page creates a
Questionwith a conversation ID and the user's text. - The page calls
AgentService.AskStreamingAsync. AgentServiceretrieves the session forPlaygroundAgentthroughAgentSessionStore.- The service calls
agent.RunStreamingAsync(...)and processes each streamed update. - Text chunks are returned with
StreamState.Answering. - Reasoning chunks are returned with
StreamState.Reasoning. - Function calls are returned with
StreamState.FunctionCalling. - After streaming completes, the session is saved and a final
StreamState.Completedmessage is returned with token usage. - The Blazor UI renders the stream incrementally and shows final token details.
The chat stream uses the StreamState enum to identify what each update represents:
Answering: normal answer text generated by the agent.Reasoning: reasoning text emitted by the model when reasoning output is enabled.FunctionCalling: a tool/function call made by the agent.Completed: the final message, containing token usage for the full response.
- Session storage: The default session store uses
HybridCache. Configure cache options as needed for your testing scenario. - Reasoning availability: Reasoning output depends on the model and options configured in
ChatOptions. - Tool-call display: Function calls are shown from streamed content emitted by the agent. Tool result formatting depends on the agent/model behavior.
- Secrets: Do not commit real API keys. Prefer user secrets, environment variables, or your secret manager of choice.
Contributions are welcome! Please open issues or pull requests. For major changes, discuss them first via an issue.
This project is licensed under the MIT License. See the LICENSE file for details.

