Stream API Function Calling Unexpected Behavior

I’ve been working on integrating function calling on the openai.beta.chat.completions.stream() API. I’m using the openai-node event helpers for displaying tokens to the user as they come in.

My function currently looks like this:

const stream = openai.beta.chat.completions
.stream({
  model: 'gpt-4-1106-preview',
  messages: messages as any,
  stream: true,
  tools: [metaphorSearchTool, readMetaphorResultTool]
})
.on('connect', onStartCallback)
.on('chunk', chunk => {
  onTokenCallback(chunk.choices[0]?.delta?.content || '')
})
.on('functionCall', functionCall => {
  const args = functionCall.arguments
  const query = JSON.parse(args).query
  onTokenCallback(`Searching the web for ${query}...`)
})
.on('functionCallResult', content => {
  onTokenCallback(content)
})
.on('error', error => {
  onTokenCallback(error.toString())
})
.on('finalChatCompletion', completion => {
  onFinalCallback(completion.choices[0]?.message.content || '')
});

for await (const _ of stream) { /* no-op */ }

And here is my search tool function that I’m trying to run:

export const metaphorSearchTool = {
  type: 'function',
  function: {
    name: 'metaphorSearch',
    description:
      'Perform a web search and returns the top 20 search results based on the search query.',
    parameters: {
      type: 'object',
      properties: {
        query: {
          type: 'string',
          description: 'The query to search for.'
        }
      },
      required: ['query']
    }
  }
}

The issue I’m facing is when I run a function, the on('functionCall') event executes successfully, but immediately after, the on('finalChatCompletion') triggers with tool_calls as the finish reason.

I need the on('finalChatCompletion') event to trigger only when the entire conversation is over, not immediately after a tool is called.

Thanks in advance for any help you can provide!