Search code examples
c#asynchronousopenai-api

OpenAI_API chat returning null


I'm attempting to stream the results from a call to ChatGPT using the OpenAI_API library.

public async IAsyncEnumerable<string> Stream(string prompt) {
    var chat = api.Chat.CreateConversation(new ChatRequest() {
        Model = this.LanguageModel,
        Temperature = 0.1,
        MaxTokens = 50
    });
    chat.AppendUserInput(prompt);
    Console.WriteLine(String.Format("Querying with prompt: {0}", prompt));

    int i = 0;
    await foreach (var resp in chat.StreamResponseEnumerableFromChatbotAsync()) {
        Console.WriteLine(i++);
        Console.WriteLine(chat.MostResentAPIResult);
        yield return resp;
    }
    Console.WriteLine("Last");
    Console.WriteLine(chat.MostResentAPIResult);
}

The documentation shows this usage:

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

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

Unfortunately, when I test my implementation (without all the console logging) it returns an empty string.

public async Task IntegrationTestPromptStream() {
    IConversation conv = new OpenAIConversation(OpenAI_API.Models.Model.GPT4);
    var response = conv.Stream("Repeat back this sentence \"This is a multi word example that should chunk\"");
    var chunks = new List<string>();
    await foreach (var chunk in response) {
        chunks.Append(chunk);
    }

    Assert.That(
        String.Join(" ", chunks),
        Is.EqualTo("This is a multi word example that should chunk"),
        "Didn't receive expected response from OpenAI chat");
}

I added the console logging statements to work out what was being invoked and this is the output

Querying with prompt: Repeat back this sentence "This is a multi word example that should chunk"
0

NUnit Adapter 4.1.0.0: Test execution complete

If I attach the debugger and attempt to examine chat.MostResentAPIResult [sic], I can see an object, but notably the .ToString() method throws a null reference exception.

enter image description here

Finally, if I just keep hte index counter in but remove the statements to output the last response, I get this

Querying with prompt: Repeat back this sentence "This is a multi word example that should chunk"
0
1
2
3
4
5
6
7
8
9
Last

So It'll iterate through empty strings all day long but attempting to look at the response returns a null or a NullReferenceException.

What am I missing?


Solution

  • Example code

    using System.Collections;
    using System.Collections.Generic;
    
    
    List<string> strings = new List<string>();
    
    void OutputAdd()
    {
        Console.WriteLine("Output for Add Mehtod ...");
    
    
        for (int i = 0; i < 10; i++)
        {
            strings.Add($"Testing using Add {i}");
        }
    
        foreach (var line in strings)
        {
            Console.WriteLine(line);
        }
    }
    
    void OutputAppend()
    {
        Console.WriteLine("Output for Append Mehtod ...");
    
    
        for (int i = 0; i < 10; i++)
        {
            strings.Append($"Testing using Append {i}");
        }
    
        foreach (var line in strings)
        {
            Console.WriteLine(line);
        }
    }
    
    void OutputAppendFixed()
    {
        Console.WriteLine("Output for Append Fixed Mehtod ...");
    
    
        for (int i = 0; i < 10; i++)
        {
            strings = strings.Append($"Testing using Append with added code {i}").ToList();
        }
    
        foreach (var line in strings)
        {
            Console.WriteLine(line);
        }
    }
    
    OutputAdd();
    
    OutputAppend();
    
    OutputAppendFixed();
    

    If you run this, you'll see that OutputAppend() will only show what was added from OutputAdd(). Then when OutputAppendFixed() runs it will add using the Append method. This has to do with Append returning an IEnumerable<T>.

    The Add modifies the original data while Append returns a new array without modifying the original data.