Skip to content
Merged
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
2 changes: 1 addition & 1 deletion src/AI.Tests/AI.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFrameworks>net8.0;net10.0</TargetFrameworks>
<NoWarn>OPENAI001;$(NoWarn)</NoWarn>
</PropertyGroup>

Expand Down
47 changes: 47 additions & 0 deletions src/AI/Chat.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System.Collections;
using Microsoft.Extensions.AI;

namespace Devlooped.Extensions.AI;

/// <summary>
/// Collection of <see cref="ChatMessage"/> for more convenient usage
/// in fluent construction of chat messages.
/// </summary>
public class Chat : IEnumerable<ChatMessage>
{
readonly List<ChatMessage> messages = [];

/// <summary>
/// Adds a message to the list of chat messages.
/// For use with collection initializer syntax.
/// </summary>
public void Add(ChatMessage message) => messages.Add(message);

/// <summary>
/// Adds a message to the list of chat messages.
/// </summary>
/// <param name="role">The message role</param>
/// <param name="message">The message text</param>
/// <remarks>
/// Example usage:
/// <code>
/// var messages = new Chat()
/// {
/// { "system", "You are a highly intelligent AI assistant." },
/// { "user", "What is 101*3?" },
/// };
/// </code>
/// </remarks>
public void Add(string role, string message)
=> messages.Add(new ChatMessage(role.ToLowerInvariant() switch
{
"system" => ChatRole.System,
"assistant" => ChatRole.Assistant,
"user" => ChatRole.User,
_ => new ChatRole(role)
}, message));

IEnumerator<ChatMessage> IEnumerable<ChatMessage>.GetEnumerator() => messages.GetEnumerator();

IEnumerator IEnumerable.GetEnumerator() => messages.GetEnumerator();
}
23 changes: 23 additions & 0 deletions src/AI/ChatExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.ComponentModel;
using Microsoft.Extensions.AI;

namespace Devlooped.Extensions.AI;

/// <summary>
/// Provides usability overloads for the <see cref="IChatClient"/> interface.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public static class ChatExtensions
{
extension(IChatClient client)
{
/// <summary>
/// Allows passing a <see cref="Chat"/> instance to the chat client
/// </summary>
/// <param name="chat">The chat messages in a single object.</param>
/// <param name="options">The optional chat options.</param>
/// <param name="cancellation">Optional cancellation token.</param>
public Task<ChatResponse> GetResponseAsync(Chat chat, ChatOptions? options = null, CancellationToken cancellation = default)
=> client.GetResponseAsync((IEnumerable<ChatMessage>)chat, options, cancellation);
}
}
23 changes: 2 additions & 21 deletions src/AI/Devlooped.Extensions.AI.props
Original file line number Diff line number Diff line change
@@ -1,34 +1,15 @@
<Project>
<PropertyGroup>
<ImplicitUsings>true</ImplicitUsings>
<Nullable>enable</Nullable>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>

<ItemGroup>
<Using Include="System.Collections.Generic"/>
<Using Include="System.Linq"/>
<Using Include="System.Net"/>
<Using Include="System.Net.Http"/>
<Using Include="System.Reflection"/>
<Using Include="System.Text.Json"/>
<Using Include="System.Threading"/>
<Using Include="System.Threading.Tasks"/>

<Using Include="Microsoft.Extensions.Configuration"/>
<Using Include="Microsoft.Extensions.Configuration.UserSecrets"/>
<Using Include="Microsoft.Extensions.DependencyInjection"/>
<Using Include="Microsoft.Extensions.Hosting"/>
<Using Include="Microsoft.Extensions.AI"/>

<Using Include="Spectre.Console"/>
<Using Include="Spectre.Console.Json"/>

<Using Include="Polly"/>
</ItemGroup>

<ItemGroup>
<AssemblyMetadata Include="MSBuildProjectName" Value="$(MSBuildProjectName)" />
<Using Include="Microsoft.Extensions.AI"/>
<Using Include="Devlooped.Extensions.AI"/>
</ItemGroup>

</Project>
Loading