57
57
)
58
58
from openai .types .chat .chat_completion_content_part_image_param import ImageURL
59
59
from openai .types .chat .chat_completion_content_part_input_audio_param import InputAudio
60
+ from openai .types .chat .chat_completion_content_part_param import File , FileFile
60
61
from openai .types .responses import ComputerToolParam , FileSearchToolParam , WebSearchToolParam
61
62
from openai .types .responses .response_input_param import FunctionCallOutput , Message
62
63
from openai .types .shared import ReasoningEffort
@@ -426,6 +427,16 @@ async def _map_user_prompt(part: UserPromptPart) -> chat.ChatCompletionUserMessa
426
427
assert item .format in ('wav' , 'mp3' )
427
428
audio = InputAudio (data = base64_encoded , format = item .format )
428
429
content .append (ChatCompletionContentPartInputAudioParam (input_audio = audio , type = 'input_audio' ))
430
+ elif item .is_document :
431
+ content .append (
432
+ File (
433
+ file = FileFile (
434
+ file_data = f'data:{ item .media_type } ;base64,{ base64_encoded } ' ,
435
+ filename = f'filename.{ item .format } ' ,
436
+ ),
437
+ type = 'file' ,
438
+ )
439
+ )
429
440
else : # pragma: no cover
430
441
raise RuntimeError (f'Unsupported binary content type: { item .media_type } ' )
431
442
elif isinstance (item , AudioUrl ): # pragma: no cover
@@ -435,25 +446,18 @@ async def _map_user_prompt(part: UserPromptPart) -> chat.ChatCompletionUserMessa
435
446
base64_encoded = base64 .b64encode (response .content ).decode ('utf-8' )
436
447
audio = InputAudio (data = base64_encoded , format = response .headers .get ('content-type' ))
437
448
content .append (ChatCompletionContentPartInputAudioParam (input_audio = audio , type = 'input_audio' ))
438
- elif isinstance (item , DocumentUrl ): # pragma: no cover
439
- raise NotImplementedError ('DocumentUrl is not supported for OpenAI' )
440
- # The following implementation should have worked, but it seems we have the following error:
441
- # pydantic_ai.exceptions.ModelHTTPError: status_code: 400, model_name: gpt-4o, body:
442
- # {
443
- # 'message': "Unknown parameter: 'messages[1].content[1].file.data'.",
444
- # 'type': 'invalid_request_error',
445
- # 'param': 'messages[1].content[1].file.data',
446
- # 'code': 'unknown_parameter'
447
- # }
448
- #
449
- # client = cached_async_http_client()
450
- # response = await client.get(item.url)
451
- # response.raise_for_status()
452
- # base64_encoded = base64.b64encode(response.content).decode('utf-8')
453
- # media_type = response.headers.get('content-type').split(';')[0]
454
- # file_data = f'data:{media_type};base64,{base64_encoded}'
455
- # file = File(file={'file_data': file_data, 'file_name': item.url, 'file_id': item.url}, type='file')
456
- # content.append(file)
449
+ elif isinstance (item , DocumentUrl ):
450
+ client = cached_async_http_client ()
451
+ response = await client .get (item .url )
452
+ response .raise_for_status ()
453
+ base64_encoded = base64 .b64encode (response .content ).decode ('utf-8' )
454
+ media_type = response .headers .get ('content-type' ).split (';' )[0 ]
455
+ file_data = f'data:{ media_type } ;base64,{ base64_encoded } '
456
+ file = File (
457
+ file = FileFile (file_data = file_data , filename = f'filename.{ item .format } ' ),
458
+ type = 'file' ,
459
+ )
460
+ content .append (file )
457
461
elif isinstance (item , VideoUrl ): # pragma: no cover
458
462
raise NotImplementedError ('VideoUrl is not supported for OpenAI' )
459
463
else :
@@ -769,10 +773,11 @@ async def _map_user_prompt(part: UserPromptPart) -> responses.EasyInputMessagePa
769
773
response = await client .get (item .url )
770
774
response .raise_for_status ()
771
775
base64_encoded = base64 .b64encode (response .content ).decode ('utf-8' )
776
+ media_type = response .headers .get ('content-type' ).split (';' )[0 ]
772
777
content .append (
773
778
responses .ResponseInputFileParam (
774
779
type = 'input_file' ,
775
- file_data = f'data:{ item . media_type } ;base64,{ base64_encoded } ' ,
780
+ file_data = f'data:{ media_type } ;base64,{ base64_encoded } ' ,
776
781
filename = f'filename.{ item .format } ' ,
777
782
)
778
783
)
0 commit comments