This commit is contained in:
Javier Calvarro Nelson
2025-12-10 17:08:40 +01:00
Unverified
parent 0340531f3a
commit 0eef9949bf
37 changed files with 75 additions and 173 deletions
+2 -23
View File
@@ -23,6 +23,8 @@
<Project Path="samples/AGUIClientServer/AGUIServer/AGUIServer.csproj" />
</Folder>
<Folder Name="/Samples/AGUIDojo/">
<File Path="samples/AGUIDojo/Design.md" />
<File Path="samples/AGUIDojo/Plan.md" />
<Project Path="samples/AGUIDojo/AGUIDojoClient/AGUIDojoClient.csproj" />
<Project Path="samples/AGUIDojo/AGUIDojoServer/AGUIDojoServer.csproj" />
</Folder>
@@ -110,29 +112,6 @@
<Project Path="samples/GettingStarted/AGUI/Step05_StateManagement/Client/Client.csproj" />
<Project Path="samples/GettingStarted/AGUI/Step05_StateManagement/Server/Server.csproj" />
</Folder>
<Folder Name="/Samples/GettingStarted/AGUI/">
<File Path="samples/GettingStarted/AGUI/README.md" />
</Folder>
<Folder Name="/Samples/GettingStarted/AGUI/Step01_GettingStarted/">
<Project Path="samples/GettingStarted/AGUI/Step01_GettingStarted/Server/Server.csproj" />
<Project Path="samples/GettingStarted/AGUI/Step01_GettingStarted/Client/Client.csproj" />
</Folder>
<Folder Name="/Samples/GettingStarted/AGUI/Step02_BackendTools/">
<Project Path="samples/GettingStarted/AGUI/Step02_BackendTools/Server/Server.csproj" />
<Project Path="samples/GettingStarted/AGUI/Step02_BackendTools/Client/Client.csproj" />
</Folder>
<Folder Name="/Samples/GettingStarted/AGUI/Step03_FrontendTools/">
<Project Path="samples/GettingStarted/AGUI/Step03_FrontendTools/Server/Server.csproj" />
<Project Path="samples/GettingStarted/AGUI/Step03_FrontendTools/Client/Client.csproj" />
</Folder>
<Folder Name="/Samples/GettingStarted/AGUI/Step04_HumanInLoop/">
<Project Path="samples/GettingStarted/AGUI/Step04_HumanInLoop/Server/Server.csproj" />
<Project Path="samples/GettingStarted/AGUI/Step04_HumanInLoop/Client/Client.csproj" />
</Folder>
<Folder Name="/Samples/GettingStarted/AGUI/Step05_StateManagement/">
<Project Path="samples/GettingStarted/AGUI/Step05_StateManagement/Server/Server.csproj" />
<Project Path="samples/GettingStarted/AGUI/Step05_StateManagement/Client/Client.csproj" />
</Folder>
<Folder Name="/Samples/GettingStarted/DevUI/">
<File Path="samples/GettingStarted/DevUI/README.md" />
<Project Path="samples/GettingStarted/DevUI/DevUI_Step01_BasicUsage/DevUI_Step01_BasicUsage.csproj" />
@@ -1,17 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFrameworks>net10.0</TargetFrameworks>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<BlazorDisableThrowNavigationException>true</BlazorDisableThrowNavigationException>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" VersionOverride="10.0.0-rc.2.25502.107" />
<PackageReference Include="System.Net.ServerSentEvents" VersionOverride="10.0.0-rc.2.25502.107" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI\Microsoft.Agents.AI.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.AGUI\Microsoft.Agents.AI.AGUI.csproj" />
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.Extensions.AI;
@@ -16,8 +16,8 @@ public readonly struct Suggestion : IEquatable<Suggestion>
/// <param name="message">The message to send when the suggestion is selected.</param>
public Suggestion(string text, ChatMessage message)
{
Text = text;
Message = message;
this.Text = text;
this.Message = message;
}
/// <summary>
@@ -26,8 +26,8 @@ public readonly struct Suggestion : IEquatable<Suggestion>
/// <param name="text">The display text for the suggestion, also used as the message content.</param>
public Suggestion(string text)
{
Text = text;
Message = new ChatMessage(ChatRole.User, text);
this.Text = text;
this.Message = new ChatMessage(ChatRole.User, text);
}
/// <summary>
@@ -41,13 +41,13 @@ public readonly struct Suggestion : IEquatable<Suggestion>
public ChatMessage Message { get; }
/// <inheritdoc/>
public override bool Equals(object? obj) => obj is Suggestion other && Equals(other);
public override bool Equals(object? obj) => obj is Suggestion other && this.Equals(other);
/// <inheritdoc/>
public bool Equals(Suggestion other) => Text == other.Text;
public bool Equals(Suggestion other) => this.Text == other.Text;
/// <inheritdoc/>
public override int GetHashCode() => Text?.GetHashCode() ?? 0;
public override int GetHashCode() => this.Text?.GetHashCode() ?? 0;
/// <summary>
/// Determines whether two <see cref="Suggestion"/> instances are equal.
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.Extensions.AI;
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.
using System.Text.Json;
using Microsoft.Extensions.AI;
@@ -4,7 +4,6 @@ using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Text;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Components.AI;
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.
using System.Text.Json.Serialization;
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.
using System.Text.Json.Serialization;
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.
using System.Text.Json;
using System.Text.RegularExpressions;
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.
using System.Text.Json.Serialization;
@@ -1,6 +1,5 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.
using AGUIDojoClient.Components.Shared;
using Microsoft.Extensions.AI;
namespace Microsoft.AspNetCore.Components.AI;
@@ -1,8 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.AI;
using Microsoft.AspNetCore.Components.Rendering;
using Microsoft.Extensions.AI;
namespace AGUIDojoClient.Components.Demos.HumanInTheLoop;
@@ -1,6 +1,5 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.
using System.Runtime.CompilerServices;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.
using System.Text.Json.Serialization;
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.
using System.Text.Json.Serialization;
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.
namespace AGUIDojoClient.Components.Demos.HumanInTheLoop;
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.
using System.Text.RegularExpressions;
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.
using System.Text.Json.Serialization;
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.
namespace AGUIDojoClient.Components.Demos.PredictiveStateUpdates;
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.
using System.Text.Json.Serialization;
@@ -1,5 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Copyright (c) Microsoft. All rights reserved.
using System.Text.Json.Serialization;
@@ -1,5 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Copyright (c) Microsoft. All rights reserved.
using System.Text.Json.Serialization;
@@ -1,5 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Copyright (c) Microsoft. All rights reserved.
using System.Text.Json.Serialization;
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.
namespace AGUIDojoClient.Components.Demos.ToolBasedGenerativeUI;
@@ -1,8 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.AI;
using Microsoft.AspNetCore.Components.Rendering;
using Microsoft.Extensions.AI;
namespace AGUIDojoClient.Components.Demos.ToolBasedGenerativeUI;
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.
namespace AGUIDojoClient.Components.Shared;
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.Agents.AI.AGUI;
using Microsoft.Extensions.AI;
@@ -19,8 +19,8 @@ public sealed class DemoService
/// <param name="httpClientFactory">Factory for creating HTTP clients.</param>
public DemoService(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
_scenarios = InitializeScenarios();
this._httpClientFactory = httpClientFactory;
this._scenarios = InitializeScenarios();
}
/// <summary>
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.
using System.Text.Json.Serialization;
@@ -27,37 +27,61 @@ public sealed class WeatherInfo
/// <summary>
/// Gets the temperature in Fahrenheit.
/// </summary>
public double TemperatureFahrenheit => (Temperature * 9.0 / 5.0) + 32;
public double TemperatureFahrenheit => (this.Temperature * 9.0 / 5.0) + 32;
/// <summary>
/// Gets an emoji icon based on weather conditions.
/// </summary>
public string ConditionIcon => GetConditionIcon(Conditions);
public string ConditionIcon => GetConditionIcon(this.Conditions);
private static string GetConditionIcon(string conditions)
{
if (string.Equals(conditions, "sunny", StringComparison.OrdinalIgnoreCase) ||
string.Equals(conditions, "clear", StringComparison.OrdinalIgnoreCase))
{
return "☀️";
}
if (string.Equals(conditions, "cloudy", StringComparison.OrdinalIgnoreCase) ||
string.Equals(conditions, "overcast", StringComparison.OrdinalIgnoreCase))
{
return "☁️";
}
if (string.Equals(conditions, "rainy", StringComparison.OrdinalIgnoreCase) ||
string.Equals(conditions, "rain", StringComparison.OrdinalIgnoreCase))
{
return "🌧️";
}
if (string.Equals(conditions, "stormy", StringComparison.OrdinalIgnoreCase) ||
string.Equals(conditions, "thunderstorm", StringComparison.OrdinalIgnoreCase))
{
return "⛈️";
}
if (string.Equals(conditions, "snowy", StringComparison.OrdinalIgnoreCase) ||
string.Equals(conditions, "snow", StringComparison.OrdinalIgnoreCase))
{
return "❄️";
}
if (string.Equals(conditions, "foggy", StringComparison.OrdinalIgnoreCase) ||
string.Equals(conditions, "fog", StringComparison.OrdinalIgnoreCase))
{
return "🌫️";
}
if (string.Equals(conditions, "windy", StringComparison.OrdinalIgnoreCase))
{
return "💨";
}
if (string.Equals(conditions, "partly cloudy", StringComparison.OrdinalIgnoreCase))
{
return "⛅";
}
return "🌡️";
}
}
@@ -35,7 +35,7 @@ builder.Services.AddChatClient(sp =>
builder.Services.AddKeyedSingleton<AIAgent>("agentic-chat", (sp, key) =>
{
HttpClient httpClient = sp.GetRequiredService<IHttpClientFactory>().CreateClient("aguiserver");
AGUIChatClient aguiChatClient = new AGUIChatClient(httpClient, "agentic_chat");
AGUIChatClient aguiChatClient = new(httpClient, "agentic_chat");
// Get the background color service for the frontend tool
IBackgroundColorService backgroundService = sp.GetRequiredService<IBackgroundColorService>();
@@ -61,7 +61,7 @@ builder.Services.AddKeyedSingleton<AIAgent>("agentic-chat", (sp, key) =>
builder.Services.AddKeyedSingleton<AIAgent>("backend-tool-rendering", (sp, key) =>
{
HttpClient httpClient = sp.GetRequiredService<IHttpClientFactory>().CreateClient("aguiserver");
AGUIChatClient aguiChatClient = new AGUIChatClient(httpClient, "backend_tool_rendering");
AGUIChatClient aguiChatClient = new(httpClient, "backend_tool_rendering");
return aguiChatClient.CreateAIAgent(
name: "BackendToolRenderingAssistant",
@@ -72,7 +72,7 @@ builder.Services.AddKeyedSingleton<AIAgent>("backend-tool-rendering", (sp, key)
builder.Services.AddKeyedSingleton<AIAgent>("human-in-the-loop", (sp, key) =>
{
HttpClient httpClient = sp.GetRequiredService<IHttpClientFactory>().CreateClient("aguiserver");
AGUIChatClient aguiChatClient = new AGUIChatClient(httpClient, "human_in_the_loop");
AGUIChatClient aguiChatClient = new(httpClient, "human_in_the_loop");
// Create the base agent and wrap it with a delegating agent that adds instructions
AIAgent baseAgent = aguiChatClient.CreateAIAgent(
@@ -86,7 +86,7 @@ builder.Services.AddKeyedSingleton<AIAgent>("human-in-the-loop", (sp, key) =>
builder.Services.AddKeyedSingleton<AIAgent>("tool-based-generative-ui", (sp, key) =>
{
HttpClient httpClient = sp.GetRequiredService<IHttpClientFactory>().CreateClient("aguiserver");
AGUIChatClient aguiChatClient = new AGUIChatClient(httpClient, "tool_based_generative_ui");
AGUIChatClient aguiChatClient = new(httpClient, "tool_based_generative_ui");
return aguiChatClient.CreateAIAgent(
name: "ToolBasedGenerativeUIAssistant",
@@ -97,7 +97,7 @@ builder.Services.AddKeyedSingleton<AIAgent>("tool-based-generative-ui", (sp, key
builder.Services.AddKeyedSingleton<AIAgent>("agentic-generative-ui", (sp, key) =>
{
HttpClient httpClient = sp.GetRequiredService<IHttpClientFactory>().CreateClient("aguiserver");
AGUIChatClient aguiChatClient = new AGUIChatClient(httpClient, "agentic_generative_ui");
AGUIChatClient aguiChatClient = new(httpClient, "agentic_generative_ui");
return aguiChatClient.CreateAIAgent(
name: "AgenticGenerativeUIAssistant",
@@ -108,7 +108,7 @@ builder.Services.AddKeyedSingleton<AIAgent>("agentic-generative-ui", (sp, key) =
builder.Services.AddKeyedSingleton<AIAgent>("shared-state", (sp, key) =>
{
HttpClient httpClient = sp.GetRequiredService<IHttpClientFactory>().CreateClient("aguiserver");
AGUIChatClient aguiChatClient = new AGUIChatClient(httpClient, "shared_state");
AGUIChatClient aguiChatClient = new(httpClient, "shared_state");
return aguiChatClient.CreateAIAgent(
name: "SharedStateAssistant",
@@ -119,7 +119,7 @@ builder.Services.AddKeyedSingleton<AIAgent>("shared-state", (sp, key) =>
builder.Services.AddKeyedSingleton<AIAgent>("predictive-state-updates", (sp, key) =>
{
HttpClient httpClient = sp.GetRequiredService<IHttpClientFactory>().CreateClient("aguiserver");
AGUIChatClient aguiChatClient = new AGUIChatClient(httpClient, "predictive_state_updates");
AGUIChatClient aguiChatClient = new(httpClient, "predictive_state_updates");
return aguiChatClient.CreateAIAgent(
name: "PredictiveStateUpdatesAssistant",
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.
namespace AGUIDojoClient.Services;
@@ -13,7 +13,7 @@ public class BackgroundColorChangedEventArgs : EventArgs
/// <param name="color">The new background color.</param>
public BackgroundColorChangedEventArgs(string color)
{
Color = color;
this.Color = color;
}
/// <summary>
@@ -59,7 +59,7 @@ public class BackgroundColorService : IBackgroundColorService
/// <inheritdoc/>
public void SetColor(string color)
{
CurrentColor = color;
this.CurrentColor = color;
ColorChanged?.Invoke(this, new BackgroundColorChangedEventArgs(color));
}
}
@@ -1,12 +1,4 @@
<<<<<<< HEAD
<<<<<<< HEAD
// Copyright (c) Microsoft. All rights reserved.
=======
// Copyright (c) Microsoft. All rights reserved.
>>>>>>> beabff3e (Update the dojo samples)
=======
// Copyright (c) Microsoft. All rights reserved.
>>>>>>> 660dee85 (cleanups)
using System.ComponentModel;
@@ -1,12 +1,4 @@
<<<<<<< HEAD
<<<<<<< HEAD
// Copyright (c) Microsoft. All rights reserved.
=======
// Copyright (c) Microsoft. All rights reserved.
>>>>>>> beabff3e (Update the dojo samples)
=======
// Copyright (c) Microsoft. All rights reserved.
>>>>>>> 660dee85 (cleanups)
using System.Text.Json.Serialization;
@@ -1,12 +1,4 @@
<<<<<<< HEAD
<<<<<<< HEAD
// Copyright (c) Microsoft. All rights reserved.
=======
// Copyright (c) Microsoft. All rights reserved.
>>>>>>> beabff3e (Update the dojo samples)
=======
// Copyright (c) Microsoft. All rights reserved.
>>>>>>> 660dee85 (cleanups)
using System.Text.Json.Serialization;
@@ -1,12 +1,4 @@
<<<<<<< HEAD
<<<<<<< HEAD
// Copyright (c) Microsoft. All rights reserved.
=======
// Copyright (c) Microsoft. All rights reserved.
>>>>>>> beabff3e (Update the dojo samples)
=======
// Copyright (c) Microsoft. All rights reserved.
>>>>>>> 660dee85 (cleanups)
using System.Text.Json.Serialization;
@@ -1,12 +1,4 @@
<<<<<<< HEAD
<<<<<<< HEAD
// Copyright (c) Microsoft. All rights reserved.
=======
// Copyright (c) Microsoft. All rights reserved.
>>>>>>> beabff3e (Update the dojo samples)
=======
// Copyright (c) Microsoft. All rights reserved.
>>>>>>> 660dee85 (cleanups)
using System.Text.Json.Serialization;
@@ -10,7 +10,6 @@ using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using OpenAI;
using ChatClient = OpenAI.Chat.ChatClient;
namespace AGUIDojoServer;
@@ -78,7 +77,6 @@ internal static class ChatClientAgentFactory
{
Name = "AgenticUIAgent",
Description = "An agent that generates agentic user interfaces using Azure OpenAI",
<<<<<<< HEAD
ChatOptions = new ChatOptions
{
Instructions = """
@@ -95,24 +93,6 @@ internal static class ChatClientAgentFactory
Only one plan can be active at a time, so do not call the `create_plan` tool
again until all the steps in current plan are completed.
""",
=======
Instructions = """
When planning use tools only, without any other messages.
IMPORTANT:
- Use the `create_plan` tool to set the initial state of the steps
- Use the `update_plan_step` tool to update the status of each step
- Do NOT repeat the plan or summarise it in a message
- Do NOT confirm the creation or updates in a message
- Do NOT ask the user for additional information or next steps
- Do NOT leave a plan hanging, always complete the plan via `update_plan_step` if one is ongoing.
- Continue calling update_plan_step until all steps are marked as completed.
Only one plan can be active at a time, so do not call the `create_plan` tool
again until all the steps in current plan are completed.
""",
ChatOptions = new ChatOptions
{
>>>>>>> beabff3e (Update the dojo samples)
Tools = [
AIFunctionFactory.Create(
AgenticPlanningTools.CreatePlan,
@@ -151,12 +131,11 @@ internal static class ChatClientAgentFactory
{
Name = "PredictiveStateUpdatesAgent",
Description = "An agent that demonstrates predictive state updates using Azure OpenAI",
<<<<<<< HEAD
ChatOptions = new ChatOptions
{
Instructions = """
You are a document editor assistant. When asked to write or edit content:
IMPORTANT:
- Use the `write_document` tool with the full document text in Markdown format
- Format the document extensively so it's easy to read
@@ -166,28 +145,9 @@ internal static class ChatClientAgentFactory
- When making edits to the document, try to make them minimal - do not change every word
- Keep stories SHORT!
- After you are done writing the document you MUST call a confirm_changes tool after you call write_document
After the user confirms the changes, provide a brief summary of what you wrote.
""",
=======
Instructions = """
You are a document editor assistant. When asked to write or edit content:
IMPORTANT:
- Use the `write_document` tool with the full document text in Markdown format
- Format the document extensively so it's easy to read
- You can use all kinds of markdown (headings, lists, bold, etc.)
- However, do NOT use italic or strike-through formatting
- You MUST write the full document, even when changing only a few words
- When making edits to the document, try to make them minimal - do not change every word
- Keep stories SHORT!
- After you are done writing the document you MUST call a confirm_changes tool after you call write_document
After the user confirms the changes, provide a brief summary of what you wrote.
""",
ChatOptions = new ChatOptions
{
>>>>>>> beabff3e (Update the dojo samples)
Tools = [
AIFunctionFactory.Create(
WriteDocument,
@@ -1,12 +1,4 @@
<<<<<<< HEAD
<<<<<<< HEAD
// Copyright (c) Microsoft. All rights reserved.
=======
// Copyright (c) Microsoft. All rights reserved.
>>>>>>> beabff3e (Update the dojo samples)
=======
// Copyright (c) Microsoft. All rights reserved.
>>>>>>> 660dee85 (cleanups)
using System.Text.Json.Serialization;