From 5ad3cec3671c293c1376a427585144234948f9dc Mon Sep 17 00:00:00 2001 From: Kazuki Ota Date: Wed, 11 Jun 2025 16:23:57 +0900 Subject: [PATCH] =?UTF-8?q?python=20=E5=AE=9F=E8=A3=85=E3=81=AB=E5=90=88?= =?UTF-8?q?=E3=82=8F=E3=81=9B=E3=81=A6=E4=BA=92=E6=8F=9B=E3=81=8C=E5=8F=96?= =?UTF-8?q?=E3=82=8A=E3=82=84=E3=81=99=E3=81=84=E5=BD=A2=E3=81=AB=E5=BE=AE?= =?UTF-8?q?=E8=AA=BF=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/Chat/ChatThread.razor | 2 +- .../Services/AgentChatService.cs | 9 ++++- .../appsettings.Development.json | 5 ++- .../Model/AgentOrchestratorStatus.cs | 1 + .../Model/IAdditionalInfo.cs | 1 + .../Model/AdditionalInfoSerializationTest.cs | 37 +++++++++++++++++++ .../Model/SourceGenerationContext.cs | 4 +- 7 files changed, 53 insertions(+), 6 deletions(-) create mode 100644 DurableMultiAgentTemplate.Test/Model/AdditionalInfoSerializationTest.cs diff --git a/DurableMultiAgentTemplate.Client/Components/Chat/ChatThread.razor b/DurableMultiAgentTemplate.Client/Components/Chat/ChatThread.razor index 48bb81a..90e5d7b 100644 --- a/DurableMultiAgentTemplate.Client/Components/Chat/ChatThread.razor +++ b/DurableMultiAgentTemplate.Client/Components/Chat/ChatThread.razor @@ -33,7 +33,7 @@ @((MarkupString)Markdown.ToHtml(agentChatMessage.Message.Content))
- 使用されたエージェント: @string.Join(", ", agentChatMessage.Message.CalledAgentNames) + 使用されたエージェント: @string.Join(", ", agentChatMessage.Message.CalledAgentNames ?? [])
diff --git a/DurableMultiAgentTemplate.Client/Services/AgentChatService.cs b/DurableMultiAgentTemplate.Client/Services/AgentChatService.cs index 4b7ef70..16e3920 100644 --- a/DurableMultiAgentTemplate.Client/Services/AgentChatService.cs +++ b/DurableMultiAgentTemplate.Client/Services/AgentChatService.cs @@ -26,7 +26,10 @@ public async Task GetAgentResponseAsync(Agen IProgress? progress = null, CancellationToken cancellationToken = default) { - var response = await httpClient.PostAsJsonAsync("api/invoke/async", agentRequestDto, cancellationToken); + var response = await httpClient.PostAsJsonAsync("api/invoke/async", + agentRequestDto, + _jsonSerializerOptions, + cancellationToken); response.EnsureSuccessStatusCode(); var agentOrchestratorStatus = AgentOrchestratorStatus.NotStarted; @@ -35,9 +38,11 @@ public async Task GetAgentResponseAsync(Agen throw new InvalidOperationException("The format of the response from the agent is invalid."); // The response from the agent is an async response, so we need to poll the status until it's completed. + var statusQueryGetUri = new Uri(invokeAsyncResult.StatusQueryGetUri).PathAndQuery; + statusQueryGetUri = statusQueryGetUri.TrimStart('/'); while (cancellationToken.IsCancellationRequested == false) { - var statusResponse = await httpClient.GetAsync(invokeAsyncResult.StatusQueryGetUri, cancellationToken); + var statusResponse = await httpClient.GetAsync(statusQueryGetUri, cancellationToken); statusResponse.EnsureSuccessStatusCode(); var status = await statusResponse.Content.ReadFromJsonAsync(_jsonSerializerOptions, cancellationToken) ?? throw new InvalidOperationException("The format of the status response from the agent is invalid."); diff --git a/DurableMultiAgentTemplate.Client/appsettings.Development.json b/DurableMultiAgentTemplate.Client/appsettings.Development.json index eac75cd..8f1a314 100644 --- a/DurableMultiAgentTemplate.Client/appsettings.Development.json +++ b/DurableMultiAgentTemplate.Client/appsettings.Development.json @@ -7,8 +7,11 @@ }, "Services": { "backend": { + "httpxxx": [ + "http://localhost:7133/" + ], "http": [ - "http://localhost:7133" + "https://cautious-carnival-g45p4rwr7fv7pg-7071.app.github.dev/" ] } }, diff --git a/DurableMultiAgentTemplate.Shared/Model/AgentOrchestratorStatus.cs b/DurableMultiAgentTemplate.Shared/Model/AgentOrchestratorStatus.cs index 254a992..f995b6e 100644 --- a/DurableMultiAgentTemplate.Shared/Model/AgentOrchestratorStatus.cs +++ b/DurableMultiAgentTemplate.Shared/Model/AgentOrchestratorStatus.cs @@ -30,6 +30,7 @@ public AgentOrchestratorStatus(AgentOrchestratorStep step) /// /// Defines the steps of the agent orchestrator. /// +[JsonConverter(typeof(JsonStringEnumConverter))] public enum AgentOrchestratorStep { /// diff --git a/DurableMultiAgentTemplate.Shared/Model/IAdditionalInfo.cs b/DurableMultiAgentTemplate.Shared/Model/IAdditionalInfo.cs index 6bee665..1fe78d9 100644 --- a/DurableMultiAgentTemplate.Shared/Model/IAdditionalInfo.cs +++ b/DurableMultiAgentTemplate.Shared/Model/IAdditionalInfo.cs @@ -6,6 +6,7 @@ namespace DurableMultiAgentTemplate.Shared.Model; /// Interface for additional information. /// Classes implementing this interface are used as supplementary information added to agent responses. /// +[JsonPolymorphic(TypeDiscriminatorPropertyName = "type")] [JsonDerivedType(typeof(AdditionalMarkdownInfo), typeDiscriminator: "markdown")] [JsonDerivedType(typeof(AdditionalLinkInfo), typeDiscriminator: "link")] public interface IAdditionalInfo; diff --git a/DurableMultiAgentTemplate.Test/Model/AdditionalInfoSerializationTest.cs b/DurableMultiAgentTemplate.Test/Model/AdditionalInfoSerializationTest.cs new file mode 100644 index 0000000..b259f46 --- /dev/null +++ b/DurableMultiAgentTemplate.Test/Model/AdditionalInfoSerializationTest.cs @@ -0,0 +1,37 @@ +using System; +using System.Text.Json; +using DurableMultiAgentTemplate.Shared.Model; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using DurableMultiAgentTemplate.Model; // 追加 + +namespace DurableMultiAgentTemplate.Test.Model; + +[TestClass] +public class AdditionalInfoSerializationTest +{ + [TestMethod] + public void AdditionalMarkdownInfo_SerializeDeserialize_WorksCorrectly() + { + var original = new AdditionalMarkdownInfo("**bold text**"); + IAdditionalInfo info = original; + var options = new JsonSerializerOptions { TypeInfoResolver = SourceGenerationContext.Default }; + string json = JsonSerializer.Serialize(info, typeof(IAdditionalInfo), options); + var deserialized = (IAdditionalInfo)JsonSerializer.Deserialize(json, typeof(IAdditionalInfo), options)!; + Assert.IsInstanceOfType(deserialized, typeof(AdditionalMarkdownInfo)); + Assert.AreEqual(original.MarkdownText, ((AdditionalMarkdownInfo)deserialized).MarkdownText); + } + + [TestMethod] + public void AdditionalLinkInfo_SerializeDeserialize_WorksCorrectly() + { + var original = new AdditionalLinkInfo("Google", new Uri("https://www.google.com/")); + IAdditionalInfo info = original; + var options = new JsonSerializerOptions { TypeInfoResolver = SourceGenerationContext.Default }; + string json = JsonSerializer.Serialize(info, typeof(IAdditionalInfo), options); + var deserialized = (IAdditionalInfo)JsonSerializer.Deserialize(json, typeof(IAdditionalInfo), options)!; + Assert.IsInstanceOfType(deserialized, typeof(AdditionalLinkInfo)); + var link = (AdditionalLinkInfo)deserialized; + Assert.AreEqual(original.LinkText, link.LinkText); + Assert.AreEqual(original.Uri, link.Uri); + } +} diff --git a/DurableMultiAgentTemplate/Model/SourceGenerationContext.cs b/DurableMultiAgentTemplate/Model/SourceGenerationContext.cs index 684cfa2..5202bcb 100644 --- a/DurableMultiAgentTemplate/Model/SourceGenerationContext.cs +++ b/DurableMultiAgentTemplate/Model/SourceGenerationContext.cs @@ -14,7 +14,7 @@ namespace DurableMultiAgentTemplate.Model; /// Configures the JSON serialization options and declares serializable types /// for performance optimization through source generation. /// -[JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, PropertyNameCaseInsensitive = true)] +[JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, PropertyNameCaseInsensitive = false)] [JsonSerializable(typeof(GetClimateRequest))] [JsonSerializable(typeof(GetDestinationSuggestRequest))] [JsonSerializable(typeof(GetHotelRequest))] @@ -24,4 +24,4 @@ namespace DurableMultiAgentTemplate.Model; [JsonSerializable(typeof(AdditionalMarkdownInfo))] [JsonSerializable(typeof(AdditionalLinkInfo))] [JsonSerializable(typeof(AgentResponseWithAdditionalInfoFormat))] -internal partial class SourceGenerationContext : JsonSerializerContext; +public partial class SourceGenerationContext : JsonSerializerContext;