Ë
    uPêj³í  ã            
       óJ  — U d dl Z d dlZd dlZd dlZd dlmZmZmZmZ d dl	m
Z
 d dlmZ d dlmZ d dlmZ d dlmZmZmZmZ d dlmZ d dlZd d	lmZmZ d d
lmZ d dlmZmZm Z  d dl!m"Z" d dl#m$Z$ d dl%m&Z& d dl'm(Z( d dl)m*Z* d dl+m,Z, d dl-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6 d dl7m8Z8m9Z9 d dl:m;Z; d dl<m=Z=m>Z> d dl?m@Z@ d dlAmBZBmCZCmDZDmEZEmFZFmGZGmHZHmIZImJZJmKZK d dlLmMZMmNZNmOZO d dlPmQZQ ddlRmSZS ddlTmUZUmVZVmWZW dZXeeYd<   dZZeeYd <   d!ee[e\e]f      d"ee\e]f   fd#„Z^d$e\d"e\fd%„Z_e\e`z  eaz  ee\   z  ee`   z  eee`      z  ee\e]f   z  ZbeeYd&<    G d'„ d(ed)¬*«      Zc G d+„ d,ed)¬*«      Zd G d-„ d.e«      Ze G d/„ d0ed)¬*«      Zfed"e e\eJz     fd1„«       Zged"e eK   fd2„«       Zh G d3„ d4e«      Zi G d5„ d6e«      Zjd7e\d"e\fd8„Zkd9ZleeYd:<   d;ee\e]f   d"ejfd<„Zmd;ee\e]f   d"e\fd=„Znd;ee\e]f   d"e[e\d>f   fd?„Zod@e\dAe[e\d>f   dBepd"e[e\e\f   fdC„Zqd;ee\e]f   dDed"e`fdE„Zr G dF„ dGeSe=«      Zs G dH„ dI«      Zty)Jé    N)ÚIterableÚMappingÚMutableMappingÚSequence)Úsuppress)Úcache)Úchain)ÚMappingProxyType)ÚAnyÚFinalÚ	TypeAliasÚ	TypedDict)Úunquote)ÚHeadersÚResponse)ÚFileDeleted)Ú	BaseModelÚ
ConfigDictÚTypeAdapter)ÚReadOnly)Úverbose_logger)Úuuid)Ú BEDROCK_INVOKE_PROVIDERS_LITERAL)ÚFilesAPIUtils)Úget_aws_dns_suffix)	ÚBEDROCK_MANAGED_S3_BATCH_PREFIXÚBEDROCK_MANAGED_S3_PREFIXESÚ BEDROCK_MANAGED_S3_UPLOAD_PREFIXÚbuild_managed_cloud_object_nameÚencode_s3_object_key_for_urlÚsanitize_cloud_object_componentÚ"should_allow_legacy_cloud_file_idsÚ"split_configured_cloud_bucket_nameÚvalidate_managed_cloud_file_id)Úextract_file_dataÚ"text_completion_prompt_to_messages)ÚBaseLLMException)ÚBaseFilesConfigÚLiteLLMLoggingObj)ÚBedrockBatchRecordKind)
ÚAllMessageValuesÚCreateFileRequestÚFileContentRequestÚ	FileTypesÚHttpxBinaryResponseContentÚ%OpenAICreateFileRequestOptionalParamsÚOpenAIFileObjectÚPathLikeÚResponseInputParamÚ!ResponsesAPIOptionalRequestParams)ÚExtractedFileDataÚLlmProvidersÚSpecialEnums)Úget_llm_provideré   )Ú
BaseAWSLLM)ÚBedrockErrorÚ merge_bedrock_aws_request_paramsÚresolve_s3_encryption_key_idÚ_s3_signed_get_headersÚS3_SIGNED_GET_HEADERS_PARAMÚ_s3_upload_content_lengthÚUPLOAD_CONTENT_LENGTH_PARAMÚitemsÚreturnc                 ó*   — t        t        | «      «      S ©N)r
   Údict)rB   s    ún/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/llms/bedrock/files/transformation.pyÚ_frozen_mappingrH   J   s   € ÜœD ›KÓ(Ð(ó    Úmodelc                 óˆ   — 	 t        | d ¬«      \  }}}}|S # t        $ r"}t        j                  d|«       | cY d }~S d }~ww xY w)N)rJ   Úcustom_llm_providerztlitellm.llms.bedrock.files.transformation.py::_strip_llm_routing_prefix() - Error inferring custom_llm_provider - %s)r8   Ú	Exceptionr   Ú	exception)rJ   Ústripped_modelÚ_Úes       rG   Ú_strip_llm_routing_prefixrR   N   sU   € ðÜ"2¸ÐTXÔ"YÑˆ˜˜1˜að Ðøô ò Ü× Ñ ð CØô	
ð �ûðús   ‚ –	AŸ<¶A¼AÚ_EmbeddingBatchInputc                   ó‚   — e Zd ZU ee   ed<   eeee   z  ee   z  eee      z     ed<   ee   ed<   ee	ee
f      ed<   y)Ú_OpenAIBatchRecordBodyrJ   ÚpromptÚinputÚmetadataN)Ú__name__Ú
__module__Ú__qualname__r   ÚstrÚ__annotations__r   ÚintrS   r   Úobject© rI   rG   rU   rU   _   sW   … Ø�C‰=ÓØ�S˜8 C™=Ñ(¨8°C©=Ñ8¸8ÀHÈSÁMÑ;RÑRÑSÓSØÐ(Ñ)Ó)Ø�w˜s F˜{Ñ+Ñ,Ô,rI   rU   F)Útotalc                   ó>   — e Zd ZU ee   ed<   ee   ed<   ee   ed<   y)Ú_OpenAIBatchRecordÚ	custom_idÚurlÚbodyN)rY   rZ   r[   r   r\   r]   rU   r`   rI   rG   rc   rc   f   s"   … Ø˜‰}ÓØ	�#‰ÓØ
Ð)Ñ
*Ô*rI   rc   c                   ó8   — e Zd ZU ee   ed<   eeeef      ed<   y)Ú_BedrockBatchRecordÚrecordIdÚ
modelInputN)rY   rZ   r[   r   r\   r]   r   r_   r`   rI   rG   rh   rh   l   s    … Ø�s‰mÓØ˜  f Ñ-Ñ.Ô.rI   rh   c                   ó>   — e Zd ZU ee   ed<   ee   ed<   ee   ed<   y)Ú_S3UploadResponseÚKeyÚBucketÚContentLengthN)rY   rZ   r[   r   r\   r]   r^   r`   rI   rG   rl   rl   q   s    … Ø	�#‰ÓØ�S‰MÓØ˜C‘=Ô rI   rl   c                  ó.   — t        t        t        z  «      S rE   )r   r\   r3   r`   rI   rG   Ú_responses_input_adapterrq   }   s   € ä”sÔ/Ñ/Ó0Ð0rI   c                  ó    — t        t        «      S rE   )r   r4   r`   rI   rG   Ú_responses_request_adapterrs   ‚   s   € äÔ8Ó9Ð9rI   c                   ó   — e Zd ZU dZ ed¬«      ZdZedz  ed<   dZ	edz  ed<   dZ
edz  ed<   dZedz  ed<   dZedz  ed	<   dZedz  ed
<   dZedz  ed<   dZedz  ed<   dZedz  ed<   dZedz  ed<   dZedz  ed<   y)Ú_BedrockS3RequestParamszGTyped view of the credential/region params the S3 GetObject path reads.Úignore©ÚextraNÚaws_access_key_idÚaws_secret_access_keyÚaws_session_tokenÚaws_region_nameÚaws_session_nameÚaws_profile_nameÚaws_role_nameÚaws_web_identity_tokenÚaws_sts_endpointÚs3_region_nameÚs3_endpoint_url)rY   rZ   r[   Ú__doc__r   Úmodel_configry   r\   r]   rz   r{   r|   r}   r~   r   r€   r�   r‚   rƒ   r`   rI   rG   ru   ru   ‡   s°   … ÙQá HÔ-€Là$(Ð�s˜T‘zÓ(Ø(,Ð˜3 ™:Ó,Ø$(Ð�s˜T‘zÓ(Ø"&€O�S˜4‘ZÓ&Ø#'Ð�c˜D‘jÓ'Ø#'Ð�c˜D‘jÓ'Ø $€M�3˜‘:Ó$Ø)-Ð˜C $™JÓ-Ø#'Ð�c˜D‘jÓ'Ø!%€N�C˜$‘JÓ%Ø"&€O�S˜4‘ZÔ&rI   ru   c                   óL   — e Zd ZU dZ ed¬«      ZdZedz  ed<   dZ	edz  ed<   y)Ú_TrustedS3ModelCredentialszPThe S3 buckets the server trusts file ids against, from the deployment snapshot.rv   rw   NÚs3_bucket_nameÚs3_output_bucket_name)
rY   rZ   r[   r„   r   r…   rˆ   r\   r]   r‰   r`   rI   rG   r‡   r‡   ™   s,   … ÙZá HÔ-€Là!%€N�C˜$‘JÓ%Ø(,Ð˜3 ™:Ô,rI   r‡   Úfile_idc                 ót  — 	 | dt        | «       dz  z  z   }t        j                  |«      j                  «       }|j	                  t
        j                  j                  «      r*d|v r&|j                  d«      d   j                  d«      d   S | j	                  d«      r| S t        d«      ‚# t        $ r Y Œ)w xY w)	zÇ
    Resolve a Bedrock file id to its S3 URI.

    Accepts either a base64-encoded LiteLLM unified file id (whose decoded
    form carries `llm_output_file_id,s3://...`) or a direct `s3://` URI.
    ú=é   zllm_output_file_id,é   ú;r   ús3://z,file_id must be a managed LiteLLM S3 file id)ÚlenÚbase64Úurlsafe_b64decodeÚdecodeÚ
startswithr7   ÚLITELM_MANAGED_FILE_ID_PREFIXÚvalueÚsplitrM   Ú
ValueError)rŠ   ÚpaddedÚdecodeds      rG   Úextract_s3_uri_from_file_idrœ   ¢   s¶   € ðØ #¬#¨g«,¨¸Ñ):Ñ";Ñ;ˆÜ×1Ñ1°&Ó9×@Ñ@ÓBˆà×Ñœl×HÑH×NÑNÔOØ$¨Ñ/Ø—}‘}Ð%:Ó;¸AÑ>×DÑDÀSÓIÈ!ÑLÐLð ×Ñ˜'Ô"Øˆä
ÐCÓ
DÐDøô ò Ùðús   ‚B
B+ Â+	B7Â6B7zzS3 bucket_name is required. Set 's3_bucket_name' in proxy config or AWS_S3_BUCKET_NAME for Bedrock file content retrieval.Ú_S3_BUCKET_REQUIRED_ERRORÚlitellm_paramsc                 ó¨   — | j                  d«      }t        |t        «      s
t        «       S i }|j	                  |«       t        j                  |«      S )NÚ#_litellm_internal_model_credentials)ÚgetÚ
isinstancer
   r‡   ÚupdateÚmodel_validate)rž   Útrusted_model_credentialsÚsnapshots      rG   Ú_trusted_s3_model_credentialsr§   ¼   sL   € Ø'5×'9Ñ'9Ð:_Ó'`ÐÜÐ/Ô1AÔBÜ)Ó+Ð+Ø)+€HØ‡O�OÐ-Ô.Ü%×4Ñ4°XÓ>Ð>rI   c                 ó€   — t        | «      j                  xs t        j                  d«      }|st	        t
        «      ‚|S )a  
    Resolve the server-configured S3 bucket for Bedrock file operations.

    Only trusts the immutable server-side credential snapshot or the
    environment; never a request-supplied param, since the bucket is what
    `validate_managed_cloud_file_id` checks file ids against.
    ÚAWS_S3_BUCKET_NAME)r§   rˆ   ÚosÚgetenvr™   r�   )rž   Úbucket_names     rG   Úget_configured_s3_bucket_namer­   Å   s;   € ô 7°~ÓF×UÑUÒxÔY[×YbÑYbÐcwÓYx€KÙÜÔ2Ó3Ð3ØÐrI   .c                 ó  — t        | «      }|j                  xs t        j                  d«      }|j                  xs t        j                  d«      }t        t        j                  d„ ||fD «       «      «      }|st        t        «      ‚|S )ao  
    Resolve the server-configured S3 buckets a Bedrock file id may live in.

    Bedrock batch outputs land in ``s3_output_bucket_name`` when it differs from
    the input bucket, so retrieval validates against both. Same trust rules as
    ``get_configured_s3_bucket_name``: only the immutable credential snapshot or
    the environment, never a request param.
    r©   ÚAWS_S3_OUTPUT_BUCKET_NAMEc              3   ó&   K  — | ]	  }|sŒ|–— Œ y ­wrE   r`   )Ú.0Úbuckets     rG   ú	<genexpr>z1get_configured_s3_bucket_names.<locals>.<genexpr>ß   s   è ø€ Ò(f°FÒ_e¬Ñ(fùs   ‚Š)
r§   rˆ   rª   r«   r‰   ÚtuplerF   Úfromkeysr™   r�   )rž   ÚtrustedÚinput_bucketÚoutput_bucketÚbucketss        rG   Úget_configured_s3_bucket_namesrº   Ó   st   € ô 3°>ÓB€GØ!×0Ñ0ÒS´B·I±IÐ>RÓ4S€LØ"×8Ñ8Òb¼B¿I¹IÐFaÓ<b€MÜœ4Ÿ=™=Ñ(f¸|È]Ð>[Ô(fÓfÓg€GÙÜÔ2Ó3Ð3Ø€NrI   Ús3_uriÚconfigured_bucket_namesÚallow_legacy_cloud_file_idsc                 óÌ   ‡ ‡— dt         dt        t         t         f   fˆˆ fd„}|d d D ]$  }t        t        «      5   ||«      cd d d «       c S   ||d   «      S # 1 sw Y   Œ;xY w)NÚconfigured_bucket_namerC   c                 ó,   •— t        ‰d| t        ‰¬«      S )Nr�   )rŠ   Úschemer¿   Úallowed_object_prefixesr½   )r$   r   )r¿   r½   r»   s    €€rG   Úvalidate_againstzF_validate_file_id_against_configured_buckets.<locals>.validate_againstê   s   ø€ Ü-ØØØ#9Ü$?Ø(Cô
ð 	
rI   éÿÿÿÿ)r\   r´   r   r™   )r»   r¼   r½   rÃ   Úcandidate_bucket_names   ` `  rG   Ú,_validate_file_id_against_configured_bucketsrÆ   å   su   ù€ ð

´ð 
¼¼sÄC¸x¹ö 
ð "9¸¸"Ð!=ò ;ÐÜ”jÓ!ñ 	;Ù#Ð$9Ó:÷	;ó 	;ð;ñ Ð3°BÑ7Ó8Ð8÷	;ð 	;ús   ºAÁA#	Úraw_responsec                 óÂ   — | j                  t        «      }t        |t        «      r|S |j                  j                  dd«      }|j                  «       rt        |«      S dS )zµ
    S3 answers PutObject with an empty body, so the stored object size comes from the
    signed request recorded by `transform_create_file_request`, not the response headers.
    zContent-LengthÚ0r   )r¡   rA   r¢   r^   ÚheadersÚisdigit)rž   rÇ   Úuploaded_sizeÚresponse_content_lengths       rG   Ú_uploaded_object_sizerÎ   ù   s]   € ð
 *×-Ñ-Ô.IÓJ€MÜ�-¤Ô%ØÐØ%1×%9Ñ%9×%=Ñ%=Ð>NÐPSÓ%TÐØ+B×+JÑ+JÔ+LŒ3Ð&Ó'ÐSÐRSÐSrI   c                   ó  ‡ — e Zd ZdZˆ fd„Zedefd„«       Zedefd„«       Z		 	 dQde
eef   ded	ee   d
ede
eef   dedz  dedz  defd„Zdedefd„Zdee   defd„Zdededefd„Zdedz  dedz  ded
edededefd„Zdedee   fd„Zded
edededef
d„ZdZdZdZdZ e!d ede"fd!„«       Z#d"Z$d#Z%d$Z&e!dedefd%„«       Z'e!d&ed'ededz  fd(„«       Z(e!dRd)e)dz  dedefd*„«       Z*d+e+dedeeef   fd,„Z,e!d+e+de-eef   fd-„«       Z.e!d+e+de-eef   fd.„«       Z/e!d+e+d/e"de-eef   fd0„«       Z0	 dSd+e-ee1f   ded1edz  deeef   fd2„Z2d3ed4ede3ee4dz  f   fd5„Z5	 dRdee   d4edee6   fd6„Z7ded7ed
edede8ez  ez  f
d8„Z9	 dSd9eded
ed:edz  de3eef   f
d;„Z:d<ede3eef   fd=„Z;dedz  d>e<d?e=dede>f
d@„Z?dAedBe@deeAz  deBfdC„ZCdDed
edede3eef   fdE„ZDd>eEjx                  d?e=dede>fdF„ZFdDed
edede3eef   fdG„ZGd>eEjx                  d?e=dedeHfdH„ZIdedz  d
edede3eef   fdI„ZJd>eEjx                  d?e=dedee>   fdJ„ZKdKeLd
e-eef   de
eef   de3eeeef   f   fdL„ZMdedMedNeNdeeef   fdO„ZOd>eEjx                  d?e=dedePfdP„ZQˆ xZRS )TÚBedrockFilesConfigzT
    Config for Bedrock Files - handles S3 uploads for Bedrock batch processing
    c                 ó@   •— t        «       | _        t        ‰| �  «        y rE   )ÚBedrockJsonlFilesTransformationÚjsonl_transformationÚsuperÚ__init__)ÚselfÚ	__class__s    €rG   rÕ   zBedrockFilesConfig.__init__
  s   ø€ Ü$CÓ$EˆÔ!Ü‰ÑÕrI   rC   c                 ó"   — t         j                  S rE   )r6   ÚBEDROCK©rÖ   s    rG   rL   z&BedrockFilesConfig.custom_llm_provider  s   € ä×#Ñ#Ð#rI   c                  ó   — y)zO
        Bedrock files are uploaded to S3, which requires PUT requests
        ÚPUTr`   rÚ   s    rG   Úfile_upload_http_methodz*BedrockFilesConfig.file_upload_http_method  s   € ð
 rI   NrÊ   rJ   ÚmessagesÚoptional_paramsrž   Úapi_keyÚapi_basec                 óš   — i }|j                  |«       |j                  t        d «      }	t        |	t        «      r|j                  |	«       |S rE   )r£   Úpopr?   r¢   r   )
rÖ   rÊ   rJ   rÞ   rß   rž   rà   rá   ÚresultÚsigned_headerss
             rG   Úvalidate_environmentz'BedrockFilesConfig.validate_environment  sD   € ð ,.ˆØ�‰�gÔØ .× 2Ñ 2Ô3NÐPTÓ UˆÜ�n¤gÔ.Ø�M‰M˜.Ô)àˆrI   Úopenai_file_contentc                 ó–  — d}t        |t        «      r|d   }n|}t        |t        «      r|}nnt        |t        «      r|}n[t        |t        «      r/t        t        |«      d«      5 }|j                  «       }ddd«       nt        |d«      r|j                  «       }t        |t        «      r|j                  d«      }|S # 1 sw Y   Œ,xY w©a  
        Helper to extract content from various OpenAI file types and return as string.

        Handles:
        - Direct content (str, bytes, IO[bytes])
        - Tuple formats: (filename, content, [content_type], [headers])
        - PathLike objects
        rI   rŽ   ÚrbNÚreadúutf-8©	r¢   r´   r\   Úbytesr2   Úopenrë   Úhasattrr”   ©rÖ   rç   ÚcontentÚfile_contentÚfs        rG   Ú_get_content_from_openai_filez0BedrockFilesConfig._get_content_from_openai_file+  óº   € ð  #ˆäÐ)¬5Ô1à.¨qÑ1‰Là.ˆLô �l¤CÔ(à"‰GÜ˜¤eÔ,à"‰GÜ˜¤hÔ/Ü”c˜,Ó'¨Ó.ð #°!ØŸ&™&›(�÷#ð #ä�\ 6Ô*à"×'Ñ'Ó)ˆGô �gœuÔ%Ø—n‘n WÓ-ˆGàˆ÷#ð #úó   Á&B?Â?CÚopenai_jsonl_contentc                 óì   — |d   j                  di «      j                  dd«      }|j                  d«      }t        |j                  dd«      d¬«      }t        › |› dt        j                  «       › d	�}|S )
z‹
        Gets a unique S3 object name for the Bedrock batch processing job

        named as: litellm-bedrock-files/{model}/{uuid}
        r   rf   rJ   Ú úbedrock/ú:ú-©Úfallbackú.jsonl©r¡   Úremoveprefixr!   Úreplacer   r   Úuuid4©rÖ   rø   Ú_modelÚ
safe_modelÚobject_names        rG   Ú$_get_s3_object_name_from_batch_jsonlz7BedrockFilesConfig._get_s3_object_name_from_batch_jsonlP  su   € ð & aÑ(×,Ñ,¨V°RÓ8×<Ñ<¸WÀbÓIˆà×$Ñ$ ZÓ0ˆä;¸F¿N¹NÈ3ÐPSÓ<TÐ_fÔgˆ
ä ?Ð@ÀÀÈAÌdÏjÉjËlÈ^Ð[aÐbˆØÐrI   Úextracted_file_dataÚpurposec                 óz  — |j                  d«      }|€t        d«      ‚|dk(  rq| j                  |«      }|j                  «       D �cg c](  }|j	                  «       sŒt        j                  |«      ‘Œ* }}t        |«      dkD  r| j                  |«      S |j                  d«      }t        t        |d¬«      S c c}w )z5
        Get the object name for the request
        rò   úfile content is requiredÚbatchr   ÚfilenameÚfile)Úprefixr  Úfallback_filename)r¡   r™   rõ   Ú
splitlinesÚstripÚjsonÚloadsr‘   r	  r   r   )rÖ   r
  r  Úextracted_file_data_contentró   Úlinerø   r  s           rG   Úget_object_namez"BedrockFilesConfig.get_object_nameb  sÅ   € ð .A×-DÑ-DÀYÓ-OÐ#à&Ð.ÜÐ7Ó8Ð8à�gÒà"&×"DÑ"DÐE`Ó"aˆLð IU×H_ÑH_ÓHaÖ*rÀÐei×eoÑeoÕeq¬4¯:©:°dÕ+;Ð*rÐ Ð*rÜÐ'Ó(¨1Ò,Ø×@Ñ@ÐAUÓVÐVð .×1Ñ1°*Ó=ˆÜ.Ü3ØØ$ô
ð 	
ùò +ss   ÁB8ÁB8Údatac                 óh  — t        ||«      }|j                  d«      xs t        j                  d«      }|st	        d«      ‚t        |«      \  }}	|j                  d«      xs |j                  d«      }
|
xs | j                  ||«      }|j                  d«      }|j                  d«      }|€t	        d«      ‚|€t	        d«      ‚t        |«      }| j                  ||«      }|	r|	› d	|› �}t        |«      }|j                  d
«      xs d|› dt        |«      › �j                  d	«      }|› d	|› d	|› �S )zE
        Get the complete S3 URL for the file upload request
        rˆ   r©   z`S3 bucket_name is required. Set 's3_bucket_name' in litellm_params or AWS_S3_BUCKET_NAME env varr‚   r  r  úfile is requiredzpurpose is requiredú/rƒ   úhttps://s3.ú.)r<   r¡   rª   r«   r™   r#   Ú_get_aws_region_namer%   r  r    r   Úrstrip)rÖ   rá   rà   rJ   rß   rž   r  Úrequest_paramsr¬   Úobject_prefixr‚   r|   Ú	file_datar  r
  r  Úencoded_object_namerƒ   s                     rG   Úget_complete_file_urlz(BedrockFilesConfig.get_complete_file_url|  se  € ô !AÀÐQ`Ó aˆØ$×(Ñ(Ð)9Ó:Ò]¼b¿i¹iÐH\Ó>]ˆÙÜØróð ô &HÈÓ%TÑ"ˆ�]à .× 2Ñ 2Ð3CÓ DÒ mÈ×H[ÑH[Ð\lÓHmˆØ!/Ò!c°4×3LÑ3LÈ^Ð]bÓ3cˆàŸ8™8 FÓ+ˆ	ØŸ™ )Ó,ˆØÐÜÐ/Ó0Ð0Øˆ?ÜÐ2Ó3Ð3Ü%6°yÓ%AÐØ×*Ñ*Ð+>ÀÓHˆÙØ*˜O¨1¨[¨MÐ:ˆKÜ%AÀ+Ó%NÐð ×ÑÐ0Ó1ò UØ˜_Ð-¨QÔ/AÀ/Ó/RÐ.SÐTß
‰&�‹+ð 	ð
 "Ð" ! K =°Ð2EÐ1FÐGÐGrI   c                 ó   — g S rE   r`   )rÖ   rJ   s     rG   Úget_supported_openai_paramsz.BedrockFilesConfig.get_supported_openai_params§  s   € Øˆ	rI   Únon_default_paramsÚdrop_paramsc                 ó   — |S rE   r`   )rÖ   r)  rß   rJ   r*  s        rG   Úmap_openai_paramsz$BedrockFilesConfig.map_openai_paramsª  s
   € ð ÐrI   )Únovaz/v1/embeddingsz/v1/completionsz/v1/responsesÚopenai_jsonl_recordc                 ó.  — | j                  d«      xt        j                  k(  r t        j                  S xt        j
                  k(  r t        j                  S xt        j                  k(  r t        j                  S x€nxdk(  rn 	 t        j                  S  	 | j                  d«      }t        |t        «      st        j                  S d|v rt        j                  S d|v rt        j                  S d|v rt        j                  S t        j                  S )aÕ  
        Decide which OpenAI endpoint shape an OpenAI batch JSONL line carries.

        Precedence (strict - any recognized `url` short-circuits):
          1. A `url` matching a supported endpoint wins. Authoritative per the
             OpenAI Batch API spec, which requires it on every record.
          2. Any other non-empty `url` -> chat. We trust the caller's explicit
             signal rather than re-deriving it from the body, and an
             unexpectedly-shaped body fails cleanly inside the chat
             transformer instead of being silently misrouted.
          3. `url` missing/empty -> fall back to body shape. `messages` wins
             over the other keys so a malformed record carrying several of
             them keeps its conversation instead of having it dropped, and a
             bare `input` stays an embedding for backwards compatibility
             (that ambiguity with `/v1/responses` is only resolvable from
             `url`).
        re   rú   rf   rÞ   rV   rW   )r¡   rÐ   ÚOPENAI_EMBEDDINGS_URLr*   Ú	EMBEDDINGÚOPENAI_TEXT_COMPLETIONS_URLÚTEXT_COMPLETIONÚOPENAI_RESPONSES_URLÚ	RESPONSESÚCHATr¢   r   )r.  rf   s     rG   Ú_classify_batch_recordz)BedrockFilesConfig._classify_batch_recordÀ  sç   € ð& "×%Ñ% eÓ,Ø9Ô#×9Õ9Ü-×7Ñ7Ð7Ø?Ô#×?Õ?Ü-×=Ñ=Ð=Ø8Ô#×8Õ8Ü-×7Ñ7Ð7Ú��àÜ-×2Ñ2Ð2ð Øð *×-Ñ-¨fÓ5ˆÜ˜$¤Ô(Ü)×.Ñ.Ð.Ø˜ÑÜ)×.Ñ.Ð.Ø�tÑÜ)×9Ñ9Ð9Ø�d‰?Ü)×3Ñ3Ð3Ü%×*Ñ*Ð*rI   Útitan_v2ztitan-embed-text-v2Úbedrock_invocation_schemac                 óN  — t         j                  | t         j                  «      }|�|t         j                  k(  S | j	                  «       }|j                  d«      }t         j                  }|j                  |«      }|dk  ry|t        |«      z   }|t        |«      k(  xs ||   dv S )aª  
        True iff `model` refers to Amazon Titan Text Embeddings V2.

        Resolution order:
          1. `model_prices_and_context_window.json` via `get_model_info`.
             The Titan v2 registry entry carries an explicit
             `provider_specific_entry.bedrock_invocation_schema` discriminator
             (`"titan_v2"`). When the registry resolves the id we trust that
             field as the source of truth - no hardcoded model-id comparison
             needed.
          2. Substring fallback (`titan-embed-text-v2` followed by `:`, `/`,
             or end-of-string) for ids the registry can't normalize. This
             catches cross-region inference profile prefixes
             (`us.amazon.titan-embed-text-v2:0`) and Bedrock ARN forms; the
             marker boundary check rejects lookalikes like
             `titan-embed-text-v20` or `titan-embed-text-v2-experimental`.

        Tolerant of common id shapes:
          - "amazon.titan-embed-text-v2:0"
          - "bedrock/amazon.titan-embed-text-v2:0"
          - "us.amazon.titan-embed-text-v2:0" (cross-region inference profile)
          - ARN forms ending in ".../amazon.titan-embed-text-v2:0"
        rû   r   F)rü   r  )	rÐ   Ú_lookup_provider_specific_fieldÚ _BEDROCK_INVOCATION_SCHEMA_FIELDÚ_TITAN_V2_INVOCATION_SCHEMAÚlowerr  Ú_TITAN_V2_EMBED_MODEL_MARKERÚfindr‘   )rJ   Úregistry_schemaÚ
normalizedÚmarkerÚidxÚends         rG   Ú_is_titan_v2_embed_modelz+BedrockFilesConfig._is_titan_v2_embed_model   s¥   € ô: "4×!SÑ!SØÔ%×FÑFó"
ˆð Ð&Ø"Ô&8×&TÑ&TÑTÐTð —[‘[“]ˆ
Ø×,Ñ,¨ZÓ8ˆ
Ü*×GÑGˆØ—_‘_ VÓ,ˆØ�Š7ØØœ3˜v›;Ñ&ˆØ”c˜*“oÑ%ÒF¨°C©¸JÐ)FÐFrI   Úmodel_idÚfieldc                 óò   — 	 ddl m}  || «      }t        |t        «      sy|j                  d«      }t        |t        «      sy|j                  |«      }t        |t        «      r|r|S dS # t        $ r Y yw xY w)aw  
        Read a nested string field from the registry entry's
        `provider_specific_entry` dict via `litellm.get_model_info`.

        Returns the field's string value when:
          - the registry resolves `model_id`,
          - the entry exposes `provider_specific_entry` as a dict, and
          - that dict has `field` mapped to a non-empty string.
        Otherwise returns `None`.

        Isolating this means feature detectors (Titan v2 today, future
        Cohere Embed / Nova Multimodal branches) share one defensive
        try/except shape instead of duplicating it. The `None` return
        covers every realistic failure mode: `get_model_info` raises
        (cross-region profile prefixes, Bedrock ARN forms, unreleased
        models), returns a non-dict, has no `provider_specific_entry`, or
        the requested field is missing / non-string / empty.
        r   )Úget_model_infoNÚprovider_specific_entry)ÚlitellmrJ  rM   r¢   rF   r¡   r\   )rG  rH  rJ  ÚinfoÚprovider_specificr—   s         rG   r;  z2BedrockFilesConfig._lookup_provider_specific_field-  s{   € ð(	Ý.á(¨Ó2ˆDô ˜$¤Ô%ØØ#'§8¡8Ð,EÓ#FÐÜÐ+¬TÔ2ØØ(×,Ñ,¨UÓ3ˆÜ" 5¬#Ô.±5ˆuÐB¸dÐBøô ò 	Ùð	ús   ‚A* Á*	A6Á5A6Ú	raw_inputc                 ó\  — | €t        d|› �«      ‚t        | t        «      r/t        | «      dk(  r| d   }nt        dt        | «      › d|› d�«      ‚| }t        |t        t        f«      rt        d|› d�«      ‚t        |t        «      s%t        d	t        |«      j                  › d
|› d�«      ‚|S )aõ  
        Normalize an OpenAI /v1/embeddings `input` field into the single
        string that Bedrock Titan v2 InvokeModel expects in `inputText`.

        Accepts: a string, or a single-element list containing one string.
        Rejects (with actionable messages):
          - None / missing -> ValueError
          - Multi-element string lists -> ValueError, prompts caller to
            emit one JSONL line per input
          - Pre-tokenized inputs (List[int], List[List[int]]) -> NotImplementedError
          - Any other type -> ValueError

        Extracted so the validation can be exercised in isolation and so
        future embedding-provider branches (Titan G1, Cohere) can reuse it
        without duplicating the type-shaping logic.
        z@Embedding batch record is missing required `input` field: model=rŽ   r   zMBedrock batch embedding requires one input per JSONL record. Got a list with z items for model=z/; emit one JSONL line per input string instead.zpBedrock Titan v2 batch embedding does not support pre-tokenized integer inputs. Pass `input` as a string (model=z).zaBedrock batch embedding `input` must be a string (or a single-element list of strings). Got type z for model=r  )	r™   r¢   Úlistr‘   r^   ÚNotImplementedErrorr\   ÚtyperY   )rO  rJ   Ú	candidates      rG   Ú!_coerce_embedding_input_to_stringz4BedrockFilesConfig._coerce_embedding_input_to_stringO  sæ   € ð$ ÐÜÐ_Ð`eÐ_fÐgÓhÐhô �i¤Ô&Ü�9‹~ Ò"Ø% a™L‘	ä ð/ä˜9“~Ð&Ð&7¸°wð ?;ð;óð ð "ˆIô �i¤$¬ Ô-Ü%ðà˜ ð$óð ô
 ˜)¤SÔ)Üð=ä˜	“?×+Ñ+Ð,¨K¸°w¸aðAóð ð
 ÐrI   Úopenai_request_bodyc                 óZ  — ddl m} | j                  |«      st        d|›d�«      ‚| j	                  |j                  d«      |¬«      }|j                  «       D ��ci c]  \  }}|dvsŒ||“Œ }}} |«       }|j                  |i ¬«      }	t        |j                  ||	¬	«      «      S c c}}w )
aË  
        Transform an OpenAI /v1/embeddings request body into the
        Bedrock InvokeModel `modelInput` for embedding models that AWS
        supports via batch inference (CreateModelInvocationJob).

        Currently routes Amazon Titan Text Embeddings V2 only; other
        embedding providers (Titan G1, Titan Multimodal, Cohere Embed,
        Nova Multimodal Embeddings) raise NotImplementedError until they
        get a dedicated branch. Splitting them keeps PR scope tight and
        lets each model's request schema be exercised by its own tests.

        AWS docs (Titan v2 InvokeModel body):
        https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-titan-embed-text.html
        r   )ÚAmazonTitanV2Configz…Bedrock batch embedding currently supports only Amazon Titan Text Embeddings V2 (model id contains 'titan-embed-text-v2'). Got model=zL. Track other embedding models in https://github.com/BerriAI/litellm/issues.rW   )rJ   ©rJ   rW   )r)  rß   )rW   Úinference_params)
Ú9litellm.llms.bedrock.embed.amazon_titan_v2_transformationrX  rF  rR  rU  r¡   rB   r,  rF   Ú_transform_request)
rÖ   rV  rJ   rX  Ú
input_textÚkÚvr)  Útitan_configrZ  s
             rG   Ú'_map_openai_embedding_to_bedrock_paramsz:BedrockFilesConfig._map_openai_embedding_to_bedrock_params‡  sÛ   € õ&	
ð ×,Ñ,¨UÔ3ô
 &ð5à5:°Ið >QðQóð ð !×BÑBÐCV×CZÑCZÐ[bÓCcÐkpÐBÓqˆ
ð
 7J×6OÑ6OÓ6Q×$q©d¨a°ÐUVÐ^pÒUp Q¨¡TÐ$qÐÑ$qÙ1Ó3ˆØ".×"@Ñ"@Ø1Øð #Aó #
Ðô �L×3Ñ3¸*ÐWgÐ3ÓhÓiÐiùó %rs   ÁB'Á)B'c           	      óÐ   — | j                  d«      }|€t        d| j                  dd«      › �«      ‚t        t        d„ | j	                  «       D «       dt        |«      ff«      «      S )aE  
        Rewrite an OpenAI `/v1/completions` batch body as a Chat Completions body.

        Bedrock batch `modelInput` is the model's InvokeModel/Converse body, and
        no Bedrock batch model takes a bare `prompt`, so the wrapping that
        `litellm.text_completion` does in real time has to happen here too.
        rV   zKBatch record for /v1/completions is missing required `prompt` field: model=rJ   rú   c              3   ó6   K  — | ]  \  }}|d k7  sŒ||f–— Œ y­w)rV   Nr`   ©r±   Úkeyr—   s      rG   r³   zRBedrockFilesConfig._transform_text_completion_body_to_chat_body.<locals>.<genexpr>Ê  s   è ø€ Ò_¡* # uÈsÐV^Ë�#�u”Ñ_ùs   ‚�	rÞ   )r¡   r™   rH   r	   rB   r&   )rV  rV   s     rG   Ú,_transform_text_completion_body_to_chat_bodyz?BedrockFilesConfig._transform_text_completion_body_to_chat_body·  s~   € ð ,×/Ñ/°Ó9ˆØˆ>ÜðØ,×0Ñ0°¸"Ó=Ð>ð@óð ô ÜÙ_Ð0C×0IÑ0IÓ0KÔ_ØÔ@ÀÓHÐIÐKóó
ð 	
rI   c                 ó°  — ddl m} | j                  d«      }|€t        d| j                  dd«      › �«      ‚|j	                  | j                  dd«      t        «       j                  |«      t        «       j                  t        d„ | j                  «       D «       «      «      | j                  d«      ¬	«      }t        d
„ |j                  «       D «       «      S )a  
        Rewrite an OpenAI `/v1/responses` batch body as a Chat Completions body.

        Delegates to the same Responses-to-Chat bridge the real-time path uses
        for providers without a native Responses API (which is every Bedrock
        model), so `input`, `instructions`, `max_output_tokens` and the tool
        params translate identically in batch and real time. The bridge always
        emits a `tools` key; an empty one is dropped rather than shipped as an
        empty array inside `modelInput`.
        r   )Ú LiteLLMCompletionResponsesConfigrW   zHBatch record for /v1/responses is missing required `input` field: model=rJ   rú   c              3   ó4   K  — | ]  \  }}|d vsŒ||f–— Œ y­w)rY  Nr`   rd  s      rG   r³   zLBedrockFilesConfig._transform_responses_body_to_chat_body.<locals>.<genexpr>ê  s&   è ø€ ò $Ù)3¨¨eÐVYÐasÒVs˜˜eœñ$ùs   ‚�	rX   )rJ   rW   Úresponses_api_requestrX   c              3   ó:   K  — | ]  \  }}|d k7  s|sŒ||f–— Œ y­w)ÚtoolsNr`   rd  s      rG   r³   zLBedrockFilesConfig._transform_responses_body_to_chat_body.<locals>.<genexpr>ñ  s$   è ø€ Òk±
°°UÐSVÐZaÒSaÒej  Uœ|Ñkùs   ‚’	)
ÚBlitellm.responses.litellm_completion_transformation.transformationrh  r¡   r™   Ú:transform_responses_api_request_to_chat_completion_requestrq   Úvalidate_pythonrs   rH   rB   )rV  rh  Úresponses_inputÚ	chat_bodys       rG   Ú&_transform_responses_body_to_chat_bodyz9BedrockFilesConfig._transform_responses_body_to_chat_bodyÏ  sß   € õ	
ð "5×!8Ñ!8¸Ó!AˆØÐ"ÜðØ,×0Ñ0°¸"Ó=Ð>ð@óð ð
 -×gÑgØ)×-Ñ-¨g°rÓ:Ü.Ó0×@Ñ@ÀÓQÜ&@Ó&B×&RÑ&RÜ#ñ $Ø7J×7PÑ7PÓ7Rô$ó ó'ð
 -×0Ñ0°Ó<ð hó 	ð 	ô Ñk¸i¿o¹oÓ>OÔkÓkÐkrI   Úrecord_kindc                 ó  — |xt         j                  k(  r t        j                  | «      S xt         j                  k(  r t        j                  | «      S xt         j                  k(  r | S t         j                  k(  rt        d«      ‚y)z�
        Normalize a non-embedding batch body to the Chat Completions shape the
        per-provider Bedrock transformations expect.
        z@Embedding batch records do not have a chat-completion equivalentN)	r*   r3  rÐ   rf  r5  rr  r6  r1  r™   )rV  rs  s     rG   Ú"_transform_batch_body_to_chat_bodyz5BedrockFilesConfig._transform_batch_body_to_chat_bodyó  so   € ð Ø7Ô'×7Õ7Ü)×VÑVÐWjÓkÐkØ1Ô'×1Õ1Ü)×PÑPÐQdÓeÐeØ,Ô'×,Õ,Ø*Ð*Ü'×1Ô1Ü Ð!cÓdÐdð 2rI   Úproviderc                 ó´  — ddl m} |j                  dg «      }|j                  «       D ��ci c]  \  }}|dvsŒ||“Œ }}}||j                  k(  r8ddlm}	  |	«       }
|
j                  i ||d¬«      }|
j                  |||i i ¬«      S || j                  v r8dd	l
m}  |«       }|j                  |i |d¬«      }|j                  |||i i ¬«      S d|i|¥S c c}}w )
a5  
        Transform OpenAI request body to Bedrock-compatible modelInput
        parameters using existing transformation logic.

        Routes to the correct per-provider transformation so that the
        resulting dict matches the InvokeModel body that Bedrock expects
        for batch inference.
        r   )r6   rÞ   )rJ   rÞ   )ÚAmazonAnthropicClaudeConfigF)r)  rß   rJ   r*  )rJ   rÞ   rß   rž   rÊ   )ÚAmazonConverseConfig)Úlitellm.types.utilsr6   r¡   rB   Ú	ANTHROPICÚQlitellm.llms.bedrock.chat.invoke_transformations.anthropic_claude3_transformationrx  r,  Útransform_requestÚCONVERSE_INVOKE_PROVIDERSÚ1litellm.llms.bedrock.chat.converse_transformationry  )rÖ   rV  rJ   rv  r6   rÞ   r^  r_  rß   rx  ÚconfigÚmapped_paramsry  Úconverse_configs                 rG   Ú_map_openai_to_bedrock_paramsz0BedrockFilesConfig._map_openai_to_bedrock_params  s8  € õ 	5à-×1Ñ1°*¸bÓAˆØ3F×3LÑ3LÓ3N×!q©4¨1¨aÐRSÐ[pÒRp ! Q¡$Ð!qˆÑ!qð �|×-Ñ-Ò-õñ 8Ó9ˆFØ"×4Ñ4Ø#%Ø /ØØ!ð	 5ó ˆMð ×+Ñ+ØØ!Ø -Ø!Øð ,ó ð ð �t×5Ñ5Ñ5õñ &:Ó%;ˆOØ+×=Ñ=Ø#2Ø "ØØ!ð	 >ó ˆMð #×4Ñ4ØØ!Ø -Ø!Øð 5ó ð ð ˜ð
àð
ð 	
ùóa "rs
   ¬C¹CÚrecord_modelÚtarget_modelc                 óŽ   — | j                  t        |«      «      }|€|s||fS | j                  t        |«      «      }|€||fS ||fS rE   )Úget_bedrock_invoke_providerrR   )rÖ   r„  r…  Úrecord_providerÚtarget_providers        rG   Ú(_resolve_batch_record_model_and_providerz;BedrockFilesConfig._resolve_batch_record_model_and_providerL  sa   € ð
 "&×!AÑ!AÔB[Ð\hÓBiÓ!jˆØÐ&©lØ Ð0Ð0Ø!%×!AÑ!AÔB[Ð\hÓBiÓ!jˆØÐ"Ø Ð0Ð0Ø˜_Ð,Ð,rI   c                 ó   — ddl }g }t        |«      D ]ù  \  }}|j                  di «      }|j                  dd«      }|j                  j                  ||«      }	| j	                  |	|¬«      \  }
}| j                  |«      }|t        j                  u r| j                  ||
¬«      }n$| j                  | j                  ||«      |
|¬«      }|j                  d	d
t        |«      j                  d«      › �«      }||dœ}|j                  |«       Œû |S )aI  
        Transforms OpenAI JSONL content to Bedrock batch format

        Bedrock batch format: { "recordId": "alphanumeric string", "modelInput": {JSON body} }
        Example:
        {
            "recordId": "CALL0000001",
            "modelInput": {
                "anthropic_version": "bedrock-2023-05-31",
                "max_tokens": 1024,
                "messages": [
                    {
                        "role": "user",
                        "content": [{"type": "text", "text": "Hello"}]
                    }
                ]
            }
        }
        r   Nrf   rJ   rú   )r„  r…  )rV  rJ   )rV  rJ   rv  rd   ÚCALLé   )ri   rj   )rL  Ú	enumerater¡   Úmodel_alias_maprŠ  r7  r*   r1  ra  rƒ  ru  r\   ÚzfillÚappend)rÖ   rø   r…  rL  Úbedrock_jsonl_contentrD  Ú_openai_jsonl_contentÚopenai_bodyr„  Úresolved_modelÚmodel_for_transformrv  rs  Úmodel_inputÚ	record_idÚbedrock_records                   rG   Ú8_transform_openai_jsonl_content_to_bedrock_jsonl_contentzKBedrockFilesConfig._transform_openai_jsonl_content_to_bedrock_jsonl_contentY  s;  € ó. 	à')ÐÜ*3Ð4HÓ*Iò 	9Ñ&ˆCÐ&à/×3Ñ3°F¸BÓ?ˆKØ&Ÿ?™?¨7°BÓ7ˆLØ$×4Ñ4×8Ñ8¸À|ÓTˆNØ,0×,YÑ,YØ+¸,ð -Zó -Ñ)Ð ð ×5Ñ5Ð6KÓLˆKØÔ4×>Ñ>Ñ>Ø"×JÑJØ(3Ð;Nð Kó ‘ð #×@Ñ@Ø(,×(OÑ(OÐP[Ð]hÓ(iØ-Ø%ð Aó �ð .×1Ñ1°+ÀÄcÈ#ÃhÇnÁnÐUVÓFWÐEXÐ?YÓZˆIØ*3À;ÑOˆNà!×(Ñ(¨Õ8ð=	9ð> %Ð$rI   Úcreate_file_datac           	      óè  — |j                  d«      }|€t        d«      ‚t        |«      }|j                  d«      }|€t        d«      ‚t        j                  ||¬«      r§| j                  |«      }|j                  «       D �	cg c](  }	|	j                  «       sŒt        j                  |	«      ‘Œ* }
}	|j                  d«      }|xs t        |t        «      r|nd}| j                  |
|¬	«      }d
j                  d„ |D «       «      }n@t        |t        «      r|j                  d«      }nt        |t        «      r|}nt        d«      ‚| j!                  dd||||¬«      }t#        ||«      }|j                  d«      xs |j                  d«      }|ri |¥d|i¥n|}| j%                  |||t'        ||¬«      ¬«      \  }}||d<   t)        |j+                  d«      «      }||t,        <   d|||xs |dœS c c}	w )z™
        Transform file request and return a pre-signed request for S3.
        This keeps the HTTP handler clean by doing all the signing here.
        r  Nr  rò   r  )r›  r
  rJ   rú   )r…  ú
c              3   óF   K  — | ]  }t        j                  |«      –— Œ y ­wrE   ©r  Údumps©r±   Úitems     rG   r³   zCBedrockFilesConfig.transform_create_file_request.<locals>.<genexpr>µ  s   è ø€ Ò$X¸$¤T§Z¡Z°×%5Ñ$Xùó   ‚!rì   zUnsupported file content type)rá   rà   rJ   rß   rž   r  r‚   r|   )rž   rß   )rò   rá   rß   Ús3_encryption_key_idÚ
upload_urlrÜ   )Úmethodre   rÊ   r  )r¡   r™   r%   r   Úis_batch_jsonl_filerõ   r  r  r  r  r¢   r\   rš  Újoinrî   r”   r&  r<   Ú_sign_s3_requestr=   r‘   ÚencoderA   )rÖ   rJ   r›  rß   rž   r$  r
  r  Úoriginal_file_contentr  rø   Úlitellm_params_modelr…  r’  ró   rá   Úmerged_paramsr‚   r"  rå   Úsigned_bodyÚupload_content_lengths                         rG   Útransform_create_file_requestz0BedrockFilesConfig.transform_create_file_request”  s>  € ð ,×/Ñ/°Ó7ˆ	ØÐÜÐ/Ó0Ð0Ü%6°yÓ%AÐØ-@×-DÑ-DÀYÓ-OÐ#à&Ð.ÜÐ7Ó8Ð8ô ×,Ñ,Ø-Ø 3õ
ð
 ,0×+MÑ+MÐNiÓ+jÐ!ØAV×AaÑAaÓAcÖ#t¸Ðgk×gqÑgqÕgs¤D§J¡J¨tÕ$4Ð#tÐ Ð#tØ*8×*<Ñ*<¸WÓ*EÐ Ø"'Ò"rÄJÐOcÔehÔDiÑ,@ÐoqˆLØ$(×$aÑ$aØ$°<ð %bó %Ð!ð  Ÿ9™9Ñ$XÐBWÔ$XÓX‰LÜÐ3´UÔ;Ø6×=Ñ=¸gÓF‰LÜÐ3´SÔ9Ø6‰LäÐ<Ó=Ð=ð ×4Ñ4ØØØØ+Ø)Ø!ð 5ó 
ˆô  @ÀÐP_Ó`ˆØ .× 2Ñ 2Ð3CÓ DÒ mÈ×H[ÑH[Ð\lÓHmˆáDRÐ@ˆ}Ð@Ð/°Ò@ÐXeð 	ð
 '+×&;Ñ&;Ø ØØ*Ü!=Ø-Ø .ô"ð	 '<ó '
Ñ#ˆ˜ð (0ˆ�|Ñ$Ü'*¨<×+>Ñ+>¸wÓ+GÓ'HÐØ6KˆÔ2Ñ3ð ØØ%ØÒ/ <ñ	
ð 	
ùòe $us   ÂG/ÂG/rò   r¤  c                 óö  — 	 ddl }ddl}ddlm} ddlm} | j                  |d¬«      }	| j                  |j                  d«      |j                  d	«      |j                  d
«      |	|j                  d«      |j                  d«      |j                  d«      |j                  d«      |j                  d«      ¬«	      }
|j                  |j                  d«      «      j                  «       }|rt        d|dœ«      n
t        i «      }t        d|dddœ|¥«      }|j                  d|||¬«      }|j                  «       } ||j                   |j"                  |j$                  |j&                  ¬«      }| j)                  |	¬«      } ||
d|«      j+                  |«       |j$                  }t-        |t.        «      r|j1                  d«      }n|€|}t3        |j&                  «      |fS # t        $ r t        d«      ‚w xY w)z’
        Sign S3 PUT request using the same proven logic as S3Logger.
        Reuses the exact pattern from litellm/integrations/s3_v2.py
        r   N©ÚS3SigV4Auth©Ú
AWSRequestú7Missing boto3 to call bedrock. Run 'pip install boto3'.rú   ©rß   rJ   ry   rz   r{   r}   r~   r   r€   r�   ©	ry   rz   r{   r|   r}   r~   r   r€   r�   rì   zaws:kms)zx-amz-server-side-encryptionz+x-amz-server-side-encryption-aws-kms-key-idzapplication/jsonÚenz0private, immutable, max-age=31536000, s-maxage=0)zContent-Typeúx-amz-content-sha256zContent-LanguagezCache-ControlrÜ   )r  rÊ   )r¦  re   r  rÊ   )r|   Ús3)ÚhashlibÚrequestsÚbotocore.authr³  Úbotocore.awsrequestrµ  ÚImportErrorr   Úget_credentialsr¡   Úsha256rª  Ú	hexdigestr
   ÚRequestÚpreparer¦  re   rf   rÊ   Ú)get_aws_region_name_for_non_llm_api_callsÚadd_authr¢   rî   r”   rF   )rÖ   rò   rá   rß   r¤  r¼  r½  r³  rµ  r|   ÚcredentialsÚcontent_hashÚsse_headersÚrequest_headersÚreqÚpreppedÚaws_requestÚsigning_regionr®  s                      rG   r©  z#BedrockFilesConfig._sign_s3_requestè  s  € ð	YÛãÝ1Ý6ð
 "&×!:Ñ!:È?ÐbdÐ!:Ó!eˆØ!×1Ñ1Ø-×1Ñ1Ð2EÓFØ"1×"5Ñ"5Ð6MÓ"NØ-×1Ñ1Ð2EÓFØ+Ø,×0Ñ0Ð1CÓDØ,×0Ñ0Ð1CÓDØ)×-Ñ-¨oÓ>Ø#2×#6Ñ#6Ð7OÓ#PØ,×0Ñ0Ð1CÓDð 2ó 

ˆð &Ÿn™n¨W¯^©^¸GÓ-DÓE×OÑOÓQˆñ $ô à4=ØCWñôô " "Ó%ð 	ô "2à 2Ø(4Ø$(Ø!Sñ	ð
 ðó"
ˆð ×%Ñ% e¨X¸GÈ_Ð%Ó]ˆØŸ™›ˆñ (Ø—>‘>Ø—‘Ø—‘Ø—O‘Oô	
ˆð !%× NÑ NÐ_nÐ NÓ oˆá�K  ~Ó6×?Ñ?ÀÔLð "×&Ñ&ˆÜ�k¤5Ô)Ø%×,Ñ,¨WÓ5‰KØÐ Ø!ˆKä�K×'Ñ'Ó(¨+Ð5Ð5øôC ò 	YÜÐWÓXÐXð	Yús   ‚G# Ç#G8Ú	https_urlc                 ó$  — ddl }d}d}|j                  ||«      }|j                  ||«      }|r(|j                  «       \  }}}	t        |	«      }	d|› d|	› �}
n�|r(|j                  «       \  }}}	t        |	«      }	d|› d|	› �}
nsddlm}  ||«      }|j                  j                  d«      j                  dd«      }t        |«      d	k\  r|d   |d   }	}t        |	«      }	d|› d|	› �}
nt        d
|› �«      ‚d|	v r|	j                  d«      d   n|	}|
|fS )a‡  
        Convert HTTPS S3 URL to s3:// URI format.

        Args:
            https_url: HTTPS S3 URL (e.g., "https://s3.us-west-2.amazonaws.com/bucket/key")

        Returns:
            Tuple of (s3_uri, filename)

        Example:
            Input: "https://s3.us-west-2.amazonaws.com/litellm-proxy/file.jsonl"
            Output: ("s3://litellm-proxy/file.jsonl", "file.jsonl")
        r   Nz0https://s3\.([^.]+)\.amazonaws\.com/([^/]+)/(.+)z1https://([^.]+)\.s3\.([^.]+)\.amazonaws\.com/(.+)r�   r  )ÚurlparserŽ   r9   zUnable to parse S3 URL: rÄ   )ÚreÚmatchÚgroupsr   Úurllib.parserÒ  ÚpathÚlstripr˜   r‘   r™   )rÖ   rÐ  rÓ  Úpattern1Úpattern2Úmatch1Úmatch2Úregionr²   re  r»   rÒ  ÚparsedÚ
path_partsr  s                  rG   Ú_convert_https_url_to_s3_uriz/BedrockFilesConfig._convert_https_url_to_s3_uri<  s6  € ó 	ð NˆØNˆàŸ™ ¨9Ó5ˆØŸ™ ¨9Ó5ˆáà"(§-¡-£/ÑˆF�F˜CÜ˜#“,ˆCØ˜V˜H A c UÐ+‰FÙà"(§-¡-£/ÑˆF�F˜CÜ˜#“,ˆCØ˜V˜H A c UÐ+‰Fõ .á$ YÓ/ˆFØ &§¡× 2Ñ 2°3Ó 7× =Ñ =¸cÀ1Ó EˆJÜ�:‹ !Ò#Ø(¨™m¨Z¸©]˜�Ü˜c“l�Ø   ¨¨#¨Ð/‘ä Ð#;¸I¸;Ð!GÓHÐHð 14°s±
˜#Ÿ)™) C›.¨Ò,Àˆà�xÐÐrI   rÇ   Úlogging_objc                 óÈ   — |j                  d«      }d}d}|r| j                  |«      \  }}t        d||t        t	        j                  «       «      dt        ||¬«      d¬«      S )zP
        Transform S3 File upload response into OpenAI-style FileObject
        r¥  rú   r  Úuploaded)rž   rÇ   r  ©r  Úidr  Ú
created_atÚstatusrî   r_   )r¡   rà  r1   r^   ÚtimerÎ   )rÖ   rJ   rÇ   rá  rž   r¥  rŠ   r  s           rG   Útransform_create_file_responsez1BedrockFilesConfig.transform_create_file_responser  sk   € ð +×.Ñ.¨|Ó<ˆ
ØˆØˆÙà $× AÑ AÀ*Ó MÑˆG�XäØØØÜœ4Ÿ9™9›;Ó'ØÜ'°~ÐT`ÔaØô
ð 	
rI   Úerror_messageÚstatus_codec                 ó   — t        |||¬«      S )N©rë  ÚmessagerÊ   )r;   )rÖ   rê  rë  rÊ   s       rG   Úget_error_classz"BedrockFilesConfig.get_error_classŽ  s   € Ü¨¸]ÐT[Ô\Ð\rI   rŠ   c                 ó   — t        d«      ‚©Nz2BedrockFilesConfig does not support file retrieval©rR  ©rÖ   rŠ   rß   rž   s       rG   Útransform_retrieve_file_requestz2BedrockFilesConfig.transform_retrieve_file_request‘  ó   € ô "Ð"VÓWÐWrI   c                 ó   — t        d«      ‚rñ  rò  ©rÖ   rÇ   rá  rž   s       rG   Ú transform_retrieve_file_responsez3BedrockFilesConfig.transform_retrieve_file_response™  rõ  rI   c                 ó   — t        d«      ‚©Nz1BedrockFilesConfig does not support file deletionrò  ró  s       rG   Útransform_delete_file_requestz0BedrockFilesConfig.transform_delete_file_request¡  ó   € ô "Ð"UÓVÐVrI   c                 ó   — t        d«      ‚rú  rò  r÷  s       rG   Útransform_delete_file_responsez1BedrockFilesConfig.transform_delete_file_response©  rü  rI   c                 ó   — t        d«      ‚©Nz0BedrockFilesConfig does not support file listingrò  )rÖ   r  rß   rž   s       rG   Útransform_list_files_requestz/BedrockFilesConfig.transform_list_files_request±  ó   € ô "Ð"TÓUÐUrI   c                 ó   — t        d«      ‚r   rò  r÷  s       rG   Útransform_list_files_responsez0BedrockFilesConfig.transform_list_files_response¹  r  rI   Úfile_content_requestc                 ó.  — |j                  d«      }|st        d«      ‚t        |«      }t        |t	        |«      t        |«      ¬«      \  }}i }|j                  |«       |j                  |«       t        j                  |«      }	|	j                  xs |	j                  }
d|
i}| j                  |d¬«      }|	j                  xs d|› dt        |«      › �j                  d	«      }|› d	|› d	t        |«      › �}| j!                  |||	¬
«      |t"        <   |i fS )a)  
        Build a SigV4-signed S3 GetObject request for a Bedrock batch file.

        Bedrock batch file ids are `s3://bucket/key` URIs (or unified ids
        that decode to one); the bucket and key are validated against the
        server-configured bucket before any request is signed.
        rŠ   z6file_id is required for Bedrock file content retrieval)r»   r¼   r½   r|   rú   r·  r  r  r  )rá   r|   r"  )r¡   r™   rœ   rÆ   rº   r"   r£   ru   r¤   r‚   r|   r   rƒ   r   r!  r    Ú_sign_s3_get_requestr?   )rÖ   r  rß   rž   rŠ   r»   r¬   Ú
object_keyr­  r"  Úregion_preferenceÚregion_paramsr|   rƒ   re   s                  rG   Útransform_file_content_requestz1BedrockFilesConfig.transform_file_content_requestÁ  s?  € ð .×1Ñ1°)Ó<ˆÙÜÐUÓVÐVä3°GÓ<ˆÜ"NØÜ$BÀ>Ó$RÜ(JÈ>Ó(Zô#
Ñˆ�Zð 35ˆØ×Ñ˜^Ô,Ø×Ñ˜_Ô-Ü 7× FÑ FÀ}Ó Uˆà#1×#@Ñ#@Ò#bÀN×DbÑDbÐØ7HÐJ[Ð6\ˆØ!%×!:Ñ!:È=Ð`bÐ!:Ó!cˆð ×*Ñ*Òs°¸OÐ;LÈAÔN`ÐapÓNqÐMrÐ.sß
‰&�‹+ð 	ð (Ð(¨¨+¨°aÔ8TÐU_Ó8`Ð7aÐbˆà6:×6OÑ6OØØ+Ø)ð 7Pó 7
ˆÔ2Ñ3ð
 �BˆwˆrI   r|   r"  c                 óà  — 	 ddl }ddlm} ddlm} | j                  |j                  |j                  |j                  ||j                  |j                  |j                  |j                  |j                  ¬«	      }|j                  d«      j!                  «       } |d|d	|i¬
«      }	 ||d|«      }
|
j#                  |	«       t%        |	j&                  «      S # t
        $ r t        d«      ‚w xY w)zY
        SigV4-sign an S3 GetObject request, mirroring `_sign_s3_request` (PUT).
        r   Nr²  r´  r¶  r¸  rI   ÚGETrº  )r¦  re   rÊ   r»  )r¼  r¾  r³  r¿  rµ  rÀ  rÁ  ry   rz   r{   r}   r~   r   r€   r�   rÂ  rÃ  rÇ  rF   rÊ   )rÖ   rá   r|   r"  r¼  r³  rµ  rÈ  Úempty_body_hashrÎ  Úauths              rG   r  z'BedrockFilesConfig._sign_s3_get_requestò  sð   € ð	YÛå1Ý6ð "×1Ñ1Ø,×>Ñ>Ø"0×"FÑ"FØ,×>Ñ>Ø+Ø+×<Ñ<Ø+×<Ñ<Ø(×6Ñ6Ø#1×#HÑ#HØ+×<Ñ<ð 2ó 

ˆð ")§¡°Ó!4×!>Ñ!>Ó!@ˆÙ'ØØØ+¨_Ð=ô
ˆñ
 " +¨t°_ÓEˆØ�‰�kÔ"Ü�K×'Ñ'Ó(Ð(øô/ ò 	YÜÐWÓXÐXð	Yús   ‚C ÃC-c                 ó�   — |j                   dk\  r,t        |j                   |j                  |j                  ¬«      ‚t	        |¬«      S )Ni�  rí  )Úresponse)rë  r;   ÚtextrÊ   r/   r÷  s       rG   Útransform_file_content_responsez2BedrockFilesConfig.transform_file_content_response  sG   € ð ×#Ñ# sÒ*ÜØ(×4Ñ4Ø$×)Ñ)Ø$×,Ñ,ôð ô
 *°<Ô@Ð@rI   )NN)rú   rE   )SrY   rZ   r[   r„   rÕ   Úpropertyr6   rL   r\   rÝ   r   r_   rQ  r+   rF   ræ   r.   rõ   r   rc   r	  r5   r  r,   r&  r0   r(  Úboolr,  r~  r0  r2  r4  Ústaticmethodr*   r7  r=  r?  r<  rF  r;  rS   rU  rU   ra  r   rf  rr  ru  r   rƒ  r´   r   rŠ  rh   rš  rî   r°  r©  rà  r   r)   r1   ré  r^   r   r'   rï  rô  Úhttpxrø  rû  r   rþ  r  r  r-   r  ru   r  r/   r  Ú__classcell__)r×   s   @rG   rÐ   rÐ     s-  ø„ ñôð ð$ \ò $ó ð$ð ð¨ò ó ðð #Ø#ñà  V Ñ,ðð ðð Ð'Ñ(ð	ð
 ðð ' s¨F {Ñ3ðð �t‘ðð ˜‘*ðð 
óð$#Àð #Èsó #ðJà&Ð'9Ñ:ðð 
óð$
Ð3Dð 
Èsð 
ÐWZó 
ð4)Hà˜‘*ð)Hð �t‘ð)Hð ð	)Hð
 ð)Hð ð)Hð  ð)Hð 
ó)HðV°ð ¸Ð>cÑ9dó ðà ðð ðð ð	ð
 ðð 
óð !*Ðð -ÐØ"3ÐØ*Ðàð'+Ð4Fð '+ÐKaò '+ó ð'+ð\ #-Ðð $9Ð ð (CÐ$àð*G¨ð *G°ò *Gó ð*GðX ðC°#ð C¸cð CÀcÈDÁjò Có ðCðB ñ5Ð5IÈDÑ5Pð 5ÐY\ð 5Ðfiò 5ó ð5ðn.jà3ð.jð ð.jð 
ˆc�6ˆkÑ	ó	.jð` ð
Ø3ð
à	��f�Ñ	ò
ó ð
ð. ð!lÐDZð !lÐ_fÐgjÐlrÐgrÑ_sò !ló ð!lðF ðeØ3ðeà+ðeð 
��f�Ñ	òeó ðeð,  $ñ	D
à$ S¨# XÑ.ðD
ð ðD
ð ˜‘*ð	D
ð
 
ˆc�6ˆkÑ	óD
ðL-àð-ð ð-ð 
ˆsÐ4°tÑ;Ð;Ñ	<ó	-ð WYñ9%Ø$,Ð-?Ñ$@ð9%ØPSð9%à	Ð!Ñ	"ó9%ðvR
àðR
ð ,ðR
ð ð	R
ð
 ðR
ð 
�‰�tÑ	óR
ðr ,0ñR6àðR6ð ðR6ð ð	R6ð
 " D™jðR6ð 
ˆt�SˆyÑ	óR6ðh4 °cð 4 ¸eÀCÈÀH¹oó 4 ðl
à�T‰zð
ð ð
ð 'ð	
ð
 ð
ð 
ó
ð8]¨Sð ]¸sð ]ÈTÐT[É^ð ]Ð`pó ]ðXàðXð ðXð ð	Xð
 
ˆs�DˆyÑ	óXðXà—n‘nðXð 'ðXð ð	Xð
 
óXðWàðWð ðWð ð	Wð
 
ˆs�DˆyÑ	óWðWà—n‘nðWð 'ðWð ð	Wð
 
óWðVà�t‘ðVð ðVð ð	Vð
 
ˆs�DˆyÑ	óVðVà—n‘nðVð 'ðVð ð	Vð
 
ÐÑ	óVð/à0ð/ð !  f Ñ-ð/ð ' s¨F {Ñ3ð	/ð
 
ˆs�D˜˜c˜‘NÐ"Ñ	#ó/ðb%)àð%)ð ð%)ð 0ð	%)ð
 
ˆc�3ˆh‰ó%)ðNAà—n‘nðAð 'ðAð ð	Að
 
$÷ArI   rÐ   c                   ó€   — e Zd ZdZ	 ddedz  deeef   fd„Zdee	   fd„Z
dee	   defd„Zdedefd	„Zd
ededefd„Zy)rÒ   z`
    Transforms OpenAI /v1/files/* requests to Bedrock S3 file uploads for batch processing
    Nrç   rC   c                 óH  — |€t        d«      ‚| j                  |«      }|j                  «       D �cg c](  }|j                  «       sŒt	        j
                  |«      ‘Œ* }}| j                  |«      }dj                  d„ |D «       «      }| j                  |¬«      }||fS c c}w )zP
        Transforms OpenAI FileContentRequest to Bedrock S3 file format
        zcontents of file are Noner�  c              3   óF   K  — | ]  }t        j                  |«      –— Œ y ­wrE   rŸ  r¡  s     rG   r³   zhBedrockJsonlFilesTransformation.transform_openai_file_content_to_bedrock_file_content.<locals>.<genexpr><  s   è ø€ Ò/cÀT´·
±
¸4×0@Ñ/cùr£  )rø   )	r™   rõ   r  r  r  r  rš  r¨  Ú_get_s3_object_name)rÖ   rç   ró   r  rø   r’  Úbedrock_jsonl_stringr  s           rG   Ú5transform_openai_file_content_to_bedrock_file_contentzUBedrockJsonlFilesTransformation.transform_openai_file_content_to_bedrock_file_content-  sª   € ð Ð&ÜÐ8Ó9Ð9à"×@Ñ@ÐATÓUˆð EQ×D[ÑD[ÓD]Ö&n¸DÐae×akÑakÕam¤t§z¡z°$Õ'7Ð&nÐÐ&nØ $× ]Ñ ]Ð^rÓ sÐØ&*§i¡iÑ/cÐMbÔ/cÓ&cÐØ!×5Ñ5ÐK_Ð5Ó`ˆØ# [Ð0Ð0ùò	 'os   ±BÁBrø   c                 ó8   — t        «       }|j                  |«      S )zO
        Delegate to the main BedrockFilesConfig transformation method
        )rÐ   rš  )rÖ   rø   r€  s      rG   rš  zXBedrockJsonlFilesTransformation._transform_openai_jsonl_content_to_bedrock_jsonl_content@  s   € ô +Ó,ˆØ×NÑNÐOcÓdÐdrI   c                 óì   — |d   j                  di «      j                  dd«      }|j                  d«      }t        |j                  dd«      d¬«      }t        › |› dt        j                  «       › d	�}|S )
z‹
        Gets a unique S3 object name for the Bedrock batch processing job

        named as: litellm-bedrock-files-{model}-{uuid}
        r   rf   rJ   rú   rû   rü   rý   rþ   r   r  r  s        rG   r  z3BedrockJsonlFilesTransformation._get_s3_object_nameI  su   € ð & aÑ(×,Ñ,¨V°RÓ8×<Ñ<¸WÀbÓIˆà×$Ñ$ ZÓ0ˆÜ;¸F¿N¹NÈ3ÐPSÓ<TÐ_fÔgˆ
Ü ?Ð@ÀÀÈAÌdÏjÉjËlÈ^Ð[aÐbˆØÐrI   c                 ó–  — d}t        |t        «      r|d   }n|}t        |t        «      r|}nnt        |t        «      r|}n[t        |t        «      r/t        t        |«      d«      5 }|j                  «       }ddd«       nt        |d«      r|j                  «       }t        |t        «      r|j                  d«      }|S # 1 sw Y   Œ,xY wré   rí   rñ   s        rG   rõ   z=BedrockJsonlFilesTransformation._get_content_from_openai_fileY  rö   r÷   r›  Ús3_upload_responsec                 ó$  — |j                  dd«      }|j                  dd«      }d|v r|j                  d«      d   n|}t        |j                  dd«      d|› d|› �|t        t	        j                  «       «      d	|j                  d
d«      d¬«      S )zP
        Transforms S3 Bucket upload file response to OpenAI FileObject
        rm   rú   rn   r  rÄ   r  r  r�   rã  ro   r   r  rä  )r¡   r˜   r1   r^   rè  )rÖ   r›  r"  r  r¬   r  s         rG   Ú2transform_s3_bucket_response_to_openai_file_objectzRBedrockJsonlFilesTransformation.transform_s3_bucket_response_to_openai_file_object~  sœ   € ð /×2Ñ2°5¸"Ó=ˆ
Ø/×3Ñ3°H¸bÓAˆð 8;¸jÑ7H˜*×*Ñ*¨3Ó/°Ò3ÈjˆäØ$×(Ñ(¨°GÓ<Ø�{�m 1 Z LÐ1ØÜœ4Ÿ9™9›;Ó'ØØ$×(Ñ(¨¸!Ó<Øô
ð 	
rI   rE   )rY   rZ   r[   r„   r.   r´   r\   r  r   rc   rš  r  rõ   r,   rl   r1   r$  r`   rI   rG   rÒ   rÒ   (  s‘   „ ñð
 7;ñ1Ø#,¨tÑ#3ð1à	ˆs�Cˆx‰ó1ð&eØ$,Ð-?Ñ$@óeðà&Ð'9Ñ:ðð 
óð #Àð #Èsó #ðJ
Ø 1ð
ØGXð
à	ô
rI   rÒ   )ur’   r  rª   rè  Úcollections.abcr   r   r   r   Ú
contextlibr   Ú	functoolsr   Ú	itertoolsr	   Útypesr
   Útypingr   r   r   r   rÖ  r   r  r   r   Úopenai.types.file_deletedr   Úpydanticr   r   r   Útyping_extensionsr   Úlitellm._loggingr   Úlitellm._uuidr   Úlitellm.constantsr   Úlitellm.files.utilsr   Ú(litellm.litellm_core_utils.aws_partitionr   Ú1litellm.litellm_core_utils.cloud_storage_securityr   r   r   r   r    r!   r"   r#   r$   Ú8litellm.litellm_core_utils.prompt_templates.common_utilsr%   r&   Ú)litellm.llms.base_llm.chat.transformationr'   Ú*litellm.llms.base_llm.files.transformationr(   r)   Úlitellm.types.llms.bedrockr*   Úlitellm.types.llms.openair+   r,   r-   r.   r/   r0   r1   r2   r3   r4   rz  r5   r6   r7   Úlitellm.utilsr8   Úbase_aws_llmr:   Úcommon_utilsr;   r<   r=   r?   r]   rA   r´   r\   r_   rH   rR   r^   ÚfloatrS   rU   rc   rh   rl   rq   rs   ru   r‡   rœ   r�   r§   r­   rº   r  rÆ   rÎ   rÐ   rÒ   r`   rI   rG   ú<module>r=     sÕ  ðÜ Û Û 	Û ß GÓ GÝ Ý Ý Ý "ß 3Ó 3Ý  ã ß #Ý 1ß 7Ñ 7Ý &å +Ý Ý >Ý -Ý G÷
÷ 
õ 
÷õ G÷õ >÷÷ ÷ ÷ NÑ MÝ *å %ß gÑ gð &>Ð ˜UÓ =ð &AÐ ˜UÓ @ð)˜8 E¨#¨v¨+Ñ$6Ñ7ð )¸GÀCÈÀKÑ<Pó )ð	 Sð 	¨Só 	ð ˆ#�I�Ñ˜ ™Ñ%¨°©Ñ5¸ÀÈ#ÁÑ8OÑOÐRYÐZ]Ð_eÐZeÑRfÑfð �ió ô
-˜Y¨eõ -ô+˜¨%õ +ô/˜)ô /ô
!˜	¨õ !ð ð1 +¨cÐ4FÑ.FÑ"Gò 1ó ð1ð ð: KÐ0QÑ$Rò :ó ð:ô'˜iô 'ô$- ô -ðE¨ð E°ó Eð. $`Ð ˜5ó  `ð?°'¸#¸v¸+Ñ2Fð ?ÐKeó ?ð°'¸#¸v¸+Ñ2Fð È3ó ð°7¸3À¸;Ñ3Gð ÈEÐRUÐWZÐRZÉOó ð$9Øð9à" 3¨ 8™_ð9ð "&ð9ð ˆ3�ˆ8�_ó	9ð(	T¨'°#°v°+Ñ*>ð 	TÈhð 	TÐ[^ó 	Tô`A˜ _ô `A÷F!k
ò k
rI   