From 8bffd618059aacc30d6190a0d143d8b0c7217faf Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Sun, 15 Sep 2024 20:28:44 +0200 Subject: [PATCH] OpenAI: Ignore chunks with an empty `choices` list (#192951) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary OpenAI added usage stats to their APIs recently: https://community.openai.com/t/usage-stats-now-available-when-using-streaming-with-the-chat-completions-api-or-completions-api/738156 However, it's somewhat non BWC: > Note that this usage-specific chunk will have choices: [], so if you turn this feature on, you may need to update any code that accesses (Héhéhé) Leveraging this feature is for another day. This PR is just about avoiding the whole thing to explode. --- .../actions/server/lib/get_token_count_from_openai_stream.ts | 4 +++- .../server/chat_complete/adapters/openai/openai_adapter.ts | 2 +- .../server/service/client/adapters/process_openai_stream.ts | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/actions/server/lib/get_token_count_from_openai_stream.ts b/x-pack/plugins/actions/server/lib/get_token_count_from_openai_stream.ts index 0aa5fca22d0ff..790a59fe6097a 100644 --- a/x-pack/plugins/actions/server/lib/get_token_count_from_openai_stream.ts +++ b/x-pack/plugins/actions/server/lib/get_token_count_from_openai_stream.ts @@ -90,7 +90,9 @@ export async function getTokenCountFromOpenAIStream({ delta: { content?: string; function_call?: { name?: string; arguments: string } }; }>; } => { - return 'object' in line && line.object === 'chat.completion.chunk'; + return ( + 'object' in line && line.object === 'chat.completion.chunk' && line.choices.length > 0 + ); } ) .reduce( diff --git a/x-pack/plugins/inference/server/chat_complete/adapters/openai/openai_adapter.ts b/x-pack/plugins/inference/server/chat_complete/adapters/openai/openai_adapter.ts index 3a89f100f2879..62af864a6037d 100644 --- a/x-pack/plugins/inference/server/chat_complete/adapters/openai/openai_adapter.ts +++ b/x-pack/plugins/inference/server/chat_complete/adapters/openai/openai_adapter.ts @@ -74,7 +74,7 @@ export const openAIAdapter: InferenceConnectorAdapter = { }), filter( (line): line is OpenAI.ChatCompletionChunk => - 'object' in line && line.object === 'chat.completion.chunk' + 'object' in line && line.object === 'chat.completion.chunk' && line.choices.length > 0 ), map((chunk): ChatCompletionChunkEvent => { const delta = chunk.choices[0].delta; diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/adapters/process_openai_stream.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/adapters/process_openai_stream.ts index 59dbd24451c09..e9dbd259182ba 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/adapters/process_openai_stream.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/adapters/process_openai_stream.ts @@ -98,7 +98,7 @@ export function processOpenAiStream({ }), filter( (line): line is CreateChatCompletionResponseChunk => - 'object' in line && line.object === 'chat.completion.chunk' + 'object' in line && line.object === 'chat.completion.chunk' && line.choices.length > 0 ), map((chunk): ChatCompletionChunkEvent => { const delta = chunk.choices[0].delta;