
    {hġ                       d dl mZ d dlZ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
 d dlmZmZmZmZmZmZmZmZ d dlmZ d dlmZmZmZ d dlmZmZmZ erd dlm Z! d d	l"m#Z# d d
l$m%Z%  ejL                  d      Z' edd      Z( edd      Z) G d de      Z* G d de#      Z+d0dZ, ejZ                  dej\                        Z/ ejZ                  d      Z0d1dZ1	 	 	 	 d2dZ2	 	 	 	 d3dZ3	 	 	 	 	 	 d4dZ4d5dZ5d6dZ6d7dZ7 G d d ee(         Z8d8d!Z9	 	 	 	 d9d"Z:d:d#Z;d;d$Z<	 	 	 	 	 	 d<d%Z=d=d&Z>d' Z? G d( d)ed*+      Z@	 	 	 	 	 	 d>d,ZAd?d-ZB	 	 	 	 d@d.ZC	 	 	 	 dAd/ZDy)B    )annotationsN)AsyncGenerator	GeneratorIterable)TYPE_CHECKINGAnyCallableGenericProtocol	TypedDictTypeVarUnion)CompletionUsage)ChatCompletionChatCompletionMessageChatCompletionMessageParam)PDFAudioImageUsage)Enum)	BaseModel
instructorR_coT)	covariantT_ModelResponse)boundc                      e Zd ZU ded<   y)r   OpenAIUsage | AnthropicUsageusageN__name__
__module____qualname____annotations__     Q/var/www/html/hubwallet-dev/venv/lib/python3.12/site-packages/instructor/utils.pyr   r   )   s    ''r)   c                  \    e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
ZdZdZdZdZdZdZdZdZdZdZy)Provideropenaivertexai	anthropicanyscaletogethergroqmistralcoheregeminigenai
databrickscerebrasdeepseek	fireworkswriterxaiunknownbedrock
perplexity
openrouterN)r$   r%   r&   OPENAIVERTEXAI	ANTHROPICANYSCALETOGETHERGROQMISTRALCOHEREGEMINIGENAI
DATABRICKSCEREBRASDEEPSEEK	FIREWORKSWRITERXAIUNKNOWNBEDROCK
PERPLEXITY
OPENROUTERr(   r)   r*   r,   r,   -   sf    FHIHHDGFFEJHHIF
CGGJJr)   r,   c                   dt        |       v rt        j                  S dt        |       v rt        j                  S dt        |       v rt        j                  S dt        |       v rt        j
                  S dt        |       v rt        j                  S dt        |       v rt        j                  S dt        |       v rt        j                  S dt        |       v rt        j                  S d	t        |       v rt        j                  S d
t        |       v rt        j                  S dt        |       v rt        j                  S dt        |       v rt        j                  S dt        |       v rt        j                  S dt        |       v rt        j                  S dt        |       v rt        j                   S dt        |       v sdt        |       v rt        j"                  S dt        |       v rt        j$                  S t        j&                  S )Nr0   r1   r/   r8   r:   r2   r-   r3   r4   r5   r7   r9   r.   r;   r?   zx.air<   r@   )strr,   rD   rE   rC   rL   rN   rF   rA   rG   rH   rI   rK   rM   rB   rO   rS   rP   rT   rQ   )base_urls    r*   get_providerrX   D   s   S]"   	s8}	$   	H	%!!!	s8}	$   	H	%!!!	3x=	 }}	S]	"	c(m	#	S]	"	S]	"	X	&"""	s8}	$   	s8}	$   	S]	"	X	&"""	3x=	 ES]$:||	X	&"""r)   z```(?:json)?\s*(.*?)\s*```z({[\s\S]*})c                :   t         j                  |       }|r!|j                  d      j                         }|S t        j                  |       }|r|j                  d      }|S | j                  d      }| j                  d      }|dk7  r|dk7  r
| ||dz    }|S | }|S )a  
    Extract JSON from a string that may contain markdown code blocks or plain JSON.

    This optimized version uses regex patterns to extract JSON more efficiently.

    Args:
        content: The string that may contain JSON

    Returns:
        The extracted JSON string
       {})_JSON_CODEBLOCK_PATTERNsearchgroupstrip_JSON_PATTERNfindrfind)contentmatchjson_contentfirst_paren
last_parens        r*   extract_json_from_codeblockrj   o   s     $**73E{{1~++-  $$W- ;;q>L  ",,s+K s+Jb Z2%5&{Z!^D   'r)   c              #  n  K   d}d}d}d}d}g }g }g }| D ]  }	|	D ]  }
|s+|
dk(  r&|j                  |
       t        |      dk(  rd}d}g }1t        |      dkD  r|
dk7  rg }|rG|sE|
dk(  r|dz  }|dk(  rd}d}^|dkD  rd}|
dk(  r$d}|j                  d       |j                  |
       |r|
dk(  r|s| }n|
d	k(  r|rd}|j                  |
       d}|r,|s*|
dk(  r|dz  }|dk(  rd}|D ]  }|  g }d} |dkD  rd}|sS|
dk(  r|j                  d       n<|
d
k(  r7|r5|j                          |s#|j                  |
       |D ]  }|  g }d} B|j                  |
       O|rS|rW|
dk(  s^d}|j                  d       |j                  |
         |r|r|D ]  }|  yyyw)aJ  
    Extract JSON from a stream of chunks, handling JSON in code blocks.

    This optimized version extracts JSON from markdown code blocks or plain JSON
    by implementing a state machine approach.

    The state machine tracks several states:
    - Whether we're inside a code block (```json ... ```)
    - Whether we've started tracking a JSON object
    - Whether we're inside a string literal
    - The stack of open braces to properly identify the JSON structure

    Args:
        chunks: An iterable of string chunks

    Yields:
        Characters within the JSON object
    Fr   `   TrZ   r[   "\r\   Nappendlenpopchunksin_codeblockcodeblock_delimiter_countjson_started	in_stringescape_nextbrace_stackbuffercodeblock_bufferchunkcharcs               r*   extract_json_from_streamr      s`    , L !LIKKF  X$ W	$DDCK ''-'(A-#'L01-')$%&*ts{#%  L3;-2-0A5',451.2 .
 3;#'L&&s+MM$' 3;{$-IT\i"&KMM$'"'K  	s{1Q6149+0L%+ (&'(%'F+0L! 2Q6451 !s{#**3/#)*"MM$/%+ (&'(%'F+0L! d#  #""3'd#oW	$X$v  	AG	 |s   E*F5.F52F59<F5c                 K   d}d}d}d}d}g }g }g }| 2 3 d{   }	|	D ]  }
|s+|
dk(  r&|j                  |
       t        |      dk(  rd}d}g }1t        |      dkD  r|
dk7  rg }|rG|sE|
dk(  r|dz  }|dk(  rd}d}^|dkD  rd}|
dk(  r$d}|j                  d       |j                  |
       |r|
d	k(  r|s| }n|
d
k(  r|rd}|j                  |
       d}|r-|s+|
dk(  r|dz  }|dk(  rd}|D ]  }| 	 g }d} |dkD  rd}|sT|
dk(  r|j                  d       n=|
dk(  r8|r6|j                          |s$|j                  |
       |D ]  }| 	 g }d} I|j                  |
       Q|rU|rY|
dk(  s`d}|j                  d       |j                  |
        7 6 |r|r|D ]  }| 	 yyyw)a^  
    Extract JSON from an async stream of chunks, handling JSON in code blocks.

    This optimized version extracts JSON from markdown code blocks or plain JSON
    by implementing a state machine approach.

    The state machine tracks several states:
    - Whether we're inside a code block (```json ... ```)
    - Whether we've started tracking a JSON object
    - Whether we're inside a string literal
    - The stack of open braces to properly identify the JSON structure

    Args:
        chunks: An async generator yielding string chunks

    Yields:
        Characters within the JSON object
    Fr   Nrl   rm   TrZ   r[   rn   ro   r\   rp   rt   s               r*   extract_json_from_stream_asyncr     si    , L !LIKKF  X$ X$e W	$DDCK ''-'(A-#'L01-')$%&*ts{#%  L3;-2-0A5',451.2 .
 3;#'L&&s+MM$' 3;{$-IT\i"&KMM$'"'K  	s{1Q6149+0L%+ (&'(%'F+0L! 2Q6451 !s{#**3/#)*"MM$/%+ (&'(%'F+0L! d#  #""3'd#oW	$X$vv  	AG	 |s8   G F,F)F,EG 5G 9G  )G )F,,G c                   | y t        | dd       }t        |t              rSt        |t              rB|xj                  |j                  xs dz  c_        |xj                  |j                  xs dz  c_        |xj
                  |j
                  xs dz  c_        |j                  x}rZ|j                  x}rL|j                  xs d|j                  xs dz   |_        |j                  xs d|j                  xs dz   |_        |j                  x}rZ|j                  x}rL|j                  xs d|j                  xs dz   |_        |j                  xs d|j                  xs dz   |_
        || _        | S 	 ddlm} t        ||      rt        ||      r|j                  sd|_        |j                  sd|_        |xj                   |j                   xs dz  c_        |xj"                  |j"                  xs dz  c_        |xj                  |j                  xs dz  c_        |xj                  |j                  xs dz  c_        || _        | S t&        j)                  d       | S # t$        $ r Y "w xY w)Nr"   r   r   z<No compatible response.usage found, token usage not updated.)getattr
isinstanceOpenAIUsagecompletion_tokensprompt_tokenstotal_tokenscompletion_tokens_detailsaudio_tokensreasoning_tokensprompt_tokens_detailscached_tokensr"   anthropic.typesr   cache_creation_input_tokenscache_read_input_tokensinput_tokensoutput_tokensImportErrorloggerdebug)responsetotal_usageresponse_usagertdttdrpdtpdAnthropicUsages           r*   update_total_usager     sT    Xw5N.+.:k;3W%%)I)I)NQN%!!^%A%A%FQF!  N$?$?$D1D !;;;C;888C8 # 0 0 5A#:J:J:OaPC$'$8$8$=A$$)$C  "777C7444C4 # 0 0 5A#:J:J:OaPC!$!2!2!7aC<M<M<RQR SC$;nn5*;
 :::;766673$$(C(C(HqH$%%)E)E)JJ%33::?a3 //66;!/ )HNO LLOPO	  s   6CI& &	I21I2c                8   | j                   | j                  xs dd}t        | d      r"| j                  | j	                         d   |d<   t        | d      r| j
                  |d   rt        |d   t              smd}|d   D ]^  }t        |t              s|j                  d      }|dk(  r|j                  dd      }||z  }B|dk(  sH|j                  dd      }||z  }` ||d<   |dxx   t        j                  | j	                         d         z  cc<   |S )	zDumps a message to a dict, to be returned to the OpenAI API.
    Workaround for an issue with the OpenAI API, where the `tool_calls` field isn't allowed to be present in requests
    if it isn't used.
     rolere   
tool_callsfunction_callre   typetextrefusal)r   re   hasattrr   
model_dumpr   r   rV   dictgetjsondumps)messageretresponse_messagecontent_messagemessage_typetext_contentrefusal_contents          r*   dump_messager     s*    ??(b'C w%'*<*<*H#..0>L)!!-	N#i.#.$&#&y> 	<ot4#2#6#6v#>L#v-'6':':62'F(L8(%2*9*=*=i*L(O;(	< .C	NI$**W%7%7%9/%JKKJr)   c                    t        j                  |       }t        | d      r2| j                  } |xs t        j                  |       }t        | d      r2|S )zGReturns true if the callable is async, accounting for wrapped callables__wrapped__)inspectiscoroutinefunctionr   r   )funcis_coroutines     r*   is_asyncr     sP    ..t4L
$
&#Hw'B'B4'H $
& r)   c                `   | sg S t        |       }g }d}t        | dt        d|             D ])  \  }}t        |j	                  dd      t
              r'd} n |r|dkD  rt        d | dd D              }| D ]  }|j	                  dd	      }|j	                  dd      }|st        |t
              rd
|dg}|ra||d   d   k(  rV|r|d   dxx   d| z  cc<   bt        |t              r|d   d   j                  |       |d   d   j                  |       |j                  ||d        |S )a  
    Merge consecutive messages from the same role into a single message.

    This optimized version pre-allocates the result list and minimizes operations.

    Args:
        messages: List of message dictionaries to merge

    Returns:
        List of merged message dictionaries
    TN
   re   r   Fc              3  \   K   | ]$  }t        |j                  d d      t               & yw)re   r   N)r   r   rV   .0ms     r*   	<genexpr>z-merge_consecutive_messages.<locals>.<genexpr>  s"     WA*QUU9b%93?Ws   *,r   userr   r   r   r]   

r   )
rr   	enumerateminr   r   rV   alllistextendrq   )	messagesmessage_countnew_messagesflat_string_ir   r   r   new_contents	            r*   merge_consecutive_messagesr     si    	 MML
 K8$<c"m&<=> A!%%	2.4K }r)WRTRUWW  H{{66*kk)R0 z+s;$*K@AK DL$4V$<<R +k]/CC+ k40 $Y/66{C !$Y/66{C + FG-H0 r)   c                       e Zd ZdZddZddZy)classpropertya  Descriptor for class-level properties.

    Examples:
        >>> from instructor.utils import classproperty

        >>> class MyClass:
        ...     @classproperty
        ...     def my_property(cls):
        ...         return cls

        >>> assert MyClass.my_property
    c                    || _         y N	cproperty)selfmethods     r*   __init__zclassproperty.__init__?  s	    r)   c                $    | j                  |      S r   r   )r   instanceclss      r*   __get__zclassproperty.__get__B  s    ~~c""r)   N)r   zCallable[[Any], R_co]returnNone)r   objectr   z	type[Any]r   r   )r$   r%   r&   __doc__r   r   r(   r)   r*   r   r   1  s     #r)   r   c                n    | sdgS | j                  dd      }t        |t              r|r|S dgS ||gS dgS )a  
    Extract content from a message and ensure it's returned as a list.

    This optimized version handles different message formats more efficiently.

    Args:
        message: A message in ChatCompletionMessageParam format

    Returns:
        The message content as a list
    r   re   )r   r   r   )r   re   s     r*   get_message_contentr   F  sS     t kk)R(G '4 !w+t+ *G3333r)   c                >   | sg S g }| D ]=  }|j                  d      dk(  s|j                  dd      }|s-|j                  |       ? d}|rdj                  t        d|            }t	        d | D              }g }dd	d
}| D ];  }|j                  dd      }||v s||   }	|j                  |	t        |      d       = |rZ|r?|d   }
t        |
j                  d      t              r|
d   j                  dd| d       |S |j                  dd| dgd       |S )a  
    Transform messages from OpenAI format to Gemini format.

    This optimized version reduces redundant processing and improves
    handling of system messages.

    Args:
        messages_chatgpt: Messages in OpenAI format

    Returns:
        Messages in Gemini format
    r   systemre   r   r   Nc              3  J   K   | ]  }|j                  d       dk7  sd  ywr   r   rZ   Nr   r   s     r*   r   z-transform_to_gemini_prompt.<locals>.<genexpr>  s     QaquuV}7PQ   ##r   model)r   	assistantr   partsr   r   *)	r   rq   joinfiltersumr   r   r   insert)messages_chatgptsystem_promptsr   re   system_promptr   messages_geminirole_mapr   gemini_rolefirst_messages              r*   transform_to_gemini_promptr   a  s]     	 N# /;;v(*kk)R0G%%g.	/ MF4$@A Q#3QQMO H $ {{62&8"4.K""$/B7/KL	 +A.M-++G4d;g&--a1]O11EF
  ""F-PQ>R=S#TUr)   c                @   | d   j                         D ]  }d|v rp|d   }t        |t              rt        |      dk7  r yg }|D ],  }t        |t              sd|v s|j                  |d          . d|v rdt        |      ddhk(  ru yd|v s|t        |      r y y	)
z
    Verify that the object does not contain any Union types (except Optional and Decimal).
    Optional[T] is allowed as it becomes Union[T, None].
    Decimal types are allowed as Union[str, float] or Union[float, str].
    
propertiesanyOf   Fr   nullstringnumberT)valuesr   r   rr   r   rq   setverify_no_unions)obj
prop_valueany_of_listtypes_in_unionitems        r*   r  r    s     ,'..0 
j $W-Kk40C4D4I  N# 8dD)fn"))$v,78
 ' >"x&:: :%.>z.J58 r)   c                    ddl } G d dt              }|j                  | d      }|j                  dd       dfd |      }t	        |      st        d	       |di |j                  d
d
      S )am  
    Map OpenAPI schema to Gemini function call schema.

    Transforms a standard JSON schema to Gemini's expected format:
    - Adds 'format': 'enum' for enum fields
    - Converts Optional[T] (anyOf with null) to nullable fields
    - Rejects true Union types (non-Optional anyOf)

    Ref: https://ai.google.dev/api/python/google/generativeai/protos/Schema
    r   Nc                      e Zd ZU dZded<   dZded<   dZded<   dZded<   dZd	ed
<   dZ	ded<   dZ
ded<   dZded<   dZded<   dZded<   y)5map_to_gemini_function_schema.<locals>.FunctionSchemaNz
str | Nonedescriptionzlist[str] | Noneenumz
Any | Noneexampleformatzbool | NonenullablezFunctionSchema | Noneitemsrequiredr   zlist[dict[str, Any]] | Noner  z dict[str, FunctionSchema] | Noner   )r$   r%   r&   r  r'   r  r  r  r  r  r  r   r  r   r(   r)   r*   FunctionSchemar    sk    "&Z&!%%""!
! $+$'+$+%)")j-1*17;
4;r)   r  F)	lazy_loadz$defsc                   t        | t              r| D cg c]
  } |       c}S t        | t              s| S i }| j                         D ]  \  }}|dk(  r|||<   d|d<   |dk(  rt        |t              rt	        |      dk(  r|D cg c](  }t        |t              r|j                  d      dk(  s|* }}t	        |      dk(  r" |d         }|j                  |       d	|d
<   g }|D ],  }t        |t              sd|v s|j                  |d          . t        |      ddhk(  r |      ||<    |      ||<    |      ||<    |S c c}w c c}w )z+Transform a single schema node recursively.r  r  r  r  r   r  rZ   r   Tr  r  r  )	r   r   r   r  rr   r   updaterq   r  )	noder  transformedkeyvaluenon_null_itemsactual_typer  transform_schema_nodes	           r*   r"  z<map_to_gemini_function_schema.<locals>.transform_schema_node  s   dD!<@AD)$/AA$%K**,  	@JCf}#(C (.H%Jud$;E
a !&"&tT2txx7G67Q " " ~&!+"7q8I"JK&&{3.2K
+ &(N % @%dD1fn*11$v,?@ >*x.BB+@+GC( ,A+GC(#8#?C A 	@D S B"s   E
-EzYGemini does not support Union types (except Optional). Please change your function schemaT)exclude_noneexclude_unset)r  r   r   r   r(   )jsonrefr   replace_refsrs   r  
ValueErrorr   )r	  r%  r  schemar"  s       @r*   map_to_gemini_function_schemar)    s     
< 
< %11#1GF
JJw,\ #6*F F#g
 	
 #F#..DPT.UUr)   c           	     ,   ddl m}m} | j                         }ddddddd	d
d}|j	                  di       }|j                         D ]#  \  }}||v s|j	                  |      }	|	|	||<   % |j	                  di       }
g |d<   |D cg c].  }||j                  k7  r|j                  j                  d      s|0 }}|D ]5  }|
j                  ||j                        }|d   j                  ||d       7 |j	                  dd      }|||d<   |S c c}w )zO
    Update keyword arguments for google.genai package from OpenAI format.
    r   HarmBlockThresholdHarmCategorymax_output_tokenstemperaturecandidate_counttop_pstop_sequencesseedpresence_penaltyfrequency_penalty)
max_tokensr/  nr1  stopr3  r4  r5  generation_configNsafety_settingsHARM_CATEGORY_IMAGE_)category	thresholdthinking_config)google.genai.typesr,  r-  copyrs   r  HARM_CATEGORY_UNSPECIFIEDname
startswithr   OFFrq   )kwargsbase_configr,  r-  
new_kwargsOPENAI_TO_GEMINI_MAPr9  
openai_key
gemini_keyvalr:  r   supported_categoriesr<  r=  r>  s                   r*   update_genai_kwargsrM    se    DJ *$ .0	 #':B?"6"<"<"> .
J**#''
3C*-J'	. !nn%6;O%'K!" 666!!"89 	
  ) 
#''2D2H2HI	%&--$&	

 !nn%6=O")8%&+s   3Dc                X   | j                         }dddddd}d|v r;|d   }|j                         D ]#  \  }}||v s|j                  |      }||||<   % d|v rt        |j                  d            |d	<   	 d
dlm}m} |j                  di       }	|	|d<   |j                  |j                  |j                  |j                  |j                  |j                  i}
|
j                         D ]#  \  }}|	j                  |      }|||kD  s||	|<   % |S # t        $ r d
dlm}m} Y w xY w)a.  
    Update keyword arguments for Gemini API from OpenAI format.

    This optimized version reduces redundant operations and uses
    efficient data transformations.

    Args:
        kwargs: Dictionary of keyword arguments to update

    Returns:
        Updated dictionary of keyword arguments
    r.  r/  r0  r1  r2  )r6  r/  r7  r1  r8  r9  r   contentsr   r+  r:  )r@  r  rs   r   r?  r,  r-  r   google.generativeai.typesr   HARM_CATEGORY_HATE_SPEECHBLOCK_ONLY_HIGHHARM_CATEGORY_HARASSMENTHARM_CATEGORY_DANGEROUS_CONTENT)rE  resultrH  
gen_configrI  rJ  rK  r,  r-  r:  DEFAULT_SAFETY_THRESHOLDSr<  r=  currents                 r*   update_gemini_kwargsrY  Y  sr    [[]F
 *$  f$/0
 ';&@&@&B 	1"J
Z' nnZ0?-0Jz*		1 V7

:8NOz
G jj!2B7O /F
 	..0B0R0R--/A/Q/Q446H6X6X!  9>>@ 2)!%%h/ ?g	1(1OH%2 M9  
	
 	

s   :D D)(D)c                 *    dt         j                  d<   y )N0PYDANTIC_ERRORS_INCLUDE_URL)osenvironr(   r)   r*   disable_pydantic_error_urlr_    s    03BJJ,-r)   c                  ,    e Zd ZU ded<   ded<   ded<   y)SystemMessagerV   r   r   zdict[str, str]cache_controlNr#   r(   r)   r*   ra  ra    s    
I
I!!r)   ra  F)totalc                   | |S t        | t        t        f      rt        |t        t        f      s#t        dt	        |        dt	        |             t        | t              rt        |t              r|  d| S t        | t              r.t        |t              rt        |       }|j                  |       |S t        | t              r1t        |t              r!t        d|       g}|j                  |       |S t        | t              r;t        |t              r+t        d|      }t        |       }|j                  |       |S | S )a)  
    Combine existing and new system messages.

    This optimized version uses a more direct approach with fewer branches.

    Args:
        existing_system: Existing system message(s) or None
        new_system: New system message(s) to add

    Returns:
        Combined system message(s)
    z.System messages must be strings or lists, got z and r   r   r   )r   rV   r   r'  r   r   ra  rq   )existing_system
new_systemrU  new_messages       r*   combine_system_messagesrh    s0   "  oT{3:S$K< <T/=R<SSXY]^hYiXjk
 	

 /3'Jz3,G ""$zl33	OT	*z*d/K o&j!	OS	)jT.J  V/BCj!	OT	*z*c/J $jAo&k" r)   c                >   | sg S t        d | D              }|dk(  rg S dd}g }| D ]t  }|j                  d      dk(  s|j                  d      }|s,t        |t              r"|D ]  }|s|j	                   ||              ^|j	                   ||             v |S )a  
    Extract system messages from a list of messages.

    This optimized version pre-allocates the result list and
    reduces function call overhead.

    Args:
        messages: List of messages to extract system messages from

    Returns:
        List of system messages
    c              3  J   K   | ]  }|j                  d       dk(  sd  ywr   r   r   s     r*   r   z*extract_system_messages.<locals>.<genexpr>  s     HQaeeFmx.GqHr   r   re   c                    t        | t              rt        d|       S t        | t              rt        di | S t	        dt        |              )Nr   r   zUnsupported content type: r(   )r   rV   ra  r   r'  r   )re   s    r*   convert_messagez0extract_system_messages.<locals>.convert_message  sH    gs# f7;;& +7++9$w-IJJr)   r   r   )re   r   r   ra  )r   r   r   r   rq   )r   system_countrl  rU  r   re   r  s          r*   extract_system_messagesrn    s     	 H(HHL q	K #%F 8;;v(*kk),G  '4(# =Dod&;<=
 og67!8$ Mr)   c                   d}| D ]  }t        |t              rt        |t              s%|j                  d      dk(  s:t        |j                  d      t              r||j                  dd      dz   z  }rt        |j                  d      t              s|j                  dg       D ]  }t        |t              s||dz   z  }  |rt        |       dk(  rt        d      t        j                  d|      rt        d	      |S )
zx
    Extract system messages from a list of messages.

    We expect an explicit system messsage for this provider.
    r   r   r   re   r   rZ   zUAt least one user message must be included. A system message alone is not sufficient.z{{.*?}}|{%.*?%}z[Jinja templating is not supported in system messages with Google GenAI, only user messages.)	r   rV   r   r   r   rr   r'  rer_   )r   system_messagesr   r  s       r*   extract_genai_system_messagerr  !  s     O 
=gs#&{{6"h.gkk)4c:#w{{9b'AF'JJOI 6= 'Ir : =%dC0+tf}<O=
= 3x=A-c
 	
 
yy#_5i
 	
 r)   c           
     d   ddl m} g }| D ]!  }t        |t              r>|j	                  |j                  d|j                  j                  |      g             Rt        ||j
                        r|j	                  |       zt        ||j                        r|j	                  |       t        |t              rZd|v sJ d|v sJ |d   dk(  r|d   d	vrt        d
|d          t        |d   t              rE|j	                  |j                  |d   |j                  j                  |d         g             8t        |d   t              sMg }|d   D ]  }t        |t              r,|j	                  |j                  j                  |             ?t        |t        t        t        f      r |j	                  |j                                zt        dt!        |              |j	                  |j                  |d   |             t        dt!        |              |S )z
    Convert a list of messages to a list of dictionaries in the format expected by the Gemini API.

    This optimized version pre-allocates the result list and
    reduces function call overhead.
    r   )typesr   )r   r   r   re   r   >   r   r   zUnsupported role: zUnsupported content item type: zUnsupported message type: )google.genairt  r   rV   rq   ContentPart	from_textFiler   r'  r   r   r   r   to_genair   )r   rt  rU  r   content_partscontent_items         r*   convert_to_genai_messagesr}  D  s#    #57F 3Kgs#MM :://W/=>   /MM'",MM'"&W$$$'''v(*v&77 #5gfo5F!GHH'),c2MM$V_$zz339K3LM "  GI.5 "$+I$6 L!,4%,,UZZ-A-A|-A-TU#L5%2EF%,,\-B-B-DE(=d<>P=QR  MM$V_+ "  9$w-IJJg3Kj Mr)   )rW   rV   r   r,   )re   rV   r   rV   )ru   zIterable[str]r   zGenerator[str, None, None])ru   AsyncGenerator[str, None]r   r~  )r   zT_Model | Noner   r!   r   zT_Model | ChatCompletion | None)r   r   r   r   )r   zCallable[..., Any]r   bool)r   list[dict[str, Any]]r   r  )r   r   r   	list[Any])r   z list[ChatCompletionMessageParam]r   r  )r	  dict[str, Any]r   r  )r	  r  r   r  )rE  r  rF  r  r   r  )rE  r  r   r  )re  z%Union[str, list[SystemMessage], None]rf  Union[str, list[SystemMessage]]r   r  )r   r  r   zlist[SystemMessage])r   r  r   rV   )r   z6list[Union[str, dict[str, Any], list[dict[str, Any]]]]r   r  )E
__future__r   r   r   loggingr]  rp  collections.abcr   r   r   typingr   r   r	   r
   r   r   r   r   openai.typesr   r   openai.types.chatr   r   r   instructor.multimodalr   r   r   r   r   r   r  r   pydanticr   	getLoggerr   r   r   r   r,   rX   compileDOTALLr^   rb   rj   r   r   r   r   r   r   r   r   r   r  r)  rM  rY  r_  ra  rh  rn  rr  r}  r(   r)   r*   <module>r     s   "    	 	 ? ?	 	 	 8  4 37  			<	(v&
):
.(x (t .#N %"**%BBIIN 

>*B~~~B~%~~B66-6 %6rB9x#GDM #*46@6@@F"JSVl77)777tIX4"IU "6:6/6 %6r6r "  FBDBBr)   