diff --git a/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj b/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj
index 18ddee55..ba1ea69d 100644
--- a/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj
+++ b/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj
@@ -31,8 +31,4 @@
-
-
-
-
diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStateService.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStateService.cs
index 26655e2b..07b713c9 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStateService.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStateService.cs
@@ -5,6 +5,7 @@ namespace BotSharp.Abstraction.Conversations;
///
public interface IConversationStateService
{
+ string GetConversationId();
ConversationState Load(string conversationId);
string GetState(string name, string defaultValue = "");
bool ContainsState(string name);
diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs
index f08e5a66..0aa0cd04 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs
@@ -32,6 +32,8 @@ public class RoleDialogModel : ITrackableMessage
///
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public object Data { get; set; }
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ public object? RichContent { get; set; }
///
/// Stop conversation completion
diff --git a/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/QuickReplyElement.cs b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/QuickReplyElement.cs
new file mode 100644
index 00000000..1be8f208
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/QuickReplyElement.cs
@@ -0,0 +1,15 @@
+
+namespace BotSharp.Abstraction.Messaging.Models.RichContent
+{
+ public class QuickReplyElement
+ {
+ [JsonPropertyName("content_type")]
+ public string ContentType { get; set; } = string.Empty;
+ public string Title { get; set; } = string.Empty;
+ public string? Payload { get; set; }
+ [JsonPropertyName("image_url")]
+ public string? ImageUrl { get; set; }
+ [JsonPropertyName("postback_url")]
+ public string? PostBackUrl { get; set; }
+ }
+}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/QuickReplyMessage.cs b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/QuickReplyMessage.cs
new file mode 100644
index 00000000..b14b27e1
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/QuickReplyMessage.cs
@@ -0,0 +1,9 @@
+
+namespace BotSharp.Abstraction.Messaging.Models.RichContent
+{
+ public class QuickReplyMessage : TextMessage
+ {
+ [JsonPropertyName("quick_replies")]
+ public List QuickReplies { get; set; } = new List();
+ }
+}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Recipient.cs b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Recipient.cs
new file mode 100644
index 00000000..5c77924a
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Recipient.cs
@@ -0,0 +1,8 @@
+
+namespace BotSharp.Abstraction.Messaging.Models.RichContent
+{
+ public class Recipient
+ {
+ public string Id { get; set; } = string.Empty;
+ }
+}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/RichContent.cs b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/RichContent.cs
new file mode 100644
index 00000000..221dc96d
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/RichContent.cs
@@ -0,0 +1,13 @@
+namespace BotSharp.Abstraction.Messaging.Models.RichContent
+{
+ public class RichContent
+ {
+ public Recipient Recipient { get; set; } = new Recipient();
+ ///
+ /// RESPONSE
+ ///
+ [JsonPropertyName("messaging_type")]
+ public string MessagingType => "RESPONSE";
+ public T Message { get; set; }
+ }
+}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/SenderActionMessage.cs b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/SenderActionMessage.cs
new file mode 100644
index 00000000..6b652e4e
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/SenderActionMessage.cs
@@ -0,0 +1,15 @@
+
+namespace BotSharp.Abstraction.Messaging.Models.RichContent
+{
+ public class SenderActionMessage
+ {
+ /*
+ * Requests to display sender action should only include the sender_action parameter and the recipient object.
+ * All other Send API properties, such as text and templates, should be sent in a separate request.
+ */
+ public Recipient Recipient { get; set; } = new Recipient();
+
+ [JsonPropertyName("sender_action")]
+ public string SenderAction { get; set; } = string.Empty;
+ }
+}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Template/AttachmentTemplate.cs b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Template/AttachmentTemplate.cs
new file mode 100644
index 00000000..89f2137e
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Template/AttachmentTemplate.cs
@@ -0,0 +1,9 @@
+
+namespace BotSharp.Abstraction.Messaging.Models.RichContent.Template
+{
+ public class AttachmentTemplate
+ {
+ public string Type => "template";
+ public T Payload { get; set; }
+ }
+}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Template/ButtonTemplate.cs b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Template/ButtonTemplate.cs
new file mode 100644
index 00000000..f610a682
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Template/ButtonTemplate.cs
@@ -0,0 +1,17 @@
+
+namespace BotSharp.Abstraction.Messaging.Models.RichContent.Template
+{
+ public class ButtonTemplate : TextMessage
+ {
+ [JsonPropertyName("template_type")]
+ public string TemplateType => "button";
+ public List Buttons { get; set; } = new List();
+ }
+
+ public class ButtonElement
+ {
+ public string Type { get; set; } = string.Empty;
+ public string? Url { get; set; }
+ public string Title { get; set; } = string.Empty;
+ }
+}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Template/CommonTemplate.cs b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Template/CommonTemplate.cs
new file mode 100644
index 00000000..e4b3ea8c
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Template/CommonTemplate.cs
@@ -0,0 +1,10 @@
+
+namespace BotSharp.Abstraction.Messaging.Models.RichContent.Template
+{
+ public class CommonTemplate
+ {
+ [JsonPropertyName("template_type")]
+ public string TemplateType { get; set; } = string.Empty;
+ public T Elements { get; set; }
+ }
+}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Template/TemplateMessage.cs b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Template/TemplateMessage.cs
new file mode 100644
index 00000000..77b4a55f
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Template/TemplateMessage.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace BotSharp.Abstraction.Messaging.Models.RichContent.Template
+{
+ public class TemplateMessage
+ {
+ public T Attachment { get; set; }
+ }
+}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/TextMessage.cs b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/TextMessage.cs
new file mode 100644
index 00000000..94d85894
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/TextMessage.cs
@@ -0,0 +1,8 @@
+
+namespace BotSharp.Abstraction.Messaging.Models.RichContent
+{
+ public class TextMessage
+ {
+ public string Text { get; set; } = string.Empty;
+ }
+}
\ No newline at end of file
diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs
index 387a18e7..482857d9 100644
--- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs
+++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs
@@ -1,4 +1,5 @@
using BotSharp.Abstraction.Agents.Models;
+using BotSharp.Abstraction.Messaging.Models.RichContent;
using BotSharp.Abstraction.Routing;
using BotSharp.Abstraction.Routing.Settings;
using System.Drawing;
@@ -100,6 +101,14 @@ public partial class ConversationService
_logger.LogInformation(text);
#endif
+ // Only read content from RichContent for UI rendering. When richContent is null, create a basic text message for richContent.
+ var state = _services.GetRequiredService();
+ message.RichContent = message.RichContent ?? new RichContent
+ {
+ Recipient = new Recipient { Id = state.GetConversationId() },
+ Message = new TextMessage { Text = message.Content }
+ };
+
var hooks = _services.GetServices().ToList();
foreach (var hook in hooks)
{
diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs
index 1f0fe199..7004b929 100644
--- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs
+++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs
@@ -28,6 +28,8 @@ public class ConversationStateService : IConversationStateService, IDisposable
_states = new ConversationState();
}
+ public string GetConversationId() => _conversationId;
+
public IConversationStateService SetState(string name, T value)
{
if (value == null)
diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs
index 5fb5cd7c..80692bc9 100644
--- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs
+++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs
@@ -12,7 +12,7 @@ public class ConversationController : ControllerBase, IApiAdapter
private readonly IServiceProvider _services;
private readonly IUserIdentity _user;
- public ConversationController(IServiceProvider services,
+ public ConversationController(IServiceProvider services,
IUserIdentity user)
{
_services = services;
@@ -40,8 +40,8 @@ public class ConversationController : ControllerBase, IApiAdapter
}
[HttpPost("/conversation/{agentId}/{conversationId}")]
- public async Task SendMessage([FromRoute] string agentId,
- [FromRoute] string conversationId,
+ public async Task SendMessage([FromRoute] string agentId,
+ [FromRoute] string conversationId,
[FromBody] NewMessageModel input)
{
var conv = _services.GetRequiredService();
@@ -73,6 +73,7 @@ public class ConversationController : ControllerBase, IApiAdapter
response.Data = inputMsg.Data;
response.Function = inputMsg.FunctionName;
response.Instruction = inputMsg.Instruction;
+ response.RichContent = inputMsg.RichContent;
return response;
}
diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Conversations/MessageResponseModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Conversations/MessageResponseModel.cs
index 4dcf0c58..4fe7781c 100644
--- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Conversations/MessageResponseModel.cs
+++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Conversations/MessageResponseModel.cs
@@ -1,6 +1,5 @@
using BotSharp.Abstraction.Functions.Models;
using BotSharp.Abstraction.Models;
-using BotSharp.Abstraction.Routing.Models;
namespace BotSharp.OpenAPI.ViewModels.Conversations;
@@ -11,4 +10,5 @@ public class MessageResponseModel : ITrackableMessage
public string Function { get; set; }
public object Data { get; set; }
public FunctionCallFromLlm Instruction { get; set; }
+ public object? RichContent { get; set; }
}