
    1j#                       d Z ddlmZ ddlZej
                  j                  dd       ddlmZ	  e	d      Z
ddl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 ddlmZ ddlZej*                  j-                  d	      Zej*                  j-                  d
      ZdZ ed      Z ed      ZdZddZdddZddZd Z e!dk(  re
jE                  d        e         yy)a  KAR-Reviewer: bewertet KAR-Issues per LLM auf 4 Achsen.
KAR-240 Reviewer-Subagent-Loop.

Klassifiziert jeden Issue in:
- verdict: implement | brain_only | spike | reject
- aria_lever: high | medium | low (wie sehr verbessert es Aria selbst)
- effort: XS | S | M | L
- quick_win: true|false (klein + hoher Hebel + klare DoD)

Output: 02-Wissen/kar-review-{date}.md mit Top-10 Quick-Wins.

Run:
  python3 aria-kar-reviewer.py --filter "video|adopt" --limit 100
    )annotationsNz/root/aria/lib)
get_loggerzaria-kar-reviewer)datetimetimezone)PathLINEAR_API_KEYANTHROPIC_API_KEYzhttps://api.linear.app/graphqlz/root/aria/brain/02-Wissenz%/root/aria/brain/youtube/.config.yamlzDu bist ein Aria-KAR-Reviewer. Klassifiziere Linear-Issues auf 4 Achsen. Antworte ausschliesslich als JSON mit den Feldern: verdict, aria_lever, effort, quick_win, reasoning.c                    t         j                  j                  d      } | r| S 	 ddl}|j	                  t
        j                  d            }|j                  di       j                  d      }|r|S 	 y# t        $ r Y yw xY w)	u   Liest Modell aus ARIA_KAR_REVIEWER_MODEL env, dann .config.yaml models.kar_reviewer_model,
    dann fällt zurück auf claude-haiku-4-5-20251001.ARIA_KAR_REVIEWER_MODELr   Nzutf-8)encodingmodelskar_reviewer_modelzclaude-haiku-4-5-20251001)osenvirongetyaml	safe_load_ARIA_CONFIG_PATH	read_text	Exception)env_val_yamlcfgmodels       '/root/aria/scripts/aria-kar-reviewer.py_get_kar_reviewer_modelr   )   s     jjnn67Goo/9979KL"%))*>?L  '  &s   AA5 5	B Bc                @   t        j                  t        ddidt        i      j	                         }t        d |d   d   d   D              }d	}t        j                  t        |d
|iddt        i      j	                         }|d   d   d   d   }|D cg c]  }|d   d   dvs| }}| rbt        j                  | t        j                        }|D cg c]3  }|j                  |d         s|d   s|j                  |d         s2|5 }}|d | S c c}w c c}w )Nqueryz$query { teams { nodes { id key } } }Authorization)jsonheadersc              3  8   K   | ]  }|d    dk(  s|d     yw)keyKARidN ).0ts     r   	<genexpr>z"fetch_open_kars.<locals>.<genexpr><   s     Uq1U8uCT1T7Us   
datateamsnodeszquery($tid: String!) { team(id: $tid) { issues(first: 250) {
        nodes { identifier title description priority state { name type } createdAt }
    }}}tid)r   	variablesteamissuesstatetype)	completedcanceledtitledescription)
requestspostURLAPI_KEYr    nextrecompile
IGNORECASEsearch)filter_regexlimitrteam_idqr0   irxs           r   fetch_open_karsrG   :   s&   c*P Q\kmt[uv{{}AUAfIg$6w$?UUG	A 	c!5':J KVegnUopuuwAvYvx(1FWA1W:f#5=V#VaWFWZZbmm4#sryy7'<=AQVXV_V_`abo`pVq!ss&5>	 X ts   D'DD6DDc           
     N   t         sddddddS d| d    d	| d
    d| d    d| j                  d      xs ddd  d	}	 t        j                  dt         dddd|ddt        ddidgd|dgdd !      }|j                         }|d"   d#   d   }t        j                  d$|t        j                        }|r$t        j                  |j                  d#            S ddddd%dS # t        $ r9}t        j                  d&t        |      | d   '       ddddd(| dcY d}~S d}~ww xY w))zOSend issue to Claude for fast classification. model is resolved once by caller.	implementmediumMF
no_api_key)verdict
aria_levereffort	quick_win	reasoninga>  Klassifiziere dieses Linear-KAR-Issue auf 4 Achsen.

Hinweise:
- "implement" = direkt umsetzbar, klare DoD, gibt Aria/Kadi/Tools-Verbesserung
- "brain_only" = Wissen aufschreiben/lesen reicht, keine Code-Aenderung notwendig
- "spike" = brauche erst 2-4h Recherche/Architektur-Decision bevor Code
- "reject" = nicht relevant, duplikat, oder schon implizit done
- aria_lever = wie viel verbessert es Aria SELBST (nicht nur Knowledge)
- effort: XS=<30min S=30-90min M=1.5-4h L=>4h
- quick_win = effort in (XS,S) UND aria_lever in (high,medium) UND verdict=implement

Issue ID: 
identifierz
Title: r5   z
Priority: Ppriorityz
Description:
r6    Ni  z

Antworte ausschliesslich als JSON:
{
  "verdict": "implement" | "brain_only" | "spike" | "reject",
  "aria_lever": "high" | "medium" | "low",
  "effort": "XS" | "S" | "M" | "L",
  "quick_win": true | false,
  "reasoning": "ein satz auf deutsch"
}z%https://api.anthropic.com/v1/messagesz
2023-06-01zprompt-caching-2024-07-31zapplication/json)z	x-api-keyzanthropic-versionzanthropic-betazcontent-type   textr2   	ephemeral)r2   rV   cache_controluser)rolecontent)r   
max_tokenssystemmessages   )r!   r    timeoutr[   r   z
\{[^{}]+\}parse_errorclaude_call_failed)errissuezerr: )r	   r   r7   r8   _KAR_REVIEWER_SYSTEM_PROMPTr    r<   r?   DOTALLloadsgroupr   _logerrorstr)rd   r   user_promptrB   r*   rV   mes           r   review_with_claudero   I   s   &h#\ap|}} 
  g * ))M b%4( ) 	*K2 }MM3.%1"= 2	 ! !' ;*0+)> '-EF )
, vvxIq!&)IImT2995::aggaj))&h#\ap}~~ }

'SV5;N
O&h#\arwxywzp{||}s$   BC" C" "	D$+.DD$D$c                    t        j                         } | j                  dd       | j                  dt        d       | j                  dt        dd	
       | j	                         }t               }t        j                  d|j                  |j                  |j                  |       t        |j                  |j                        }d }|D cg c]  } ||d         |j                  k\  s| }}t        dt        |       d|j                   dd       g }t        |d      D ]s  \  }}|dz  dk(  rt        d| dt        |       d       t        ||      }|d   |d<   |d   |d<   |d   |d<   |j!                  |       t#        j$                  d       u ddlm}	  |	d |D              }
|D cg c]
  }|d   s	| }}|D cg c]  }|d   dk(  s|d    d!k(  s| }}t+        j,                  t.        j0                        j3                  d"      }t4        d#| d$z  }d%d&| d'd(d)| d*d+d%d,d-| d,d.t        |       d/|j                   dd,d0d,g}|
j7                         D ]  \  }}|j!                  d1| d2|         |j9                  g d3       t;        |d4 5      D ]E  }|j!                  d6|d    d7|d8    d|d    d9|d   d d:         |j!                  d;|d<           G |j9                  g d=       t;        |d> 5      D ]?  }|j!                  d6|d    d7|d8    d9|d   d d:         |j!                  d;|d<           A |j9                  g d?       |D ]A  }|d   rd@nd,}|j!                  dA|d    dB|d     dC|d    dC|d8    dC| dC|d   d dD  dE       C |j=                  dFj?                  |             t        dGt        |       dHt        |       dItA        |
              t        dJ|        t        j                  dKt        |      t        |      tA        |
      L       y c c}w c c}w c c}w )MNz--filterz!Regex filter on title/description)helpz--limitrU   )r2   defaultz--min-kar-idi  z!Only review KAR-N where N >= this)r2   rr   rq   reviewer_start)filterrA   min_karr   c                j    t        j                  d|       }|rt        |j                  d            S dS )Nz	KAR-(\d+)   r   )r<   matchintrh   )identrm   s     r   kar_numzmain.<locals>.kar_num   s+    HH\5)"#s1771:**    rR   z[reviewer] z KARs to review (filtered min=)T)flushrw   
   r   /r5   rS   g      ?)Counterc              3  &   K   | ]	  }|d      yw)rM   Nr&   )r'   rB   s     r   r)   zmain.<locals>.<genexpr>   s     6q|6s   rP   rN   highrM   rI   z%Y-%m-%dzkar-review-z.mdz---ztitle: KAR-Review ztype: auditz4tags: [kar-review, aria-improvement, prioritization]zdate: zstatus: aktivzlinear: KAR-240rT   u   # KAR-Reviewer Output — z**Reviewed:** z KARs (min KAR-ID: z## Verdict-Aggregatz- **z**: )rT   zL## Top-Quick-Wins (effort XS/S + aria_lever high/medium + verdict implement)rT   c                D    | d   t        | d   dk(  rd       fS d       fS )NrO   rN   r   ab)ordxs    r   <lambda>zmain.<locals>.<lambda>   s1    q{S,[aHa=k<k.l gj=k<k.l r|   )r#   z- `z` [rO   z] A   u     → rQ   )rT   z7## High-Aria-Lever (implement, lever=high, alle Effort)rT   c                    | d   S )NrO   r&   r   s    r   r   zmain.<locals>.<lambda>   s
    ak r|   )rT   z## Full ReviewrT   z/| KAR | Verdict | Lever | Effort | QW | Title |z|---|---|---|---|---|---|u   ✓z| `z` | z | 2   z |
u   [reviewer] DONE — quick_wins=z high_lever=z
 verdicts=z[reviewer] Report: reviewer_done)
quick_wins
high_leververdicts)!argparseArgumentParseradd_argumentry   
parse_argsr   ri   eventrt   rA   
min_kar_idrG   printlen	enumeratero   appendtimesleepcollectionsr   r   nowr   utcstrftimeOUT_DIRmost_commonextendsorted
write_textjoindict)apargsr   r0   r{   rE   reviewednrM   r   r   rB   r   r   dateout_pathlinesvqws                      r   mainr      s   		 	 	"BOOJ%HOIOOICO5OONc@cOd==?D#%EJJ4::tfkJlT[[$**5F+  OA71\?#;t#NaOFO	KF}$B4??BSST
U]abH&!$ 1r6Q;Ks!CK=1>$Q. !,W:
m
 

3 $6X66H%8;!8J8%c<F)Bq|WbGb!cJc <<%..z:D;tfC00H

TF#

>





$TF+

X':4??:K1M

E" $$& (1tA3d1#&'(	LL  
 J$lm 0s1\?+3q{m1Q|_<MRPQRYPZ[^\^P_O`abvan-./0 
LL  
 J$9: 0s1\?+3q{m2aj"o=NOPvan-./0 
LL    AnU"s1\?+4)~S<@QQTUVW_U`Taadegdhhklmnulvwzxzl{k||~  	AA 		%()	+C
O+<LZHYYcdhiqdrcs
tu	z
*+JJ3z?s:aefnaoJpQ P" 9cs*   Q0Q:
Q
Q
QQ&Q__main__script_start)returnrk   )NrU   )r@   z
str | NonerA   ry   r   z
list[dict])rd   r   r   rk   r   r   )#__doc__
__future__r   sys_syspathinsertaria_loggingr   _get_loggerri   r   r    r   r<   r   r   r   pathlibr   r7   r   r   r:   r	   r9   r   r   re   r   rG   ro   r   __name__r   r&   r|   r   <module>r      s    #  		  $ % 2&' ( ( ( '  
**..)
*JJNN#67 &
+
,@A 9 '"=}@Vqr zJJ~F r|   