
    j                         d Z ddlZddlmZmZ ddlmZ ddlmZmZm	Z	 dZ
dedefd	Zd
edeeef   deeeeef   f   de	eeef      deee	eeef      f   deeeeef   f   defdZy)u  자체 완결 HTML 리포트 — 표 중심, 프롬프트는 줄 발췌만.

측정 정의 라벨(metrics/attribute 의 정의와 일치):
- 발송량은 전수 합(외삽 없음), 단위는 '자'(code point).
- '정적' = 그 스텝 호출의 90% 이상에 실린 줄.
    N)datetimetimezone)Path)AnyDictLista  
body{font-family:'Apple SD Gothic Neo',sans-serif;margin:24px;
     background:#fafafa;color:#222}
h1{font-size:22px} h2{font-size:17px;margin-top:32px}
table{border-collapse:collapse;background:#fff;font-size:13px}
th,td{border:1px solid #ddd;padding:4px 8px;text-align:right}
th{background:#f0f0f0} td.l,th.l{text-align:left}
td.line{font-family:monospace;font-size:11px;max-width:680px;
        overflow-wrap:anywhere;text-align:left}
.warn{color:#b00} .dim{color:#888}
sreturnc                 >    t        j                  t        |             S )N)htmlescapestr)r	   s    R/Users/manta/Documents/Projects/TheRoad-I1/tools/opik_prompt_audit/audit/report.py_escr      s    ;;s1v    out_dirmetastepsdupscurvesattributionsc                 $   | j                  dd       t        |j                         d       }t        d |j	                         D              }g }|j                  d       |j                  d       |j                  dt         d	       |j                  d
       |j                  dt        |j                  d             dt        |j                  dd             d|j                  d|j                  d             d|ddt        j                  t        j                        j                  d       d       |j                  d       |j                  d      M|j                  d|j                  d      dd|j                  dd      dd|j                  dd      dd        |j                  d!      r*|j                  d"t        t        |d!                d       |j                  d#       |j                  d$       |D ]]  \  }	}
|r|
d%   |z  d&z  nd}|j                  d't        |	       d(|
d)    d(|
d*   dd(|
d+   dd(|
d,    d(|
d-    d(|
d%   dd(|d.d/       _ |j                  d0       |j                  d1       |j                  d2       |j                  d3       |d d4 D ]  }|j                  d5t        |d6   d d7        d8t        d9j                  |d:                d(|d;    d8t        d<j                  |d=   d d>              t!        |d=         d>kD  rd?nd d(|d@   ddA        |j                  d0       |j                  dB       |j                  dC       g }|j                         D ]a  \  }}|dDd  }|dE   dF   |d   dF   z
  }|dE   dG   j                  dHd      |d   dG   j                  dHd      z
  }|j                  ||||f       c |j#                  dI       |j                  dJ       |d dK D ]]  \  }}}}dLj                  dM |D              }|dkD  rdNnd}|j                  d't        |       d8t        |       dO| dP|dQd(|dQdA       _ |j                  d0       |j                  dR       |j                  dS       |d dT D ]  \  }	}
|j                  |	      }|s|j                  dUt        |	       dV       |j                  dW       t%        |dX   j                               d d> D ]'  \  }}|j                  d't        |       d(|ddA       ) |j                  dY|dZ   ddA       |j                  d0        | d[z  }|j'                  d\j                  |      d]^       |S )_NT)parentsexist_okc                     | d   d    S )N   total_chars )kvs    r   <lambda>zrender.<locals>.<lambda>&   s    A}1E0Er   )keyc              3   &   K   | ]	  }|d      yw)r   Nr   .0rs     r   	<genexpr>zrender.<locals>.<genexpr>'   s     9.Q- .s   z<meta charset="utf-8">u'   <title>Opik 프롬프트 감사</title>z<style>z</style>u+   <h1>Opik 역추적 프롬프트 감사</h1>u   <p class=dim>창: sincez ~ until u    · 호출 
call_counttrace_countu   건 · 총 발송(전수 합) ,u   자 · 생성 seconds)timespecz</p>u   <p class=dim>측정 정의: 단위는 자(code point, wire byte·token 아님) · <b>호출=Opik span 1건</b>(provider retry 미반영) · 정적=그 스텝 호출의 90% 이상에 실린 줄 · system/user 역할만 집계.</p>excluded_test_rowsu#   <p class=dim>시험 기록 제외: u   건 (수집 	raw_countr   u   건 → 집계 u   건)</p>caveatz<p class=dim>u;   <h2>① 스텝별 발송량 (전수 합, 내림차순)</h2>u   <table><tr><th class=l>스텝</th><th>호출</th><th>sys 평균</th><th>usr 평균</th><th>sys 정적</th><th>usr 정적</th><th>총량(자)</th><th>비중</th></tr>r   d   z<tr><td class=l>z	</td><td>calls
system_avguser_avgsystem_static_ratiouser_static_ratioz.1fz%</td></tr>z</table>u>   <h2>② 교차 스텝 중복 조각 (노출량 상위 25)</h2>u   <p class=dim>role 이 user 뿐인 행은 여러 스텝이 공유한 입력 데이터(시나리오 전문 등)일 수 있다 — 규칙 중복과 다른 부류이니 발췌를 보고 가를 것.</p>u   <table><tr><th class=l>문장(발췌)</th><th class=l>role</th><th>스텝 수</th><th class=l>스텝</th><th>노출량(자)</th></tr>   z<tr><td class=line>line   z</td><td class=l>+roles
step_countz, r      u    …exposure_charsz
</td></tr>uJ   <h2>③ 팩 버전 성장 추이 (표시 구간 첫→끝 Δ 큰 순)</h2>u   <p class=dim>bytes=버전 디렉토리 안 stem 파일 전체 합(schema 포함, os byte). system.md 열은 그 stem 단독. Δ는 아래 나열된 구간(최근 5버전)의 첫→끝 차이다.</p>bytesstemsz	system.md)reverseu   <table><tr><th class=l>module</th><th class=l>버전(월일): 합계</th><th>구간 Δ(합계)</th><th>구간 Δ(system.md)</th></tr>   u    → c              3   L   K   | ]  }d |d    d|d   dd  d|d   d  y	w)
vversion(ts      z): rB   r,   Nr   r#   s     r   r&   zrender.<locals>.<genexpr>t   s?       )~Qqwq|nC'
1~>s   "$z class=warnz</td><td>z+,uH   <h2>④ 스텝별 정적분의 팩 귀속 (발송량 상위 스텝)</h2>u   <p class=dim>한계: 현재 checkout 최신 팩만 색인(당시 활성판·오버레이 미반영) · exact-line 일치 · 같은 줄이 여러 팩에 있으면 정렬상 첫 파일로 귀속. 40자 미만 줄은 귀속 대상 밖.</p>rL   z<h3 style='font-size:14px'>z</h3>uS   <table><tr><th class=l>팩 파일(module/version/stem)</th><th>정적 자</th></tr>
pack_bytesuO   <tr><td class='l dim'>팩 색인 밖(코드 내장·조립 산문 등)</td><td>unmatched_byteszreport.html
zutf-8)encoding)mkdirsorteditemssumvaluesappendCSSr   getr   nowr   utc	isoformatr   joinlensortlist
write_text)r   r   r   r   r   r   rowsgrandpartsstepr%   sharedgrownmodulerstaildelta	sys_deltaseqclsattsrcbouts                            r   renderrt      s    MM$M.%++-%EFD9%,,.99EE	LL)*	LL:;	LL73%x()	LL>?	LL
T$((7"345S"%&
'{dhh|TXXVcMd6e5f g&&+AYn<<%///C
DD	JK
 
LL	YZ xx$%11xx,-a0 1xxQ/2/xxa(+85	6
 xx}T#d8n*=%>$?tDE	LLNO	LL	34 a27- 5(3.QtDzl)AgJ< @\?1%Yq}Q.? @*+, -()* +]#A&ic{+	G	H  
LL	LLQR	LL	+, 
LL	QR #2Y!$qy#"7!8 97 456 7\?# $		!G*Ra. 9:;QwZ1,v"5 6%&q)5	6  
LL	LL]^	LL	=> Elln
"#wR!DGG$44"Xg&**;:Aww'++K;<	eY56 % 
JJtJ	LL	LM +0*&y&$ll    %qymbtF|n,=d3i[se1U2Ji	"~ZI	J +5 
LL	LL[\	LL	UV 8at$24:,eDE'	( 3|,2245bq9FCLL"49+Yqe:FH : 	-.q1=	> 	Z    M
!CNN499U#gN6Jr   )__doc__r   r   r   pathlibr   typingr   r   r   rX   objectr   r   rt   r   r   r   <module>ry      s     '  " "
F s ww
sCx.w T#s(^#$w tCH~
	w
 d4S>**+w sDcN*+w 
wr   