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

Add streaming methods for Conversation class #74

Merged
merged 3 commits into from
Apr 2, 2023

Conversation

JasonWei512
Copy link
Contributor

@JasonWei512 JasonWei512 commented Mar 10, 2023

Add streaming methods for Conversation class for convenience.

Using the new C# 8.0 async iterators:

var chat = api.Chat.CreateConversation();
chat.AppendUserInput("How to make a hamburger?");

await foreach (var res in chat.StreamResponseEnumerableFromChatbotAsync())
{
    Console.Write(res);
}

Or if using classic .NET framework or C# <8.0:

var chat = api.Chat.CreateConversationAsync();
chat.AppendUserInput("How to make a hamburger?");

await chat.StreamResponseFromChatbotAsync(res =>
{
    Console.Write(res);
});

@JasonWei512 JasonWei512 marked this pull request as ready for review March 10, 2023 12:46
Copy link

@Baklap4 Baklap4 left a comment

Choose a reason for hiding this comment

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

As i'm not the owner, but just saw this project today and wanted to contribute here's my 50cents...

/// If you are on the latest C# supporting async enumerables, you may prefer the cleaner syntax of <see cref="StreamResponseEnumerableFromChatbot"/> instead.
/// </summary>
/// <param name="resultHandler">An action to be called as each new result arrives.</param>
public async Task StreamResponseFromChatbot(Action<string> resultHandler)
Copy link

Choose a reason for hiding this comment

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

Please use suffix Async

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Conversation's async Task<string> GetResponseFromChatbot() doesn't have Async suffix. But some async methods in other classes have. So I am a little bit confused.

Copy link

Choose a reason for hiding this comment

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

The majority of the codebase uses Async suffix except for the tests, but you're right aswell. One of the questions i still had when looking through the code :)
Per Microsoft Async suffix should not be used unless you have synchronous AND asynchronous methods for the same functionality. But to not exclude synchronous or create ambiguity it's best practice to suffix it with Async to always have the option open. But yeah it should be consistent heheh. #71 will help with this i guess

Copy link
Owner

Choose a reason for hiding this comment

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

Sorry, I guess I missed one

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added "Async" suffix

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Conversation class already has a GetResponseFromChatbot() method. So I name the stream methods StreamResponseFromChatbot and StreamResponseEnumerableFromChatbot.

With Async suffix it will be like StreamResponseEnumerableFromChatbotAsync, which seems too long.

In CompletionEndpoint we have CreateCompletionAsync() and StreamCompletionAsync(). So maybe this is better?

  • GetResponseAsync()
  • StreamResponseAsync()
  • StreamResponseEnumerableAsync()

Can I modify the name of GetResponseFromChatbot() in this pull request?

OpenAI_API/Chat/Conversation.cs Outdated Show resolved Hide resolved
if (res.Choices.FirstOrDefault()?.Delta is ChatMessage delta)
{
responseRole = delta.Role;
string deltaContent = delta.Content;
Copy link

Choose a reason for hiding this comment

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

ChatMessage.Content is a string so you can use var here instead of the alias string for the variable

req.Messages = _Messages.ToList();

StringBuilder responseStringBuilder = new StringBuilder();
ChatMessageRole responseRole = null;
Copy link

Choose a reason for hiding this comment

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

C# 8 comes with NRT, please use it appropiatly: ChatMessageRole? responseRole = null;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I wanted to do so, but nullable is not enabled for this project

Copy link

Choose a reason for hiding this comment

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

Hmm without the nullable feature you can say: #nullable enable around your methods/classes.
The NRT feature mostly enables static analysis in this case.. You clearly assign null to the variable so why not explicitly state so? This way intent is shown and it's clear that this variable is indeed null at start.

@popyoung
Copy link

When will it be merged into a release version?

@OkGoDoIt
Copy link
Owner

OkGoDoIt commented Apr 2, 2023

I'm sorry about the inconsistent naming with Async, however I am leery of changing the names at this point because I don't want to break anything. Perhaps this can be saved for a major v2 along with other breaking changes.

As for nullable, I'm trying to keep this as backward-compatible as possible, working on .NET Standard and .NET framework as well. I don't think that can be done if I enable nullable? To be honest .NET has been changing so fast, I'm not really sure about this new nullable stuff.

@OkGoDoIt
Copy link
Owner

OkGoDoIt commented Apr 2, 2023

Thanks @JasonWei512, this is a much better implementation of streaming results from chat!

@OkGoDoIt OkGoDoIt merged commit e0de00a into OkGoDoIt:master Apr 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants