Skip to content

Commit

Permalink
Fixes #97: adds user names to chat, support multiple inputs for moder…
Browse files Browse the repository at this point in the history
…ation
  • Loading branch information
OkGoDoIt committed Apr 2, 2023
1 parent d4b0eed commit 1265387
Show file tree
Hide file tree
Showing 5 changed files with 245 additions and 66 deletions.
6 changes: 6 additions & 0 deletions OpenAI_API/Chat/ChatMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,11 @@ public ChatMessageRole Role
/// </summary>
[JsonProperty("content")]
public string Content { get; set; }

/// <summary>
/// An optional name of the user in a multi-user chat
/// </summary>
[JsonProperty("name")]
public string Name { get; set; }
}
}
9 changes: 9 additions & 0 deletions OpenAI_API/Chat/Conversation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,15 @@ public void AppendMessage(ChatMessage message)
/// </summary>
/// <param name="content">Text content generated by the end users of an application, or set by a developer as an instruction</param>
public void AppendUserInput(string content) => this.AppendMessage(new ChatMessage(ChatMessageRole.User, content));

/// <summary>
/// Creates and appends a <see cref="ChatMessage"/> to the chat hstory with the Role of <see cref="ChatMessageRole.User"/>. The user messages help instruct the assistant. They can be generated by the end users of an application, or set by a developer as an instruction.
/// </summary>
/// <param name="userName">The name of the user in a multi-user chat</param>
/// <param name="content">Text content generated by the end users of an application, or set by a developer as an instruction</param>
public void AppendUserInputWithName(string userName, string content) => this.AppendMessage(new ChatMessage(ChatMessageRole.User, content) { Name = userName });


/// <summary>
/// Creates and appends a <see cref="ChatMessage"/> to the chat hstory with the Role of <see cref="ChatMessageRole.System"/>. The system message helps set the behavior of the assistant.
/// </summary>
Expand Down
41 changes: 36 additions & 5 deletions OpenAI_API/Moderation/ModerationRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using OpenAI_API.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

Expand All @@ -22,8 +23,27 @@ public class ModerationRequest
/// <summary>
/// The input text to classify
/// </summary>
[JsonIgnore]
public string Input
{
get
{
if (Inputs == null)
return null;
else
return Inputs.FirstOrDefault();
}
set
{
Inputs = new string[] { value };
}
}

/// <summary>
/// An array of inputs to classify
/// </summary>
[JsonProperty("input")]
public string Input { get; set; }
public string[] Inputs { get; set; }

/// <summary>
/// Cretes a new, empty <see cref="ModerationRequest"/>
Expand All @@ -45,13 +65,24 @@ public ModerationRequest(string input, Model model)
}

/// <summary>
/// Creates a new <see cref="ModerationRequest"/> with the specified input and the <see cref="Model.TextModerationLatest"/> model.
/// Creates a new <see cref="ModerationRequest"/> with the specified parameters
/// </summary>
/// <param name="input">The prompt to classify</param>
public ModerationRequest(string input)
/// <param name="inputs">An array of prompts to classify</param>
/// <param name="model">The model to use. You can use <see cref="ModelsEndpoint.GetModelsAsync()"/> to see all of your available models, or use a standard model like <see cref="Model.TextModerationLatest"/>.</param>
public ModerationRequest(string[] inputs, Model model)
{
Model = model;
this.Inputs = inputs;
}

/// <summary>
/// Creates a new <see cref="ModerationRequest"/> with the specified input(s) and the <see cref="Model.TextModerationLatest"/> model.
/// </summary>
/// <param name="input">One or more prompts to classify</param>
public ModerationRequest(params string[] input)
{
Model = OpenAI_API.Models.Model.TextModerationLatest;
this.Input = input;
this.Inputs = input;
}
}
}
66 changes: 66 additions & 0 deletions OpenAI_Tests/ChatEndpointTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using OpenAI_API.Chat;
using OpenAI_API.Completions;
using OpenAI_API.Models;
using OpenAI_API.Moderation;
using System;
using System.Collections.Generic;
using System.Linq;
Expand Down Expand Up @@ -53,7 +54,45 @@ public void BasicCompletion()
Assert.That(results.Choices.All(c => c.Message.Role.Equals(ChatMessageRole.Assistant)));
Assert.That(results.Choices.All(c => c.Message.Content.Length > 1));
}
[Test]
public void BasicCompletionWithNames()
{
var api = new OpenAI_API.OpenAIAPI();

Assert.IsNotNull(api.Chat);

var results = api.Chat.CreateChatCompletionAsync(new ChatRequest()
{
Model = Model.ChatGPTTurbo,
Temperature = 0.1,
MaxTokens = 5,
Messages = new ChatMessage[] {
new ChatMessage(ChatMessageRole.System, "You are the moderator in this workplace chat. Answer any questions asked of the participants."),
new ChatMessage(ChatMessageRole.User, "Hello everyone") { Name="John"},
new ChatMessage(ChatMessageRole.User, "Good morning all") { Name="Edward"},
new ChatMessage(ChatMessageRole.User, "Is John here? Answer yes or no.") { Name = "Cindy" }
}
}).Result;
Assert.IsNotNull(results);
if (results.CreatedUnixTime.HasValue)
{
Assert.NotZero(results.CreatedUnixTime.Value);
Assert.NotNull(results.Created);
Assert.Greater(results.Created.Value, new DateTime(2018, 1, 1));
Assert.Less(results.Created.Value, DateTime.Now.AddDays(1));
}
else
{
Assert.Null(results.Created);
}
Assert.NotNull(results.Object);
Assert.NotNull(results.Choices);
Assert.NotZero(results.Choices.Count);
Assert.AreEqual(ChatMessageRole.Assistant, results.Choices[0].Message.Role);
Assert.That(results.Choices.All(c => c.Message.Role.Equals(ChatMessageRole.Assistant)));
Assert.That(results.Choices.All(c => c.Message.Content.Length > 1));
Assert.That(results.ToString().ToLower().Contains("yes"));
}
[Test]
public void SimpleCompletion()
{
Expand Down Expand Up @@ -92,6 +131,7 @@ public void ChatBackAndForth(string model)

var chat = api.Chat.CreateConversation();
chat.Model = model;
chat.RequestParameters.Temperature = 0;

chat.AppendSystemMessage("You are a teacher who helps children understand if things are animals or not. If the user tells you an animal, you say \"yes\". If the user tells you something that is not an animal, you say \"no\". You only ever respond with \"yes\" or \"no\". You do not say anything else.");
chat.AppendUserInput("Is this an animal? Cat");
Expand All @@ -110,6 +150,32 @@ public void ChatBackAndForth(string model)
Assert.AreEqual("No", res.Trim());
}

[Test]
public void ChatWithNames()
{
var api = new OpenAI_API.OpenAIAPI();

var chat = api.Chat.CreateConversation();
chat.RequestParameters.Temperature = 0;

chat.AppendSystemMessage("You are the moderator in this workplace chat. Answer any questions asked of the participants.");
chat.AppendUserInputWithName("John", "Hello everyone");
chat.AppendUserInputWithName("Edward", "Good morning all");
chat.AppendUserInputWithName("Cindy", "Is John here? Answer yes or no.");
chat.AppendExampleChatbotOutput("Yes");
chat.AppendUserInputWithName("Cindy", "Is Monica here? Answer yes or no.");
string res = chat.GetResponseFromChatbot().Result;
Assert.NotNull(res);
Assert.IsNotEmpty(res);
Assert.That(res.ToLower().Contains("no"));
chat.AppendUserInputWithName("Cindy", "Is Edward here? Answer yes or no.");
res = chat.GetResponseFromChatbot().Result;
Assert.NotNull(res);
Assert.IsNotEmpty(res);
Assert.That(res.ToLower().Contains("yes"));
}


[Test]
public async Task StreamCompletionEnumerableAsync_ShouldStreamData()
{
Expand Down
189 changes: 128 additions & 61 deletions OpenAI_Tests/ModerationEndpointTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,71 +6,138 @@

namespace OpenAI_Tests
{
public class ModerationEndpointTests
{
[SetUp]
public void Setup()
{
OpenAI_API.APIAuthentication.Default = new OpenAI_API.APIAuthentication(Environment.GetEnvironmentVariable("TEST_OPENAI_SECRET_KEY"));
}

[Test]
public void NoViolations()
{
var api = new OpenAI_API.OpenAIAPI();

Assert.IsNotNull(api.Moderation);

var results = api.Moderation.CallModerationAsync(new ModerationRequest("Hello world")).Result;
Assert.IsNotNull(results);
if (results.CreatedUnixTime.HasValue)
{
Assert.NotZero(results.CreatedUnixTime.Value);
Assert.NotNull(results.Created);
Assert.Greater(results.Created.Value, new DateTime(2018, 1, 1));
public class ModerationEndpointTests
{
[SetUp]
public void Setup()
{
OpenAI_API.APIAuthentication.Default = new OpenAI_API.APIAuthentication(Environment.GetEnvironmentVariable("TEST_OPENAI_SECRET_KEY"));
}

[Test]
public void NoViolations()
{
var api = new OpenAI_API.OpenAIAPI();

Assert.IsNotNull(api.Moderation);

var results = api.Moderation.CallModerationAsync(new ModerationRequest("Hello world")).Result;
Assert.IsNotNull(results);
if (results.CreatedUnixTime.HasValue)
{
Assert.NotZero(results.CreatedUnixTime.Value);
Assert.NotNull(results.Created);
Assert.Greater(results.Created.Value, new DateTime(2018, 1, 1));
Assert.Less(results.Created.Value, DateTime.Now.AddDays(1));
} else
{
Assert.Null(results.Created);
}
Assert.NotNull(results.Results);
Assert.NotZero(results.Results.Count);
var result = results.Results[0];
Assert.False(result.Flagged);
Assert.Zero(result.FlaggedCategories.Count);
Assert.Greater(result.HighestFlagScore, 0d);
Assert.Null(result.MainContentFlag);
}

[Test]
public void ViolenceExample()
{
var api = new OpenAI_API.OpenAIAPI();

Assert.IsNotNull(api.Moderation);

var results = api.Moderation.CallModerationAsync("I want to kill them.").Result;
Assert.IsNotNull(results);
if (results.CreatedUnixTime.HasValue)
{
Assert.NotZero(results.CreatedUnixTime.Value);
Assert.NotNull(results.Created);
Assert.Greater(results.Created.Value, new DateTime(2018, 1, 1));
else
{
Assert.Null(results.Created);
}
Assert.NotNull(results.Results);
Assert.NotZero(results.Results.Count);
var result = results.Results[0];
Assert.False(result.Flagged);
Assert.Zero(result.FlaggedCategories.Count);
Assert.Greater(result.HighestFlagScore, 0d);
Assert.Null(result.MainContentFlag);
}


[Test]
public void MultipleInputs()
{
var api = new OpenAI_API.OpenAIAPI();

Assert.IsNotNull(api.Moderation);

var results = api.Moderation.CallModerationAsync(new ModerationRequest("Hello world", "Good morning")).Result;
Assert.IsNotNull(results);
if (results.CreatedUnixTime.HasValue)
{
Assert.NotZero(results.CreatedUnixTime.Value);
Assert.NotNull(results.Created);
Assert.Greater(results.Created.Value, new DateTime(2018, 1, 1));
Assert.Less(results.Created.Value, DateTime.Now.AddDays(1));
} else
{
Assert.Null(results.Created);
}
Assert.NotNull(results.Results);
Assert.NotZero(results.Results.Count);
var result = results.Results[0];
Assert.True(result.Flagged);
Assert.NotZero(result.FlaggedCategories.Count);
Assert.Greater(result.HighestFlagScore, 0.5d);
Assert.AreEqual("violence", result.MainContentFlag);
Assert.AreEqual(result.HighestFlagScore, result.CategoryScores["violence"]);
Assert.AreEqual("violence", result.FlaggedCategories.First());
else
{
Assert.Null(results.Created);
}
Assert.NotNull(results.Results);
Assert.AreEqual(2, results.Results.Count);
foreach (var result in results.Results)
{
Assert.False(result.Flagged);
Assert.Zero(result.FlaggedCategories.Count);
Assert.Greater(result.HighestFlagScore, 0d);
Assert.Null(result.MainContentFlag);
}
}



[Test]
public void MultipleInputsFailing()
{
var api = new OpenAI_API.OpenAIAPI();

Assert.IsNotNull(api.Moderation);

var results = api.Moderation.CallModerationAsync(new ModerationRequest("You are going to die, you scum", "I want to kill them")).Result;
Assert.IsNotNull(results);
if (results.CreatedUnixTime.HasValue)
{
Assert.NotZero(results.CreatedUnixTime.Value);
Assert.NotNull(results.Created);
Assert.Greater(results.Created.Value, new DateTime(2018, 1, 1));
Assert.Less(results.Created.Value, DateTime.Now.AddDays(1));
}
else
{
Assert.Null(results.Created);
}
Assert.NotNull(results.Results);
Assert.AreEqual(2, results.Results.Count);
foreach (var result in results.Results)
{
Assert.True(result.Flagged);
Assert.NotZero(result.FlaggedCategories.Count);
Assert.Greater(result.HighestFlagScore, 0.5d);
Assert.NotNull(result.MainContentFlag);
}
}

[Test]
public void ViolenceExample()
{
var api = new OpenAI_API.OpenAIAPI();

Assert.IsNotNull(api.Moderation);

var results = api.Moderation.CallModerationAsync("I want to kill them.").Result;
Assert.IsNotNull(results);
if (results.CreatedUnixTime.HasValue)
{
Assert.NotZero(results.CreatedUnixTime.Value);
Assert.NotNull(results.Created);
Assert.Greater(results.Created.Value, new DateTime(2018, 1, 1));
Assert.Less(results.Created.Value, DateTime.Now.AddDays(1));
}
else
{
Assert.Null(results.Created);
}
Assert.NotNull(results.Results);
Assert.NotZero(results.Results.Count);
var result = results.Results[0];
Assert.True(result.Flagged);
Assert.NotZero(result.FlaggedCategories.Count);
Assert.Greater(result.HighestFlagScore, 0.5d);
Assert.AreEqual("violence", result.MainContentFlag);
Assert.AreEqual(result.HighestFlagScore, result.CategoryScores["violence"]);
Assert.AreEqual("violence", result.FlaggedCategories.First());
}

}
}
}

0 comments on commit 1265387

Please sign in to comment.