
    Ti-              	          d Z ddlZddlZddlZddlmZ ddlmZ ddlmZ dZ	e	ej                  vrej                  j                  de	       dZ ed      Zd	Z ed
      Z ed      Zd dedededdfdZdedee   fdZd Zdee   dedefdZdedefdZdededdfdZdeddfdZdeddfdZd!dZedk(  r ej@                   e              yy)"u   
conversation_memory.py의 generate_insight() 기능 통합 테스트 러너.
실제 대화 데이터를 로드하고 정리 기능을 실행하여 결과물을 확인한다.
    N)deque)datetime)Pathz+/home/jay/workspace/services/multimodel-boti zA/home/jay/workspace/memory/groupchat/test-import-2026-03-15.jsonlz$/home/jay/workspace/memory/groupchatzD/home/jay/workspace/memory/groupchat/insights/test-insight-result.mdz./home/jay/workspace/memory/groupchat/summarieslabelokdetailreturnc                 J    |rdnd}d| d|  }|r|d| z  }t        |       y )NOKFAIL[z]     — )print)r   r   r   statusmsgs        H/home/jay/workspace/services/multimodel-bot/tools/test_insight_runner.pystepr   %   s8    TVFfXRw
Cvh	#J    pathc           	         g }| j                         st        ddd|         |S t        | dd      5 }t        |d      D ]=  \  }}|j	                         }|s	 |j                  t        j                  |             ? 	 ddd       t        dt        |      | j                   dt        |       d       |S # t        j                  $ r}t        d	| d
|        Y d}~d}~ww xY w# 1 sw Y   kxY w)uG   JSONL 파일의 각 줄을 파싱하여 dict 목록으로 반환한다.u   JSONL 파일 존재 확인Fu   파일 없음: rutf-8encoding   )startu     [WARN] 줄 u     JSON 파싱 실패, 건너뜀: Nu   JSONL 파일 로드r   u   개 레코드)existsr   open	enumeratestripappendjsonloadsJSONDecodeErrorr   boolnamelen)r   recordsfhlinenorawexcs         r   
load_jsonlr-   2   s    G;;=)5OD62JK	dC'	* Ub$Rq1 	UKFC))+CUtzz#/	UU 	W99+U3w<.6
 N '' UfX-McUSTTUU Us5   'C,$B;?C,;C)C$C,$C))C,,C5c                      	 ddl m} m} t        dd       || fS # t        $ r }t        ddt        |             Y d}~yd}~ww xY w)uT   conversation_memory 모듈을 import하고 (ConversationMemory, ChatMessage) 반환.r   )ChatMessageConversationMemoryzconversation_memory importTFN)NN)conversation_memoryr/   r0   r   ImportErrorstr)r/   r0   r,   s      r   import_memory_moduler4   P   sD    G)40!;.. )5#c(;s    	A>Ar(   chat_idc                    || j                   vr#t        | j                        | j                   |<   d}|D ]  }	 |j                  dd      }	 t	        j
                  |      } ||j                  dd      |j                  dd      |t        |j                  dd	            
      }| j                   |   j                  |       |dz  } || j                  |<   | j                  j                  |       t!        d|dkD  d| d| d| j                   d       |S # t        t        f$ r t	        j                         }Y w xY w# t        $ r}	t        d|	 d|       Y d}	~	/d}	~	ww xY w)u   JSONL 레코드를 ChatMessage로 변환하여 _messages[chat_id] deque에 직접 삽입.

    add_message()를 사용하면 JSONL에 다시 append되므로 deque에 직접 넣는다.
    )maxlenr   	timestamp senderunknowntextis_botF)r:   r<   r8   r=   r   u-     [WARN] 레코드 변환 실패, 건너뜀: z | rec=Nu   deque 직접 로드zchat_id=r   u   개 메시지 삽입 (maxlen=))	_messagesr   _max_messagesgetr   fromisoformat
ValueError	TypeErrornowr%   r!   	Exceptionr   _message_count_loaded_chatsaddr   )
memoryr/   r(   r5   loadedrects_rawtsr   r,   s
             r   populate_dequerO   a   s}   
 f&&&$)1E1E$F!F W	WWW["-F$++F3 wwx3WWVR(CGGHe45	C W%,,S1aKFW( &,F'"
W%

7)5(EfFZFZE[[\]
 M1 	* $\\^$  	WA#gcWUVV	Ws<   ED"A(E#E?EEE	E*E%%E*c                   K   t        d| d       	 | j                  |       d{   }t        |      xr d|dd v}t        d|t	        |       d       |S 7 3# t
        $ r}d	| }t        dd
|       |cY d}~S d}~ww xY ww)uK   generate_insight(chat_id)를 호출하고 결과 문자열을 반환한다.z!
[STEP] generate_insight(chat_id=   ) 호출 중...r5   Nu   실패   u   generate_insight 호출u
   자 반환u    generate_insight 예외 발생: F)r   generate_insightr%   r   r'   rF   )rJ   r5   resultr   r,   r   s         r   run_generate_insightrV      s     	.wi
GH..w.??&\9hfSbk9&s6{m:,FG @  06&s3
sD   BA A2A BA 	B'B :B;B BBinsight_textdestc                     	 |j                   j                  dd       |j                  | d       t        ddt	        |             y# t
        $ r }t        ddt	        |             Y d}~yd}~ww xY w)u.   insight 결과를 dest 경로에 저장한다.T)parentsexist_okr   r   u   insight 결과 저장FN)parentmkdir
write_textr   r3   rF   )rW   rX   r,   s      r   save_insight_resultr_      sc    7$6w7$dCI6 7$eSX667s   AA	 		A2A--A2c                   K   t        d| d       d| j                  |<   t        j                         j	                  d      }| j
                  | j                  j                  |d      z
  }t        d| d| j
                          	 | j                  |       d	{    t        d
d       y	7 # t        $ r }t        d
dt        |             Y d	}~y	d	}~ww xY ww)uV   _do_generate_summary(chat_id)를 직접 호출하여 요약 생성을 테스트한다.z%
[STEP] _do_generate_summary(chat_id=rQ   F%Y-%m-%dr   u     LLM 예산 잔여: /rR   Nu   _do_generate_summary 호출T)r   _summary_lockr   rE   strftime_daily_llm_budget_llm_call_countrA   _do_generate_summaryr   rF   r3   )rJ   r5   todaybudget_remainingr,   s        r   run_do_generate_summaryrj      s     	27)?
KL %*F! LLN##J/E//&2H2H2L2LUTU2VV	!"2!31V5M5M4N
OP=))'):::*D1 	; =*E3s8<<=sB   BC	B2 B0B2 /C0B2 2	C;CCCCsummaries_dirc                 &   t        d|         | j                         st        ddd       yt        j                         j                  d      }t        | j                  | d            }t        dt        |      t        |       d	       |D ]  }	 t        j                  |j                  d
            }|j                  dd      dd j                  dd      }t        d|j                          t        d|j                  dd              t        d|j                  dg               t        d|j                  dd              t        d|         y# t         $ r%}t        d|j                   d|        Y d}~d}~ww xY w)uR   summaries/ 디렉토리에 오늘 날짜로 생성된 JSON 파일을 확인한다.u(   
[STEP] summaries/ 디렉토리 확인: u   summaries/ 디렉토리 존재Fu   디렉토리가 없습니다Nra   z_*.jsonu   summaries/ 오늘 파일 확인u   개 파일 발견r   r   summaryr9   P   
 z  - z    topic_tag     : 	topic_tag?z    key_topics    : 
key_topicsz    consensus     : consensus_levelu       summary (앞80): u    — 읽기 실패: )r   r   r   r   rE   rd   sortedglobr%   r'   r"   r#   	read_textrA   replacer&   rF   )rk   rh   today_filesfpdatasummary_previewr,   s          r   check_summaries_dirr}      s   	5m_
EF!-u6TULLN##J/E++ugW,=>?K)[{
-.  
=		=::bllGl<=D"hhy"5cr:BB4MOD	"#(+s)C(DEF(,)C(DEF(2CS)I(JKL)/):;<
=  	=D	!5cU;<<	=s   C
E""	F+FFc            	        K   t        d       t        d       t        dt        j                         j                                 t        d       t        d       	 ddlm}  t        ddd	       t        dt                t        t              }|st        d       t        d       t               \  }}|t        d       y  |t              }t        dddt         d|j                          t        dt         d       t        |||t              }t        |j                   j#                  t        g             }t        d| d|j                   d| d       t%        |t               d {   }t        dt&         d       t)        |t&               t        d       t        |d d        t        |      dkD  rt        dt        |       d        t        d!       t+        |t               d {    t-        t.               t        d"       t        d#       t        d$t&                t        d%t.                t        d       y # t        $ r}t        dd
| d       Y d }~d }~ww xY w7 7 w)&Nz<============================================================u,     generate_insight() 통합 테스트 러너u     실행 시각: u$   
[STEP] call_claude import 확인...r   )call_claudezcall_claude importTu+   engine_v2.bot_api.call_claude 사용 가능Fu#    — LLM 호출 시 fallback 발동u   
[STEP] JSONL 읽기: uQ   [WARN] 로드된 레코드가 없습니다. 빈 대화로 계속 진행합니다.u1   
[STEP] ConversationMemory 인스턴스 생성...uK   [ERROR] conversation_memory import 실패 — 테스트를 중단합니다.)storage_baseu   ConversationMemory 생성zstorage_base=z, max_messages=u5   
[STEP] 메시지를 deque에 직접 로드 (chat_id=z)...rR   u     deque 실제 크기: u   개 (maxlen=u   , 로드 시도=u   개)u   
[STEP] insight 결과를 u    에 저장...u1   
--- insight 내용 미리보기 (앞 500자) ---i  u     ... (총 u   자)z---z=
============================================================u     테스트 완료u     insight 파일: u     summaries 디렉토리: )r   r   rE   	isoformatengine_v2.bot_apir   r   r2   
JSONL_PATHr-   r4   STORAGE_BASEr@   CHAT_IDrO   r'   r?   rA   rV   INSIGHT_RESULT_PATHr_   rj   r}   SUMMARIES_DIR)	r   r,   r(   r0   r/   rJ   loaded_countactual_in_dequerW   s	            r   mainr      sU    	(O	
89	hlln6689
:;	(O 

12W1!4)VW
 
#J<
01$Gab 

>?&:&<#![\\:F#
~_V5I5I4JK 
B7)4
PQ!&+wPL&**..w;<O	#O#44DVEYEYDZZjkwjxx|
}~ .fgFFL 
'(;'<N
KL&9: 

>?	,t

<3C-.d34	%L "&'
::: & 
/	
	23
45	&}o
67	(Om  W!5SE1T*UVVW< G ;sQ   AJI 1DJ5I<6BJ;I?<AJ	I9I4.J4I99J?J__main__)r9   )r	   N)!__doc__asyncior"   syscollectionsr   r   pathlibr   MULTIMODEL_BOT_DIRr   insertr   r   r   r   r   r3   r%   r   listdictr-   r4   intrO   rV   r_   rj   r}   r   __name__run r   r   <module>r      sJ  
   
    C SXX%HHOOA)* UV
5ab EF  s D T d4j <	"&d &c &c &\  &7c 7 7$ 7=3 =4 =0=t = =FBJ zGKK r   