+
    yj%                    <   R t ^ RIHt ^ RIt^ RIt^ RIHt ^ RIHtH	t	 ^ RI
HtHtHtHtHtHt ^ RIHt ]P&                  ! ]4      t]P,                  ! R4      tR R	 lt ! R
 R]4      tRtR R lt ! R R]4      t ! R R]4      tRtR R ltR R lt R R lt!R# )uu  Hızlı 2-yönlü çeviri yardımcıları — TR ↔ EN, prior-art akışı için.

Tasarım:
- Dil tespiti heuristik (TR karakterler) — LLM çağırmadan ucuz/hızlı
- Structured output zorla, kısa kalıp
- Hit çevirisi BATCH — tek istek, paralel hit'ler. 10x ucuz.

Sağlayıcı sınırı (bkz. app/services/llm/router.py):

- `translate_query` → **Claude**. Arama sorgusu buluşun anahtar kelimelerini
  taşır; hangi konuda çalışıldığını ifşa eder. Kamuya açık veri DEĞİLDİR.
- `translate_hits_to_tr` → **Gemini Flash**. Girdi Espacenet/Google Patents'ten
  dönen başlık+özet, yani zaten YAYIMLANMIŞ patent dokümanı. Toplu ve mekanik
  iş; tek PUBLIC görev. Gemini yoksa Claude'a düşer.

Hatalar yutulmaz değil ama None döner — çağıran kodun fallback davranışı
prior-art aramasını engellemeden devam etmek (orijinal dilde göster).
)annotationsN)APIError)	BaseModelField)LLMNotConfiguredErrorProvidergeminiget_anthropic_clientresolvesystem_block)record_usageu   [ıİşŞğĞçÇüÜöÖ]c                    V ^8  d   QhRRRR/# )   textstrreturn )formats   "Z/Users/zincirx/Documents/projelerim/patentyazar/backend-python/app/services/translation.py__annotate__r   ,   s      # #     c                T    V '       g   R# \         P                  V 4      '       d   R# R# )u   Çok kaba dil tespiti: 'tr' veya 'en'.

- Türkçe karakter varsa → 'tr'
- Aksi halde → 'en' (varsayılan; Almanca/Fransızca gibi diller de
  EN'e fall back; pratikte vekiller TR veya EN yazar)
entr)	_TR_CHARSsearch)r   s   &r   detect_languager   ,   s!     r   c                  :    ] tR t^?t$ Rt]! RRR7      tR]R&   RtR# )	_QueryTranslationu.   Bir patent arama sorgusunun TR↔EN çevirisi..u]   Hedef dile çevrilmiş sorgu — kısa, anahtar kelime ağırlıklı, patent terminolojisindedescriptionr   
translatedr   N)	__name__
__module____qualname____firstlineno____doc__r   r!   __annotations____static_attributes__r   r   r   r   r   ?   s    8"J r   r   u   Sen bir patent arama sorgusunu Türkçe ↔ İngilizce arasında çeviren bir
asistansın. Çeviride:

1. Patent terminolojisini koru (örn. "buluş" → "invention", "tertibat" →
   "apparatus", "yöntem" → "method").
2. Anlam değiştirme; kelime kelime değil ama anlam birebir.
3. Kısa tut — orijinalin uzunluğu kadar veya biraz daha az.
4. Marka/kısaltmaları olduğu gibi bırak (TLS, AI, IoT vs).
5. Hedef dilde yaygın patent araması terimlerini kullan.
6. Sadece çevrilmiş sorguyu döndür.
c               $    V ^8  d   QhRRRRRR/# )r   r   r   target_langr   z
str | Noner   )r   s   "r   r   r   W   s!     * * *# ** *r   c           	       "   V P                  4       '       g   R#  \        4       pTR8X  d   RMRpRT RT  R2p\        R4      p TP                  P                  TP                  TP                  \        TP                  \        4      R	R
RT/.\        R7      G Rj  xL
 p\        TP                  TP                  TP                  R7       TP                  pT'       d   TP                  P                  4       # R#   \         d     R# i ; i Lr  \          d"   p\"        P%                  RT4        Rp?R# Rp?i\&         d"   p\"        P%                  RT4        Rp?R# Rp?ii ; i5i)u   Bir patent arama sorgusunu hedef dile çevir.

target_lang: 'tr' veya 'en'

Returns:
    Çevrilmiş metin veya None (LLM yapılandırılmamışsa / hata)
Nr   u   İngilizceyeu
   Türkçeyeu$   Aşağıdaki patent arama sorgusunu u    çevir:

```
z
```translation.queryroleusercontentmodel
max_tokenssystemmessagesoutput_formatr1   usageendpointzQuery translation failed: %sz&Query translation unexpected error: %s)stripr	   r   r
   r4   parser1   r2   r   _QUERY_SYSTEMr   r   r7   taskparsed_outputr!   r   loggerwarning	Exception)	r   r*   client	directionuser_msgspecrespparsedexcs	   &&       r   translate_queryrH   W   sG     ::<<%' #."5<I5i[@QRVQWW\]H&'D__****
  

M:vy(;<+ + 

 

 	****YY	

 ,0+=+=,2v  &&(<<1 ! 

$  5s; ?Es   E,
C? E,AD DAD <E,=D >E,?D
E,DE,D E)D:4E,:E)E)E$E,$E))E,c                  r    ] tR t^t$ Rt]! RRR7      tR]R&   ]! RR7      tR	]R
&   ]! RR7      t	R	]R&   Rt
R# )_TranslatedHitu    Bir hit'in çevirilen alanları..u+   0-based sıra; hangi hit olduğunu belirlerr   intindex )defaultr   titleabstractr   N)r"   r#   r$   r%   r&   r   rL   r'   rO   rP   r(   r   r   r   rJ   rJ      s5    *s(UVE3Vr"E3""%Hc%r   rJ   c                  8    ] tR t^t$ Rt]! ]R7      tR]R&   Rt	R# )_BatchHitTranslationu$   Birden fazla hit'in toplu çevirisi.)default_factoryzlist[_TranslatedHit]itemsr   N)
r"   r#   r$   r%   r&   r   listrT   r'   r(   r   r   r   rR   rR      s    ."'"=E=r   rR   uO  Sen patent başlıkları ve özetlerini Türkçeye çeviren bir asistansın.

Kurallar:
1. Patent terminolojisini Türkçe karşılığıyla koru ("apparatus" → "tertibat",
   "method" → "yöntem", "system" → "sistem", "device" → "cihaz" vs).
2. Marka/kısaltmaları olduğu gibi bırak (örn. TLS, IoT, RFID).
3. Anlam birebir; gereksiz Türkçeleştirme yapma.
4. Resmi, teknik, vekil dilinde — günlük dil değil.
5. Boş/None gelirse boş string döndür.
6. Index numarasını koru; hit sırasını karıştırma.

Çıktı: structured JSON, açıklama veya markdown EKLEME.
c                    V ^8  d   QhRRRR/# )r   rT   #list[tuple[str | None, str | None]]r   *list[tuple[str | None, str | None]] | Noner   )r   s   "r   r   r      s      4A 4A.4A/4Ar   c           	       "   V '       g   . # . p\        V 4       Fv  w  pw  r4T;'       g    RP                  4       pT;'       g    RP                  4       p\        V4      R8  d   VR,          R,           pVP                  RV RV RV 24       Kx  	  RR	P	                  V4      ,           p\        R
4      pVP                  \        P                  J d   \        P                  ! 4       '       d    \        P                  ! VP                  \        V\        VP                  R7      G Rj  xL
 w  r\!        VP                  WP"                  R7       V	e   \%        V	\        V 4      4      # \&        P)                  R4       \-        V\        V 4      4      G Rj  xL
 #  Lr  \*         d!   p\&        P)                  RT4        Rp?LERp?ii ; i L45i)u  Birden fazla (title, abstract) çiftini Türkçeye çevir.

Args:
    items: [(title, abstract), ...] — None'lar boş string olarak çevrilir

Returns:
    Aynı uzunlukta liste, [(tr_title, tr_abstract), ...]
    None döner: LLM yapılandırılmamış veya hata.
rM   iX  :NiX  Nu   …z### Hit z
**Title:** z
**Abstract:** ud   Aşağıdaki patent hit'lerini Türkçeye çevir. Her hit için index, title ve abstract döndür.

z

translation.hits)r1   r3   r.   schemar2   Nr6   u>   Gemini hit translation parse edilemedi; Claude'a düşülüyoru:   Gemini hit translation failed (%s); Claude'a düşülüyor)	enumerater9   lenappendjoinr
   providerr   GOOGLEr   is_configuredgenerate_structuredr1   _HIT_SYSTEMrR   r2   r   r<   _by_original_orderr>   r?   r@   _translate_hits_anthropic)rT   numberedirO   rP   tarC   rD   rF   r7   rG   s   &           r   translate_hits_to_trrk      s     	 H )% 0E[[b!^^""$ q6C<$%A(1#]1#5EaSIJ !1	*,2KK,A	B 
 %&D
 }}'F,@,@,B,B	^"("<"<jj"+??# MF tzzK!)&#e*==NN[\
 +8SZ@@@  	^NNWY\]]	^ Ase   (GGB*G1:F  +F,?F  +G,F  GGGF   G+GGGGc               $    V ^8  d   QhRRRRRR/# )r   rF   rR   countrK   r   rW   r   )r   s   "r   r   r      s)     A A A),A(Ar   c                   V P                    Uu/ uF9  q"P                  VP                  ;'       g    RVP                  ;'       g    R3bK;  	  pp\	        V4       Uu. uF  qCP                  VR4      NK  	  up# u upi u upi )u|   Modelden dönen index'li sonuçları orijinal hit sırasına dizer.

LLM sırayı bozabilir; eksik index (None, None) olur.
N)NN)rT   rL   rO   rP   rangeget)rF   rm   xby_indexrh   s   &&   r   re   re      sk     IOU1!''//T1::+=+=>>HU38<@<aLLL)<@@ V@s   !A:A:A:A?c               $    V ^8  d   QhRRRRRR/# )r   rC   r   rm   rK   r   rX   r   )r   s   "r   r   r      s$          / r   c           	       "    \        4       p\        R4      pTP                  p TP                  P                  TR\        T\        4      RRRT /.\        R7      G Rj  xL
 p\        YEP                  RR	7       TP                  pT'       g   R# \        Ya4      #   \         d     R# i ; i LN  \         d"   p\        P                  R
T4        Rp?R# Rp?i\          d"   p\        P                  RT4        Rp?R# Rp?ii ; i5i)uJ   Hit çevirisinin Claude yolu — Gemini yoksa/başarısızsa kullanılır.Nr,   i  r-   r.   r/   r0   rZ   r6   zHit translation failed: %sz$Hit translation unexpected error: %s)r	   r   r
   r1   r4   r:   r   rd   rR   r   r7   r=   re   r   r>   r?   r@   )rC   rm   rA   fallback_specr1   rE   rF   rG   s   &&      r   rf   rf      s     %' /0ME__**{3vy(;<. + 
 
 	5

=OP.2.@.@!&00) ! 
  3S9 =sCs   D

B D
:B1  B/!/B1 D

B1 D
B,(D
+B,,D
/B1 1D<CD
D%D&D<D
DD
)"r&   
__future__r   loggingre	anthropicr   pydanticr   r   app.services.llmr   r   r   r	   r
   r   app.services.llm.usage_logr   	getLoggerr"   r>   compiler   r   r   r;   rH   rJ   rR   rd   rk   re   rf   r   r   r   <module>r      s   & #  	  %  4			8	$ JJ45	&	 *d&Y &>9 > 4AnA r   