
    Ni                        d Z ddlmZ ddlZddlmZmZ ddlmZ 	 ddlZ	dZ
ddlmZ  ed	      Z ed
      ZddZddZddZddZdddZy# e$ r dZ	dZ
Y 7w xY w)u>   engine_v2/cost_tracker.py — JSONL append-only 비용 추적.    )annotationsN)datetimetimezone)PathTF)EngineResultz/home/jay/workspace/memoryz-/home/jay/workspace/config/engine_budget.yamlc                     t        j                  t        j                        } d| j	                  d       d}t
        |z  S )u   월별 파일 경로 반환.engine_usage_%Y-%m.jsonl)r   nowr   utcstrftime_LOG_DIR)r   filenames     E/home/jay/workspace/services/multimodel-bot/engine_v2/cost_tracker.py_get_log_pathr      s7    
,,x||
$Cs||G45V<Hh    c                *   t        j                  t        j                        j	                         | j
                  | j                  | j                  |t        | j                        | j                  | j                  | j                  t        |d      | j                  d}t               }|j                   j#                  dd       t%        |dd      5 }|j'                  t)        j*                  |d	      d
z          ddd       y# 1 sw Y   yxY w)u    사용량 기록 (JSONL append).   )tstask_idstepengineprompt_charsoutput_chars	token_estfallback_usedflagged_countduration_secerrorT)parentsexist_okautf-8encodingF)ensure_ascii
N)r   r   r   r   	isoformatr   r   r   lencontentr   r   r   roundr    r   parentmkdiropenwritejsondumps)resultr   r   entrylog_pathfs         r   	log_usager7      s     ll8<<(224>>--$FNN+%%----lA.E HOO$6	hg	. >!	

5u5<=> > >s   *D		Dc                 X   t         j                         si S 	 t        r7t        1t	        t         dd      5 } t        j
                  |       }ddd       ni S t        t              si S |j                  di       }t        |t              r|S i S # 1 sw Y   AxY w# t        $ r i cY S w xY w)u   config/engine_budget.yaml을 읽어 daily_limits를 반환.

    yaml 파일이 없거나 읽기 실패 시 빈 dict 반환 (한도 무제한).
    Nrr$   r%   daily_limits)
_BUDGET_PATHexists_YAML_AVAILABLE	_yaml_modr/   	safe_load
isinstancedictget	Exception)r6   datalimitss      r   _load_budgetrF   3   s    
  	y4lC': .a **1-. . I$%I."-#FD1v9r9. .  	s:   B B
B B )#B B BB B)(B)c                |    t               }|sy|j                         }t        |t              sy|j                  d      }t        |t              syt        j                  t        j                        }|j                  d      |j                  d      }t        |      }t         fd|D              }||k\  S )u   오늘의 엔진 호출 수가 일일 한도를 초과했는지 확인.

    Args:
        engine: 확인할 엔진 이름 ("claude", "gemini", "codex" 등)

    Returns:
        True이면 한도 초과 (차단 필요), False이면 허용.
    F	max_callsz%Y-%m-%dr
   c              3     K   | ]M  }|j                  d       k(  r7t        |j                  d      t              r|d   j                        rd O yw)r   r      N)rB   r@   str
startswith).0r4   r   	today_strs     r   	<genexpr>zcheck_budget.<locals>.<genexpr>d   sN      99X&(uyy,$K""9-	 	
s   AA)rF   rB   r@   rA   intr   r   r   r   r   
read_usagesum)	r   r:   engine_limitrH   r   
year_monthentries
call_countrN   s	   `       @r   check_budgetrW   I   s      >L##F+LlD)  -Ii% ,,x||
$CZ(Ig&J$G  J ""r   c                z   | 4t        j                  t        j                        }|j	                  d      } t
        d|  dz  }|j                         sg S g }t        |dd      5 }|D ]9  }|j                         }|s|j                  t        j                  |             ; 	 ddd       |S # 1 sw Y   |S xY w)u   사용량 읽기.Nr
   r	   r   r9   r$   r%   )r   r   r   r   r   r   r<   r/   stripappendr1   loads)rT   r   r5   rU   r6   lines         r   rQ   rQ   o   s    ll8<<(\\'*
M*V<<H??	')G	hg	. 1! 	1D::<Dtzz$/0	11
 N1
 Ns   &B0?&B00B:)returnr   )r3   r   r   rP   r   floatr]   None)r]   zdict[str, object])r   rK   r]   bool)N)rT   z
str | Noner]   zlist[dict[str, object]])__doc__
__future__r   r1   r   r   pathlibr   yamlr>   r=   ImportErrorengine_v2.engine_resultr   r   r;   r   r7   rF   rW   rQ    r   r   <module>rh      sr    D "  ' O
 1,-CD>*,##LE  IOs   A 	AA