Streaming on top of requires_action functionality

I had everything working before, but after trying to implement streaming only normal responses work, as soon as a function (get_events) is called and parameters are trying to be parsed, it sort of half streams the parameters then the JSON stringify gets confused why the json is half completed upon trying to send parameters to the endpoint.

app.post("/chat", async (req, res) => {
  const { thread_id, message } = req.body;

  if (!thread_id || !message) {
    return res.status(400).send("Missing thread_id or message");
  }

  try {
    const now = new Date();
    const dateTimeString = `${now.toISOString()}`;
    const updatedMessage = `The current date and time is ${dateTimeString}.`;

    console.log(
      `Received message: ${updatedMessage} for thread ID: ${thread_id}`,
    );

    const assistantMessageResponse = await openai.beta.threads.messages.create(
      thread_id,
      {
        role: "user",
        content: message,
      },
    );

    console.log("Assistant message response:", assistantMessageResponse);

    // Set the response headers for SSE (Server-Sent Events)
    res.writeHead(200, {
      "Content-Type": "text/event-stream",
      "Cache-Control": "no-cache",
      Connection: "keep-alive",
    });

    let toolCallArguments = "";

    const run = await openai.beta.threads.runs.createAndStream(thread_id, {
      assistant_id: assistantId,
      instructions: `${defaultInstructions}\n\n${updatedMessage}`,
    });

    run.on("textCreated", (text) => {
      console.log("Text created:", text);
    });

    run.on("textDelta", (textDelta, snapshot) => {
      console.log("Text delta:", textDelta);
      res.write(textDelta.value);
    });

    run.on("toolCallCreated", (toolCall) => {
      console.log(`Tool call created: ${toolCall.type}`);
    });

    run.on("toolCallDelta", async (toolCallDelta, snapshot) => {
      console.log("Tool call delta:", toolCallDelta);
      if (toolCallDelta.type === "function") {
        toolCallArguments += toolCallDelta.function.arguments;
        console.log("Tool call arguments (accumulated):", toolCallArguments);

        try {
          const argumentsObj = JSON.parse(toolCallArguments);
          console.log("Parsed arguments object:", argumentsObj);

          const {
            cityName,
            areaSlug,
            ageName,
            musicGenreName,
            startDate,
            whatsOnTag,
          } = argumentsObj;

          let queryString = new URLSearchParams({
            cityName,
            ...(areaSlug && { areaSlug }),
            ...(ageName && { ageName }),
            ...(musicGenreName && { musicGenreName }),
            startDate,
            ...(whatsOnTag && { whatsOnTag }),
          }).toString();

          console.log("Query string:", queryString);

          try {
            console.log("Fetching events data");
            const eventsResponse = await fetch(
              `http://localhost:${port}/events?${queryString}`,
            );
            const eventsData = await eventsResponse.json();
            console.log("Events data:", eventsData);

            // Send the events data back to the ChatGPT bot
            await openai.beta.threads.runs.submitToolOutputs(
              thread_id,
              run.id,
              {
                tool_outputs: [
                  {
                    tool_call_id: toolCallDelta.id,
                    output: JSON.stringify(eventsData),
                  },
                ],
              },
            );

            // Reset the toolCallArguments for the next tool call
            toolCallArguments = "";
          } catch (error) {
            console.error("Error while fetching events:", error);
            const errorMessage = {
              message: `Error fetching events: ${error.message}`,
            };

            // Send the error message back to the ChatGPT bot
            await openai.beta.threads.runs.submitToolOutputs(
              thread_id,
              run.id,
              {
                tool_outputs: [
                  {
                    tool_call_id: toolCallDelta.id,
                    output: JSON.stringify(errorMessage),
                  },
                ],
              },
            );

            // Reset the toolCallArguments for the next tool call
            toolCallArguments = "";
          }
        } catch (error) {
          console.error("Error parsing tool call arguments:", error);
          // Ignore the error and wait for more data
        }
      }
    });

    await new Promise((resolve) => {
      run.on("done", async () => {
        console.log("Run completed");
        res.write(`data: [DONE]\n\n`);
        res.end();
        resolve();
      });
    });
  } catch (error) {
    console.error("Error during chat operation:", error);
    res.status(500).send("Error processing chat message");
  }
});

For added context, error looks like this

Tool call created: function
Tool call delta: { index: 0, type: 'function', function: { arguments: '{"' } }
Tool call arguments (accumulated): {"
Error parsing tool call arguments: SyntaxError: Unterminated string in JSON at position 2