autogen/dotnet/test/AutoGen.Anthropic.Tests/AnthropicClientTest.cs

180 lines
7.3 KiB
C#
Raw Normal View History

// Copyright (c) Microsoft Corporation. All rights reserved.
// AnthropicClientTest.cs
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using AutoGen.Anthropic.DTO;
using AutoGen.Anthropic.Utils;
using AutoGen.Tests;
using FluentAssertions;
using Xunit;
2024-06-10 13:32:33 -04:00
namespace AutoGen.Anthropic.Tests;
public class AnthropicClientTests
{
[ApiKeyFact("ANTHROPIC_API_KEY")]
public async Task AnthropicClientChatCompletionTestAsync()
{
var anthropicClient = new AnthropicClient(new HttpClient(), AnthropicConstants.Endpoint, AnthropicTestUtils.ApiKey);
var request = new ChatCompletionRequest();
request.Model = AnthropicConstants.Claude3Haiku;
request.Stream = false;
request.MaxTokens = 100;
request.Messages = new List<ChatMessage>() { new ChatMessage("user", "Hello world") };
ChatCompletionResponse response = await anthropicClient.CreateChatCompletionsAsync(request, CancellationToken.None);
Assert.NotNull(response);
Assert.NotNull(response.Content);
Assert.NotEmpty(response.Content);
response.Content.Count.Should().Be(1);
response.Content.First().Should().BeOfType<TextContent>();
var textContent = (TextContent)response.Content.First();
Assert.Equal("text", textContent.Type);
Assert.NotNull(response.Usage);
response.Usage.OutputTokens.Should().BeGreaterThan(0);
}
[ApiKeyFact("ANTHROPIC_API_KEY")]
public async Task AnthropicClientStreamingChatCompletionTestAsync()
{
var anthropicClient = new AnthropicClient(new HttpClient(), AnthropicConstants.Endpoint, AnthropicTestUtils.ApiKey);
var request = new ChatCompletionRequest();
request.Model = AnthropicConstants.Claude3Haiku;
request.Stream = true;
request.MaxTokens = 500;
request.SystemMessage = "You are a helpful assistant that convert input to json object, use JSON format.";
request.Messages = new List<ChatMessage>()
{
new("user", "name: John, age: 41, email: g123456@gmail.com")
};
var response = anthropicClient.StreamingChatCompletionsAsync(request, CancellationToken.None);
var results = await response.ToListAsync();
results.Count.Should().BeGreaterThan(0);
// Merge the chunks.
StringBuilder sb = new();
foreach (ChatCompletionResponse result in results)
{
if (result.Delta is not null && !string.IsNullOrEmpty(result.Delta.Text))
{
sb.Append(result.Delta.Text);
}
}
string resultContent = sb.ToString();
Assert.NotNull(resultContent);
var person = JsonSerializer.Deserialize<Person>(resultContent);
Assert.NotNull(person);
person.Name.Should().Be("John");
person.Age.Should().Be(41);
person.Email.Should().Be("g123456@gmail.com");
Assert.NotNull(results.First().streamingMessage);
results.First().streamingMessage!.Role.Should().Be("assistant");
}
2024-06-10 13:32:33 -04:00
[ApiKeyFact("ANTHROPIC_API_KEY")]
public async Task AnthropicClientImageChatCompletionTestAsync()
{
var anthropicClient = new AnthropicClient(new HttpClient(), AnthropicConstants.Endpoint, AnthropicTestUtils.ApiKey);
var request = new ChatCompletionRequest();
request.Model = AnthropicConstants.Claude3Haiku;
request.Stream = false;
request.MaxTokens = 100;
request.SystemMessage = "You are a LLM that is suppose to describe the content of the image. Give me a description of the provided image.";
var base64Image = await AnthropicTestUtils.Base64FromImageAsync("square.png");
var messages = new List<ChatMessage>
{
new("user",
[
new ImageContent { Source = new ImageSource {MediaType = "image/png", Data = base64Image} }
])
};
request.Messages = messages;
var response = await anthropicClient.CreateChatCompletionsAsync(request, CancellationToken.None);
Assert.NotNull(response);
Assert.NotNull(response.Content);
Assert.NotEmpty(response.Content);
response.Content.Count.Should().Be(1);
response.Content.First().Should().BeOfType<TextContent>();
var textContent = (TextContent)response.Content.First();
Assert.Equal("text", textContent.Type);
Assert.NotNull(response.Usage);
response.Usage.OutputTokens.Should().BeGreaterThan(0);
}
[ApiKeyFact("ANTHROPIC_API_KEY")]
public async Task AnthropicClientTestToolsAsync()
{
var anthropicClient = new AnthropicClient(new HttpClient(), AnthropicConstants.Endpoint, AnthropicTestUtils.ApiKey);
var request = new ChatCompletionRequest();
request.Model = AnthropicConstants.Claude3Haiku;
request.Stream = false;
request.MaxTokens = 100;
request.Messages = new List<ChatMessage>() { new("user", "Use the stock price tool to look for MSFT. Your response should only be the tool.") };
request.Tools = new List<Tool>() { AnthropicTestUtils.StockTool };
ChatCompletionResponse response =
await anthropicClient.CreateChatCompletionsAsync(request, CancellationToken.None);
Assert.NotNull(response.Content);
Assert.True(response.Content.First() is ToolUseContent);
ToolUseContent toolUseContent = ((ToolUseContent)response.Content.First());
Assert.Equal("get_stock_price", toolUseContent.Name);
Assert.NotNull(toolUseContent.Input);
Assert.True(toolUseContent.Input is JsonNode);
JsonNode jsonNode = toolUseContent.Input;
Assert.Equal("{\"ticker\":\"MSFT\"}", jsonNode.ToJsonString());
}
[ApiKeyFact("ANTHROPIC_API_KEY")]
public async Task AnthropicClientTestToolChoiceAsync()
{
var anthropicClient = new AnthropicClient(new HttpClient(), AnthropicConstants.Endpoint, AnthropicTestUtils.ApiKey);
var request = new ChatCompletionRequest();
request.Model = AnthropicConstants.Claude3Haiku;
request.Stream = false;
request.MaxTokens = 100;
request.Messages = new List<ChatMessage>() { new("user", "What is the weather today? Your response should only be the tool.") };
request.Tools = new List<Tool>() { AnthropicTestUtils.StockTool, AnthropicTestUtils.WeatherTool };
// Force to use get_stock_price even though the prompt is about weather
request.ToolChoice = ToolChoice.ToolUse("get_stock_price");
ChatCompletionResponse response =
await anthropicClient.CreateChatCompletionsAsync(request, CancellationToken.None);
Assert.NotNull(response.Content);
Assert.True(response.Content.First() is ToolUseContent);
ToolUseContent toolUseContent = ((ToolUseContent)response.Content.First());
Assert.Equal("get_stock_price", toolUseContent.Name);
Assert.NotNull(toolUseContent.Input);
Assert.True(toolUseContent.Input is JsonNode);
}
private sealed class Person
{
[JsonPropertyName("name")]
public string Name { get; set; } = string.Empty;
[JsonPropertyName("age")]
public int Age { get; set; }
[JsonPropertyName("email")]
public string Email { get; set; } = string.Empty;
}
}