Skip to content

Commit

Permalink
Added streaming support for completions and fine tune events.
Browse files Browse the repository at this point in the history
  • Loading branch information
johniwasz committed Jan 4, 2023
1 parent f409195 commit 27aef57
Show file tree
Hide file tree
Showing 8 changed files with 290 additions and 70 deletions.
12 changes: 4 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@

# Whetstone.ChatGPT

A simple light-weight library that wraps ChatGPT API completions. Additions to support images and other beta features are in progress.
A simple light-weight library that wraps ChatGPT API completions.

This library includes quality of life improvements:

- including support for __CancellationTokens__
- documentation comments
- conversions of Unix Epoch time to DateTime, etc.
- __IChatGPTClient__ interface for use with dependency injection
- Streaming completion responses and fine tune events

Supported features include:

Expand All @@ -21,17 +22,13 @@ Supported features include:
- Embeddings
- Moderations

Pending features:

- Handling streamed responses

## Completion

ChatGPT Completions use [models](https://beta.openai.com/docs/models) answer a wide variety of tasks, including but not limited to classification, sentiment analysis, answering questions, etc.
ChatGPT Completions use [models](https://beta.openai.com/docs/models) to answer a wide variety of tasks, including but not limited to classification, sentiment analysis, answering questions, etc.

### Completion Quickstart

This shows a direct useage of the text-davinci-003 model without any prompts.
This shows a direct useage of the __text-davinci-003__ model without any prompts.

``` C#
using Whetstone.ChatGPT;
Expand Down Expand Up @@ -186,7 +183,6 @@ ChatGPTCreateImageRequest imageRequest = new()
ResponseFormat = CreatedImageFormat.Base64
};


using (IChatGPTClient client = new ChatGPTClient("YOURAPIKEY"))
{
ChatGPTImageResponse? imageResponse = await client.CreateImageAsync(imageRequest);
Expand Down
25 changes: 25 additions & 0 deletions src/Whetstone.ChatGPT.Test/ChatClientTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,31 @@ public async Task GPTModelsListWithHttpClient()

}

[Fact]
public async Task TestGPTClientStreamCompletion()
{

using (IChatGPTClient client = ChatGPTTestUtilties.GetClient())
{

// Using Ada in this test to keep costs down.

var gptRequest = new ChatGPTCompletionRequest
{
Model = ChatGPTCompletionModels.Ada,
Prompt = "How is the weather?",
Temperature = 0.9f,
MaxTokens = 10
};

await foreach(var completion in client.StreamCompletionAsync(gptRequest))
{
if(completion is not null)
Assert.NotNull(completion.GetCompletionText());
}
}
}


[Fact]
public async Task GPTModel()
Expand Down
55 changes: 52 additions & 3 deletions src/Whetstone.ChatGPT.Test/ChatGPTFineTuneTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,57 @@ public async Task SubmitFineTuningRequestCancelAndDeleteAsync()

}
}


[Fact(Skip = "Takes to long to validate during an automatited test run. Run manually.")]
public async Task SubmitFineTuneJobAndGetEventsAsync()
{

await InitializeTest();

using (ChatGPTClient client = (ChatGPTClient) ChatGPTTestUtilties.GetClient())
{

ChatGPTCreateFineTuneRequest tuningRequest = new ChatGPTCreateFineTuneRequest
{
TrainingFileId = _fileTestFixture.ExistingFileId
};

ChatGPTFineTuneJob? tuneResponse = await client.CreateFineTuneAsync(tuningRequest);

Assert.NotNull(tuneResponse);
Assert.NotNull(tuneResponse.Status);
Assert.NotNull(tuneResponse.Id);

_testOutputHelper.WriteLine($"Status: {tuneResponse.Status}");



string jobId = tuneResponse.Id;
await foreach(ChatGPTEvent? fineTuneEvent in client.StreamFineTuneEventsAsync(tuneResponse.Id))
{
if(fineTuneEvent is not null)
_testOutputHelper.WriteLine($"Event: {fineTuneEvent.Level} - {fineTuneEvent.Message} - {fineTuneEvent.CreatedAt}");


tuneResponse = await client.RetrieveFineTuneAsync(jobId);

if (tuneResponse is not null)
_testOutputHelper.WriteLine($"Status: {tuneResponse.Status}");

_testOutputHelper.WriteLine(string.Empty);

}

ChatGPTDeleteResponse? deleteResponse = await client.DeleteModelAsync(tuneResponse.FineTunedModel);

Assert.NotNull(deleteResponse);
Assert.NotNull(deleteResponse.Object);

_testOutputHelper.WriteLine($"Deleted: {deleteResponse.Deleted}");
}
}


[Fact]
public async Task SubmitBadFineTuningRequestAsync()
Expand Down Expand Up @@ -193,13 +244,11 @@ public async Task DeleteModelAsync()
[Fact]
public async Task GPTFineTuneCompletion()
{
await InitializeTest();

using (IChatGPTClient client = ChatGPTTestUtilties.GetClient())
{
var gptRequest = new ChatGPTCompletionRequest
{
Model = _fineTuneFixture.ExistingFineTunedModel,
Model = "ada:ft-personal-2023-01-02-03-04-14",
Prompt = "How is the weather?",
Temperature = 0.9f,
MaxTokens = 10
Expand Down
17 changes: 1 addition & 16 deletions src/Whetstone.ChatGPT.Test/ImageTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,24 +48,9 @@ public async Task GenerateImageAsync()
[Fact]
public async Task GenerateImageVariation()
{
string fileName = "sailboat.png";

string filePath = $"ImageFiles/{fileName}";

if (!File.Exists(filePath))
{
throw new FileNotFoundException($"Test file {filePath} not found");
}

byte[] fileBytes = await File.ReadAllBytesAsync($"ImageFiles/{fileName}");

ChatGPTFileContent fileContents = new ChatGPTFileContent();
fileContents.FileName = fileName;
fileContents.Content = fileBytes;

ChatGPTCreateImageVariationRequest imageRequest = new()
{
Image = fileContents,
Image = await LoadFileAsync("ImageFiles/sailboat.png"),
Size = CreatedImageSize.Size1024,
ResponseFormat = CreatedImageFormat.Base64
};
Expand Down
Loading

0 comments on commit 27aef57

Please sign in to comment.