diff --git a/bc2/core/common/openai.py b/bc2/core/common/openai.py index 77f0226..9210e28 100644 --- a/bc2/core/common/openai.py +++ b/bc2/core/common/openai.py @@ -43,6 +43,12 @@ ) +class FilteredContentError(Exception): + """Error we throw when OpenAI content moderation is triggered.""" + + pass + + class OpenAIClientConfig(BaseModel): """OpenAI API settings.""" @@ -457,7 +463,21 @@ def invoke( ) # Interpret completion response. - content = completion.choices[0].message.content + if not completion.choices: + raise ValueError("Completion choices not found in response.") + + choice = completion.choices[0] + stop_reason = getattr(choice, "finish_reason", None) + if stop_reason == "length": + # This should be planned for / expected by the caller. + logger.debug("OpenAI response hit max tokens") + elif stop_reason == "content_filter": + raise FilteredContentError( + "OpenAI request blocked by content filter. " + "Please check the content moderation settings." + ) + + content = choice.message.content if not completion.usage: raise ValueError("Completion usage not found in response.") diff --git a/bc2/core/control/chunk.py b/bc2/core/control/chunk.py index 4d576a3..2e1e3e1 100644 --- a/bc2/core/control/chunk.py +++ b/bc2/core/control/chunk.py @@ -132,7 +132,9 @@ def __call__( output = self._get_initial_state(input.text) while remainder.text: - logger.debug(f"Chunk iteration {iteration} ...") + logger.debug( + f"Chunk iteration {iteration} with {len(remainder.text)} bytes left ..." + ) iteration += 1 # Run the processor on the current chunk