Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
264 changes: 263 additions & 1 deletion src/libraries/Core/Microsoft.Agents.Core/Models/Activity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
namespace Microsoft.Agents.Core.Models
{
/// <inheritdoc/>
public class Activity :
public partial class Activity :
IActivity,
IConversationUpdateActivity,
IContactRelationUpdateActivity,
Expand Down Expand Up @@ -142,6 +142,268 @@ public bool IsType(string type)
return string.Equals(type, Type, StringComparison.OrdinalIgnoreCase);
}

/// <inheritdoc/>
public IActivity WithText(string text)
{
Text = text;
return this;
}

/// <inheritdoc/>
public IActivity WithSpeak(string speak)
{
Speak = speak;
return this;
}

/// <inheritdoc/>
public IActivity WithInputHint(string inputHint)
{
InputHint = inputHint;
return this;
}

/// <inheritdoc/>
public IActivity WithSummary(string summary)
{
Summary = summary;
return this;
}

/// <inheritdoc/>
public IActivity WithLocale(string locale)
{
Locale = locale;
return this;
}

/// <inheritdoc/>
public IActivity WithTextFormat(string textFormat)
{
TextFormat = textFormat;
return this;
}

/// <inheritdoc/>
public IActivity WithAttachmentLayout(string attachmentLayout)
{
AttachmentLayout = attachmentLayout;
return this;
}

/// <inheritdoc/>
public IActivity WithDeliveryMode(string deliveryMode)
{
DeliveryMode = deliveryMode;
return this;
}

/// <inheritdoc/>
public IActivity WithName(string name)
{
Name = name;
return this;
}

/// <inheritdoc/>
public IActivity WithValue(object value)
{
Value = value;
return this;
}

/// <inheritdoc/>
public IActivity WithValue(object value, string valueType)
{
Value = value;
ValueType = valueType;
return this;
}

/// <inheritdoc/>
public IActivity WithSuggestedActions(SuggestedActions suggestedActions)
{
SuggestedActions = suggestedActions;
return this;
}

/// <inheritdoc/>
public IActivity AddText(string text)
{
Text += text;
return this;
}

/// <inheritdoc/>
public IActivity AddAttachment(params Attachment[] attachments)
{
if (attachments == null)
{
return this;
}

Attachments ??= [];
foreach (var attachment in attachments)
{
Attachments.Add(attachment);
}

return this;
}

/// <inheritdoc/>
public IActivity AddCard(Card card) => card == null ? this : AddAttachment(card.ToAttachment());

/// <inheritdoc/>
public IActivity AddEntity(params Entity[] entities)
{
if (entities == null)
{
return this;
}

Entities ??= [];
foreach (var entity in entities)
{
Entities.Add(entity);
}

return this;
}

/// <inheritdoc/>
public bool IsMessage() => IsType(ActivityTypes.Message);

/// <inheritdoc/>
public bool IsEvent() => IsType(ActivityTypes.Event);

/// <inheritdoc/>
public bool IsInvoke() => IsType(ActivityTypes.Invoke);

/// <inheritdoc/>
public bool IsTyping() => IsType(ActivityTypes.Typing);

/// <inheritdoc/>
public bool IsConversationUpdate() => IsType(ActivityTypes.ConversationUpdate);

/// <inheritdoc/>
public bool IsEndOfConversation() => IsType(ActivityTypes.EndOfConversation);

/// <inheritdoc/>
public bool IsHandoff() => IsType(ActivityTypes.Handoff);

/// <inheritdoc/>
public bool IsTrace() => IsType(ActivityTypes.Trace);

/// <inheritdoc/>
public bool IsCommand() => IsType(ActivityTypes.Command);

/// <inheritdoc/>
public bool IsCommandResult() => IsType(ActivityTypes.CommandResult);

/// <inheritdoc/>
public IActivity AddMention(ChannelAccount account, string text = null, bool addText = true)
{
var mentionText = text ?? account?.Name;
var markup = $"<at>{mentionText}</at>";

if (addText)
{
Text = string.IsNullOrEmpty(Text) ? markup : $"{markup} {Text}";
}

return AddEntity(new Mention(mentioned: account, text: markup));
}
Comment thread
tracyboehrer marked this conversation as resolved.

/// <inheritdoc/>
public Mention[] GetMentions()
{
var result = new List<Mention>();
if (Entities != null)
{
foreach (var entity in Entities)
{
if (entity is Mention mention)
{
result.Add(mention);
}
}
}

return [.. result];
}

/// <inheritdoc/>
public Mention GetAccountMention(string accountId)
{
if (Entities == null || accountId == null)
{
return null;
}

foreach (var entity in Entities)
{
if (entity is Mention mention && mention.Mentioned?.Id == accountId)
{
return mention;
}
}

return null;
}

/// <inheritdoc/>
public bool IsRecipientMentioned()
{
return Recipient?.Id != null && GetAccountMention(Recipient.Id) != null;
}

/// <inheritdoc/>
public string RemoveRecipientMention()
{
return this.RemoveMentionText(Recipient?.Id);
}

/// <inheritdoc/>
public bool IsTargetedActivity()
{
if (Entities == null || Entities.Count == 0)
{
return false;
}

foreach (var entity in Entities)
{
if (entity.Type == EntityTypes.ActivityTreatment && entity is ActivityTreatment treatment && treatment.Treatment == ActivityTreatmentTypes.Targeted)
{
return true;
}
}

return false;
}

/// <inheritdoc/>
public IActivity MakeTargetedActivity(ChannelAccount user = null)
{
if (IsTargetedActivity())
{
return this;
}

if (Recipient == null && user == null)
{
throw new InvalidOperationException("Cannot mark activity as targeted because both the Activity.Recipient and `user` argument are null. At least one must be provided.");
}

Entities ??= [];
Entities.Add(new ActivityTreatment() { Treatment = ActivityTreatmentTypes.Targeted });

Recipient = user ?? Recipient;

return this;
}

/// <inheritdoc/>
public string Type { get; set; }

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#nullable disable

using System.IO;
using System.Text;

namespace Microsoft.Agents.Core.Models
{
/// <summary> A card that carries a raw Adaptive Card JSON payload. </summary>
/// <remarks>
/// The JSON is stored verbatim in <see cref="Content"/> and unpacked into the attachment as nested
/// JSON when the activity is serialized.
/// </remarks>
public class AdaptiveCardCard : Card
{
/// <summary>
/// The content type value of an <see cref="Microsoft.Agents.Core.Models.AdaptiveCardCard"/>.
/// </summary>
public const string ContentType = Models.ContentTypes.AdaptiveCard;

/// <summary> The Adaptive Card content as a JSON string. </summary>
public string Content;

/// <summary> Initializes a new instance of <see cref="Microsoft.Agents.Core.Models.AdaptiveCardCard"/> from an Adaptive Card JSON string. </summary>
/// <param name="json"> The Adaptive Card content as a JSON string. </param>
public AdaptiveCardCard(string json)
{
Content = json;
}

/// <summary> Initializes a new instance of <see cref="Microsoft.Agents.Core.Models.AdaptiveCardCard"/> from a stream containing Adaptive Card JSON. </summary>
/// <param name="stream"> A stream containing the Adaptive Card JSON. The stream is left open. </param>
public AdaptiveCardCard(Stream stream)
{
using var reader = new StreamReader(stream, Encoding.UTF8, detectEncodingFromByteOrderMarks: true, bufferSize: 1024, leaveOpen: true);
Content = reader.ReadToEnd();
}

/// <inheritdoc/>
public override Attachment ToAttachment()
{
return new Attachment
{
ContentType = ContentType,
Content = Content
};
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
namespace Microsoft.Agents.Core.Models
{
/// <summary> An animation card (Ex: gif or short video clip). </summary>
public class AnimationCard
public class AnimationCard : Card
{
/// <summary> Initializes a new instance of AnimationCard. </summary>
public AnimationCard()
Expand Down Expand Up @@ -57,7 +57,7 @@ public AnimationCard(string title = default, string subtitle = default, string t
/// </summary>
/// <param name="card"> The instance of <see cref="Microsoft.Agents.Core.Models.AnimationCard"/>.</param>
/// <returns> The generated attachment.</returns>
public Attachment ToAttachment()
public override Attachment ToAttachment()
{
return new Attachment
{
Expand All @@ -66,22 +66,6 @@ public Attachment ToAttachment()
};
}

/// <summary>
/// Creates a new message activity that includes this animation card as an attachment.
/// </summary>
/// <remarks>Use this method to generate a message activity suitable for sending to a user, with
/// the current animation card included as an attachment. The returned activity has its type set to <see
/// langword="ActivityTypes.Message"/>.</remarks>
/// <returns>An <see cref="IActivity"/> representing a message activity with the animation card attached.</returns>
public IActivity ToMessage()
{
return new Activity
{
Type = ActivityTypes.Message,
Attachments = [ToAttachment()]
};
}

/// <summary> Title of this card. </summary>
public string Title { get; set; }
/// <summary> Subtitle of this card. </summary>
Expand All @@ -107,5 +91,12 @@ public IActivity ToMessage()
/// <summary> Supplementary parameter for this card. </summary>
[JsonConverter(typeof(Serialization.Converters.ObjectTypeConverter))]
public object Value { get; set; }

/// <summary> Adds a media URL and returns this card. </summary>
public AnimationCard AddMedia(MediaUrl media) { Media ??= []; Media.Add(media); return this; }
/// <summary> Adds a media URL by string and returns this card. </summary>
public AnimationCard AddMedia(string url, string profile = null) { Media ??= []; Media.Add(new MediaUrl(url, profile)); return this; }
/// <summary> Adds a button and returns this card. </summary>
public AnimationCard AddButton(CardAction button) { Buttons ??= []; Buttons.Add(button); return this; }
}
}
Loading
Loading