Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenAI-DotNet 7.3.0 #168

Merged
merged 80 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
4b92dd8
Assistants Endpoint (#166)
khoroshevj Nov 15, 2023
a064b8b
Threads Endpoint (#167)
khoroshevj Nov 15, 2023
5db6575
update workflows
StephenHodgson Nov 15, 2023
ac3dfa3
updated image endpoint return types to ImageResult list
StephenHodgson Nov 15, 2023
60bf212
bump version to 7.3.0
StephenHodgson Nov 15, 2023
d0b6f81
use block scoped namespaces in solution
StephenHodgson Nov 15, 2023
5fbf0fe
refactor threads endpoint
StephenHodgson Nov 15, 2023
d0bac4d
properly deserialize thread responses
StephenHodgson Nov 15, 2023
5bc30aa
clean up assistants
StephenHodgson Nov 15, 2023
0cc8b20
renamed test classes
StephenHodgson Nov 15, 2023
2f834f9
thread messages and runs (#171)
khoroshevj Nov 16, 2023
e524233
cleanup pass
StephenHodgson Nov 16, 2023
ece3d24
Update OpenAI-DotNet-Tests/TestFixture_03_Chat.cs
StephenHodgson Nov 16, 2023
8f7c6b2
refactor list mechanism
StephenHodgson Nov 16, 2023
c8717f2
more cleanup
StephenHodgson Nov 16, 2023
e771c55
remove dup
StephenHodgson Nov 17, 2023
0d9716b
more cleanup
StephenHodgson Nov 17, 2023
e75938d
renamed MessageContent -> Content
StephenHodgson Nov 17, 2023
7f05376
even more cleanup
StephenHodgson Nov 17, 2023
bb19571
remove duplicate type
StephenHodgson Nov 17, 2023
8837b5e
renamed some classes to better represent their usage
StephenHodgson Nov 17, 2023
6b5412e
refactored datetime
StephenHodgson Nov 17, 2023
8669e0f
standardized timekeeping
StephenHodgson Nov 17, 2023
4b75f77
updated assistant test to remove test file
StephenHodgson Nov 17, 2023
36a1b75
rename method for clarification on use
StephenHodgson Nov 17, 2023
478ba9a
fixed rename
StephenHodgson Nov 17, 2023
ede4ddb
updated threads test
StephenHodgson Nov 18, 2023
227fb8e
Added OpenAIClient to BaseRespones for future extension capabilities
StephenHodgson Nov 18, 2023
428bbea
refactored more tests
StephenHodgson Nov 19, 2023
c15ee25
misc cleanup
StephenHodgson Nov 19, 2023
713bcc4
some organization
StephenHodgson Nov 19, 2023
1b7cf64
cleanup usings in OpenAIClient
StephenHodgson Nov 19, 2023
9c7271c
more method renames
StephenHodgson Nov 19, 2023
e53e04a
organization
StephenHodgson Nov 19, 2023
f3e4754
updated test workflow with code coverage summary
StephenHodgson Nov 19, 2023
3bad47e
updated tests
StephenHodgson Nov 19, 2023
b713d45
added a bunch of overloads
StephenHodgson Nov 19, 2023
d3135ec
more refactoring and overloads
StephenHodgson Nov 19, 2023
c156f5f
make AssisstantRequest optional in CreateAssistantAsync
StephenHodgson Nov 19, 2023
f2d445e
renamed AssistantFile to AssistantFileResponse
StephenHodgson Nov 19, 2023
a11cff7
Replaced FileData -> FileResponse
StephenHodgson Nov 19, 2023
1048be3
CompletionsResult -> CompletionsResponse
StephenHodgson Nov 19, 2023
3e50fc7
more unit time naming standardization
StephenHodgson Nov 19, 2023
4293095
updated changelog
StephenHodgson Nov 19, 2023
81f6e11
updated package description and readme
StephenHodgson Nov 19, 2023
c5e0b01
more thread refactoring
StephenHodgson Nov 19, 2023
985a574
added thread extensions
StephenHodgson Nov 19, 2023
77162d1
cleanup
StephenHodgson Nov 19, 2023
b292c2b
more overloads and extensions!
StephenHodgson Nov 19, 2023
fc13d61
refactored thread run cancellation and status checking
StephenHodgson Nov 19, 2023
f6259e5
fix rename
StephenHodgson Nov 19, 2023
c1101cd
added assistant extensions
StephenHodgson Nov 19, 2023
f8f03d4
we're in the endgame now
StephenHodgson Nov 20, 2023
744b613
Update OpenAI-DotNet/FineTuning/FineTuneJob.cs
StephenHodgson Nov 20, 2023
5d4a8f9
some more cleanup
StephenHodgson Nov 20, 2023
71c462f
updated changelog
StephenHodgson Nov 20, 2023
c45e44d
updated tests
StephenHodgson Nov 20, 2023
49f3135
Update .github/workflows/Publish-Nuget.yml
StephenHodgson Nov 20, 2023
5e67d80
Update .github/workflows/Publish-Nuget.yml
StephenHodgson Nov 20, 2023
15d8325
Apply suggestions from code review
StephenHodgson Nov 20, 2023
0056a5d
Update Publish-Nuget.yml
StephenHodgson Nov 20, 2023
c6e3ffe
Update .github/workflows/Publish-Nuget.yml
StephenHodgson Nov 20, 2023
5e0ec0b
Update OpenAI-DotNet-Tests.csproj
StephenHodgson Nov 20, 2023
7ea5cea
Update Publish-Nuget.yml
StephenHodgson Nov 20, 2023
4eb91c8
Update Publish-Nuget.yml
StephenHodgson Nov 20, 2023
d5d6198
Update Publish-Nuget.yml
StephenHodgson Nov 20, 2023
ef1a855
Update Publish-Nuget.yml
StephenHodgson Nov 20, 2023
7c5569e
Update Publish-Nuget.yml
StephenHodgson Nov 20, 2023
80a0eef
Update Publish-Nuget.yml
StephenHodgson Nov 20, 2023
b90e1fc
Update Publish-Nuget.yml
StephenHodgson Nov 20, 2023
6e8ec42
Fix unit tests for linux (#173)
StephenHodgson Nov 20, 2023
07cf855
updated readme
StephenHodgson Nov 20, 2023
21e3024
added a few more thread extensions
StephenHodgson Nov 20, 2023
6a79d7c
suppress cancellation exception when polling run status
StephenHodgson Nov 20, 2023
855443c
revert task timeout suppression
StephenHodgson Nov 20, 2023
52b6a88
updated more unit tests and readme
StephenHodgson Nov 20, 2023
0d9ad8d
updated unit tests
StephenHodgson Nov 20, 2023
574ba39
addressed some review change requests
StephenHodgson Nov 21, 2023
39978a0
moved some extensions out of endpoint impl
StephenHodgson Nov 21, 2023
6f8ac1e
ready, set go!
StephenHodgson Nov 21, 2023
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 .github/workflows/Publish-Nuget.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
runs-on: windows-latest

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-dotnet@v3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace OpenAI.Tests
{
internal class TestFixture_00_Authentication
internal class TestFixture_00_00_Authentication
{
[SetUp]
public void Setup()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace OpenAI.Tests
{
internal class TextFixture_11_Proxy : AbstractTestFixture
internal class TestFixture_00_01_Proxy : AbstractTestFixture
{
[Test]
public async Task Test_01_Health()
Expand Down
9 changes: 6 additions & 3 deletions OpenAI-DotNet-Tests/TestFixture_03_Chat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -451,8 +451,9 @@ public async Task Test_07_GetChatToolCompletion()
Assert.IsTrue(result.Choices.Count == 1);
}

var usedTool = result.FirstChoice.Message.ToolCalls[0];
Assert.IsTrue(result.FirstChoice.FinishReason == "tool_calls");
var usedTool = result.FirstChoice.Message.ToolCalls[0];
Assert.IsNotNull(usedTool);
Assert.IsTrue(usedTool.Function.Name == nameof(WeatherService.GetCurrentWeather));
Console.WriteLine($"{result.FirstChoice.Message.Role}: {usedTool.Function.Name} | Finish Reason: {result.FirstChoice.FinishReason}");
Console.WriteLine($"{usedTool.Function.Arguments}");
Expand Down Expand Up @@ -553,6 +554,7 @@ public async Task Test_08_GetChatToolCompletion_Streaming()

Assert.IsTrue(result.FirstChoice.FinishReason == "tool_calls");
var usedTool = result.FirstChoice.Message.ToolCalls[0];
Assert.IsNotNull(usedTool);
Assert.IsTrue(usedTool.Function.Name == nameof(WeatherService.GetCurrentWeather));
Console.WriteLine($"{result.FirstChoice.Message.Role}: {usedTool.Function.Name} | Finish Reason: {result.FirstChoice.FinishReason}");
Console.WriteLine($"{usedTool.Function.Arguments}");
Expand Down Expand Up @@ -627,12 +629,13 @@ public async Task Test_09_GetChatToolForceCompletion()
Assert.IsTrue(result.Choices.Count == 1);
messages.Add(result.FirstChoice.Message);

var usedTool = result.FirstChoice.Message.ToolCalls[0];
Assert.IsTrue(result.FirstChoice.FinishReason == "stop");
var usedTool = result.FirstChoice.Message.ToolCalls[0];
Assert.IsNotNull(usedTool);
Assert.IsTrue(usedTool.Function.Name == nameof(WeatherService.GetCurrentWeather));
Console.WriteLine($"{result.FirstChoice.Message.Role}: {usedTool.Function.Name} | Finish Reason: {result.FirstChoice.FinishReason}");
Console.WriteLine($"{usedTool.Function.Arguments}");
var functionArgs = JsonSerializer.Deserialize<WeatherArgs>(result.FirstChoice.Message.ToolCalls[0].Function.Arguments.ToString());
var functionArgs = JsonSerializer.Deserialize<WeatherArgs>(usedTool.Function.Arguments.ToString());
var functionResult = WeatherService.GetCurrentWeather(functionArgs);
Assert.IsNotNull(functionResult);
messages.Add(new Message(usedTool, functionResult));
Expand Down
8 changes: 6 additions & 2 deletions OpenAI-DotNet-Tests/TestFixture_05_Images.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ public async Task Test_1_GenerateImages()

Assert.IsNotNull(results);
Assert.NotZero(results.Count);
Assert.IsNotEmpty(results[0]);

foreach (var result in results)
{
Assert.IsNotNull(result);
Console.WriteLine(result);
}
}
Expand All @@ -36,10 +36,10 @@ public async Task Test_2_GenerateImages_B64_Json()

Assert.IsNotNull(results);
Assert.NotZero(results.Count);
Assert.IsNotEmpty(results[0]);

foreach (var result in results)
{
Assert.IsNotNull(result);
Console.WriteLine(result);
}
}
Expand All @@ -60,6 +60,7 @@ public async Task Test_3_GenerateImageEdits()

foreach (var result in results)
{
Assert.IsNotNull(result);
Console.WriteLine(result);
}
}
Expand All @@ -80,6 +81,7 @@ public async Task Test_4_GenerateImageEdits_B64_Json()

foreach (var result in results)
{
Assert.IsNotNull(result);
Console.WriteLine(result);
}
}
Expand All @@ -98,6 +100,7 @@ public async Task Test_5_GenerateImageVariations()

foreach (var result in results)
{
Assert.IsNotNull(result);
Console.WriteLine(result);
}
}
Expand All @@ -116,6 +119,7 @@ public async Task Test_6_GenerateImageVariations_B64_Json()

foreach (var result in results)
{
Assert.IsNotNull(result);
Console.WriteLine(result);
}
}
Expand Down
28 changes: 12 additions & 16 deletions OpenAI-DotNet-Tests/TestFixture_09_FineTuning.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,9 @@ public async Task Test_02_ListFineTuneJobs()
Assert.IsNotNull(OpenAIClient.FineTuningEndpoint);
var list = await OpenAIClient.FineTuningEndpoint.ListJobsAsync();
Assert.IsNotNull(list);
Assert.IsNotEmpty(list.Jobs);
Assert.IsNotEmpty(list.Items);

foreach (var job in list.Jobs.OrderByDescending(job => job.CreatedAt))
foreach (var job in list.Items.OrderByDescending(job => job.CreatedAt))
{
Console.WriteLine($"{job.Id} -> {job.CreatedAt} | {job.Status}");
}
Expand All @@ -120,9 +120,9 @@ public async Task Test_03_RetrieveFineTuneJobInfo()
Assert.IsNotNull(OpenAIClient.FineTuningEndpoint);
var list = await OpenAIClient.FineTuningEndpoint.ListJobsAsync();
Assert.IsNotNull(list);
Assert.IsNotEmpty(list.Jobs);
Assert.IsNotEmpty(list.Items);

foreach (var job in list.Jobs.OrderByDescending(job => job.CreatedAt))
foreach (var job in list.Items.OrderByDescending(job => job.CreatedAt))
{
var request = await OpenAIClient.FineTuningEndpoint.GetJobInfoAsync(job);
Assert.IsNotNull(request);
Expand All @@ -136,22 +136,18 @@ public async Task Test_04_ListFineTuneEvents()
Assert.IsNotNull(OpenAIClient.FineTuningEndpoint);
var list = await OpenAIClient.FineTuningEndpoint.ListJobsAsync();
Assert.IsNotNull(list);
Assert.IsNotEmpty(list.Jobs);
Assert.IsNotEmpty(list.Items);

foreach (var job in list.Jobs)
foreach (var job in list.Items)
{
if (job.Status == JobStatus.Cancelled)
{
continue;
}
if (job.Status == JobStatus.Cancelled) { continue; }

var eventList = await OpenAIClient.FineTuningEndpoint.ListJobEventsAsync(job);
Assert.IsNotNull(eventList);
Assert.IsNotEmpty(eventList.Events);

Console.WriteLine($"{job.Id} -> status: {job.Status} | event count: {eventList.Events.Count}");
Assert.IsNotEmpty(eventList.Items);
Console.WriteLine($"{job.Id} -> status: {job.Status} | event count: {eventList.Items.Count}");

foreach (var @event in eventList.Events.OrderByDescending(@event => @event.CreatedAt))
foreach (var @event in eventList.Items.OrderByDescending(@event => @event.CreatedAt))
{
Console.WriteLine($" {@event.CreatedAt} [{@event.Level}] {@event.Message}");
}
Expand All @@ -166,9 +162,9 @@ public async Task Test_05_CancelFineTuneJob()
Assert.IsNotNull(OpenAIClient.FineTuningEndpoint);
var list = await OpenAIClient.FineTuningEndpoint.ListJobsAsync();
Assert.IsNotNull(list);
Assert.IsNotEmpty(list.Jobs);
Assert.IsNotEmpty(list.Items);

foreach (var job in list.Jobs)
foreach (var job in list.Items)
{
if (job.Status is > JobStatus.NotStarted and < JobStatus.Succeeded)
{
Expand Down
134 changes: 134 additions & 0 deletions OpenAI-DotNet-Tests/TestFixture_11_Assistants.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
using NUnit.Framework;
using OpenAI.Assistants;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;

namespace OpenAI.Tests
{
internal class TestFixture_11_Assistants : AbstractTestFixture
{
private static string testAssistantId;

[Test]
public async Task Test_01_CreateAssistant()
{
Assert.IsNotNull(OpenAIClient.AssistantsEndpoint);
const string testFilePath = "assistant_test.txt";
await File.WriteAllTextAsync(testFilePath, "Knowledge is power!");
Assert.IsTrue(File.Exists(testFilePath));
var file = await OpenAIClient.FilesEndpoint.UploadFileAsync(testFilePath, "assistants");
File.Delete(testFilePath);
Assert.IsFalse(File.Exists(testFilePath));
var request = new AssistantRequest("gpt-3.5-turbo-1106",
name: "test-assistant",
description: "Used for unit testing.",
instructions: "You are test assistant",
metadata: new Dictionary<string, string>
{
["int"] = "1",
["test"] = Guid.NewGuid().ToString()
},
tools: new[]
{
Tool.Retrieval
},
fileIds: new[] { file.Id });
var assistant = await OpenAIClient.AssistantsEndpoint.CreateAssistantAsync(request);
Assert.IsNotNull(assistant);
Assert.AreEqual("test-assistant", assistant.Name);
Assert.AreEqual("Used for unit testing.", assistant.Description);
Assert.AreEqual("You are test assistant", assistant.Instructions);
Assert.AreEqual("gpt-3.5-turbo-1106", assistant.Model);
Assert.IsNotEmpty(assistant.Metadata);
testAssistantId = assistant.Id;
Console.WriteLine($"{assistant} -> {assistant.Metadata["test"]}");
}

[Test]
public async Task Test_02_ListAssistants()
{
Assert.IsNotNull(OpenAIClient.AssistantsEndpoint);
var assistantsList = await OpenAIClient.AssistantsEndpoint.ListAssistantsAsync();
Assert.IsNotNull(assistantsList);
Assert.IsNotEmpty(assistantsList.Items);

foreach (var assistant in assistantsList.Items)
{
Console.WriteLine($"{assistant} -> {assistant.CreatedAt}");
}
}

[Test]
public async Task Test_03_ListAssistantFiles()
{
Assert.IsFalse(string.IsNullOrWhiteSpace(testAssistantId));
Assert.IsNotNull(OpenAIClient.AssistantsEndpoint);
var filesList = await OpenAIClient.AssistantsEndpoint.ListAssistantFilesAsync(testAssistantId);
Assert.IsNotNull(filesList);
Assert.IsNotEmpty(filesList.Items);

foreach (var file in filesList.Items)
{
Assert.IsNotNull(file);
var retrieved = await OpenAIClient.AssistantsEndpoint.RetrieveAssistantFileAsync(file.AssistantId, file.Id);
Assert.IsNotNull(retrieved);
Console.WriteLine($"{retrieved.AssistantId}'s file -> {retrieved.Id}");
}
}

[Test]
public async Task Test_04_DeleteAssistantFile()
{
Assert.IsFalse(string.IsNullOrWhiteSpace(testAssistantId));
Assert.IsNotNull(OpenAIClient.AssistantsEndpoint);
var filesList = await OpenAIClient.AssistantsEndpoint.ListAssistantFilesAsync(testAssistantId);
Assert.IsNotNull(filesList);
Assert.IsNotEmpty(filesList.Items);

foreach (var file in filesList.Items)
{
Assert.IsNotNull(file);
var isRemoved = await OpenAIClient.AssistantsEndpoint.DeleteAssistantFileAsync(file);
Assert.IsTrue(isRemoved);
var isDeleted = await OpenAIClient.FilesEndpoint.DeleteFileAsync(file);
Assert.IsTrue(isDeleted);
}

filesList = await OpenAIClient.AssistantsEndpoint.ListAssistantFilesAsync(testAssistantId);
Assert.IsNotNull(filesList);
Assert.IsEmpty(filesList.Items);
}

[Test]
public async Task Test_05_ModifyAssistants()
{
Assert.IsFalse(string.IsNullOrWhiteSpace(testAssistantId));
Assert.IsNotNull(OpenAIClient.AssistantsEndpoint);
var request = new AssistantRequest(
model: "gpt-4-1106-preview",
name: "Test modified",
description: "Modified description",
instructions: "You are modified test assistant");
var assistant = await OpenAIClient.AssistantsEndpoint.ModifyAssistantAsync(testAssistantId, request);
Assert.IsNotNull(assistant);
Assert.AreEqual("Test modified", assistant.Name);
Assert.AreEqual("Modified description", assistant.Description);
Assert.AreEqual("You are modified test assistant", assistant.Instructions);
Assert.AreEqual("gpt-4-1106-preview", assistant.Model);
Assert.IsTrue(assistant.Metadata.ContainsKey("test"));
Console.WriteLine($"{assistant.Id} -> modified");
}

[Test]
public async Task Test_06_DeleteAssistant()
{
Assert.IsFalse(string.IsNullOrWhiteSpace(testAssistantId));
Assert.IsNotNull(OpenAIClient.AssistantsEndpoint);
var result = await OpenAIClient.AssistantsEndpoint.DeleteAssistantAsync(testAssistantId);
Assert.IsTrue(result);
Console.WriteLine($"{testAssistantId} -> deleted");
}
}
}
76 changes: 76 additions & 0 deletions OpenAI-DotNet-Tests/TestFixture_12_Threads.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using NUnit.Framework;
using OpenAI.Threads;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace OpenAI.Tests
{
internal class TestFixture_12_Threads : AbstractTestFixture
{
private static CreateThreadRequest TestThread { get; } = new CreateThreadRequest(
new List<Message>
{
new Message("Test message")
},
new Dictionary<string, string>
{
["text"] = "test"
}
);

[Test]
public async Task Test_01_CreateThread()
{
Assert.IsNotNull(OpenAIClient.ThreadsEndpoint);
var thread = await OpenAIClient.ThreadsEndpoint.CreateThreadAsync(TestThread);
Assert.IsNotNull(thread);
Assert.IsNotNull(thread.Metadata);
Assert.IsNotEmpty(thread.Metadata);
Assert.Contains("text", thread.Metadata.Keys.ToList());
Assert.AreEqual("test", thread.Metadata["text"]);
}

[Test]
public async Task Test_02_RetrieveThread()
{
Assert.IsNotNull(OpenAIClient.ThreadsEndpoint);
var thread = await OpenAIClient.ThreadsEndpoint.CreateThreadAsync(TestThread);
Assert.IsNotNull(thread);
var retrieved = await OpenAIClient.ThreadsEndpoint.RetrieveThreadAsync(thread);
Assert.IsNotNull(retrieved);
Assert.AreEqual(thread.Id, retrieved.Id);
Assert.IsNotNull(retrieved.Metadata);
Assert.Contains("text", retrieved.Metadata.Keys.ToList());
Assert.AreEqual("test", retrieved.Metadata["text"]);
}

[Test]
public async Task Test_03_ModifyThread()
{
Assert.IsNotNull(OpenAIClient.ThreadsEndpoint);
var thread = await OpenAIClient.ThreadsEndpoint.CreateThreadAsync(TestThread);
Assert.IsNotNull(thread);
var newMetadata = new Dictionary<string, string>
{
["text"] = "test2"
};
var modified = await OpenAIClient.ThreadsEndpoint.ModifyThreadAsync(thread, newMetadata);
Assert.IsNotNull(modified);
Assert.AreEqual(thread.Id, modified.Id);
Assert.IsNotNull(modified.Metadata);
Assert.Contains("text", modified.Metadata.Keys.ToList());
Assert.AreEqual("test2", modified.Metadata["text"]);
}

[Test]
public async Task Test_04_DeleteThread()
{
Assert.IsNotNull(OpenAIClient.ThreadsEndpoint);
var thread = await OpenAIClient.ThreadsEndpoint.CreateThreadAsync(TestThread);
Assert.IsNotNull(thread);
var isDeleted = await OpenAIClient.ThreadsEndpoint.DeleteThreadAsync(thread);
Assert.IsTrue(isDeleted);
}
}
}
Loading