+
    yjB                      a  0 t $ R t^ RIHt ^ RIt^ RIt^ RIt^ RIHt ^ RI	H
t
Ht ^ RIHt ^ RIHt ^ RIHtHtHt ^ RIHt ^ R	IHtHt ]P2                  ! ]4      t]! R
4      P8                  tRt ! R R]4      t R R lt!]PD                  RRR.3R. ROO3RRR.3R. RPO3RRR.3.]PF                  RRR.3RRR .3R!R"R#.3R$. RQO3RR%R&.3RR'R(.3.]PH                  R)RR.3R*RR .3R+. RRO3R,. RSO3R-R.R/.3./t%R0]&R1&   ]PD                  R2R30]PF                  RR20]PH                  RR20/t'R4]&R5&   R6 R7 lt(R8 R9 lt)R:t*R;t+R<t,]PD                  ]*]PF                  ]+]PH                  ],/t-R=]&R>&   ]PD                  R?.]PF                  R@RA.]PH                  RB./t.RC]&RD&   RE RF lt/RG RH lt0 ! RI RJ]
4      t1 ! RK RL]
4      t2]PD                  3RM RN llt3R# )Tu  İtiraz / şekli inceleme yazısı ayıklama mantığı.

PDF'ten metin çıkarır (pypdf) ve Claude Haiku ile patent ofisinin tespit
ettiği eksiklik maddelerini yapılandırılmış biçimde ayıklar. Üç ofis
desteklenir; her birinin sistem prompt'u, kural anahtar tablosu ve başvuru
numarası regex'i ayrıdır:

- TR (TürkPatent): "Şekli İnceleme" yazısı, formality.rules TR kuralları
- EP (EPO): Communication under Rule 57/58 EPC, formality.epo kuralları
- US (USPTO): Notice to File Missing Parts / Office Action (formal),
  formality.uspto kuralları

Çıkarılan her madde, mümkünse `formality` modülünün kural kimlikleriyle
eşleştirilir — "itiraz → düzeltme → değişiklik evrakı" döngüsünün halkasıdır.
)annotationsN)APIError)	BaseModelField)	PdfReader)Jurisdiction)LLMNotConfiguredErrorget_anthropic_clientresolve)record_usage)ObjectionItemObjectionReportzobjection.extracti.  c                      ] tR t^*tRtRtR# )ObjectionExtractionErroruG   PDF okunamadığında veya metin çıkarılamadığında fırlatılır. N)__name__
__module____qualname____firstlineno____doc____static_attributes__r       b/Users/zincirx/Documents/projelerim/patentyazar/backend-python/app/services/objection/extractor.pyr   r   *   s    Qr   r   c                    V ^8  d   QhRRRR/# )   	pdf_bytesbytesreturnstrr   )formats   "r   __annotate__r    .   s      e  r   c                    \        \        P                  ! V 4      4      p. pTP
                   F-  p TP                  TP                  4       ;'       g    R4       K/  	  RP                  T4      P                  4       pT'       g   \	        R4      hT#   \         d   p\	        RT 24      ThRp?ii ; i  \         d     K  i ; i)u   PDF baytlarından düz metin çıkarır.

Metin tabanlı PDF'ler için çalışır. Taranmış (görüntü) PDF'lerde boş
veya çok az metin döner — bu durumda LLM katmanı da bir şey bulamaz.
u   PDF okunamadı: N 
uH   PDF'ten metin çıkarılamadı — belge taranmış görüntü olabilir.)
r   ioBytesIO	Exceptionr   pagesappendextract_textjoinstrip)r   readerexcpartspagetexts   &     r   extract_objection_textr1   .   s    2::i01 E	LL**,223 
 99U!!#D&V
 	
 K!  &se$
	  		s.   B !B6B6B3B..B36CCzclaims.no_subheadingsu   alt başlıkz
alt baslikzabstract.missing_titlezclaims.numbering_gap
numaralandzbirbirini izleyenzterms.foreign_phrasezclaims.multi_sentenceu
   tek cümlez	tek cumlezepo.abstract_missingzabstract is missingzno abstractzepo.claims_missingz	no claimszclaims are missingzepo.abstract_too_longabstract exceedszmore than 150 wordszepo.abstract_merit_languagezsub-heading
subheadingzsingle sentencezmore than one sentencezuspto.abstract_missingzuspto.claims_missingzuspto.abstract_too_longzuspto.abstract_prior_artzuspto.no_dependent_claimszdependent claimzno dependentz/dict[Jurisdiction, list[tuple[str, list[str]]]]_RULE_KEYWORDS_BY_JURISzclaims.numbering_startzabstract.too_longzdict[Jurisdiction, set[str]]_EXTRA_VALID_BY_JURISc                    V ^8  d   QhRRRR/# )r   jurisdictionr   r   zset[str]r   )r   s   "r   r    r       s     , ,, ,8 ,r   c                t    \         V ,           UUu0 uF  w  rVkK	  	  upp\        V ,          ,          # u uppi N)r5   r6   )r8   rid_s   &  r   _valid_rule_idsr=      s8    1,???l+, , s   4c               (    V ^8  d   QhRRRRRRRR/# )r   descriptionr   	llm_guessr8   r   r   r   )r   s   "r   r    r       s,      !$4@r   c                  a V'       d   V\        V4      9   d   V# V P                  4       o\        V,           FI  w  r4\        ;QJ d    V3R lV 4       F  '       g   K   RM	  RM! V3R lV 4       4      '       g   KG  Vu # 	  R# )u   Bir eksiklik açıklamasını ofisin kural kimliğine eşler.

Önce LLM'in önerisini doğrular; geçerli bir kimlikse onu kullanır.
Aksi halde ofisin anahtar kelime tablosuna düşer.
c              3  ,   <"   T F	  qS9   x  K  	  R # 5ir:   r   ).0kwlows   & r   	<genexpr>_match_rule.<locals>.<genexpr>   s     ,8RSy8s   TFr"   )r=   lowerr5   any)r?   r@   r8   rule_idkeywordsrE   s   &&&  @r   _match_rulerL      si     Y/,"??



C4\BB3,8,333,8,,,N C r   u'  Sen Türk patent başvurularının şekli inceleme uzmanısın. Görevin: TürkPatent'in (Türk Patent ve Marka Kurumu) gönderdiği bir şekli inceleme veya itiraz yazısının metnini alıp, Kurumun tespit ettiği eksiklik maddelerini yapılandırılmış biçimde çıkarmak.

ÇIKARILACAKLAR:
1. items — Kurumun tespit ettiği HER eksiklik ayrı bir madde. Yazıda genellikle tire (-) veya numara ile listelenir. Her madde için:
   - description: eksikliğin metni (Kurumun ifadesiyle, kısaltarak).
   - category: "istemler" | "tarifname" | "ozet" | "resimler" | "genel".
   - rule_id_guess: aşağıdaki listeden uygun olanı, emin değilsen boş bırak:
       claims.no_subheadings        (istemlerde alt başlık kullanılmış)
       abstract.missing_title       (özette buluş başlığı yok)
       claims.numbering_gap         (sayfa/istem numaralandırma hatası)
       claims.numbering_start       (numaralandırma 1'den başlamıyor)
       terms.foreign_phrase         (yabancı ifadenin Türkçe karşılığı yok)
       claims.multi_sentence        (istem tek cümle değil)
       abstract.too_long            (özet 150 kelimeyi aşıyor)
   - suggested_fix: eksikliğin nasıl giderileceğine dair tek cümlelik öneri.
2. deadline — Eksikliklerin giderilmesi için verilen süre (örn. "iki ay"). Yoksa boş.
3. application_number — Yazıdaki başvuru numarası (örn. "2026/005880").
4. letter_reference — Yazının sayı ve tarih bilgisi.

KURALLAR:
- Yalnızca yazıda AÇIKÇA belirtilen eksiklikleri çıkar; yorum ekleme.
- Genel bilgilendirme cümlelerini (yıllık ücret, yayım, tebligat vb.) madde olarak ALMA — yalnızca giderilmesi gereken şekli eksiklikleri al.
- Eksiklik yoksa items boş liste döner.

Çıktı yalnızca structured JSON olarak döner; ek açıklama yapma.
uu  You are an expert in European Patent Office (EPO) formal examination. Your task: read a formal communication issued by the EPO (e.g. under Rule 57/58 EPC, noting missing parts or formal defects) and extract each defect in a structured form.

EXTRACT:
1. items — each defect raised by the EPO is a separate item. They are typically listed by bullet, dash or numbering. For each:
   - description: the defect as stated by the EPO, concisely.
   - category: "claims" | "description" | "abstract" | "drawings" | "general".
   - rule_id_guess: one of the following if appropriate, else leave empty:
       epo.abstract_missing            (no abstract is filed)
       epo.claims_missing              (no claims are filed)
       epo.abstract_too_long           (abstract exceeds 150 words)
       epo.abstract_merit_language     (abstract makes merit/comparison claims)
       claims.no_subheadings           (claims use forbidden sub-headings)
       claims.multi_sentence           (a claim is not a single sentence)
       claims.numbering_gap            (claims/pages not consecutively numbered)
       claims.numbering_start          (claim numbering does not start at 1)
   - suggested_fix: one-sentence remedy suggestion.
2. deadline — period given to remedy the deficiencies (e.g. "two months"). Empty if not stated.
3. application_number — the EP application number (e.g. "EP 21 123 456.7" or "21123456.7").
4. letter_reference — the communication reference and/or date.

RULES:
- Extract only deficiencies the EPO EXPLICITLY raises; do not add interpretation.
- Skip purely informational paragraphs (renewal fees, publication, service of documents, etc.) — only items that the applicant must remedy.
- If there are no deficiencies, items is an empty list.
- Output language: match the communication's language (English/French/German).

Output is structured JSON only; no additional commentary.
u  You are an expert in USPTO formal examination. Your task: read a USPTO formal Office Action (e.g. Notice to File Missing Parts, Notice of Incomplete Application, or formality-related rejection) and extract each deficiency in a structured form.

EXTRACT:
1. items — each deficiency raised by the USPTO is a separate item. They are typically listed by bullet or numbering. For each:
   - description: the deficiency as stated, concisely.
   - category: "claims" | "specification" | "abstract" | "drawings" | "general".
   - rule_id_guess: one of the following if appropriate, else leave empty:
       uspto.abstract_missing          (no Abstract of the Disclosure)
       uspto.claims_missing            (no claims; 37 CFR 1.75)
       uspto.abstract_too_long         (abstract exceeds 150 words; 37 CFR 1.72(b))
       uspto.abstract_prior_art        (abstract compares with prior art; MPEP 608.01(b))
       uspto.no_dependent_claims       (no dependent claims; 37 CFR 1.75(c))
       claims.numbering_gap            (claims/pages not consecutively numbered)
       claims.numbering_start          (claim numbering does not start at 1)
       claims.multi_sentence           (a claim is not a single sentence)
   - suggested_fix: one-sentence remedy suggestion.
2. deadline — period given to reply (e.g. "two months from the mailing date"). Empty if not stated.
3. application_number — the U.S. application number (e.g. "17/123,456" or "17/123456").
4. letter_reference — the Office Action mailing date and/or paper number.

RULES:
- Extract only deficiencies the USPTO EXPLICITLY raises; do not add interpretation.
- Skip purely informational paragraphs (filing receipt, fee schedule, publication, etc.) — only items the applicant must remedy.
- If there are no deficiencies, items is an empty list.
- Output language: match the Office Action (English).

Output is structured JSON only; no additional commentary.
zdict[Jurisdiction, str]_SYSTEM_PROMPTSz\b(20\d{2}/\d{4,6})\bz)\b(EP\s?\d{2}\s?\d{3}\s?\d{3}(?:\.\d)?)\bz\b(\d{8}\.\d)\bz\b(\d{2}/\d{3},?\d{3})\bzdict[Jurisdiction, list[str]]_APP_NUMBER_PATTERNSc               $    V ^8  d   QhRRRRRR/# r   r0   r   r8   r   r   r   )r   s   "r   r    r    %  s!      c  # r   c                    \         V,           F4  p\        P                  ! W 4      pV'       g   K#  VP                  ^4      u # 	  R# )u?   Metinden ofisin başvuru numarası biçimini regex ile çıkar.r"   )rN   researchgroup)r0   r8   patternms   &&  r   _extract_app_numberrW   %  s:    '55IIg$1771: 6 r   c               $    V ^8  d   QhRRRRRR/# rP   r   )r   s   "r   r    r    .  s!       < C r   c                    V P                  4       R\         pV\        P                  8X  d
   RV,           # V\        P                  8X  d
   RV,           # RV,           # )u>   LLM'e gönderilen kullanıcı mesajını ofise göre hazırla.Nus   Aşağıdaki TürkPatent şekli inceleme/itiraz yazısını incele ve tespit edilen eksiklik maddelerini çıkar:

zQRead the following EPO formal communication and extract each deficiency raised:

zSRead the following USPTO formal Office Action and extract each deficiency raised:

)r+   
_MAX_CHARSr   TREP)r0   r8   excerpts   && r   _user_messager^   .  se    jjl;J'G|&>@GH	
 |&%'./	

	!#*	+r   c                      ] tR tRt$ Rt]! RRR7      tR]R&   ]! RR	7      tR]R
&   ]! RRR7      t	R]R&   ]! RR	7      t
R]R&   RtR# )_RawObjectionItemiA  u#   Haiku'nun ayıkladığı ham madde..zEksiklik metni)r?   r   r?   geneldefaultcategoryr"   u(   Tahmini şekli tarayıcı kural kimliği)rc   r?   rule_id_guesssuggested_fixr   N)r   r   r   r   r   r   r?   __annotations__rd   re   rf   r   r   r   r   r`   r`   A  sN    -S.>?K?'*Hc* JM3  r*M3*r   r`   c                      ] tR tRt$ Rt]! ]^R7      tR]R&   ]! RR7      t	R]R	&   ]! RR7      t
R]R
&   ]! RR7      tR]R&   RtR# )_RawObjectionReportiL  u%   Haiku'nun structured output şeması.)default_factory
max_lengthzlist[_RawObjectionItem]itemsr"   rb   r   deadlineapplication_numberletter_referencer   N)r   r   r   r   r   r   listrl   rg   rm   rn   ro   r   r   r   r   ri   ri   L  sF    /%*4B%OE"O"%Hc%#B//!"-c-r   ri   c               $    V ^8  d   QhRRRRRR/# )r   pdf_textr   r8   r   r   r   r   )r   s   "r   r    r    U  s+     H HHH Hr   c                H  "   \        4       p\        W4      p \        4       p\
        T,          p\        Y4      p TP                  P                  \        RRRRTRRR//.RRRT/.\        R	7      G R
j  xL
 p\        \        TP                  RTP                  P                  4        2R7       TP                  pRTn        TP*                  Tn        TP,                  Tn        TP                  ;'       g    TTn        TP.                   Fr  p
TP.                  P1                  \3        T
P4                  T
P6                  ;'       g    R\9        T
P4                  T
P:                  T4      T
P<                  R7      4       Kt  	  \?        TP.                  4      Tn         T#   \         d    Y2n        Tu # i ; i ELC  \          d)   p	\"        P%                  RT	4       Y2n        Tu R
p	?	# R
p	?	i\&         d)   p	\"        P%                  RT	4       Y2n        Tu R
p	?	# R
p	?	ii ; i5i)u-  İtiraz yazısı metninden eksiklik maddelerini ayıklar.

Ofise (`jurisdiction`) göre sistem prompt'u, kural anahtar tablosu ve
başvuru numarası regex'i seçilir. LLM yapılandırılmamışsa (API key yok)
`extracted=False` ile boş rapor döner — çağıran taraf kullanıcıyı
bilgilendirir.
i   typer0   cache_control	ephemeralroleusercontent)model
max_tokenssystemmessagesoutput_formatNzobjection.parse.)rz   usageendpointu-   Objection parse — Anthropic API hatası: %su3   Objection parse — yanıt ayrıştırılamadı: %sTra   )r?   rd   matched_rule_idrf   )!r   rW   r	   r   rn   rM   r^   r}   parse_MODELri   r   r   valuerH   parsed_outputr   _logwarningr&   	extractedrm   ro   rl   r(   r   r?   rd   rL   re   rf   len
item_count)rr   r8   reportfallback_app_noclientsystem_promptuser_messageresprawr-   items   &&         r   parse_objectionr   U  s     F)(AO%'
 $L1M 8L__**  FM#fk%: vy,?@- + 
 
 	**'(:(:(@(@(B'CD	

 $(#5#5 FllFO!22F # 6 6 I I/F		 ,,11' +$$d&8&8,! #00		
  FLL)FMq ! $3!
*  DcJ$3! JCP$3!	s   H"
F H"9F; 5F86AF; =;H"9AH"AH"F52H"4F55H"8F; ;HG)#H$H")H6H7HHH"HH")u   özet başlığızozet basligiu   özet sayfası)u   yabancı dilzyabanci dilu   türkçe karşıl)zalleged meritsmeritzcomparison with the prior art)zexceeds 150 wordsr3   z	150 words)comparez	prior artmerits)4__conditional_annotations__r   
__future__r   r$   loggingrR   	anthropicr   pydanticr   r   pypdfr   app.services.formality.modelsr   app.services.llmr   r	   r
   app.services.llm.usage_logr   app.services.objection.modelsr   r   	getLoggerr   r   rz   r   rZ   r&   r   r1   r[   r\   USr5   rg   r6   r=   rL   _SYSTEM_PROMPT_TR_SYSTEM_PROMPT_EP_SYSTEM_PROMPT_USrM   rN   rW   r^   r`   ri   r   )r   s   @r   <module>r      s    # 	  	  %  6 Q Q 3 H" 
$	%	+	+ 
Ry RF OO	 ><"@A$C	
 
 ,0C!DE"@	
 
!<"=> OO	"7!GH	-ABC#!67	

 *H	

 $L)	
 
!#46N"OP" OO	!$9=#IJ	+/C!DE%B	

 '.	

 (/	
?/L H /f OO.0CDOO,.FGOO,.FG7 3 ,* B" H" J OO&OO&OO&,(  OO./OO4
 OO12
7 3 
&+	 +.) . ".H Hr   