DEV Community

Cover image for My Latest Contribution to ChatCraft
Amir Helali
Amir Helali

Posted on

My Latest Contribution to ChatCraft

Latest Changes

So, to pick up where I left off from my previous post, I was able to stick to my plan of using the Strategy Pattern within the functional component paradigm structure instead of class component paradigm. Here are the changes I made to the code base to reflect my plan:

  • I created an interface function which defines the structure for my response handling functions:
interface ResponseHandlerStrategy {
  (response: any): Promise<any>;
}
Enter fullscreen mode Exit fullscreen mode
  • I created a responseHandler which is in charge of selecting the right response handler function based on the boolean streaming flag:
  const responseHandler: ResponseHandlerStrategy = streaming
    ? handleStreamingResponse
    : handleNonStreamingResponse;
Enter fullscreen mode Exit fullscreen mode
  • I created 2 different implementations for handling the responses. One is for handling an streaming response and the other is for handling a non-streaming response:
  const handleStreamingResponse: ResponseHandlerStrategy = async (
    streamResponse: Stream<ChatCompletionChunk>
  ) => {
    for await (const streamChunk of streamResponse) {
      const parsedData = parseOpenAIChunkResponse(streamChunk);
      await streamOpenAIResponse(
        parsedData.token,
        parsedData.functionName,
        parsedData.functionArgs
      );
    }

    const content = buffer.join("");
    return handleOpenAIResponse(content, functionName, functionArgs);
  };
Enter fullscreen mode Exit fullscreen mode
  const handleNonStreamingResponse: ResponseHandlerStrategy = async (response: ChatCompletion) => {
    const { content, functionName, functionArgs } = parseOpenAIResponse(response);
    return handleOpenAIResponse(content, functionName, functionArgs);
  };
Enter fullscreen mode Exit fullscreen mode
  • Implemented the above functions in the main chatWithLLM function and modified the code base to support these functions within a single code path:
[...]
 const responsePromise = openai.chat.completions
    .create(
      chatCompletionParams as OpenAI.Chat.ChatCompletionCreateParamsStreaming,
      chatCompletionReqOptions
    )
    .then(async (response) => {
      return responseHandler(response);
    })
    .catch((err) => {
      return handleError(err);
    })
    .finally(() => {
      removeEventListener("keydown", handleCancel);
    });

  return {
    promise: responsePromise,
    cancel,
    pause,
    resume,
    togglePause,
  };
Enter fullscreen mode Exit fullscreen mode
  • Ran the application to make sure that these new functions were working correctly and didn't break the overall functionality of the program.

  • Formatted the code with Prettier via VSCode, committed my changes, and created a PR.

What I Leveraged

  • I used the OpenAI API chat documentation to familiarize myself with and understand different chat objects, types of responses, and the different return types.
  • I researched the strategy pattern and its application in Typescript from different sources online.
  • I used the comments and the feedbacks provided in a previous PR for the project that were related to the issue I worked on. I used these to understand what was needed for me to do and the overall logic and the structure of the code base.

Conclusion

At first I was a bit intimidated to contribute to a larger project. However, I am happy that I jumped into it with a plan which guided me throughout my contribution. I am happy that my original plan worked out, even though I had to change my approach to fit the functional structure of the code-base. I am glad that I got to work on a project which used OpenAI API so I could learn more about it. Also, I am happy that I got to use a design pattern that I had learned theoretically but never had the chance to apply it in Typescript. I am still waiting for my PR to be reviewed, and based on the feedback, if there are any changes needed, I will make sure to address them with appropriate adjustments.

Top comments (0)