Skip to content
This repository has been archived by the owner on Mar 13, 2024. It is now read-only.

Implement Chat Completion, see Issue #57 #58

Merged
merged 4 commits into from
Apr 8, 2023
Merged

Implement Chat Completion, see Issue #57 #58

merged 4 commits into from
Apr 8, 2023

Conversation

jsissler
Copy link
Collaborator

OpenAI API Changes for Chat Completion

Changes to Existing Code

  • Runtime\Scenes\Api\Utility\EngineNames\EEngineName.cs: Added new model enumeration gpt_3_5_turbo
  • Runtime\Scenes\Api\Utility\EngineNames\UTEngineNames.cs: Added new model enumeration gpt_3_5_turbo
  • Runtime\Scripts\Api\V1\OpenAiApiV1.cs: Added ChatCompletions resource
  • Editor\Scripts\Unity\V1\EMPrefabs.cs: Added editor menu OpenAi/V1/CreateChatCompleter

Additions

  • Editor\Scripts\Examples\EMExampleChatRuntimeScene.cs
  • Runtime\Prefabs\OpenAiChatCompleterV1.prefab
  • Runtime\Scenes\ExampleChatRuntimeScene.unity
  • Runtime\Scripts\Api\V1\Models\ChatCompletionV1.cs
  • Runtime\Scripts\Api\V1\Models\UsageV1.cs
  • Runtime\Scripts\Api\V1\Models\ChatChoiceV1.cs
  • Runtime\Scripts\Api\V1\Models\ChatCompletionV1.cs
  • Runtime\Scripts\Api\V1\Models\MessageV1.cs
  • Runtime\Scripts\Api\V1\Api\Engines\ChatCompletion\ChatCompletionRequestV1.cs
  • Runtime\Scripts\Api\V1\Api\Engines\ChatCompletion\ChatCompletionResourceV1.cs
  • Runtime\Scripts\Examples\ExampleChatRuntime.cs
  • Runtime\Scripts\Unity\V1\ChatCompleter\OpenAiChatCompleterV1.cs
  • Runtime\Scripts\Unity\V1\ChatCompleter\SOChatCompletionArgsV1.cs
  • Runtime\Config\DefaultChatCompletionArgs.asset

OpenAI API Changes for Chat Completion

Changes to Existing Code
- Runtime\Scenes\Api\Utility\EngineNames\EEngineName.cs: Added new model enumeration gpt_3_5_turbo
- Runtime\Scenes\Api\Utility\EngineNames\UTEngineNames.cs: Added new model enumeration gpt_3_5_turbo
- Runtime\Scripts\Api\V1\OpenAiApiV1.cs: Added ChatCompletions resource
- Editor\Scripts\Unity\V1\EMPrefabs.cs: Added editor menu OpenAi/V1/CreateChatCompleter

Additions

- Editor\Scripts\Examples\EMExampleChatRuntimeScene.cs
- Runtime\Prefabs\OpenAiChatCompleterV1.prefab
- Runtime\Scenes\ExampleChatRuntimeScene.unity
- Runtime\Scripts\Api\V1\Models\ChatCompletionV1.cs
- Runtime\Scripts\Api\V1\Models\UsageV1.cs
- Runtime\Scripts\Api\V1\Models\ChatChoiceV1.cs
- Runtime\Scripts\Api\V1\Models\ChatCompletionV1.cs
- Runtime\Scripts\Api\V1\Models\MessageV1.cs
- Runtime\Scripts\Api\V1\Api\Engines\ChatCompletion\ChatCompletionRequestV1.cs
- Runtime\Scripts\Api\V1\Api\Engines\ChatCompletion\ChatCompletionResourceV1.cs
- Runtime\Scripts\Examples\ExampleChatRuntime.cs
- Runtime\Scripts\Unity\V1\ChatCompleter\OpenAiChatCompleterV1.cs
- Runtime\Scripts\Unity\V1\ChatCompleter\SOChatCompletionArgsV1.cs
- Runtime\Config\DefaultChatCompletionArgs.asset
Copy link
Owner

@hexthedev hexthedev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wanted to say a big thanks for this PR. It's a great contribution to the project.

In order to get it passed the post:

  • Address the comments on the code. There is a slight inconsitency with other resources. The main functionality looks sound though.
  • Update the README.md to tell people about your new endpoint. I think people will be interested in trying this.
  • I would like to see a Unit Test added to /Tests/Runtime/Scripts/Core/V1/V1PlayTests.cs that verifys that the endpoint is working.

What I did not do in the PR:

  • I did not test it. I am out of OpenAI tokens and need to talk to them to get more. So you will need to test it to verify that it works resonably well.

public class ChatCompletionsResourceV1 : AApiResource<OpenAiApiV1>
{
/// <inheritdoc/>
public override string Endpoint => "/chat/completions";
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently in the library, when someone wants to use a REST Api call associated with <engine_id>/completions, they call EnginesResource.Engine(<engine_id>).Completions, which follows engines/<engine_id>/completions.

This ChatCompletionResource should be split into a ChatResource and a ChatCompletionsResources with the chat resource containing something along the lines of

 public class ChatResourceV1 : AApiResource<OpenAiApiV1>
 {
    public ChatCompletionsV1 Completions => new ChatCompletionsV1(this);
 }

This will maintain the call pattern. engines/<engine_id>/chat/completions as EnginesResource.Engine(<engine_id>).Chat.Completions, instead of EnginesResource.Engine(<engine_id>).ChatCompletions

This is necessary becuase in the future chat might end up having more API endpoints following it.

@@ -54,6 +59,7 @@ public OpenAiApiV1(SAuthArgsV1 authArgs)
Engines = new EnginesResourceV1(this);
Files = new FilesResourceV1(this);
Classifications = new ClassificationsResourceV1(this);
ChatCompletions = new ChatCompletionsResourceV1(this);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the ChatCompletions resource is accessed via the EnginesResource (Specifically in the EngineResource), it should not appear in this class. It should appear as a child of the EngineResource

I just took a look at the API quickly, and I see some major concepts have changed. Engines is depreceated.

However, I think that in this PR, the code should remain as consistent as possible with the existing Resources, so that when I or someone else does a refactor based on the new API concepts, everything can be moved in the same way.

So, to finalize this comment.

  • Remove the ChatCompletions property from this class. Accessing this resource should be done through OpenAiApiV1.Engines.Engine("engine_id").Chat.Completions

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I originally tried to treat chat completions as an engine consistent with prompt completions but chat completions cannot be accessed via the endpoint engines/<engine_id>/chat/completions. I think chat must be accessed via an endpoint that does not include the engine; the model is passed as part of the JSON payload, example below. So that's the rationale for adding the chat resource to the root of the API rather than as an engine. Let me know your thoughts when you have a chance. I'll look into your other PR change requests.

curl https://api.openai.com/v1/chat/completions
-H "Content-Type: application/json"
-H "Authorization: Bearer $OPENAI_API_KEY"
-d '{
"model": "gpt-3.5-turbo",
"messages": [{"role": "user", "content": "Hello!"}]
}'

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, if that is the case (which I can see from reading the API specs), then we still need two objects instead of one. Since the endpoint is chat/completions to stay consistent we want the access to work as OpenAiApiV1.Chat.Completions rather than OpenAiApiV1.ChatCompletions. That way if there are more chat/ endpoints in the future they will be easy to add.

I know there is already a CompletionsResourceV1 object so naming the new one ChatCompletionsResourceV1 will work. But in the ChatResourceV1 the property name should still be Completions. I.E.:

public class ChatResourceV1 : AApiResource<OpenAiApiV1>
{
   ...
   public ChatCompletionsResourceV1 Completions { get; private set;} // not ChatCompletionsResourceV1 ChatCompletions
   ...
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, will make this change. Thank you for taking the time to work with me on this James.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactored OpenAiApiV1.ChatCompletions into OpenAiApiV1.Chat.Completions. Getting there...

Tests were based on tests covering existing prompt completion. Also fixed an issue with empty JSON objects and added unit tests.  The last record of a chat stream has a finish reason and an empty delta object.
@jsissler
Copy link
Collaborator Author

jsissler commented Apr 2, 2023

Added chat completion unit tests. Also needed to fix an issue with empty JSON objects (delta: {}). Have a look, might be a better way to fix this.

Still need to address documentation, TODO.

Comment on lines +39 to +45
// Handle empty object, i.e.: object: {}
if (syntax[index] == "}")
{
parent.NestedValues = new List<JsonObject>();
return index + 1;
}

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, this is a decent solution.

@hexthedev
Copy link
Owner

Added chat completion unit tests. Also needed to fix an issue with empty JSON objects (delta: {}). Have a look, might be a better way to fix this.

Still need to address documentation, TODO.

Hey just took a look. Tests look good!

Also created distinct enumeration type EChatModelNames and removed gtp-3.5-turbo out of EEngineNames. Did not include gpt-4 models as these are still in beta.
Copy link
Owner

@hexthedev hexthedev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can tell tell this looks good to me. Glad to have it added to the library.

To clarify, what I did do:

  • Read code to look for consistency with rest of the library.

What I didn't do:

  • Run the code on my side
  • Run the tests on my side
  • Check the objects against the actual API

If everything looks good your end and tests are passing I will merge the PR. Just give me the go ahead when you're ready.

Added some documentation for chat/completions and separated DeltaV1 from MessageV1 as role is not optional for messages but is for message deltas. Also need to see message role in Unity Inspector.
@jsissler
Copy link
Collaborator Author

jsissler commented Apr 7, 2023

Committed another small change which included adding a few lines of documentation to the README.md and separating JSON objects DeltaV1 and MessageV1.

I'm good for you to merge. Here's an unlisted video that demonstrates the example chat scene and unit tests.

https://youtu.be/Dr2sSH3mNEo

@hexthedev hexthedev merged commit 05875dd into hexthedev:main Apr 8, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants