Skip to content

Commit bb93932

Browse files
committed
Add more intuitive API for creating chat messages
Allows using collection initializer syntax for multiple messages, with a more python-esque style: ```csharp var messages = new Chat() { { "system", "You are a highly intelligent AI assistant." }, { "user", "What is 101*3?" }, }; ```
1 parent bbe6921 commit bb93932

File tree

4 files changed

+73
-22
lines changed

4 files changed

+73
-22
lines changed

src/AI.Tests/AI.Tests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net8.0</TargetFramework>
4+
<TargetFrameworks>net8.0;net10.0</TargetFrameworks>
55
<NoWarn>OPENAI001;$(NoWarn)</NoWarn>
66
</PropertyGroup>
77

src/AI/Chat.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using System.Collections;
2+
using Microsoft.Extensions.AI;
3+
4+
namespace Devlooped.Extensions.AI;
5+
6+
/// <summary>
7+
/// Collection of <see cref="ChatMessage"/> for more convenient usage
8+
/// in fluent construction of chat messages.
9+
/// </summary>
10+
public class Chat : IEnumerable<ChatMessage>
11+
{
12+
readonly List<ChatMessage> messages = [];
13+
14+
/// <summary>
15+
/// Adds a message to the list of chat messages.
16+
/// For use with collection initializer syntax.
17+
/// </summary>
18+
public void Add(ChatMessage message) => messages.Add(message);
19+
20+
/// <summary>
21+
/// Adds a message to the list of chat messages.
22+
/// </summary>
23+
/// <param name="role">The message role</param>
24+
/// <param name="message">The message text</param>
25+
/// <remarks>
26+
/// Example usage:
27+
/// <code>
28+
/// var messages = new Chat()
29+
/// {
30+
/// { "system", "You are a highly intelligent AI assistant." },
31+
/// { "user", "What is 101*3?" },
32+
/// };
33+
/// </code>
34+
/// </remarks>
35+
public void Add(string role, string message)
36+
=> messages.Add(new ChatMessage(role.ToLowerInvariant() switch
37+
{
38+
"system" => ChatRole.System,
39+
"assistant" => ChatRole.Assistant,
40+
"user" => ChatRole.User,
41+
_ => new ChatRole(role)
42+
}, message));
43+
44+
IEnumerator<ChatMessage> IEnumerable<ChatMessage>.GetEnumerator() => messages.GetEnumerator();
45+
46+
IEnumerator IEnumerable.GetEnumerator() => messages.GetEnumerator();
47+
}

src/AI/ChatExtensions.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System.ComponentModel;
2+
using Microsoft.Extensions.AI;
3+
4+
namespace Devlooped.Extensions.AI;
5+
6+
/// <summary>
7+
/// Provides usability overloads for the <see cref="IChatClient"/> interface.
8+
/// </summary>
9+
[EditorBrowsable(EditorBrowsableState.Never)]
10+
public static class ChatExtensions
11+
{
12+
extension(IChatClient client)
13+
{
14+
/// <summary>
15+
/// Allows passing a <see cref="Chat"/> instance to the chat client
16+
/// </summary>
17+
/// <param name="chat">The chat messages in a single object.</param>
18+
/// <param name="options">The optional chat options.</param>
19+
/// <param name="cancellation">Optional cancellation token.</param>
20+
public Task<ChatResponse> GetResponseAsync(Chat chat, ChatOptions? options = null, CancellationToken cancellation = default)
21+
=> client.GetResponseAsync((IEnumerable<ChatMessage>)chat, options, cancellation);
22+
}
23+
}
Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,15 @@
11
<Project>
22
<PropertyGroup>
3-
<ImplicitUsings>true</ImplicitUsings>
43
<Nullable>enable</Nullable>
54
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
65
</PropertyGroup>
76

87
<ItemGroup>
9-
<Using Include="System.Collections.Generic"/>
10-
<Using Include="System.Linq"/>
11-
<Using Include="System.Net"/>
12-
<Using Include="System.Net.Http"/>
13-
<Using Include="System.Reflection"/>
14-
<Using Include="System.Text.Json"/>
15-
<Using Include="System.Threading"/>
16-
<Using Include="System.Threading.Tasks"/>
17-
18-
<Using Include="Microsoft.Extensions.Configuration"/>
19-
<Using Include="Microsoft.Extensions.Configuration.UserSecrets"/>
20-
<Using Include="Microsoft.Extensions.DependencyInjection"/>
21-
<Using Include="Microsoft.Extensions.Hosting"/>
22-
<Using Include="Microsoft.Extensions.AI"/>
23-
24-
<Using Include="Spectre.Console"/>
25-
<Using Include="Spectre.Console.Json"/>
26-
27-
<Using Include="Polly"/>
288
</ItemGroup>
299

3010
<ItemGroup>
31-
<AssemblyMetadata Include="MSBuildProjectName" Value="$(MSBuildProjectName)" />
11+
<Using Include="Microsoft.Extensions.AI"/>
12+
<Using Include="Devlooped.Extensions.AI"/>
3213
</ItemGroup>
3314

3415
</Project>

0 commit comments

Comments
 (0)