From 92e3d5b8ffb896551ea2aab51a0ec6e6f1ea0664 Mon Sep 17 00:00:00 2001 From: nacim-coder Date: Wed, 20 May 2026 11:20:32 +0000 Subject: [PATCH 1/2] fix: skip empty streaming choices in prompt generation --- backend/utils/llm_utils.py | 4 ++++ test/backend/utils/test_llm_utils.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/backend/utils/llm_utils.py b/backend/utils/llm_utils.py index e99b9f384..8d7941f06 100644 --- a/backend/utils/llm_utils.py +++ b/backend/utils/llm_utils.py @@ -100,6 +100,10 @@ def call_llm_for_system_prompt( reasoning_content_seen = False content_tokens_seen = 0 for chunk in current_request: + if not getattr(chunk, "choices", None): + logger.debug("Skipping streaming chunk without choices during prompt generation") + continue + delta = chunk.choices[0].delta reasoning_content = getattr(delta, "reasoning_content", None) new_token = delta.content diff --git a/test/backend/utils/test_llm_utils.py b/test/backend/utils/test_llm_utils.py index 2052bba54..0feeffeae 100644 --- a/test/backend/utils/test_llm_utils.py +++ b/test/backend/utils/test_llm_utils.py @@ -173,6 +173,34 @@ def test_call_llm_for_system_prompt_exception(self, mocker: MockFixture): # Verify AppException is raised with correct error code for unmapped errors assert exc_info.value.error_code == ErrorCode.MODEL_PROMPT_GENERATION_FAILED + def test_call_llm_for_system_prompt_skips_empty_choices_chunks(self, mocker: MockFixture): + mock_get_model_by_id = mocker.patch('backend.utils.llm_utils.get_model_by_model_id') + mock_get_model_name = mocker.patch('backend.utils.llm_utils.get_model_name_from_config') + mock_openai = mocker.patch('backend.utils.llm_utils.OpenAIModel') + + mock_get_model_by_id.return_value = {"base_url": "http://x", "api_key": "k"} + mock_get_model_name.return_value = "deepseek-ai/DeepSeek-V4-Flash" + + empty_choices_chunk = MagicMock() + empty_choices_chunk.choices = [] + + content_chunk = MagicMock() + content_chunk.choices = [MagicMock()] + content_chunk.choices[0].delta.content = "Generated prompt" + + mock_instance = mock_openai.return_value + mock_instance.client = MagicMock() + mock_instance.client.chat.completions.create.return_value = [ + empty_choices_chunk, + content_chunk, + ] + mock_instance._prepare_completion_kwargs.return_value = {} + + res = call_llm_for_system_prompt(1, "u", "s") + + assert res == "Generated prompt" + + class TestProcessThinkingTokens: def test_process_thinking_tokens_normal_token(self): From d8107d772dc210d2d16d3e6f7bdb6d2b31959c83 Mon Sep 17 00:00:00 2001 From: nacim-coder Date: Wed, 20 May 2026 16:28:55 +0000 Subject: [PATCH 2/2] test: use https URL in prompt generation test --- test/backend/utils/test_llm_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/backend/utils/test_llm_utils.py b/test/backend/utils/test_llm_utils.py index 0feeffeae..89b89b66d 100644 --- a/test/backend/utils/test_llm_utils.py +++ b/test/backend/utils/test_llm_utils.py @@ -178,7 +178,7 @@ def test_call_llm_for_system_prompt_skips_empty_choices_chunks(self, mocker: Moc mock_get_model_name = mocker.patch('backend.utils.llm_utils.get_model_name_from_config') mock_openai = mocker.patch('backend.utils.llm_utils.OpenAIModel') - mock_get_model_by_id.return_value = {"base_url": "http://x", "api_key": "k"} + mock_get_model_by_id.return_value = {"base_url": "https://example.com", "api_key": "k"} mock_get_model_name.return_value = "deepseek-ai/DeepSeek-V4-Flash" empty_choices_chunk = MagicMock()