6363
6464# Maximum file size for media content in tool results (20MB)
6565_MAX_MEDIA_SIZE_BYTES = 20 * 1024 * 1024
66+ _MAX_MEDIA_SIZE_LABEL = "20MB"
67+ _DEFAULT_MIME_TYPE = "application/octet-stream"
68+ _CONTEXT_WINDOW_OVERFLOW_MSG = "OpenAI Responses API threw context window overflow error"
69+ _RATE_LIMIT_MSG = "OpenAI Responses API threw rate limit error"
6670
6771
6872def _encode_media_to_data_url (data : bytes , format_ext : str , media_type : str = "image" ) -> str :
@@ -77,13 +81,14 @@ def _encode_media_to_data_url(data: bytes, format_ext: str, media_type: str = "i
7781 Base64-encoded data URL string.
7882
7983 Raises:
80- ValueError: If the media size exceeds the maximum allowed size (20MB) .
84+ ValueError: If the media size exceeds the maximum allowed size.
8185 """
8286 if len (data ) > _MAX_MEDIA_SIZE_BYTES :
8387 raise ValueError (
84- f"{ media_type .capitalize ()} size { len (data )} bytes exceeds maximum of { _MAX_MEDIA_SIZE_BYTES } bytes (20MB)"
88+ f"{ media_type .capitalize ()} size { len (data )} bytes exceeds maximum of"
89+ f" { _MAX_MEDIA_SIZE_BYTES } bytes ({ _MAX_MEDIA_SIZE_LABEL } )"
8590 )
86- mime_type = mimetypes .types_map .get (f".{ format_ext } " , "application/octet-stream" )
91+ mime_type = mimetypes .types_map .get (f".{ format_ext } " , _DEFAULT_MIME_TYPE )
8792 encoded_data = base64 .b64encode (data ).decode ("utf-8" )
8893 return f"data:{ mime_type } ;base64,{ encoded_data } "
8994
@@ -193,17 +198,17 @@ async def stream(
193198 ContextWindowOverflowException: If the input exceeds the model's context window.
194199 ModelThrottledException: If the request is throttled by OpenAI (rate limits).
195200 """
196- logger .debug ("formatting request for OpenAI Responses API" )
201+ logger .debug ("Step 1: formatting request for OpenAI Responses API" )
197202 request = self ._format_request (messages , tool_specs , system_prompt , tool_choice )
198- logger .debug ("formatted request=<%s>" , request )
203+ logger .debug ("Step 1: formatted request=<%s>" , request )
199204
200- logger .debug ("invoking OpenAI Responses API model" )
205+ logger .debug ("Step 2: invoking OpenAI Responses API model" )
201206
202207 async with openai .AsyncOpenAI (** self .client_args ) as client :
203208 try :
204209 response = await client .responses .create (** request )
205210
206- logger .debug ("got response from OpenAI Responses API model" )
211+ logger .debug ("Step 3: streaming response from OpenAI Responses API model" )
207212
208213 yield self ._format_chunk ({"chunk_type" : "message_start" })
209214
@@ -291,11 +296,11 @@ async def stream(
291296 break
292297 except openai .BadRequestError as e :
293298 if hasattr (e , "code" ) and e .code == "context_length_exceeded" :
294- logger .warning ("OpenAI Responses API threw context window overflow error" )
299+ logger .warning (_CONTEXT_WINDOW_OVERFLOW_MSG )
295300 raise ContextWindowOverflowException (str (e )) from e
296301 raise
297302 except openai .RateLimitError as e :
298- logger .warning ("OpenAI Responses API threw rate limit error" )
303+ logger .warning (_RATE_LIMIT_MSG )
299304 raise ModelThrottledException (str (e )) from e
300305
301306 # Close current content block if we had any
@@ -330,7 +335,7 @@ async def stream(
330335 if final_usage :
331336 yield self ._format_chunk ({"chunk_type" : "metadata" , "data" : final_usage })
332337
333- logger .debug ("finished streaming response from OpenAI Responses API model" )
338+ logger .debug ("Step 4: finished streaming response from OpenAI Responses API model" )
334339
335340 @override
336341 async def structured_output (
@@ -360,11 +365,11 @@ async def structured_output(
360365 )
361366 except openai .BadRequestError as e :
362367 if hasattr (e , "code" ) and e .code == "context_length_exceeded" :
363- logger .warning ("OpenAI Responses API threw context window overflow error" )
368+ logger .warning (_CONTEXT_WINDOW_OVERFLOW_MSG )
364369 raise ContextWindowOverflowException (str (e )) from e
365370 raise
366371 except openai .RateLimitError as e :
367- logger .warning ("OpenAI Responses API threw rate limit error" )
372+ logger .warning (_RATE_LIMIT_MSG )
368373 raise ModelThrottledException (str (e )) from e
369374
370375 if response .output_parsed :
@@ -511,15 +516,13 @@ def _format_request_message_content(cls, content: ContentBlock) -> dict[str, Any
511516 ValueError: If the image or document size exceeds the maximum allowed size (20MB).
512517 """
513518 if "document" in content :
514- data_url = _encode_media_to_data_url (
515- content ["document" ]["source" ]["bytes" ], content ["document" ]["format" ], "document"
516- )
519+ doc = content ["document" ]
520+ data_url = _encode_media_to_data_url (doc ["source" ]["bytes" ], doc ["format" ], "document" )
517521 return {"type" : "input_file" , "file_url" : data_url }
518522
519523 if "image" in content :
520- data_url = _encode_media_to_data_url (
521- content ["image" ]["source" ]["bytes" ], content ["image" ]["format" ], "image"
522- )
524+ img = content ["image" ]
525+ data_url = _encode_media_to_data_url (img ["source" ]["bytes" ], img ["format" ], "image" )
523526 return {"type" : "input_image" , "image_url" : data_url }
524527
525528 if "text" in content :
@@ -572,15 +575,13 @@ def _format_request_tool_message(cls, tool_result: ToolResult) -> dict[str, Any]
572575 output_parts .append ({"type" : "input_text" , "text" : content ["text" ]})
573576 elif "image" in content :
574577 has_media = True
575- data_url = _encode_media_to_data_url (
576- content ["image" ]["source" ]["bytes" ], content ["image" ]["format" ], "image"
577- )
578+ img = content ["image" ]
579+ data_url = _encode_media_to_data_url (img ["source" ]["bytes" ], img ["format" ], "image" )
578580 output_parts .append ({"type" : "input_image" , "image_url" : data_url })
579581 elif "document" in content :
580582 has_media = True
581- data_url = _encode_media_to_data_url (
582- content ["document" ]["source" ]["bytes" ], content ["document" ]["format" ], "document"
583- )
583+ doc = content ["document" ]
584+ data_url = _encode_media_to_data_url (doc ["source" ]["bytes" ], doc ["format" ], "document" )
584585 output_parts .append ({"type" : "input_file" , "file_url" : data_url })
585586
586587 # Return array if has media content, otherwise join as string for simpler text-only cases
0 commit comments