Files
agent-framework/dotnet/src/Microsoft.Agents.AI.DevUI/ServiceCollectionsExtensions.cs
Jacob Alber 0086d38f58 .NET: [BREAKING] Workflows API Review Naming Changes (Part 1?) (#4090)
* refactor: Normalize Run/RunStreaming with AIAgent

* refactor: Clarify Session vs. Run -level concepts

* Rename RunId to SessionId to better match Run/Session terminology in AIAgent
* [BREAKING]: Will break existing checkpointed sessions in CosmosDb due to field rename

* refactor: Rename and simplify interface around getting typed data out of ExternalRequest/Response

* Also adds hints around using value types in PortableValue

* refactor: Rename AddFanInEdge to AddFanInBarrierEdge

This will prevent a breaking change later when we introduce a programmable FanIn edge, analogous to the FanOut edge's EdgeSelector.

The goal, in the long run is to support a number of different FanIn scenarios, with naive FanIn (no barrier) by default, similar to FanOut.

* refactor: AsAgent(this Workflow, ...) => AsAIAgent(...)

* misc - part1: SwitchBuilder internal

---------

Co-authored-by: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com>
2026-02-20 02:05:18 +00:00

62 lines
2.2 KiB
C#

// Copyright (c) Microsoft. All rights reserved.
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Workflows;
using Microsoft.Shared.Diagnostics;
namespace Microsoft.Extensions.DependencyInjection;
/// <summary>
/// Extension methods for <see cref="IServiceCollection"/> to configure DevUI.
/// </summary>
public static class MicrosoftAgentAIDevUIServiceCollectionsExtensions
{
/// <summary>
/// Adds services required for DevUI integration.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection"/> to configure.</param>
/// <returns>The <see cref="IServiceCollection"/> for method chaining.</returns>
public static IServiceCollection AddDevUI(this IServiceCollection services)
{
ArgumentNullException.ThrowIfNull(services);
// a factory that tries to construct an AIAgent from Workflow,
// even if workflow was not explicitly registered as an AIAgent.
#pragma warning disable IDE0001 // Simplify Names
services.AddKeyedSingleton<AIAgent>(KeyedService.AnyKey, (sp, key) =>
{
var keyAsStr = key as string;
Throw.IfNullOrEmpty(keyAsStr);
var workflow = sp.GetKeyedService<Workflow>(keyAsStr);
if (workflow is not null)
{
return workflow.AsAIAgent(name: workflow.Name);
}
// another thing we can do is resolve a non-keyed workflow.
// however, we can't rely on anything than key to be equal to the workflow.Name.
// so we try: if we fail, we return null.
workflow = sp.GetService<Workflow>();
if (workflow is not null && workflow.Name?.Equals(keyAsStr, StringComparison.Ordinal) == true)
{
return workflow.AsAIAgent(name: workflow.Name);
}
// and it's possible to lookup at the default-registered AIAgent
// with the condition of same name as the key.
var agent = sp.GetService<AIAgent>();
if (agent is not null && agent.Name?.Equals(keyAsStr, StringComparison.Ordinal) == true)
{
return agent;
}
return null!;
});
#pragma warning restore IDE0001 // Simplify Names
return services;
}
}