+
    ̯yj                        R t ^ RIHt ^ RIt^ RIHt ^ RIHt ^ RIH	t	 ^ RI
Ht ]P                  ! ]4      t ! R R]4      t]R	 R
 l4       tR R ltR R ltR ! 4       tR# )uu  Google Gemini sağlayıcısı — YALNIZCA kamuya açık veri görevleri için.

Bu modül `router.Sensitivity.PUBLIC` işaretli görevlerde kullanılır. Gizlilik
sınırı `router.TaskSpec` içinde zorlanır: `CONFIDENTIAL` bir görev buraya
yönlendirilemez (import anında ValueError).

Tasarım kararı — **yumuşak bağımlılık**: Gemini yapılandırılmamışsa veya
çağrı başarısız olursa çağıran taraf Claude'a düşer. PUBLIC görevlerde her
iki sağlayıcı da hukuken uygun olduğu için fallback güvenlidir; bu sayede
`GEMINI_API_KEY` olmayan bir ortamda (CI, yerel geliştirme) hiçbir şey
bozulmaz.
)annotationsN)	lru_cache)Any	BaseModel)get_settingsc                      ] tR t^tRtRtR# )GeminiNotConfiguredErroruH   GEMINI_API_KEY tanımlı değil — çağıran taraf Claude'a düşmeli. N)__name__
__module____qualname____firstlineno____doc____static_attributes__r
       Y/Users/zincirx/Documents/projelerim/patentyazar/backend-python/app/services/llm/gemini.pyr	   r	      s    Rr   r	   c                   V ^8  d   QhRR/# )   returnr   r
   )formats   "r   __annotate__r       s     9 9 9r   c                     \        4       p V P                  '       g   \        R4      h ^ RIHp TP                  T P                  R7      #   \
         d   p\        R4      ThRp?ii ; i)u   Global async-capable Gemini client.

`google-genai` import'u fonksiyon içindedir: paket kurulu değilse modül
import'u patlamasın, yalnızca fiilen Gemini çağrılırsa hata versin.
u    GEMINI_API_KEY tanımlı değil.)genaiu;   google-genai paketi kurulu değil: pip install google-genaiN)api_key)r   gemini_api_keyr	   googler   ImportErrorClient)settingsr   excs      r   _clientr!      si     ~H"""&'IJJ 
 << 7 7<88	  &I
	s   A A'A""A'c                   V ^8  d   QhRR/# )r   r   boolr
   )r   s   "r   r   r   2   s      t r   c                 Z     \        4        R#   \         d     R# \         d     R# i ; i)uM   Gemini kullanılabilir mi? Çağıran taraf fallback kararı için kullanır.FT)r!   r	   	Exceptionr
   r   r   is_configuredr&   2   s0    	
 	 $  s   
 ****c                    V ^8  d   QhRRRR/# )r   usage_metadatar   r   zdict[str, int]r
   )r   s   "r   r   r   =   s      C N r   c                   a  S f   / # R V 3R llpV! R4      pV! R4      pR\        W#,
          ^ 4      RV! R4      R^ R	V/# )
u  Gemini `usage_metadata`'yı `record_usage()`'ın beklediği şekle çevirir.

Gemini alan adları Anthropic'ten farklı; ortak maliyet borusunu tek
formatta tutmak için burada eşliyoruz.

Not: Gemini'de `prompt_token_count`, cache kullanıldığında cache'lenmiş
token'ları DA içerir. Anthropic'te `input_tokens` cache'lenmemiş kısımdır.
Çift sayımı önlemek için cache'li kısmı düşüyoruz.
c                    V ^8  d   QhRRRR/# )r   namestrr   intr
   )r   s   "r   r   %usage_as_record.<locals>.__annotate__J   s     : :3 :3 :r   c                D   < \        \        SV ^ 4      ;'       g    ^ 4      # )    )r-   getattr)r+   r(   s   &r   _getusage_as_record.<locals>._getJ   s    7>4388q99r   prompt_token_countcached_content_token_countinput_tokensoutput_tokenscandidates_token_countcache_creation_input_tokenscache_read_input_tokens)max)r(   r2   promptcacheds   f   r   usage_as_recordr>   =   s_     	: : &'F./FFOQ/67%q!6	 r   c                 $    R RR l6;p3R R lu6# )T)   c                    V ^8  d   Qh\         # )r   r   ).formats   "r   r@   r@   W   s    r   c               0    V ^8  d   QhRRRRRRRRRRR	R
/# )r   modelr,   systemuserschemaztype[T]
max_tokensr-   r   ztuple[T | None, dict[str, int]]r
   )r   s   "r   r   r   W   sF     + ++ + 	+
 + + %+r   c                  "   ^ RI Hp \        4       pVP                  P                  P                  V VVP                  VRVVR7      R7      G Rj  xL
 p\        \        VRR4      4      p\        VRR4      p	V	e'   \        W4      '       g    VP                  V	4      p	W3# W3#  LT  \         d%   p
\        P                  RT
4       Rp	 Rp
?
Y3# Rp
?
ii ; i5i)	u   Şema-doğrulanmış JSON üret.

Returns:
    (parsed, usage_record). Parse edilemezse (None, usage).

Raises:
    GeminiNotConfiguredError: yapılandırma yoksa — çağıran Claude'a düşer.
)typeszapplication/json)system_instructionresponse_mime_typeresponse_schemamax_output_tokens)rE   contentsconfigNr(   parsedu#   Gemini yanıtı şemaya uymadı: %s)google.genairK   r!   aiomodelsgenerate_contentGenerateContentConfigr>   r1   
isinstancemodel_validater%   loggerwarning)rE   rF   rG   rH   rI   rK   clientresponseusagerR   r    s   $$$$$      r   generate_structuredr_   W   s       #YFZZ&&77**%1"(	 + 
 8 	 	H GH.>EFE Xx.F*V"<"<	**62F
 =6=1	(  	NN@#FF=		s<   ACB&<CB(  C(C3CCCCr
   )	.defaultsr@   s     r   +<generic parameters of generate_structured>ra   W   s    ll +r   )r   
__future__r   logging	functoolsr   typingr   pydanticr   
app.configr   	getLoggerr   rZ   RuntimeErrorr	   r!   r&   r>   r_   r
   r   r   <module>rj      sd    #     #			8	$S| S 9 9$4+ +r   