
    jd                     f   d Z ddlmZmZ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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 m!Z! ddl"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z( ddl)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0 ddl1m2Z2 ddl3m4Z4 ddl5m6Z6m7Z7 er	ddl8m9Z: e:Z;neZ; G d de6e4e2      Z< G d de      Z=y)zT
Translates from OpenAI's `/v1/chat/completions` to Databricks' `/chat/completions`
    )TYPE_CHECKINGAnyAsyncIterator	CoroutineIteratorListLiteralOptionalTupleUnioncastoverloadN)	BaseModelRESPONSE_FORMAT_TOOL_NAME)#_handle_invalid_parallel_tool_calls&_should_convert_tool_call_to_json_mode)strip_name_from_message)BaseModelResponseIterator)AllAnthropicToolsValues)AllDatabricksContentValuesDatabricksChoiceDatabricksFunctionDatabricksResponseDatabricksTool)AllMessageValues#ChatCompletionRedactedThinkingBlockChatCompletionThinkingBlock%ChatCompletionToolChoiceFunctionParam#ChatCompletionToolChoiceObjectParamChatCompletionToolParam)ChatCompletionMessageToolCallChoicesMessageModelResponseModelResponseStreamProviderFieldUsage   )AnthropicConfig)OpenAILikeChatConfig   )DatabricksBaseDatabricksException)Loggingc                       e Zd ZU dZdZee   ed<   dZee   ed<   dZ	ee   ed<   dZ
ee   ed<   dZeeee   ef      ed<   dZee   ed<   	 	 	 	 	 	 d>dee   dee   dee   dee   deeee   ef      dee   d	dfd
Ze fd       Zd	ee   fdZ	 	 d?dededee   dededee   dee   d	efdZ	 d@dee   dee   dedededee   d	efdZd@dee   d	efdZdee   d	ee   fdZdeded	ee   fdZdedee   deded	ee   f
dZ 	 d@dedee   deed      d	e!ee   eed      f   fd Z"	 dAd"ededed#ed$ed	ef fd%Z#ded	efd&Z$e%dee   ded'e&d!   d	e'e(e(ee   f   fd(       Z)e%	 dBdee   ded'e&d)   d	ee   fd*       Z)	 dBdee   ded'ed	eee   e'e(e(ee   f   f   f fd+Z)d,ed	efd-Z*e+d.ee,   d	ee   fd/       Z-e+d.ee,   d	e!ee   eeee.e/f         f   fd0       Z0e+d.ee,   d	eee(      fd1       Z1	 d@d2ee2   d3ee   d	ee3   fd4Z4	 	 d?ded5e5jl                  d6e7d7e8d8edee   deded9e(dee   d3ee   d	e7fd:Z9	 dBd;ee:e   e;e   e7f   d<ed3ee   fd=Z< xZ=S )CDatabricksConfigzv
    Reference: https://docs.databricks.com/en/machine-learning/foundation-models/api-reference.html#chat-request
    N
max_tokenstemperaturetop_ptop_kstopnreturnc                     t               j                         }|j                         D ]%  \  }}	|dk7  s|	t        | j                  ||	       ' y )Nself)localscopyitemssetattr	__class__)
r:   r2   r3   r4   r5   r6   r7   locals_keyvalues
             /Users/manta/Documents/Projects/TheRoad-I1/backend/.venv/lib/python3.12/site-packages/litellm/llms/databricks/chat/transformation.py__init__zDatabricksConfig.__init__R   sA     (--/!--/JCf}!2U3 *    c                      t         |          S N)super
get_config)clsr?   s    rC   rI   zDatabricksConfig.get_config`   s    w!##rE   c                 >    t        dddd      t        dddd      gS )	zDFor a given provider, return it's required fields with a descriptionapi_keystringzYour Databricks API Key.zdapi...)
field_name
field_typefield_descriptionfield_valueapi_basezYour Databricks API Base.zhttps://adb-..)r'   )r:   s    rC   get_required_paramsz$DatabricksConfig.get_required_paramsd   s8     $#"<%	 %#"=,	
 	
rE   headersmodelmessagesoptional_paramslitellm_paramsrL   rR   c                 B    | j                  ||dd|      \  }}d|d<   |S )Nchat_completionsF)rR   rL   endpoint_typecustom_endpointrT   zapplication/jsonzContent-Type)databricks_validate_environment)r:   rT   rU   rV   rW   rX   rL   rR   s           rC   validate_environmentz%DatabricksConfig.validate_environmentu   s?     !@@,! A 
' #5rE   streamc                 2    | j                  |      }| d}|S )Nz/chat/completions)_get_api_base)r:   rR   rL   rU   rW   rX   r_   complete_urls           rC   get_complete_urlz!DatabricksConfig.get_complete_url   s'     %%h/"#45rE   c                 
    g dS )N)r_   r6   r3   r4   r2   max_completion_tokensr7   response_formattoolstool_choicereasoning_effortthinking )r:   rU   s     rC   get_supported_openai_paramsz,DatabricksConfig.get_supported_openai_params   s    
 	
rE   toolc                     |y |d   t        t        |j                  d      xs i       d}|j                  d      }| t        t        t        t        f   |      |d<   t        d|      S )Nnameinput_schema)ro   
parametersdescriptionfunctiontypers   )r   dictgetr   strr   )r:   rm   function_paramsrr   s       rC   )convert_anthropic_tool_to_databricks_toolz:DatabricksConfig.convert_anthropic_tool_to_databricks_tool   sw     < LtTXXn%=%CD/
 hh}-"-1%c	2BK-POM*$
 	
rE   rg   c           	          d|vr|S | j                  |      \  }}|D cg c]!  }t        t        | j                  |            # }}|S c c}w )Nclaude)rg   )
_map_toolsr   r   rz   )r:   rU   rg   anthropic_tools_rm   databricks_toolss          rC   _map_openai_to_dbrx_toolz)DatabricksConfig._map_openai_to_dbrx_tool   sn    5 L "__ - 

 (
' !O!OPT!UV' 	 
  	
s   &A
rB   is_thinking_enabledc                 T    |y | j                  |||      }| j                  |      }|S rG   )%map_response_format_to_anthropic_toolrz   )r:   rU   rB   rW   r   rm   databricks_tools          rC   &map_response_format_to_databricks_toolz7DatabricksConfig.map_response_format_to_databricks_tool   s<     =99?$7
 HHNrE   r!   c                 
    ||fS )z
        Override the parent class method to preserve cache_control for models on Databricks.
        Databricks supports Anthropic-style cache control for Claude models.
        Databricks ignores the cache_control flag with other models.
        rk   )r:   rU   rV   rg   s       rC   1remove_cache_control_flag_from_messages_and_toolszBDatabricksConfig.remove_cache_control_flag_from_messages_and_tools   s     rE   Tnon_default_paramsdrop_params-replace_max_completion_tokens_with_max_tokensc                 L   | j                  |      }t        
| 	  ||||      }d|v r| j                  ||d         |d<   d|v r|r|d   |d<   |j	                  dd        d|v rjd|v rf| j                  ||d   ||      }|;| j                  ||g       d|d	<   |s t        d
t        t                    }	|	|d<   |j	                  dd        d|v r=d|v r9t        j                  |j                  d            |d<   |j	                  dd        | j                  ||       |S )Nrg   )rU   rg   re   r2   rf   r|   )rW   rg   T	json_moders   )ro   rt   rh   ri   rj   )r   rW   )r   rH   map_openai_paramsr   popr   _add_tools_to_optional_paramsr    r   r   r*   _map_reasoning_effortrw   +update_optional_params_with_thinking_tokens)r:   r   rW   rU   r   r   r   mapped_params_tool_tool_choicer?   s             rC   r   z"DatabricksConfig.map_openai_params   s    #667IJ1
 m#%)%B%B=#9 &C &M'" $'99=*<'+M,' 5t< 22x57H??"#45#	E  22$3E7 3  04,*#F'!F!:"$L 6BOM2!4 !33E8I*9*O*O"&&'9:+OJ'  2D9881= 	9 	
 rE   c                 (    |j                  d      yy)zN
        Databricks doesn't support 'response_format' while streaming
        rf   TF)rw   )r:   rW   s     rC   _should_fake_streamz$DatabricksConfig._should_fake_stream*  s     01=rE   is_asyncc                      y rG   rk   r:   rV   rU   r   s       rC   _transform_messagesz$DatabricksConfig._transform_messages3  s     	rE   Fc                      y rG   rk   r   s       rC   r   z$DatabricksConfig._transform_messages9  s     	rE   c                    g }t        |      D ]}  \  }}t        |t              r|j                  d      }n|}t	        |dg      }d|v r0t        |j                  d      t              r| j                  |      }|j                  |        |r#t        | )  ||t        t        d   d            S t        | )  ||t        t        d   d            S )	zP
        Databricks does not support:
        - 'name' in user message.
        T)exclude_noneuser)allowed_name_rolescache_controlcontent)rV   rU   r   F)	enumerate
isinstancer   
model_dumpr   rw   rx   -_move_cache_control_into_string_content_blockappendrH   r   r   r	   )	r:   rV   rU   r   new_messagesidxmessage_messager?   s	           rC   r   z$DatabricksConfig._transform_messagesB  s     %h/LC'9-"--4-@".xVHUH(*z(,,y:QSV/WMMhW) 0 7.%UT'$-QU=V /   7.%UT'%.RW=X /  rE   r   c                     |j                  d      }t        t        t        t        f   |j                               }|j                  d      }d||dg|d<   t        t        |      S )a  
        Moves message-level cache_control into a content block when content is a string.
        
        Transforms:
            {"role": "user", "content": "text", "cache_control": {...}}
        Into:
            {"role": "user", "content": [{"type": "text", "text": "text", "cache_control": {...}}]}
        
        This is required for Anthropic's prompt caching API when cache_control is specified
        at the message level but content is a simple string (not already an array of content blocks).
        r   r   text)ru   r   r   )rw   r   rv   rx   r   r<   r   r   )r:   r   r   transformed_messager   s        rC   r   z>DatabricksConfig._move_cache_control_into_string_content_block^  sk     ++i("4S>7<<>B+//@ !.*
I& $&9::rE   r   c                    | y t        | t              r| S t        | t              rDd}| D ];  }|j                  d      dk(  s|j                  dd      }||t        |      ndz  }= |S t	        dt        |              )N ru   r   zUnsupported content type: )r   rx   listrw   	Exceptionru   )r   content_stritem
text_values       rC   extract_content_strz$DatabricksConfig.extract_content_strx  s     ?gs#N&K88F#v-!%&"!5Jj6L3z?RTTK   8gHIIrE   c           
      b   | yd}d}t        | t              r| D ]  }|j                  d      dk(  s|j                  dg       }t        |t              s;|D ]Q  }|d}||d   z  }t        d|j                  dd      |j                  d	d      
      }|g }|j	                  |       S  ||fS )zN
        Extract and return the reasoning content and thinking blocks
        NNNru   	reasoningsummaryr   r   rj   	signature)ru   rj   r   )r   r   rw   r   r   )r   thinking_blocksreasoning_contentr   summary_listsumthinking_blocks          rC   extract_reasoning_contentz*DatabricksConfig.extract_reasoning_content  s     ?
 	 	
 ,0gt$88F#{2#'88Ir#:L!,5#/C0846 1-V<--H%/),)<*-''+r*B.N
  /624+22>B $0	    !/11rE   c           	          | y g }t        | t              rR| D ]M  }|j                  dd       }|j                  d      x}s)|j                  |D cg c]
  }i |d|i c}       O |xs d S c c}w )Nr   	citationssupported_text)r   r   rw   r   )r   r   r   r   citations_itemcitations         rC   extract_citationsz"DatabricksConfig.extract_citations  s     ?	gt$xx-%)XXk%::>:$$ -;,: Ax@)94@,:    D s   A.
choicesr   c           
         g }|D ]X  }|d   j                  dd       }|4g }|D ]  }t        di |}|j                  |         t        |      }	|	|	}d }
d }|rBt	        ||      r5t        |d   d   j                  dd            xs d }|t        |      }
d	}|
t        j                  |d   d
         }t        j                  |d   j                  d
            \  }}t        j                  |d   j                  d
            }t        d||||d   j                  d      |d|ind       }
||d   }t        ||d   |
d d       }|j                  |       [ |S )Nr   
tool_calls)r   convert_tool_call_to_json_moder   rs   	argumentsr   )r   r6   r   	assistantr   )roler   r   r   r   provider_specific_fieldsfinish_reasonindex)r   r   r   logprobsenhancementsrk   )rw   r"   r   r   r   rx   r$   r1   r   r   r   r#   )r:   r   r   transformed_choiceschoicer   _openai_tool_calls_tc
_openai_tcfixed_tool_callstranslated_messager   json_mode_content_strr   r   r   r   translated_choices                     rC   _transform_dbrx_choicesz(DatabricksConfig._transform_dbrx_choices  s    !F	*..|TBJ%%'"%C!>!E!EJ&--j9 & $G&$  $/!1J48+/MD%/8 
1j155k2FGO4 & )4)09N)O&$*M!).BB9%i0 %>>9%)))4%#
 ->>9%)))4	 &-$'&7$3%i044\B , /:9-E	&" $ & 7 '+Wo*!!  &&'89K N #"rE   raw_responsemodel_responselogging_objrequest_dataencodingc           
         |j                  ||
|j                  d|i       	 t        di |j                         }|d   |_
        |d   |_        |d   |_        t        |d	t        di |d	          | j                  |d
   |      |_        |S # t        $ rM}t        |dd       }t        dj                  t        |      |j                        |j                  |      d }~ww xY w)Ncomplete_input_dict)inputrL   original_responseadditional_argsrT   z7Unable to get json response - {}, Original Response: {})r   status_coderT   rU   idcreatedusager   )r   r   rk   )	post_callr   r   jsonr   getattrr.   formatrx   r   rU   r   r   r>   r(   r   r   )r:   rU   r   r   r   r   rV   rW   rX   r   rL   r   completion_responseeresponse_headerss                  rC   transform_responsez#DatabricksConfig.transform_response  s    	*//2LA	 	 	

	"4"K|7H7H7J"K  37;/5!4Y!?)N1DW1M)NO!%!=!='	2 "> "

 )  	&|YE%QXXFL-- )44( 	s   B 	C&AC!!C&streaming_responsesync_streamc                     t        |||      S )N)r   r   r   )DatabricksChatResponseIterator)r:   r   r   r   s       rC   get_model_response_iteratorz,DatabricksConfig.get_model_response_iteratorC  s     .1#
 	
rE   )NNNNNNr   rG   )TF)>__name__
__module____qualname____doc__r2   r
   int__annotations__r3   r4   r5   r6   r   r   rx   r7   rD   classmethodrI   r'   rS   rv   r   r^   boolrc   r   rl   r   r   rz   r   r   r   r   r   r   r   r	   r   r   r   r   staticmethodr   r   r   r   r   r   r   r#   r   httpxResponser%   LiteLLMLoggingObjr   r   r   r   __classcell__r?   s   @rC   r1   r1   F   s    !%J$!%K#%E8C=E8C=,0D(5cC(
)0Ax} %)%)##044SM4 c]4 }	4
 }4 uT#Y^,-4 C=4 
4 $ $
T-%8 
0 "&"&  '(	
   # 3- 
8 "&3- # 	
    

# 
$ 
 
45
	.	!
, c  $  4CW   ~ 	
 " 
.	!* <@	 '( 678	
 
t$%x5N0O'PP	Q* ?C< < < 	<
 < 8<< 
<|4 D  -.7:FMdm	3T"233	4 
 
 $)	'(  %.	
 
	  NS-.7:FJ	t$%yc4@P;Q1Q'RR	S8;EU ;Zj ;4 J45J	#J J" &245&2	13VVW	
	
&2 &2P !45!	$s)	! !& LPL#,-L#:B4.L#	gL#r "&$(-- nn- &	-
 '- - '(- - - - #- D>- 
-f %*	

!(3-s1C]"RS

 

 D>	

rE   r1   c                   ^     e Zd Z	 ddeee   ee   ef   dede	e   f fdZ
dedefdZ xZS )	r   r   r   r   c                 B    t         |   ||       || _        d | _        y rG   )rH   rD   r   _last_function_name)r:   r   r   r   r?   s       rC   rD   z'DatabricksChatResponseIterator.__init__Q  s$     	+[9"#' rE   chunkr8   c                 $   	 g }|d   D ]  }|d   j                  d      }|r| j                  rddlm} ddlm} |d   j                  di       j                  d      }||| _        | j                  |k(  s||k(  rq ||      }|g|j                  d	k(  rd
|_        |j                  |d   d<   d |d   d<   n6|r4|D ]/  }	|	j                  di       j                  d      d	k(  s(d
|	d   d<   1 t        |d   j                  d      t              r;|d   d   x}
r1|
d   j                  d      x}r|d   |d   j                  di       d<   t        j                  |d   j                  d            }t        j                  |d   j                  d            \  }}||d   d<   ||d   d<   ||d   d<   |j                  |        t        |d   d|d   |d   |      S # t         $ r}t#        d| d| d      d }~wt$        $ r}|d }~ww xY w)Nr   deltar   r   r   )!_convert_tool_response_to_messagers   ro   z{}r   r   r   r   r   r   r   r   r   zchat.completion.chunkr   rU   )r   objectr   rU   r   z
KeyError: z+, Got unexpected response from Databricks: i  )r   r   )rw   r   litellm.constantsr    litellm.llms.base_llm.base_utilsr  r
  r   r   r   
setdefaultr1   r   r   r   r&   KeyErrorr.   r   )r:   r  translated_choicesr   r   r   r  function_namer   r   r   r   r   r   r   r   s                   rC   chunk_parserz+DatabricksChatResponseIterator.chunk_parser\  s   O	!#	*#G_00>
$.. L
 %/qM$5$5j"$E$I$I&$QM$03@0
 004MM(,EE #DJ"O".&$6249@F7OI6<@F7OL9)77:r266{CtK;=C
OK8  * fWo11)<dC%gy99G9$+AJNN;$??y?
 & w223MrR& /BB7O''	2 %>>7O''	2%#
 .9w	*7Hw 345Dw 12"))&1 +@ ';.i(Gn*   	%$QC'RSXRYZ   	G	s+   C G  #C<G   	H)G<<HH

Hr   )r   r   r   r   r   rx   r   r%   r  r
   rD   rv   r&   r  r  r  s   @rC   r   r   P  sY    
 %*		(!(3-s1C]"RS	( 	( D>		(P$ P+> PrE   r   )>r   typingr   r   r   r   r   r   r	   r
   r   r   r   r   r  pydanticr   r  r   Flitellm.litellm_core_utils.llm_response_utils.convert_dict_to_responser   r   8litellm.litellm_core_utils.prompt_templates.common_utilsr   )litellm.llms.base_llm.base_model_iteratorr   litellm.types.llms.anthropicr   litellm.types.llms.databricksr   r   r   r   r   litellm.types.llms.openair   r   r   r   r    r!   litellm.types.utilsr"   r#   r$   r%   r&   r'   r(   anthropic.chat.transformationr*   openai_like.chat.transformationr+   common_utilsr-   r.   *litellm.litellm_core_utils.litellm_loggingr/   _LiteLLMLoggingObjr  r1   r   rk   rE   rC   <module>r%     s         7 P @     = C >X*G
~';_ G
T\%> \rE   