
    i                     "   d dl Z d dlZd dlZd dlZd dlmZ d dlmZmZm	Z	m
Z
mZmZmZmZmZmZ d dl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 d dlmZ d d	lmZm Z  erd d
l!m"Z" d dl#m$Z$ neZ$eZ" G d de      Z% G d de&      Z' G d d      Z(y)    N)datetime)
TYPE_CHECKINGAnyDictListLiteralOptionalTupleUnioncastget_args)	BaseModel)verbose_logger)	DualCache)#BEDROCK_EMBEDDING_PROVIDERS_LITERAL BEDROCK_INVOKE_PROVIDERS_LITERALBEDROCK_MAX_POLICY_SIZE)tracer)
get_secretget_secret_str)AWSPreparedRequestCredentialsc                   2    e Zd ZU eed<   eed<   ee   ed<   y)Boto3CredentialsInfocredentialsaws_region_nameaws_bedrock_runtime_endpointN)__name__
__module____qualname__r   __annotations__strr	        r/Users/manta/Documents/Projects/TheRoad-I1/.venv/lib/python3.12/site-packages/litellm/llms/bedrock/base_aws_llm.pyr   r   (   s    "*3-/r%   r   c                        e Zd Z fdZ xZS )AwsAuthErrorc                     || _         || _        t        j                  dd      | _        t        j
                  || j                        | _        t        | !  | j                         y )NPOSTz0https://us-west-2.console.aws.amazon.com/bedrock)methodurl)status_coderequest)	r-   messagehttpxRequestr.   Responseresponsesuper__init__)selfr-   r/   	__class__s      r&   r5   zAwsAuthError.__init__/   sT    &}}Q
 ;ULL	
r%   )r   r    r!   r5   __classcell__r7   s   @r&   r(   r(   .   s    	
 	
r%   r(   c                   <    e Zd ZdG fdZdHdeeeef      fdZde	eee   f   defdZ
 ej                         	 	 	 	 	 	 	 	 	 	 	 dIdee   dee   d	ee   d
ee   dee   dee   dee   dee   dee   dee   deeeef      fd       Zdee   dee   fdZededee   fd       Zededee   fd       Zededee   dedefd       Zedededefd       Zededefd       Zededee   fd       Z	 	 dJdedee   dee   defdZ	 dHd
ee   fd Zed!edeeeeef      fd"       Z	 dHdedeeeef      defd#Z ej                         	 	 dJdededed
ee   dee   dee   deeeef      deeee   f   fd$       Z 	 	 	 dKd%ededed&ed'edee   dee   deeeef      defd(Z!	 	 	 dKdeded&edee   dee   deeeef      defd)Z"d*edeeee   f   fd+Z# ej                         	 	 	 	 dLdee   dee   d	ee   deded
ee   dee   dee   deeeef      deeee   f   fd,       Z$ ej                         dedeeee   f   fd-       Z% ej                         deded	edeeee   f   fd.       Z& ej                         deded
ee   deeee   f   fd/       Z' ej                         deeee   f   fd0       Z( ej                         defd1       Z)	 dMd2ee   d3ee   d
ed4ee*d5      deeef   f
d6Z+d4ee*d5      d
edefd7Z,	 dHdedee   de-fd8Z. ej                         	 dHd9ed
ed:ee   d;ed<eee/f   d=ed>ee   de0fd?       Z1d=edefd@Z2	 	 	 	 dLdAe*dB   d=ededCed2edee   dDee   dEee   d>ee   deeee/   f   fdFZ3 xZ4S )N
BaseAWSLLMreturnc                 R    t               | _        t        |           g d| _        y )N)aws_access_key_idaws_secret_access_keyaws_session_tokenr   aws_session_nameaws_profile_nameaws_role_nameaws_web_identity_tokenaws_sts_endpointr   aws_external_id)r   	iam_cacher4   r5   aws_authentication_params)r6   r7   s    r&   r5   zBaseAWSLLM.__init__<   s!    "*
&r%   
ssl_verifyc                      ddl m}  ||      S )av  
        Get SSL verification setting for boto3 clients.

        This ensures that custom CA certificates are properly used for all AWS API calls,
        including STS and Bedrock services.

        Returns:
            Union[bool, str]: SSL verification setting - False to disable, True to enable,
                            or a string path to a CA bundle file
        r   )get_ssl_verifyrI   )&litellm.llms.custom_httpx.http_handlerrK   )r6   rI   rK   s      r&   _get_ssl_verifyzBaseAWSLLM._get_ssl_verifyM   s     	J44r%   credential_argsc                     t        j                  |d      }t        j                  |j	                               j                         S )zP
        Generate a unique cache key based on the credential arguments.
        T)	sort_keys)jsondumpshashlibsha256encode	hexdigest)r6   rO   credential_strs      r&   get_cache_keyzBaseAWSLLM.get_cache_key\   s5    
 OtD~~n3356@@BBr%   r>   r?   r@   r   rA   rB   rC   rD   rE   rF   c                 <   |||||||||	|
g
}t        |      D ]  \  }}|r6|j                  d      r%t        |      }|'t        |t              s8|||<   >|A| j
                  |   }|j                         t        j                  v sqt        j                  |j                               ||<    |\
  }}}}}}}}}	}
t        j                  d|||||||||	|
       t               j                         D ci c]  \  }}|j                  d      s|dk(  r||  }}}| j                  |      }| j                  j!                  |      }|r|S | ||| j#                  |||||	|
      \  }}n|| j%                  ||      r*t        j                  d|       | j'                         \  }}nt        j                  d       |.d	t)        t+        j,                         j/                                }| j1                  |||||||	|
|
	      \  }}nf|| j3                  |      \  }}nO|||| j5                  |||      \  }}n1|||| j7                  |||      \  }}n| j'                         \  }}| j                  j9                  |||       |S c c}}w )z3
        Return a boto3.Credentials object
        zos.environ/zin get credentials
aws_access_key_id=%s
aws_secret_access_key=%s
aws_session_token=%s
aws_region_name=%s
aws_session_name=%s
aws_profile_name=%s
aws_role_name=%s
aws_web_identity_token=%s
aws_sts_endpoint=%s
aws_external_id=%saws_rI   )rD   rC   rA   r   rE   rF   rL   z<Already running as target role %s, using ambient credentialsz2Using role assumption: calling _auth_with_aws_rolezlitellm-session-)	r>   r?   r@   rC   rA   r   rE   rF   rI   r>   r?   r@   )r>   r?   r   )ttl)	enumerate
startswithr   
isinstancer#   rH   upperosenvirongetenvr   debuglocalsitemsrY   rG   	get_cache_auth_with_web_identity_token_is_already_running_as_role_auth_with_env_varsintr   now	timestamp_auth_with_aws_role_auth_with_aws_profile_auth_with_aws_session_token$_auth_with_access_key_and_secret_key	set_cache)r6   r>   r?   r@   r   rA   rB   rC   rD   rE   rF   rI   params_to_checkiparam_vkeykvargs	cache_key_cached_credentialsr   
_cache_ttls                           r&   get_credentialszBaseAWSLLM.get_credentialsd   sE   ( !"0
 "/2HAu))-8&>jS&9)+OA&44Q799;"**,)+399;)?OA& 3, 	
!" 	
! !"+	
6 (
(1||F#qL'8 qD( 	 
 &&t,	"nn66yA&& #.) ,&*&H&H'=+!1 /!1 / 'I '#K & //*/U$$R! +/*B*B*D'Z$$H $+*3x||~/G/G/I+J*KL % +/*B*B&7*?&7"/%5$3%5$3) +C 
+'Z )&*&A&ABR&S#K)%1!-&*&G&G"3&;"3 'H '#K )%1+&*&O&O"3&; / 'P '#K '+&>&>&@#K  KZ Ho
s   8#Jmodelc                     	 t        |t              rd|vry |j                  d      }t        |      dk  ry |d   }|sy |S # t        $ r Y y w xY w)Nzarn:aws:bedrock:      )r`   r#   splitlen	Exception)r6   r   partsregions       r&   _get_aws_region_from_model_arnz)BaseAWSLLM._get_aws_region_from_model_arn  sb    	eS)->e-K KK$E5zA~ 1XFM 		s    A A A A 	AA
model_pathc                     | j                  d      }t        |      dk\  r&|d   }|t        t              v rt	        t        |      S y)at  
        Helper function to get the provider from a model path with format: provider/model-name

        Args:
            model_path (str): The model path (e.g., 'llama/arn:aws:bedrock:us-east-1:086734376398:imported-model/r4c4kewx2s0n' or 'anthropic/model-name')

        Returns:
            Optional[str]: The provider name, or None if no valid provider found
        /   r   N)r   r   r   r   r   )r   r   providers      r&   _get_provider_from_model_pathz(BaseAWSLLM._get_provider_from_model_path$  sG       %u:?QxH8$DEE<hGGr%   c                    | j                  d      r| j                  ddd      } d| j                         v r!dt        t              v rt        t        d      S | j                  d      d   }|t        t              v rt        t        |      S t        j                  |       }||S t        t              D ]
  }|| v s|c S  y)a  
        Helper function to get the bedrock provider from the model

        handles 3 scenarions:
        1. model=invoke/anthropic.claude-3-5-sonnet-20240620-v1:0 -> Returns `anthropic`
        2. model=anthropic.claude-3-5-sonnet-20240620-v1:0 -> Returns `anthropic`
        3. model=llama/arn:aws:bedrock:us-east-1:086734376398:imported-model/r4c4kewx2s0n -> Returns `llama`
        4. model=us.amazon.nova-pro-v1:0 -> Returns `nova`
        invoke/ r   nova.r   N)	r_   replacelowerr   r   r   r   r;   r   )r   _split_modelr   s      r&   get_bedrock_invoke_providerz&BaseAWSLLM.get_bedrock_invoke_provider8  s     I&MM)R3E U[[]""BCC<fEE{{3'*8$DEE8,GG ;;EBO !ABH5  C r%   optional_paramsr   c                    | j                  dd       }|t        j                  |      }n|}|j                  ddd      }|dk(  rd|v rt        j	                  |d      }|S |d	k(  rd
|v rt        j	                  |d	      }|S |dk(  rd|v rt        j	                  |d      }|S |dk(  rd|v rt        j	                  |d      }|S |dk(  rd|v rt        j	                  |d      }|S |dk(  rd|v rt        j	                  |d      }|S |dk(  rd|v rt        j	                  |d      }|S d|v rt        j	                  |d      }|S d|v rt        j	                  |d      }|S )Nmodel_idr   r   r   r   llamazllama/)specdeepseek_r1zdeepseek_r1/openaizopenai/qwen2zqwen2/qwen3zqwen3/	stabilityz
stability/moonshotz	moonshot/znova-2/znova-2znova/r   )popr;   encode_model_idr   "_get_model_id_from_model_with_spec)r   r   r   r   s       r&   get_bedrock_model_idzBaseAWSLLM.get_bedrock_model_id\  s    #&&z48!1181DHH##Ir15w8x#7!DDw E HF A &>X+E!DD} E H> 9 !i8&;!DDx E H6 1  X%9!DDw E H. )  X%9!DDw E H& ! $)A!DD{ E H  #x(?!DDz E H  ("!DDx E H 	  !DDv E H r%   r   c                 X    | j                  |dz   d      }t        j                  |      S )zp
        Remove `llama` from modelID since `llama` is simply a spec to follow for custom bedrock models
        r   r   r   )r   r;   r   )r   r   r   s      r&   r   z-BaseAWSLLM._get_model_id_from_model_with_spec  s,     ==R0))8)<<r%   r   c                 D    t         j                  j                  | d      S )z
        Double encode the model ID to ensure it matches the expected double-encoded format.
        Args:
            model_id (str): The model ID to encode.
        Returns:
            str: The double-encoded model ID.
        r   )safe)urllibparsequoter   s    r&   r   zBaseAWSLLM.encode_model_id  s     ||!!(!44r%   c                    d| j                         v r!dt        t              v rt        t        d      S d| v rk| j	                  d      }t        |      dk\  r&|d   }|t        t              v rt        t        |      S |d   }|t        t              v rt        t        |      S t        t              D ]  }|| v st        t        |      c S  y)a  
        Helper function to get the bedrock embedding provider from the model

        Handles scenarios like:
        1. model=cohere.embed-english-v3:0 -> Returns `cohere`
        2. model=amazon.titan-embed-text-v1 -> Returns `amazon`
        3. model=amazon.nova-2-multimodal-embeddings-v1:0 -> Returns `nova`
        4. model=us.twelvelabs.marengo-embed-2-7-v1:0 -> Returns `twelvelabs`
        5. model=twelvelabs.marengo-embed-2-7-v1:0 -> Returns `twelvelabs`
        r   r      r   r   N)r   r   r   r   r   r   )r   r   potential_providerr   s       r&   get_bedrock_embedding_providerz)BaseAWSLLM.get_bedrock_embedding_provider  s      U[[]""EFF?HH %<KK$E5zQ%*&" &2U)VV CEWXX "'" "X.Q%RR?ASTT !!DEH5 ?JJ F r%   c                    |j                  dd      }|i|| j                  |      }n| j                  |      }t        dd      }||t        |t              r|}t        dd      }||t        |t              r|}|J	 ddl}t        j                  d      5  |j                         }ddd       j                  }	|	r|	}|S d}	 |S |S # 1 sw Y   "xY w# t        $ r d}Y |S w xY w)ar  
        Get the AWS region name from the environment variables.

        Parameters:
            optional_params (dict): Optional parameters for the model call
            model (str): The model name
            model_id (str): The model ID. This is the ARN of the model, if passed in as a separate param.

        Returns:
            str: The AWS region name
        r   NAWS_REGION_NAME
AWS_REGIONr   boto3.Session()	us-west-2)getr   r   r`   r#   boto3r   traceSessionregion_namer   )
r6   r   r   r   r   litellm_aws_region_namestandard_aws_region_namer   sessionconfigured_regions
             r&   _get_aws_region_namezBaseAWSLLM._get_aws_region_name  s   " *--.?F"#"&"E"Eh"O"&"E"Ee"L&01BD&I#  '+76<"9'1,'E$',87=":".\\"34#mmoG 5$+$7$7!$&7O 	 '2O  54  ."-.s0   C C+C C CC C'&C'c                     |Dt        dd      }|t        |t              r|}t        dd      }|t        |t              r|}|d}|S )a  
        Get the AWS region name for non-llm api calls.

        LLM API calls check the model arn and end up using that as the region name.

        For non-llm api calls eg. Guardrails, Vector Stores we just need to check the dynamic param or env vars.
        Nr   r   r   )r   r`   r#   )r6   r   r   r   s       r&   )get_aws_region_name_for_non_llm_api_callsz4BaseAWSLLM.get_aws_region_name_for_non_llm_api_calls  sh     "&01BD&I#&2z'8 #:'1,'E$'3
(#9 #;&"-r%   arnc                 T   | j                  d      }t        |      dk  s|d   dk7  ry|d   }|d   }dj                  |dd       }|j                  d	      r|j                  d
      d   }n8|j                  d      r&|j                  d
      }t        |      dk\  r|d   }nyy|||fS )a?  
        Parse an ARN and return (partition, account_id, role_name).

        Handles:
        - arn:aws:iam::123456789012:role/MyRole
        - arn:aws:iam::123456789012:role/path/to/MyRole
        - arn:aws:sts::123456789012:assumed-role/MyRole/session-name

        Returns None if the ARN cannot be parsed.
        r      r   r   Nr   r      zrole/r   zassumed-role/r   )r   r   joinr_   )r   r   	partition
account_idresource	role_name
role_partss          r&    _parse_arn_account_and_role_namez+BaseAWSLLM._parse_arn_account_and_role_name*  s     		#u:>U1X.!H	1X
88E!"I&w' s+B/I  1!,J:!#&qM	*i//r%   c                 l   | j                  |      }|y|\  }}}t        j                  d      }t        j                  d      }|r|r||k(  S 	 ddl}	t	        j
                  d      5  |	j                  d| j                  |            }
|
j                         }|j                  d	d
      }ddd       | j                        }|,|\  }}}||k(  r!||k(  r||k(  rt        j                  d|       yy# 1 sw Y   IxY w# t        $ r)}t        j                  dt        |             Y d}~yd}~ww xY w)ay  
        Check if the current environment is already running as the target IAM role.

        This handles multiple AWS environments:
        - IRSA (EKS): AWS_ROLE_ARN + AWS_WEB_IDENTITY_TOKEN_FILE are set
        - ECS task roles: Uses sts:GetCallerIdentity to check current role ARN
        - EC2 instance profiles: Uses sts:GetCallerIdentity to check current role ARN

        Compares partition, account ID, and role name to avoid cross-account
        false matches.

        Returns True if the current identity matches the target role, meaning
        we can skip sts:AssumeRole and use ambient credentials directly.
        NFAWS_ROLE_ARNAWS_WEB_IDENTITY_TOKEN_FILEr   z%boto3.client(sts).get_caller_identitysts)verifyArnr   z0Current identity already matches target role: %sTz-Could not determine current role identity: %s)r   rb   rd   r   r   r   clientrN   get_caller_identityr   r   re   r   r#   )r6   rC   rI   target_parsedtarget_partitiontarget_accounttarget_rolecurrent_role_arnweb_identity_token_filer   
sts_clientidentity
caller_arncaller_parsedcaller_partitioncaller_accountcaller_rolees                     r&   rj   z&BaseAWSLLM._is_already_running_as_roleP  sR   & ==mL 8E5.+ 99^4"$)),I"J 7#}44	EF"\\$"6"6z"B * 
 &99;%\\%4
 G !AA*MM(@M= .+$(88&.8#{2"((J%   5 GF*  	  ?Q  	s2   D (AC5-AD 5C>:D 	D3
D..D3c           	         ddl }t        j                  d| d| d|        |d| d}	n|}	t        |      }
|
t	        dd	
      t        j                  d      5  |j                  d||	| j                  |            }ddd       |||
ddd}|||d<    j                  di |}|d   d   |d   d   |d   d   |d}|d   t        kD  rt        j                  d|d           t        j                  d      5   |j                  di |}ddd       j                         }|| j                         fS # 1 sw Y   xY w# 1 sw Y   7xY w)z:
        Authenticate with AWS Web Identity Token
        r   NzIN Web Identity Token: z | Role Name: z | Session Name: zhttps://sts..amazonaws.comz6OIDC token could not be retrieved from secret manager.i  )r/   r-   boto3.client(sts)r   )r   endpoint_urlr   i  a  {"Version":"2012-10-17","Statement":[{"Sid":"BedrockLiteLLM","Effect":"Allow","Action":["bedrock:InvokeModel","bedrock:InvokeModelWithResponseStream"],"Resource":"*","Condition":{"Bool":{"aws:SecureTransport":"true"},"StringLike":{"aws:UserAgent":"litellm/*"}}}]})RoleArnRoleSessionNameWebIdentityTokenDurationSecondsPolicy
ExternalIdr   AccessKeyIdSecretAccessKeySessionToken)r>   r?   r@   r   PackedPolicySizezKThe policy size is greater than 75% of the allowed size, PackedPolicySize: zboto3.Session(**iam_creds_dict)r$   )r   r   re   r   r(   r   r   r   rN   assume_role_with_web_identityr   warningr   r   &_get_default_ttl_for_boto3_credentials)r6   rD   rC   rA   r   rE   rF   rI   r   sts_endpoint
oidc_tokenr   assume_role_paramssts_responseiam_creds_dictr   	iam_credss                    r&   ri   z(BaseAWSLLM._auth_with_web_identity_token  s    	%&<%=^M?Zkl|k}~	
 #)/):.IL+L 67
P 
 \\-.+)++J7	 & J / %/ *# `
 &/>|,?z??UBTU ".m!<]!K%1-%@AR%S!-m!<^!L*	
 *+.EE""]^jk}^~]  A \\;<#emm5n5G = ++-	$EEGGGQ /.H =<s   %D= E	=E	Eirsa_role_arnr   r   c	                    ddl }	t        j                  d       t        |d      5 }
|
j	                         j                         }ddd       || j                  |      d}|||d<   t        j                  d      5   |	j                  di |}ddd       t        j                  d| d	|        j                  ||
      }|d   }t        j                  d      5   |	j                  	 d|d   |d   |d   d|}ddd       	 j                         }t        j                  d|j                  dd              t        j                  d| d|        ||d}|||d<    j                  di |S # 1 sw Y   9xY w# 1 sw Y   xY w# 1 sw Y   xY w# t        $ r"}t        j                  d|        Y d}~d}~ww xY w)z.Handle cross-account role assumption for IRSA.r   Nz&Cross-account role assumption detectedrr   r   r   z!boto3.client(sts) for manual IRSAzManually assuming IRSA role z with session )r   r   r   r   z.boto3.client(sts) with manual IRSA credentialsr   r   r   r\   z/Current identity after manual IRSA assumption: r   unknownFailed to get caller identity: z"Attempting to assume target role:  with session: r   r   r   r   r$   )r   r   re   openreadstriprN   r   r   r   r   r   r   r   assume_role)r6   r   rC   rA   r   r   rF   rE   rI   r   fweb_identity_tokenirsa_sts_kwargsr   irsa_response
irsa_credssts_client_with_credscaller_identityr   r   s                       r&   _handle_irsa_cross_accountz%BaseAWSLLM._handle_irsa_cross_account  s    	EF )3/1!"!1 0 "**:6!
 '.>ON+ \\=>%??J ? 	*=/HXGYZ	
 #@@!,/ A 
 #=1
 \\JK$0ELL%",]";&01B&C",^"<	%
 "%! L	H3GGIO  A/BUBUV[]fBgAhi 	0O_N`a	
 %/
 &/>|,0$00F3EFFw 0/ ?>" LK  	H  #B1#!FGG	Hs;   E<=F	!!F8F! <F	FF!	G*GGc                 "   ddl }|| j                  |      d}|||d<   t        j                  d       t	        j
                  d      5   |j                  di |}	ddd       	 	j                         }
t        j                  d|
j                  dd	              t        j                  d| d|        ||d}|||d<    	j                  di |S # 1 sw Y   {xY w# t        $ r"}t        j                  d
|        Y d}~kd}~ww xY w)z-Handle same-account role assumption for IRSA.r   Nr  r   z2Same account role assumption, using automatic IRSAz%boto3.client(sts) with automatic IRSAzCurrent IRSA identity: r   r  r  zAttempting to assume role: r  r  r   r  r$   )r   rN   r   re   r   r   r   r   r   r   r
  )r6   rC   rA   r   rF   rE   rI   r   r  r   r  r   r   s                r&   _handle_irsa_same_accountz$BaseAWSLLM._handle_irsa_same_account(  s4    	 "**:6!
 '.>ON+QR\\AB%??J C	H(<<>O  )/*=*=eY*O)PQ 	)-HXGYZ	
 %/
 &/>|,%z%%;(:;;3 CB  	H  #B1#!FGG	Hs$   
C&8C# C #	D,D		Dr   c                     ddl m} |d   } ||d   |d   |d         }|d   }t        |t        j                  |j
                        z
  j                               }||fS )	z.Extract credentials and TTL from STS response.r   r   r   r   r   r   
access_key
secret_keytoken
Expiration)botocore.credentialsr   rl   r   rm   tzinfototal_seconds)r6   r   r   sts_credentialsr   expiration_timer]   s          r&   _extract_credentials_and_ttlz'BaseAWSLLM._extract_credentials_and_ttlW  sw     	5&}5!&}5&'89!.1
 *,7x||O,B,BCCRRT
 Cr%   c
           
         ddl }
ddlm} t        j                  d      }t        j                  d      }|xs, t        j                  d      xs t        j                  d      }|rl|rj|h|ft        j                  d|        	 |xs d	}||k7  r| j                  ||||||||	
      }n| j                  ||||||	
      }| j                  |      S d| j                  |	      i}|||d<   |||d<   |3|1t        j                  d      5   |
j                   d"i |}ddd       n5t        j                  d      5   |
j                   	 d"|||d|}ddd       ||d}|||d<   	  j"                  d#i |}|d   } ||d   |d   |d         }|d    }t+        j,                  |j.                        }||z
  j1                         d!z
  }||fS # t        $ rT}t        j                  d|        dt        |      v r)dt        |      v rt        j                  d| d| d        d}~ww xY w# 1 sw Y   xY w# 1 sw Y   xY w# t        $ rk}t        |      }d|v rV| j%                  ||	      r,t        j&                  d||       | j)                         cY d}~S t        j                  d||        d}~ww xY w)$z,
        Authenticate with AWS Role
        r   Nr   r   r   r   AWS_DEFAULT_REGIONz-IRSA detected: using web identity token from z	us-east-1)rE   rI   z Failed to assume role via IRSA: AccessDeniedz,is not authorized to perform: sts:AssumeRolez)Access denied when trying to assume role z$. Please ensure the trust policy of zV allows the current role to assume it. Current identity: check logs with verbose mode.r   r   r   r   r\   r  r   rL   zkAssumeRole failed for %s (%s). Caller is already running as this role; falling back to ambient credentials.zUAssumeRole AccessDenied for %s and caller is NOT the same role. Re-raising. Error: %sr   r   r   r   r  r  <   r  r$   )r   r  r   rb   rd   r   re   r  r  r   r   r#   errorrN   r   r   r   r
  rj   r   rk   r   rm   r  r  )r6   r>   r?   r@   rC   rA   r   rE   rF   rI   r   r   r   r   r   r   r   sts_client_kwargsr   r   	error_strr  r   
sts_expirycurrent_timests_ttls                             r&   ro   zBaseAWSLLM._auth_with_aws_rolek  s|     	4 #%)),I"J		.1  /yy&/yy-. 	 $!)%-   ?@W?XY(.; !M1#'#B#B%%(/')9#- $C 	$L $(#A#A%(')9#- $B $L 88FF$ $,T-A-A*-M"N/5m,'0@n-$)>)F12)U\\E3DE
 32 12)U\\&7*?&7	
 (
 3 %/
 &/>|,	1:11G4FGL< '}5!&}5&'89!.1
 %\2
||J$5$56,;;=BG##k  $$'Gs%KL!S& DAN"((CM? S==JO Lij , 32 32(  	AI* 33!j 4  #**? &!  3355$$;!	 5	sW   AG H4>I +I 	H1AH,,H14H= I		K AJ;K #J;;K c                     ddl }t        j                  d      5  |j                  |      }|j	                         dfcddd       S # 1 sw Y   yxY w)z/
        Authenticate with AWS profile
        r   Nz,boto3.Session(profile_name=aws_profile_name))profile_namer   r   r   r   r   )r6   rB   r   r   s       r&   rp   z!BaseAWSLLM._auth_with_aws_profile	  sE     	 \\HI]]0@]AF))+T1 JII   $AAc                 ,    ddl m}  ||||      }|dfS )z5
        Authenticate with AWS Session Token
        r   r   r  N)r  r   )r6   r>   r?   r@   r   r   s         r&   rq   z'BaseAWSLLM._auth_with_aws_session_token  s'     	5!(,#
 D  r%   c                     ddl }t        j                  d      5  |j                  |||      }ddd       j	                         }|| j                         fS # 1 sw Y   +xY w)zA
        Authenticate with AWS Access Key and Secret Key
        r   Nz|boto3.Session(aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key, region_name=aws_region_name))r>   r?   r   )r   r   r   r   r   r   )r6   r>   r?   r   r   r   r   s          r&   rr   z/BaseAWSLLM._auth_with_access_key_and_secret_key,  sm     	 \\ K
 mm"3&;+ $ G
 --/DGGIII
 
s   AA"c                     ddl }t        j                  d      5  |j                         }|j	                         }|dfcddd       S # 1 sw Y   yxY w)z=
        Authenticate with AWS Environment Variables
        r   Nr   r-  )r6   r   r   r   s       r&   rk   zBaseAWSLLM._auth_with_env_varsE  sA    
 	\\+,mmoG!113K$ -,,r.  c                      y)zj
        Get the default TTL for boto3 credentials

        Returns `3600-60` which is 59 minutes
        i  r$   )r6   s    r&   r   z1BaseAWSLLM._get_default_ttl_for_boto3_credentialsQ  s     r%   api_baser   endpoint_type)runtimeagent	agentcorec                    t        d      }||}n=|t        |t              r|}n(|rt        |t              r|}n| j                  ||      }|t        |t              r|}||fS |rt        |t              r|}||fS |}||fS )NAWS_BEDROCK_RUNTIME_ENDPOINT)r4  r   )r   r`   r#   _select_default_endpoint_url)r6   r3  r   r   r4   env_aws_bedrock_runtime_endpointr   proxy_endpoint_urls           r&   get_runtime_endpointzBaseAWSLLM.get_runtime_endpointZ  s     ,66T+U(#L)5*(#;
 8L-*,c3
 <L<<+ / = L (3
(#9
 "> /// .*,c3
 "B /// ".///r%   c                 :    |dk(  rd| dS |dk(  rd| dS d| dS )z
        Select the default endpoint url based on the endpoint type

        Default endpoint url is https://bedrock-runtime.{aws_region_name}.amazonaws.com
        r6  zhttps://bedrock-agent-runtime.r   r7  zhttps://bedrock-agentcore.zhttps://bedrock-runtime.r$   )r6   r4  r   s      r&   r:  z'BaseAWSLLM._select_default_endpoint_url  sD     G#3O3DNSSk)//@OO-o->nMMr%   c                 B   	 ddl m} |j                  dd      }|j                  dd      }|j                  dd      }| j	                  ||      }|j                  dd       |j                  d	d      }|j                  d
d      }	|j                  dd      }
|j                  dd      }|j                  dd      }|j                  dd      }|j                  dd      }| j                  |||||	|
||||
      }t        |||      S # t        $ r t        d      w xY w)z
        Get boto3 credentials from optional params

        Args:
            optional_params (dict): Optional parameters for the model call

        Returns:
            Credentials: Boto3 credentials object
        r   r   7Missing boto3 to call bedrock. Run 'pip install boto3'.r?   Nr>   r@   r   rC   rA   rB   rD   rE   r   rF   
r>   r?   r@   r   rA   rB   rC   rD   rE   rF   )r   r   r   )r  r   ImportErrorr   r   r   r   )r6   r   r   r   r?   r>   r@   r   rC   rA   rB   rD   rE   r   rF   r   s                   r&   *_get_boto_credentials_from_optional_paramsz5BaseAWSLLM._get_boto_credentials_from_optional_params  sd   	Y8
 !0 3 34KT R+//0CTJ+//0CTJ33OUK-t4'++OTB*../A4H*../A4H!0!4!45Mt!T*../A4H'6':':*D(
$ *--.?F#'#7#7/"7/+--'#9-+ $8 $
 $#+)E
 	
A  	YWXX	Ys   D	 	Dr   extra_headersr   dataheadersapi_keyc                    ||}nt        d      }|r	 ddlm}	 d| |d<    |	d|||      }
n	 dd	lm} ddlm}	 | j                  |      } ||d
|      } |	d|||      }
|j                  |
       |j                         D ]  \  }}|	||
j                  |<    |d|v r|d   |
j                  d<   |
j                         }|S # t        $ r t        d      w xY w# t        $ r t        d      w xY w)NAWS_BEARER_TOKEN_BEDROCKr   
AWSRequestr@  Bearer Authorizationr*   r+   r,   rE  rF  	SigV4Authbedrock)r   botocore.awsrequestrK  rB  botocore.authrP  !_filter_headers_for_aws_signatureadd_authrg   rF  prepare)r6   r   r   rD  r   rE  rF  rG  aws_bearer_tokenrK  r.   rP  aws_signature_headerssigv4header_nameheader_valuepreppeds                    r&   get_request_headerszBaseAWSLLM.get_request_headers  s?    .5-.HI:
 *11A0B'CGO$ <dGG3: %)$J$J7$S!k9oFE  -	G NN7# .5]]_)\+3?GOOK0 .=
 )o.N3@3Q0//#Q  !M   !M s   C C  C C5c                     i }h d}|j                         D ]D  \  }}|	|j                         }||v s#|j                  d      s|j                  d      s@|||<   F |S )z
        Filter headers to only include those that AWS SigV4 includes in signature calculation.
        This Fixes forwarded client headers from breaking the signature calculation.
        >
   
x-amz-datecontent-typex-amz-algorithmx-amz-signaturex-amz-credentialx-amz-signedheadersx-amz-content-sha256x-amz-security-tokendatehostzx-amz-zx-amzn-)rg   r   r_   )r6   rF  rX  aws_headersrZ  r[  header_lowers          r&   rT  z,BaseAWSLLM._filter_headers_for_aws_signature  sv    
 !#
 *1%K#&,,.L+**84**955A%k2 *9 %$r%   service_name)rQ  	sagemakerzbedrock-agentcore	s3vectorsrequest_datastreamfake_streamc
                    |	|	}
nt        d      }
|
r8|xs i }d|d<   d|
 |d<   |t        j                  |      j                         fS 	 ddlm} dd	lm} dd
lm	} |j                  dd      }|j                  dd      }|j                  dd      }|j                  dd      }|j                  dd      }|j                  dd      }|j                  dd      }|j                  dd      }|j                  dd      }| j                  ||      }| j                  ||||||||||
      } ||||      }|ddi|}nddi}| j                  |      } |d|t        j                  |      |      }|j                  |       t!        |j"                        }|j%                         D ]  \  }}|	|||<    |d|v r|d   |d<   ||j&                  fS # t        $ r t        d      w xY w)z
        Sign a request for Bedrock or Sagemaker

        Returns:
            Tuple[dict, Optional[str]]: A tuple containing the headers and the json str body of the request
        NrI  zapplication/jsonzContent-TyperL  rM  r   rO  rJ  r   r@  r?   r>   r@   rC   rA   rB   rD   rE   rF   )r   r   rA  r*   rN  )r   rR   rS   rV   rS  rP  rR  rK  r  r   rB  r   r   r   rT  rU  dictrF  rg   body)r6   rk  rF  r   rn  r3  r   ro  rp  rG  rW  rP  rK  r   r?   r>   r@   rC   rA   rB   rD   rE   rF   r   r   rY  rX  r.   request_headers_dictrZ  r[  s                                  r&   _sign_requestzBaseAWSLLM._sign_request"  si   $ .5-.HI mG&8GN#)01A0B'CGO$DJJ|4;;===	Y/68 !0 3 34KT R+//0CTJ+//0CTJ'++OTB*../A4H*../A4H!0!4!45Mt!T*../A4H)--.?F33+5 4 
 $(#7#7/"7/+--'#9-+ $8 $
 +|_E%'9EWEG%'9:G $ F Fw OL))	
 	w#GOO4 *1%K'4@$[1 *9 Ow$>4;O4L 1#W\\11s  	YWXX	Ys   G G,)r<   N)N)NNNNNNNNNNN)NN)NNN)NNNN)r5  )5r   r    r!   r5   r	   r   boolr#   rN   r   rY   r   wrapr   r   staticmethodr   r   r   rr  r   r   r   r   r   r   r   r
   r   rj   r   rl   ri   r  r  r   ro   rp   rq   rr   rk   r   r   r=  r:  r   rC  bytesr   r]  rT  ru  r8   r9   s   @r&   r;   r;   ;   s   
"5(5s3C*D 5CT#x}2D-E C# C V[[] ,0/3+/)-*.*.'+04*.)-15h#C=h  (}h $C=	h
 "#h #3-h #3-h  }h !)h #3-h "#h U49-.h hTHSM hsm * 	2	3 & !!	2	3! !F 00;<0 0 
	0 0d === 
= = 5# 5# 5 5 **	5	6* *^  $"&	88 }8 3-	8
 
8x *.!#< #0#0	%S#&	'#0 #0P 26== U49-.= 
	=~ V[[] *.15HH #HH HH 	HH
 "#HH #3-HH "#HH U49-.HH 
{HSM)	*HH HHb *.*.15LGLG LG 	LG
 LG "%LG "#LG #3-LG U49-.LG 
LGf *.*.15-<-< -< 	-<
 "#-< #3--< U49-.-< 
-<^   	{HSM)	* ( V[[] *.*.)-15[$#C=[$  (}[$ $C=	[$
 [$ [$ "#[$ #3-[$ "#[$ U49-.[$ 
{HSM)	*[$ [$z V[[]2 #2	{HSM)	*2 2 V[[]!!  #! 	!
 
{HSM)	*! !( V[[]JJ  #J "#	J
 
{HSM)	*J J0 V[[]	%U;+E%F 	% 	% V[[]   MV$03-$0 '/sm$0 	$0
  (G HI$0 
sCx$0LN(G HIN N 
	N$ =A2
#2
,4SM2
	2
h V[[] "&: : :  ~	:
 : CJ: : #: 
: :x% %$ %N  $!%&*!%\2VW\2 \2 	\2
 \2 \2 }\2 \2 d^\2 #\2 
tXe_$	%\2r%   r;   ))rT   rR   rb   urllib.parser   r   typingr   r   r   r   r   r	   r
   r   r   r   r0   pydanticr   litellm._loggingr   litellm.caching.cachingr   litellm.constantsr   r   r   %litellm.litellm_core_utils.dd_tracingr   litellm.secret_managers.mainr   r   rR  r   r  r   r   r   r(   r;   r$   r%   r&   <module>r     s{      	       + - 
 9 C60K09 0

9 

C2 C2r%   