// Copyright (c) Microsoft. All rights reserved. using System; using System.Collections.Generic; using Aspire.Hosting.AgentFramework; namespace Aspire.Hosting.ApplicationModel; /// /// An annotation that tracks an agent service backend referenced by a DevUI resource. /// /// /// This annotation is used to configure DevUI to aggregate entities from multiple /// agent service backends. Each annotation represents one backend that DevUI should /// connect to for entity discovery and request routing. /// public class AgentServiceAnnotation : IResourceAnnotation { /// /// Initializes a new instance of the class. /// /// The agent service resource. /// /// An optional prefix to add to entity IDs from this backend to avoid conflicts. /// If not specified, the resource name will be used as the prefix. /// /// /// Optional list of agents declared by this backend. When provided, the aggregator builds the entity /// listing directly from these declarations instead of querying the backend's /v1/entities endpoint. /// public AgentServiceAnnotation(IResource agentService, string? entityIdPrefix = null, IReadOnlyList? agents = null) { ArgumentNullException.ThrowIfNull(agentService); this.AgentService = agentService; this.EntityIdPrefix = entityIdPrefix; this.Agents = agents ?? []; } /// /// Gets the agent service resource that exposes AI agents. /// public IResource AgentService { get; } /// /// Gets the prefix to use for entity IDs from this backend. /// /// /// When null, the resource name will be used as the prefix. /// Entity IDs will be formatted as "{prefix}/{entityId}" to ensure uniqueness /// across multiple agent backends. /// public string? EntityIdPrefix { get; } /// /// Gets the list of agents declared by this backend. /// /// /// When non-empty, the DevUI aggregator uses these declarations to build the entity listing /// without querying the backend. When empty, the aggregator falls back to calling /// GET /v1/entities on the backend for discovery. /// public IReadOnlyList Agents { get; } }