add typesubscription.cs

This commit is contained in:
Griffin Bassman 2025-01-27 12:49:14 -05:00 committed by Jack Gerrits
parent e006240676
commit 4e7162e808

View File

@ -0,0 +1,101 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// TypeSubscription.cs
using System.Diagnostics.CodeAnalysis;
namespace Microsoft.AutoGen.Contracts.Python;
/// <summary>
/// This subscription matches on topics based on the exact type and maps to agents using the source of the topic as the agent key.
/// This subscription causes each source to have its own agent instance.
/// </summary>
/// <remarks>
/// Example:
/// <code>
/// var subscription = new TypeSubscription("t1", "a1");
/// </code>
/// In this case:
/// - A <see cref="TopicId"/> with type `"t1"` and source `"s1"` will be handled by an agent of type `"a1"` with key `"s1"`.
/// - A <see cref="TopicId"/> with type `"t1"` and source `"s2"` will be handled by an agent of type `"a1"` with key `"s2"`.
/// </remarks>
public class TypeSubscription : ISubscriptionDefinition
{
private readonly string _topicType;
private readonly AgentType _agentType;
private readonly string _id;
/// <summary>
/// Initializes a new instance of the <see cref="TypeSubscription"/> class.
/// </summary>
/// <param name="topicType">The exact topic type to match against.</param>
/// <param name="agentType">Agent type to handle this subscription.</param>
/// <param name="id">Unique identifier for the subscription. If not provided, a new UUID will be generated.</param>
public TypeSubscription(string topicType, AgentType agentType, string? id = null)
{
_topicType = topicType;
_agentType = agentType;
_id = id ?? Guid.NewGuid().ToString();
}
/// <summary>
/// Gets the unique identifier of the subscription.
/// </summary>
public string Id => _id;
/// <summary>
/// Gets the exact topic type used for matching.
/// </summary>
public string TopicType => _topicType;
/// <summary>
/// Gets the agent type that handles this subscription.
/// </summary>
public AgentType AgentType => _agentType;
/// <summary>
/// Checks if a given <see cref="TopicId"/> matches the subscription based on an exact type match.
/// </summary>
/// <param name="topic">The topic to check.</param>
/// <returns><c>true</c> if the topic's type matches exactly, <c>false</c> otherwise.</returns>
public bool Matches(TopicId topic)
{
return topic.Type == _topicType;
}
/// <summary>
/// Maps a <see cref="TopicId"/> to an <see cref="AgentId"/>. Should only be called if <see cref="Matches"/> returns true.
/// </summary>
/// <param name="topic">The topic to map.</param>
/// <returns>An <see cref="AgentId"/> representing the agent that should handle the topic.</returns>
/// <exception cref="InvalidOperationException">Thrown if the topic does not match the subscription.</exception>
public AgentId MapToAgent(TopicId topic)
{
if (!Matches(topic))
{
throw new InvalidOperationException("TopicId does not match the subscription.");
}
return new AgentId(_agentType, topic.Source);
}
/// <summary>
/// Determines whether the specified object is equal to the current subscription.
/// </summary>
/// <param name="obj">The object to compare with the current instance.</param>
/// <returns><c>true</c> if the specified object is equal to this instance; otherwise, <c>false</c>.</returns>
public override bool Equals([NotNullWhen(true)] object? obj)
{
return obj is TypeSubscription other &&
(Id == other.Id ||
(AgentType == other.AgentType && TopicType == other.TopicType));
}
/// <summary>
/// Returns a hash code for this instance.
/// </summary>
/// <returns>A hash code for this instance, suitable for use in hashing algorithms and data structures.</returns>
public override int GetHashCode()
{
return HashCode.Combine(Id, AgentType, TopicType);
}
}