Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public override async Task<AgentRunResponse> RunAsync(IEnumerable<ChatMessage> m
}

// Clone the input messages and turn them into response messages with upper case text.
List<ChatMessage> responseMessages = CloneAndToUpperCase(messages, this.DisplayName).ToList();
List<ChatMessage> responseMessages = CloneAndToUpperCase(messages, this.Name).ToList();

// Notify the thread of the input and output messages.
await typedThread.MessageStore.AddMessagesAsync(messages.Concat(responseMessages), cancellationToken);
Expand All @@ -69,7 +69,7 @@ public override async IAsyncEnumerable<AgentRunResponseUpdate> RunStreamingAsync
}

// Clone the input messages and turn them into response messages with upper case text.
List<ChatMessage> responseMessages = CloneAndToUpperCase(messages, this.DisplayName).ToList();
List<ChatMessage> responseMessages = CloneAndToUpperCase(messages, this.Name).ToList();

// Notify the thread of the input and output messages.
await typedThread.MessageStore.AddMessagesAsync(messages.Concat(responseMessages), cancellationToken);
Expand All @@ -79,7 +79,7 @@ public override async IAsyncEnumerable<AgentRunResponseUpdate> RunStreamingAsync
yield return new AgentRunResponseUpdate
{
AgentId = this.Id,
AuthorName = this.DisplayName,
AuthorName = message.AuthorName,
Role = ChatRole.Assistant,
Contents = message.Contents,
ResponseId = Guid.NewGuid().ToString("N"),
Expand All @@ -88,7 +88,7 @@ public override async IAsyncEnumerable<AgentRunResponseUpdate> RunStreamingAsync
}
}

private static IEnumerable<ChatMessage> CloneAndToUpperCase(IEnumerable<ChatMessage> messages, string agentName) => messages.Select(x =>
private static IEnumerable<ChatMessage> CloneAndToUpperCase(IEnumerable<ChatMessage> messages, string? agentName) => messages.Select(x =>
{
// Clone the message and update its author to be the agent.
var messageClone = x.Clone();
Expand Down
8 changes: 1 addition & 7 deletions dotnet/src/Microsoft.Agents.AI.A2A/A2AAgent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ internal sealed class A2AAgent : AIAgent
private readonly string? _id;
private readonly string? _name;
private readonly string? _description;
private readonly string? _displayName;
private readonly ILogger _logger;

/// <summary>
Expand All @@ -40,17 +39,15 @@ internal sealed class A2AAgent : AIAgent
/// <param name="id">The unique identifier for the agent.</param>
/// <param name="name">The the name of the agent.</param>
/// <param name="description">The description of the agent.</param>
/// <param name="displayName">The display name of the agent.</param>
/// <param name="loggerFactory">Optional logger factory to use for logging.</param>
public A2AAgent(A2AClient a2aClient, string? id = null, string? name = null, string? description = null, string? displayName = null, ILoggerFactory? loggerFactory = null)
public A2AAgent(A2AClient a2aClient, string? id = null, string? name = null, string? description = null, ILoggerFactory? loggerFactory = null)
{
_ = Throw.IfNull(a2aClient);

this._a2aClient = a2aClient;
this._id = id;
this._name = name;
this._description = description;
this._displayName = displayName;
this._logger = (loggerFactory ?? NullLoggerFactory.Instance).CreateLogger<A2AAgent>();
}

Expand Down Expand Up @@ -203,9 +200,6 @@ public override async IAsyncEnumerable<AgentRunResponseUpdate> RunStreamingAsync
/// <inheritdoc/>
public override string? Name => this._name ?? base.Name;

/// <inheritdoc/>
public override string DisplayName => this._displayName ?? base.DisplayName;

/// <inheritdoc/>
public override string? Description => this._description ?? base.Description;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,8 @@ public static class A2AClientExtensions
/// <param name="id">The unique identifier for the agent.</param>
/// <param name="name">The the name of the agent.</param>
/// <param name="description">The description of the agent.</param>
/// <param name="displayName">The display name of the agent.</param>
/// <param name="loggerFactory">Optional logger factory for enabling logging within the agent.</param>
/// <returns>An <see cref="AIAgent"/> instance backed by the A2A agent.</returns>
public static AIAgent GetAIAgent(this A2AClient client, string? id = null, string? name = null, string? description = null, string? displayName = null, ILoggerFactory? loggerFactory = null) =>
new A2AAgent(client, id, name, description, displayName, loggerFactory);
public static AIAgent GetAIAgent(this A2AClient client, string? id = null, string? name = null, string? description = null, ILoggerFactory? loggerFactory = null) =>
new A2AAgent(client, id, name, description, loggerFactory);
}
12 changes: 0 additions & 12 deletions dotnet/src/Microsoft.Agents.AI.Abstractions/AIAgent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,6 @@ public abstract class AIAgent
/// </remarks>
public virtual string? Name { get; }

/// <summary>
/// Gets a display-friendly name for the agent.
/// </summary>
/// <value>
/// The agent's <see cref="Name"/> if available, otherwise the <see cref="Id"/>.
/// </value>
/// <remarks>
/// This property provides a guaranteed non-null string suitable for display in user interfaces,
/// logs, or other contexts where a readable identifier is needed.
/// </remarks>
public virtual string DisplayName => this.Name ?? this.Id;

/// <summary>
/// Gets a description of the agent's purpose, capabilities, or behavior.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ private static EntityInfo CreateAgentEntityInfo(AIAgent agent)
return new EntityInfo(
Id: entityId,
Type: "agent",
Name: agent.DisplayName,
Name: agent.Name ?? agent.Id,
Description: agent.Description,
Framework: "agent_framework",
Tools: tools,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public static IEndpointConventionBuilder MapOpenAIChatCompletions(

path ??= $"/{agent.Name}/v1/chat/completions";
var group = endpoints.MapGroup(path);
var endpointAgentName = agent.DisplayName;
var endpointAgentName = agent.Name ?? agent.Id;

group.MapPost("/", async ([FromBody] CreateChatCompletion request, CancellationToken cancellationToken)
=> await AIAgentChatCompletionsProcessor.CreateChatCompletionAsync(agent, request, cancellationToken).ConfigureAwait(false))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public static IEndpointConventionBuilder MapOpenAIResponses(
var handlers = new ResponsesHttpHandler(responsesService);

var group = endpoints.MapGroup(responsesPath);
var endpointAgentName = agent.DisplayName;
var endpointAgentName = agent.Name ?? agent.Id;

// Create response endpoint
group.MapPost("/", handlers.CreateResponseAsync)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,14 +125,14 @@ public HandoffsWorkflowBuilder WithHandoff(AIAgent from, AIAgent to, string? han
{
Throw.ArgumentException(
nameof(to),
$"The provided target agent '{to.DisplayName}' has no description, name, or instructions, and no handoff description has been provided. " +
$"The provided target agent '{to.Name ?? to.Id}' has no description, name, or instructions, and no handoff description has been provided. " +
"At least one of these is required to register a handoff so that the appropriate target agent can be chosen.");
}
}

if (!handoffs.Add(new(to, handoffReason)))
{
Throw.InvalidOperationException($"A handoff from agent '{from.DisplayName}' to agent '{to.DisplayName}' has already been registered.");
Throw.InvalidOperationException($"A handoff from agent '{from.Name ?? from.Id}' to agent '{to.Name ?? to.Id}' has already been registered.");
}

return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ internal sealed class AgentRunStreamingExecutor(AIAgent agent, bool includeInput

protected override async ValueTask TakeTurnAsync(List<ChatMessage> messages, IWorkflowContext context, bool? emitEvents, CancellationToken cancellationToken = default)
{
List<ChatMessage>? roleChanged = messages.ChangeAssistantToUserForOtherParticipants(agent.DisplayName);
List<ChatMessage>? roleChanged = messages.ChangeAssistantToUserForOtherParticipants(agent.Name ?? agent.Id);

List<AgentRunResponseUpdate> updates = [];
await foreach (var update in agent.RunStreamingAsync(messages, cancellationToken: cancellationToken).ConfigureAwait(false))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ protected override RouteBuilder ConfigureRoutes(RouteBuilder routeBuilder) =>
List<AgentRunResponseUpdate> updates = [];
List<ChatMessage> allMessages = handoffState.Messages;

List<ChatMessage>? roleChanges = allMessages.ChangeAssistantToUserForOtherParticipants(this._agent.DisplayName);
List<ChatMessage>? roleChanges = allMessages.ChangeAssistantToUserForOtherParticipants(this._agent.Name ?? this._agent.Id);

await foreach (var update in this._agent.RunStreamingAsync(allMessages,
options: this._agentOptions,
Expand All @@ -85,7 +85,7 @@ await AddUpdateAsync(
new AgentRunResponseUpdate
{
AgentId = this._agent.Id,
AuthorName = this._agent.DisplayName,
AuthorName = this._agent.Name ?? this._agent.Id,
Contents = [new FunctionResultContent(fcc.CallId, "Transferred.")],
CreatedAt = DateTimeOffset.UtcNow,
MessageId = Guid.NewGuid().ToString("N"),
Expand Down
4 changes: 3 additions & 1 deletion dotnet/src/Microsoft.Agents.AI/OpenTelemetryAgent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,9 @@ private void UpdateCurrentActivity(Activity? previousActivity)

// Override information set by OpenTelemetryChatClient to make it specific to invoke_agent.

activity.DisplayName = $"{OpenTelemetryConsts.GenAI.InvokeAgent} {this.DisplayName}";
activity.DisplayName = string.IsNullOrWhiteSpace(this.Name)
? $"{OpenTelemetryConsts.GenAI.InvokeAgent} {this.Id}"
: $"{OpenTelemetryConsts.GenAI.InvokeAgent} {this.Name}({this.Id})";
activity.SetTag(OpenTelemetryConsts.GenAI.Operation.Name, OpenTelemetryConsts.GenAI.InvokeAgent);

if (!string.IsNullOrWhiteSpace(this._providerName))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,14 @@ public void Constructor_WithAllParameters_InitializesPropertiesCorrectly()
const string TestId = "test-id";
const string TestName = "test-name";
const string TestDescription = "test-description";
const string TestDisplayName = "test-display-name";

// Act
var agent = new A2AAgent(this._a2aClient, TestId, TestName, TestDescription, TestDisplayName);
var agent = new A2AAgent(this._a2aClient, TestId, TestName, TestDescription);

// Assert
Assert.Equal(TestId, agent.Id);
Assert.Equal(TestName, agent.Name);
Assert.Equal(TestDescription, agent.Description);
Assert.Equal(TestDisplayName, agent.DisplayName);
}

[Fact]
Expand All @@ -70,7 +68,6 @@ public void Constructor_WithDefaultParameters_UsesBaseProperties()
Assert.NotEmpty(agent.Id);
Assert.Null(agent.Name);
Assert.Null(agent.Description);
Assert.Equal(agent.Id, agent.DisplayName);
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,15 @@ public void GetAIAgent_WithAllParameters_ReturnsA2AAgentWithSpecifiedProperties(
const string TestId = "test-agent-id";
const string TestName = "Test Agent";
const string TestDescription = "This is a test agent description";
const string TestDisplayName = "Test Display Name";

// Act
var agent = a2aClient.GetAIAgent(TestId, TestName, TestDescription, TestDisplayName);
var agent = a2aClient.GetAIAgent(TestId, TestName, TestDescription);

// Assert
Assert.NotNull(agent);
Assert.IsType<A2AAgent>(agent);
Assert.Equal(TestId, agent.Id);
Assert.Equal(TestName, agent.Name);
Assert.Equal(TestDescription, agent.Description);
Assert.Equal(TestDisplayName, agent.DisplayName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ public void Properties_DelegateToInnerAgent()
Assert.Equal("TestAgent", agent.Name);
Assert.Equal("This is a test agent.", agent.Description);
Assert.Equal(innerAgent.Id, agent.Id);
Assert.Equal(innerAgent.DisplayName, agent.DisplayName);
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ public void Properties_DelegateToInnerAgent()
Assert.Equal("TestAgent", agent.Name);
Assert.Equal("This is a test agent.", agent.Description);
Assert.Equal(innerAgent.Id, agent.Id);
Assert.Equal(innerAgent.DisplayName, agent.DisplayName);
}

[Fact]
Expand Down Expand Up @@ -170,7 +169,7 @@ async static IAsyncEnumerable<AgentRunResponseUpdate> CallbackAsync(
Assert.Equal("localhost", activity.GetTagItem("server.address"));
Assert.Equal(12345, (int)activity.GetTagItem("server.port")!);

Assert.Equal("invoke_agent TestAgent", activity.DisplayName);
Assert.Equal($"invoke_agent {agent.Name}({agent.Id})", activity.DisplayName);
Assert.Equal("invoke_agent", activity.GetTagItem("gen_ai.operation.name"));
Assert.Equal("TestAgentProviderFromAIAgentMetadata", activity.GetTagItem("gen_ai.provider.name"));
Assert.Equal(innerAgent.Name, activity.GetTagItem("gen_ai.agent.name"));
Expand Down Expand Up @@ -431,7 +430,15 @@ async static IAsyncEnumerable<AgentRunResponseUpdate> CallbackAsync(
Assert.Equal("localhost", activity.GetTagItem("server.address"));
Assert.Equal(12345, (int)activity.GetTagItem("server.port")!);

Assert.Equal($"invoke_agent {innerAgent.DisplayName}", activity.DisplayName);
if (string.IsNullOrWhiteSpace(innerAgent.Name))
{
Assert.Equal($"invoke_agent {innerAgent.Id}", activity.DisplayName);
}
else
{
Assert.Equal($"invoke_agent {innerAgent.Name}({innerAgent.Id})", activity.DisplayName);
}

Assert.Equal("invoke_agent", activity.GetTagItem("gen_ai.operation.name"));
Assert.Equal("TestAgentProviderFromAIAgentMetadata", activity.GetTagItem("gen_ai.provider.name"));
Assert.Equal(innerAgent.Name, activity.GetTagItem("gen_ai.agent.name"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ protected override IEnumerable<ChatMessage> GetEpilogueMessages(AgentRunOptions?
{
return [new(ChatRole.Assistant, [new FunctionCallContent(Guid.NewGuid().ToString("N"), handoff.Name)])
{
AuthorName = this.DisplayName,
AuthorName = this.Name ?? this.Id,
MessageId = Guid.NewGuid().ToString("N"),
CreatedAt = DateTime.UtcNow
}];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ IEnumerable<ChatMessage> echoMessages
select
UpdateThread(new ChatMessage(ChatRole.Assistant, $"{prefix}{message.Text}")
{
AuthorName = this.DisplayName,
AuthorName = this.Name ?? this.Id,
CreatedAt = DateTimeOffset.Now,
MessageId = Guid.NewGuid().ToString("N")
}, thread as InMemoryAgentThread);
Expand Down
Loading