| File: Pipeline\UIAgentOptions.cs | Web Access |
| Project: src\aspnetcore\src\Components\AI\src\Microsoft.AspNetCore.Components.AI.csproj (Microsoft.AspNetCore.Components.AI) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.Extensions.AI; namespace Microsoft.AspNetCore.Components.AI; /// <summary> /// Configures a <see cref="UIAgent"/>. /// </summary> /// <example> /// <code> /// var agent = new UIAgent(chatClient, options => /// { /// options.ChatOptions = new ChatOptions { Instructions = "You are a helpful assistant." }; /// }); /// </code> /// </example> public class UIAgentOptions { /// <summary> /// Gets or sets the options passed to the underlying <see cref="IChatClient"/>. /// </summary> public ChatOptions? ChatOptions { get; set; } /// <summary> /// Gets or sets a callback that maps model updates into typed agent state. /// </summary> public Action<StateMapperContext>? StateMapper { get; set; } /// <summary> /// Gets or sets the persistent conversation thread that receives completed turns. /// </summary> public IConversationThread? Thread { get; set; } internal List<IHandlerRegistration> HandlerRegistrations { get; } = new(); internal Dictionary<string, AIFunction> UIActions { get; } = new(StringComparer.Ordinal); /// <summary> /// Registers a handler that maps model updates into content blocks. Registered handlers /// run before the built-in ones, so they can claim content the built-in handlers would /// otherwise map. /// </summary> /// <typeparam name="TState">The state the handler keeps across updates.</typeparam> /// <param name="handler">The handler to register.</param> public void AddBlockHandler<TState>(ContentBlockHandler<TState> handler) where TState : new() { ArgumentNullException.ThrowIfNull(handler); HandlerRegistrations.Add(new HandlerRegistration<TState>(handler)); } /// <summary> /// Registers a function that a matching model tool call executes in the UI. /// The function is sent to the chat client as a declaration, not as an executable server tool. /// </summary> /// <param name="function"> /// The function to execute in the UI. Its name must be unique among the registered UI actions. /// </param> /// <exception cref="ArgumentException"> /// An action with the same name is already registered. /// </exception> public void RegisterUIAction(AIFunction function) { ArgumentNullException.ThrowIfNull(function); UIActions.Add(function.Name, function); } internal interface IHandlerRegistration { IHandlerEntry CreateEntry(); } private sealed class HandlerRegistration<TState> : IHandlerRegistration where TState : new() { private readonly ContentBlockHandler<TState> _handler; internal HandlerRegistration(ContentBlockHandler<TState> handler) { _handler = handler; } public IHandlerEntry CreateEntry() => new HandlerEntry<TState>(_handler); } } /// <summary> /// Configures a <see cref="UIAgent{TState}"/>. /// </summary> /// <typeparam name="TState">The type of state associated with the agent.</typeparam> public sealed class UIAgentOptions<TState> : UIAgentOptions where TState : class, new() { internal UIAgentOptions(TState? initialState) { State = new AgentState<TState>(initialState); } /// <summary> /// Gets the observable state associated with the agent. /// </summary> public AgentState<TState> State { get; } }