
    i=]                       d Z ddlmZ ddlZddlmc mZ ddl	Z	ddl
Z
ddlZddlmZ ddlmZmZ ddlZ ee
j$                  j'                  dd            Z ee      ej,                  vr"ej,                  j/                  d ee             ddlmZ ddd	Z G d
 d      Z G d d      Z G d d      Z G d d      Z G d d      Zy)uG  
tests/test_session_auto_compress.py

SessionAutoCompress 단위 테스트 (TDD - RED 단계)

테스트 항목:
- auto_compress: 메시지 리스트 압축 → 반환 메시지 수 감소 확인
- auto_compress: 이벤트 파일 생성 확인 + JSON 형식 검증
- auto_compress: monitor.reset() 호출 확인
- save_session_summary: 파일 생성 + 경로 반환 확인
- save_session_summary: 파일 내용에 task_id, team_id, modified_files 등 필수 필드 포함 확인
- save_session_summary: 빈 메시지 → 에러 없이 처리
- setup_auto_hooks: 콜백 등록 확인
    )annotationsN)Path)	MagicMockpatchWORKSPACE_ROOT/home/jay/workspace)SessionMonitorc                    g }t        |       D ]A  }|dz  dk(  r|j                  dd| ddz   d       '|j                  dd	| dd
z   d       C |S )u^   테스트용 메시지 리스트를 생성한다. 압축이 일어날 만큼 충분한 크기.   r   useru   질문 z:   xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrolecontent	assistantu   답변   yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy)rangeappend)countmsgsis      7/home/jay/workspace/tests/test_session_auto_compress.py_make_messagesr   %   sj    D5\ Wq5A:KKgaSOi4OPQKK71#R99TUV	W
 K    c                  :    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
y	)
TestAutoCompressuC   auto_compress()가 올바르게 메시지를 압축하는지 확인c                n	   ddl m} t        d      } ||d|dz  |dz        }t        d      }|j	                  |      }t        |t              }|sd	d
t        j                         v st        j                  t
              rt        j                  t
              nd
dt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }t        t        j                  |            d}t        |      }	d}
|	|
k(  }|st        j                  d|fd|	|
f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |	      t        j                  |
      dz  }dd|iz  }t        t        j                  |            dx}	x}}
|\  }}t        |t               }|sd	d
t        j                         v st        j                  t
              rt        j                  t
              nd
dt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  t               rt        j                  t               ndt        j                  |      dz  }t        t        j                  |            d}t        |t"              }|sd	d
t        j                         v st        j                  t
              rt        j                  t
              nd
dt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  t"              rt        j                  t"              ndt        j                  |      dz  }t        t        j                  |            d}y)u<   auto_compress가 (list, dict) 튜플을 반환해야 한다.r   SessionAutoCompress@ context_limiteventssessionsmonitorr"   
events_dirsessions_dir   5assert %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}
isinstanceresulttuplepy0py1py2py4Nr   ==z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)slenr/   r0   py3py6assert %(py8)spy8compressed_msgslist
event_infodict)utils.session_auto_compressr   r	   r   auto_compressr+   r-   @py_builtinslocals
@pytest_ar_should_repr_global_name	_safereprAssertionError_format_explanationr6   _call_reprcomparer=   r?   )selftmp_pathr   r&   sacmessagesr,   @py_assert3@py_format5@py_assert2@py_assert5@py_assert4@py_format7@py_format9r<   r>   s                   r    test_auto_compress_returns_tuplez1TestAutoCompress.test_auto_compress_returns_tuple8   sy   C w7!!(*!J.	
 ""%""8,&%((((((((z(((z((((((&(((&((((((%(((%((((((((((6{a{a{ass66{a&,#/400000000z000z000000/000/000000400040000000000*d++++++++z+++z++++++*+++*++++++d+++d++++++++++r   c           	        ddl m} t        d      } ||d|dz  |dz        }t        d      }|j	                  |      \  }}t        |      }t        |      }	||	k  }
|
st        j                  d	|
fd
||	f      dt        j                         v st        j                  t
              rt        j                  t
              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dt        j                         v st        j                  t
              rt        j                  t
              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |	      dz  }dd|iz  }t        t        j                  |            dx}x}
}	y)uD   압축 후 메시지 수가 원본보다 적거나 같아야 한다.r   r   r    r!   r#   r$   r%      )<=)zN%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} <= %(py8)s
{%(py8)s = %(py5)s(%(py6)s)
}r6   r<   rM   )r/   r0   r8   py5r9   r;   zassert %(py10)spy10N)r@   r   r	   r   rA   r6   rD   rI   rB   rC   rE   rF   rG   rH   )rJ   rK   r   r&   rL   rM   r<   _rP   @py_assert7rR   rT   @py_format11s                r   (test_auto_compress_reduces_message_countz9TestAutoCompress.test_auto_compress_reduces_message_countK   s"   C w7!!(*!J.	
 ""% ..x8?#4s8}4#}4444#}444444s444s444444?444?444#444444s444s44444484448444}4444444r   c                   ddl m} t        d      }|dz  } ||d||dz        }t        d      }|j	                  |       t        |j                  d	            }t        |      }d
}	||	k(  }
|
st        j                  d|
fd||	f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |	      dz  }dd|iz  }t        t        j                  |            dx}x}
}	y)uD   압축 후 events_dir에 이벤트 파일이 생성되어야 한다.r   r   r    r!   r#   r$   r%   
   session-compressed-*.json   r3   r5   r6   event_filesr7   r:   r;   N)r@   r   r	   r   rA   r=   globr6   rD   rI   rB   rC   rE   rF   rG   rH   )rJ   rK   r   r&   r'   rL   rM   rc   rP   rQ   rR   rS   rT   s                r   %test_auto_compress_event_file_createdz6TestAutoCompress.test_auto_compress_event_file_created\   s    C w7(
!!!!J.	
 ""%(#:??+FGH;$1$1$$$$1$$$$$$s$$$s$$$$$$;$$$;$$$$$$1$$$$$$$r   c                   ddl m} t        d      }|dz  } ||d||dz        }t        d      }|j	                  |       t        |j                  d	            }t        |      }d
}	||	k(  }
|
st        j                  d|
fd||	f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |	      dz  }dd|iz  }t        t        j                  |            dx}x}
}	t!        |d   d      5 }t#        j$                  |      }ddd       d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}d}||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }d d!|iz  }t        t        j                  |            dx}}d"}||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }d d!|iz  }t        t        j                  |            dx}}d#}||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }d d!|iz  }t        t        j                  |            dx}}d$}||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }d d!|iz  }t        t        j                  |            dx}}d%}||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }d d!|iz  }t        t        j                  |            dx}}|d"   }t        |      }	||	k(  }|st        j                  d|fd&||	f      t        j                  |      dt        j                         v st        j                  t              rt        j                  t              ndd't        j                         v st        j                  |      rt        j                  |      nd't        j                  |	      d(z  }dd|iz  }t        t        j                  |            dx}x}}	y# 1 sw Y   xY w))uO   이벤트 파일이 올바른 JSON 형식과 필수 키를 포함해야 한다.r   r   r    r!   r#   r$   r%   r`   ra   rb   r3   r5   r6   rc   r7   r:   r;   Nutf-8encodingeventsession_compressedz%(py1)s == %(py4)sr0   r2   assert %(py6)sr9   	timestampinz%(py1)s in %(py3)sdatar0   r8   assert %(py5)srY   before_countafter_counttokens_beforetokens_after)z0%(py1)s == %(py6)s
{%(py6)s = %(py3)s(%(py4)s)
}rM   )r0   r8   r2   r9   )r@   r   r	   r   rA   r=   rd   r6   rD   rI   rB   rC   rE   rF   rG   rH   openjsonload)rJ   rK   r   r&   r'   rL   rM   rc   rP   rQ   rR   rS   rT   frs   @py_assert0rN   rO   @py_format4@py_format6s                       r   )test_auto_compress_event_file_json_formatz:TestAutoCompress.test_auto_compress_event_file_json_formatn   s   C w7(
!!!!J.	
 ""%(#:??+FGH;$1$1$$$$1$$$$$$s$$$s$$$$$$;$$$;$$$$$$1$$$$$$$+a.73 	 q99Q<D	  G}4 44} 44444} 4444}444 44444444"{d""""{d"""{""""""d"""d"""""""%~%%%%~%%%~%%%%%%%%%%%%%%%%$}$$$$}$$$}$$$$$$$$$$$$$$$$&$&&&&$&&&&&&&&&$&&&$&&&&&&&%~%%%%~%%%~%%%%%%%%%%%%%%%%N#4s8}4#}4444#}444#444444s444s44444484448444}4444444	  	 s   =Y((Y2c                   ddl m} t        d      }|j                  d        ||d|dz  |dz  	      }t	        d
      }|j                  |       |j                         }|d   }d}||k  }	|	slt        j                  d|	fd||f      t        j                  |      t        j                  |      dz  }
dd|
iz  }t        t        j                  |            dx}x}	}y)u5   압축 후 monitor.reset()이 호출되어야 한다.r   r   r    r!   i  )	new_totalr#   r$   r%   r`   total_tokens)<)z%(py1)s < %(py4)srm   rn   r9   N)r@   r   r	   resetr   rA   get_usage_statusrD   rI   rF   rG   rH   )rJ   rK   r   r&   rL   rM   statusr~   rN   rP   rO   rS   s               r   'test_auto_compress_monitor_reset_calledz8TestAutoCompress.test_auto_compress_monitor_reset_called   s    C w7(!!(*!J.	
 ""%(# ))+n%//%////%///%//////////r   c                    ddl m} t        d      } ||d|dz  |dz        }|j                  g       \  }}g }||k(  }|st	        j
                  d|fd	||f      d
t        j                         v st	        j                  |      rt	        j                  |      nd
t	        j                  |      dz  }	dd|	iz  }
t        t	        j                  |
            dx}}t        |t              }|sddt        j                         v st	        j                  t              rt	        j                  t              nddt        j                         v st	        j                  |      rt	        j                  |      nddt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      dz  }t        t	        j                  |            d}y)@   빈 메시지 리스트도 에러 없이 처리되어야 한다.r   r   r    r!   r#   r$   r%   r3   )z%(py0)s == %(py3)sr<   )r/   r8   ru   rY   Nr*   r+   r>   r?   r.   )r@   r   r	   rA   rD   rI   rB   rC   rE   rF   rG   rH   r+   r?   )rJ   rK   r   r&   rL   r<   r>   rP   @py_assert1r   r   rN   rO   s                r   !test_auto_compress_empty_messagesz2TestAutoCompress.test_auto_compress_empty_messages   s'   C w7!!(*!J.	
 '*&7&7&;#"$$"$$$$"$$$$$$$$$$$$"$$$$$$$*d++++++++z+++z++++++*+++*++++++d+++d++++++++++r   c                h   ddl m} t        d      } ||d|dz  |dz        }t        d      }|j	                  |      \  }}d	}||v }	|	st        j                  d
|	fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }
dd|
iz  }t        t        j                  |            dx}}	|d	   }d}||k(  }	|	slt        j                  d|	fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}	}d}||v }	|	st        j                  d
|	fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }
dd|
iz  }t        t        j                  |            dx}}	d}||v }	|	st        j                  d
|	fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }
dd|
iz  }t        t        j                  |            dx}}	y)uB   반환된 event_info dict에 필수 키가 포함되어야 한다.r   r   r    r!   r#   r$   r%   r`   rj   rp   rr   r>   rt   ru   rY   Nrk   r3   rl   rm   rn   r9   rv   rw   )r@   r   r	   r   rA   rD   rI   rF   rB   rC   rE   rG   rH   )rJ   rK   r   r&   rL   rM   r[   r>   r~   rP   r   r   rN   rO   rS   s                  r   'test_auto_compress_event_info_in_returnz8TestAutoCompress.test_auto_compress_event_info_in_return   s   C w7!!(*!J.	
 ""%))(3:$w*$$$$w*$$$w$$$$$$*$$$*$$$$$$$'":&::"&:::::"&::::":::&::::::::+~++++~+++~++++++++++++++++*}
****}
***}******
***
*******r   N)__name__
__module____qualname____doc__rU   r^   re   r   r   r   r    r   r   r   r   5   s(    M,&5"%$5:0*,+r   r   c                  X    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zy)TestSaveSessionSummaryuN   save_session_summary()가 올바르게 요약 파일을 저장하는지 확인c                   ddl m} t        d      }|dz  } ||d|dz  |      }t        d      }|j	                  |d	d
      }t        |t              }|sddt        j                         v st        j                  t
              rt        j                  t
              nddt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }	t        t        j                  |	            d}y)u;   save_session_summary가 Path 객체를 반환해야 한다.r   r   r    r!   r$   r#   r%      
task-100.1	dev6-teamrM   task_idteam_idr*   r+   r,   r   r.   N)r@   r   r	   r   save_session_summaryr+   r   rB   rC   rD   rE   rF   rG   rH   )
rJ   rK   r   r&   r(   rL   rM   r,   rN   rO   s
             r   &test_save_session_summary_returns_pathz=TestSaveSessionSummary.test_save_session_summary_returns_path   s    C w7*,!!(*%	
 "!$))  * 

 &$''''''''z'''z''''''&'''&''''''$'''$''''''''''r   c                j   ddl m} t        d      }|dz  } ||d|dz  |      }t        d      }|j	                  |d	d
      }|j
                  } |       }	|	sddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |	      dz  }
t        t        j                  |
            dx}}	|j                  }d}||k(  }	|	st        j                  d|	fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}	}y)uK   save_session_summary 호출 후 파일이 실제로 생성되어야 한다.r   r   r    r!   r$   r#   r%   r   r   r   r   Aassert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}pathr/   r1   r2   Nz.mdr3   )z.%(py2)s
{%(py2)s = %(py0)s.suffix
} == %(py5)s)r/   r1   rY   assert %(py7)spy7)r@   r   r	   r   r   existsrB   rC   rD   rE   rF   rG   rH   suffixrI   )rJ   rK   r   r&   r(   rL   rM   r   r   rN   rO   rR   r   @py_format8s                 r   %test_save_session_summary_file_existsz<TestSaveSessionSummary.test_save_session_summary_file_exists   s$   C w7*,!!(*%	
 "!$''  ( 

 {{{}}tt{}{{#e#{e####{e######t###t###{###e#######r   c                   ddl m} t        d      }|dz  } ||d|dz  |      }t        d      }|j	                  |d	d
      }d	}|j
                  }	||	v }
|
st        j                  d|
fd||	f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |	      dz  }dd|iz  }t        t        j                  |            dx}x}
}	y)u:   저장 파일 이름에 task_id가 포함되어야 한다.r   r   r    r!   r$   r#   r%   r   z
task-999.9r   r   rp   )z,%(py1)s in %(py5)s
{%(py5)s = %(py3)s.name
}r   )r0   r8   rY   r   r   N)r@   r   r	   r   r   namerD   rI   rF   rB   rC   rE   rG   rH   )rJ   rK   r   r&   r(   rL   rM   r   r~   rR   rP   r   r   s                r   3test_save_session_summary_filename_contains_task_idzJTestSaveSessionSummary.test_save_session_summary_filename_contains_task_id   s    C w7*,!!(*%	
 "!$''  ( 

 (tyy(|y((((|y(((|((((((t(((t(((y(((((((r   c                   ddl m} t        d      }|dz  } ||d|dz  |      }t        d      }|j	                  |d	d
      }|j                  d      }d	}	|	|v }
|
st        j                  d|
fd|	|f      t        j                  |	      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}	}
y)u3   파일 내용에 task_id가 포함되어야 한다.r   r   r    r!   r$   r#   r%   r   r   r   r   rg   rh   rp   rr   r   rt   ru   rY   Nr@   r   r	   r   r   	read_textrD   rI   rF   rB   rC   rE   rG   rH   rJ   rK   r   r&   r(   rL   rM   r   r   r~   rP   r   r   s                r   -test_save_session_summary_content_has_task_idzDTestSaveSessionSummary.test_save_session_summary_content_has_task_id  s    C w7*,!!(*%	
 "!$''  ( 

 ..'.2&|w&&&&|w&&&|&&&&&&w&&&w&&&&&&&r   c                   ddl m} t        d      }|dz  } ||d|dz  |      }t        d      }|j	                  |d	d
      }|j                  d      }d
}	|	|v }
|
st        j                  d|
fd|	|f      t        j                  |	      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}	}
y)u3   파일 내용에 team_id가 포함되어야 한다.r   r   r    r!   r$   r#   r%   r   r   r   r   rg   rh   rp   rr   r   rt   ru   rY   Nr   r   s                r   -test_save_session_summary_content_has_team_idzDTestSaveSessionSummary.test_save_session_summary_content_has_team_id  s    C w7*,!!(*%	
 "!$''  ( 

 ..'.2%{g%%%%{g%%%{%%%%%%g%%%g%%%%%%%r   c                L   ddl m} t        d      }|dz  } ||d|dz  |      }t        d      }|j	                  |d	d
ddg      }|j                  d      }d}	|	|v }
|
st        j                  d|
fd|	|f      t        j                  |	      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}	}
d}	|	|v }
|
st        j                  d|
fd|	|f      t        j                  |	      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}	}
y)uA   파일 내용에 modified_files 목록이 포함되어야 한다.r   r   r    r!   r$   r#   r%   r   r   r   zutils/foo.pyzutils/bar.py)rM   r   r   modified_filesrg   rh   rp   rr   r   rt   ru   rY   Nr   r   s                r   4test_save_session_summary_content_has_modified_fileszKTestSaveSessionSummary.test_save_session_summary_content_has_modified_files2  s*   C w7*,!!(*%	
 "!$'' *N;	 ( 
 ..'.2(~((((~(((~(((((((((((((((((~((((~(((~((((((((((((((((r   c                L   ddl m} t        d      }|dz  } ||d|dz  |      }t        d      }|j	                  |d	d
ddg      }|j                  d      }d}	|	|v }
|
st        j                  d|
fd|	|f      t        j                  |	      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}	}
d}	|	|v }
|
st        j                  d|
fd|	|f      t        j                  |	      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}	}
y)uB   파일 내용에 remaining_tasks 목록이 포함되어야 한다.r   r   r    r!   r$   r#   r%   r   r   r   u   작업A 완료u   작업B 시작)rM   r   r   remaining_tasksrg   rh   rp   rr   r   rt   ru   rY   Nr   r   s                r   5test_save_session_summary_content_has_remaining_taskszLTestSaveSessionSummary.test_save_session_summary_content_has_remaining_tasksI  s1   C w7*,!!(*%	
 "!$'' -/?@	 ( 
 ..'.2*7****7*********7***7********7****7*********7***7*******r   c                   ddl m} t        d      }|dz  } ||d|dz  |      }t        d      }|j	                  |d	d
d      }|j                  d      }d}	|	|v }
|
st        j                  d|
fd|	|f      t        j                  |	      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}	}
y)u=   파일 내용에 last_success_step이 포함되어야 한다.r   r   r    r!   r$   r#   r%   r   r   r   u   테스트 통과 완료)rM   r   r   last_success_steprg   rh   rp   rr   r   rt   ru   rY   Nr   r   s                r   7test_save_session_summary_content_has_last_success_stepzNTestSaveSessionSummary.test_save_session_summary_content_has_last_success_step`  s    C w7*,!!(*%	
 "!$'' 7	 ( 
 ..'.2(3(G3333(G333(333333G333G3333333r   c                L   ddl m} t        d      }|dz  } ||d|dz  |      }t        d      }|j	                  |d	d
ddg      }|j                  d      }d}	|	|v }
|
st        j                  d|
fd|	|f      t        j                  |	      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}	}
d}	|	|v }
|
st        j                  d|
fd|	|f      t        j                  |	      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}	}
y)u9   파일 내용에 errors 목록이 포함되어야 한다.r   r   r    r!   r$   r#   r%   r   r   r   zImportError: module not foundzTypeError: expected str)rM   r   r   errorsrg   rh   rp   rr   r   rt   ru   rY   Nr   r   s                r   ,test_save_session_summary_content_has_errorszCTestSaveSessionSummary.test_save_session_summary_content_has_errorsv  s1   C w7*,!!(*%	
 "!$'' 35NO	 ( 
 ..'.2.9.'9999.'999.999999'999'9999999(3(G3333(G333(333333G333G3333333r   c                2   ddl m} t        d      }|dz  } ||d|dz  |      }|j                  g dd	
      }|j                  } |       }|sddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }	t        t        j                  |	            dx}}|j                  d      }
d}||
v }|st        j                  d|fd||
f      t        j                  |      dt        j                         v st        j                  |
      rt        j                  |
      nddz  }dd|iz  }t        t        j                  |            dx}}y)r   r   r   r    r!   r$   r#   r%   ztask-empty.1r   r   r   r   r   Nrg   rh   rp   rr   r   rt   ru   rY   )r@   r   r	   r   r   rB   rC   rD   rE   rF   rG   rH   r   rI   )rJ   rK   r   r&   r(   rL   r   r   rN   rO   r   r~   rP   r   r   s                  r   (test_save_session_summary_empty_messagesz?TestSaveSessionSummary.test_save_session_summary_empty_messages  s   C w7*,!!(*%	
 ''" ( 

 {{{}}tt{}..'.2(~((((~(((~((((((((((((((((r   c           	        ddl m} t        d      }|dz  } ||d|dz  |      }t        d      }|j	                  |d	d
dddd      }|j
                  } |       }	|	sddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |	      dz  }
t        t        j                  |
            dx}}	y)uG   optional 필드가 None일 때도 에러 없이 처리되어야 한다.r   r   r    r!   r$   r#   r%      z
task-opt.1z	dev1-teamN)rM   r   r   r   r   r   r   r   r   r   )r@   r   r	   r   r   r   rB   rC   rD   rE   rF   rG   rH   )rJ   rK   r   r&   r(   rL   rM   r   r   rN   rO   s              r   .test_save_session_summary_none_optional_fieldszETestSaveSessionSummary.test_save_session_summary_none_optional_fields  s    C w7*,!!(*%	
 "!$''  " ( 
 {{{}}tt{}r   c                   ddl m} t        d      }|dz  } ||d|dz  |      }t        d      }|j	                  |d	d
      }|j                  d      }d}	|	|v }
|
st        j                  d|
fd|	|f      t        j                  |	      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}	}
d}	|	|v }
|
st        j                  d|
fd|	|f      t        j                  |	      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}	}
d}	|	|v }
|
st        j                  d|
fd|	|f      t        j                  |	      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}	}
y)u@   파일 내용에 마크다운 헤더 구조가 있어야 한다.r   r   r    r!   r$   r#   r%   r   r   r   r   rg   rh   u   # 세션 요약rp   rr   r   rt   ru   rY   Nu   ## 기본 정보u   ## 자동 요약r   r   s                r   *test_save_session_summary_markdown_headerszATestSaveSessionSummary.test_save_session_summary_markdown_headers  s   C w7*,!!(*%	
 "!$''  ( 

 ..'.2 + G++++ G+++ ++++++G+++G+++++++!,!W,,,,!W,,,!,,,,,,W,,,W,,,,,,,!,!W,,,,!W,,,!,,,,,,W,,,W,,,,,,,r   N)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r      sA    X(($*)('*&*).+.4,4.),0-r   r   c                  (    e Zd ZdZd Zd Zd Zd Zy)TestSetupAutoHooksuC   setup_auto_hooks()가 콜백을 올바르게 등록하는지 확인c                   ddl m} t        d      } ||d|dz  |dz        }t        |j                  j                  dg             }|j                          t        |j                  j                  dg             }d	}||z   }||k(  }	|	st        j                  d
|	fd||f      dt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }
dd|
iz  }t        t        j                  |            dx}	x}}y)uQ   setup_auto_hooks 호출 후 monitor에 critical 콜백이 등록되어야 한다.r   r   r    r!   r#   r$   r%   criticalrb   r3   z%(py0)s == (%(py2)s + %(py4)s)rw   rv   r   r   r   Nr@   r   r	   r6   
_callbacksgetsetup_auto_hooksrD   rI   rB   rC   rE   rF   rG   rH   rJ   rK   r   r&   rL   rv   rw   rN   rQ   r   r   r   s               r   (test_setup_auto_hooks_registers_callbackz;TestSetupAutoHooks.test_setup_auto_hooks_registers_callback  s    C w7!!(*!J.	
 7--11*bAB',,00R@A-..lQ..{.....{.......{...{......l...l...Q.......r   c                   ddl m} t        d      } ||d|dz  |dz        }|j                          |j                  j                  dg       }t        |      }d}||kD  }|st        j                  d	|fd
||f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            dx}x}}|d   }t        |      }|sddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |      dz  }t        t        j                  |            dx}}y)u-   등록된 콜백이 callable이어야 한다.r   r   r    r!   r#   r$   r%   r   >)z/%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} > %(py6)sr6   	callbacksr7   r:   r;   Nz,assert %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}callabler   )r@   r   r	   r   r   r   r6   rD   rI   rB   rC   rE   rF   rG   rH   r   )rJ   rK   r   r&   rL   r   rP   rQ   rR   rS   rT   r   rN   rO   s                 r   *test_setup_auto_hooks_callback_is_callablez=TestSetupAutoHooks.test_setup_auto_hooks_callback_is_callable  s=   C w7!!(*!J.	
 	&&**:r:	9~!!~!!!!~!!!!!!s!!!s!!!!!!9!!!9!!!~!!!!!!!!!!!"&x&&&&&&&&x&&&x&&&&&&&&&&&&&r   c                    ddl m} t        d      } ||d|dz  |dz        }|j                          	 |j	                  ddd	       y# t
        $ r"}t        j                  d
|        Y d}~yd}~ww xY w)uF   critical 레벨 도달 시 등록된 콜백이 호출되어야 한다.r   r   r    r!   r#   r$   r%   i )input_tokensoutput_tokensu*   critical 콜백 실행 중 예외 발생: N)r@   r   r	   r   update	Exceptionpytestfail)rJ   rK   r   r&   rL   excs         r   2test_setup_auto_hooks_callback_invoked_on_criticalzETestSetupAutoHooks.test_setup_auto_hooks_callback_invoked_on_critical  s}    C w7!!(*!J.	
 		LNNGaHI 	LKKDSEJKK	Ls   A 	A6A11A6c                   ddl m} t        d      } ||d|dz  |dz        }t        |j                  j                  dg             }|j                          |j                          t        |j                  j                  dg             }d	}||z   }||k(  }	|	st        j                  d
|	fd||f      dt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }
dd|
iz  }t        t        j                  |            dx}	x}}y)uR   setup_auto_hooks를 두 번 호출하면 콜백이 두 번 등록되어야 한다.r   r   r    r!   r#   r$   r%   r   r   r3   r   rw   rv   r   r   r   Nr   r   s               r    test_setup_auto_hooks_idempotentz3TestSetupAutoHooks.test_setup_auto_hooks_idempotent  s   C w7!!(*!J.	
 7--11*bAB',,00R@A-..lQ..{.....{.......{...{......l...l...Q.......r   N)r   r   r   r   r   r   r   r   r   r   r   r   r     s    M/"' L(/r   r   c                  "    e Zd ZdZd Zd Zd Zy)TestDefaultPathsub   기본 경로가 WORKSPACE/memory/events/, WORKSPACE/memory/sessions/으로 설정되는지 확인c                   ddl m} t        d      } ||      }t        t        j
                  j                  dd            }|j                  }d}||z  }d	}||z  }	||	k(  }
|
st        j                  d
|
fd||	f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}
x}x}x}}	y)u>   events_dir 기본값이 WORKSPACE/memory/events/여야 한다.r   r   r    r!   r&   r   r   memoryr#   r3   )zJ%(py2)s
{%(py2)s = %(py0)s.events_dir
} == ((%(py4)s / %(py6)s) / %(py9)s)rL   	workspacer/   r1   r2   r9   py9assert %(py12)spy12N)r@   r   r	   r   osenvironr   r'   rD   rI   rB   rC   rE   rF   rG   rH   rJ   r   r&   rL   r   r   rQ   r\   @py_assert8@py_assert10rN   r]   @py_format13s                r   test_default_events_dirz(TestDefaultPaths.test_default_events_dir+  s    C w7!'2(8:OPQ	~~@X@X!5@@!5!@@~!@@@@@~!@@@@@@@s@@@s@@@~@@@@@@@@@@@@X@@@@@@@@@@@r   c                   ddl m} t        d      } ||      }t        t        j
                  j                  dd            }|j                  }d}||z  }d	}||z  }	||	k(  }
|
st        j                  d
|
fd||	f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}
x}x}x}}	y)uB   sessions_dir 기본값이 WORKSPACE/memory/sessions/여야 한다.r   r   r    r!   r   r   r   r   r$   r3   )zL%(py2)s
{%(py2)s = %(py0)s.sessions_dir
} == ((%(py4)s / %(py6)s) / %(py9)s)rL   r   r   r   r   N)r@   r   r	   r   r   r   r   r(   rD   rI   rB   rC   rE   rF   rG   rH   r   s                r   test_default_sessions_dirz*TestDefaultPaths.test_default_sessions_dir4  s    C w7!'2(8:OPQ	DxD9x#7D*D#7*#DD#DDDDD#DDDDDDDsDDDsDDDDDDDDD9DDD9DDDxDDD*DDDDDDDDr   c                   ddl m} t        d      } |||dz  |dz        }|j                  }d}||z  }||k(  }|st	        j
                  d|fd	||f      d
t        j                         v st	        j                  |      rt	        j                  |      nd
t	        j                  |      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      dz  }	dd|	iz  }
t        t	        j                  |
            dx}x}x}}|j                  }d}||z  }||k(  }|st	        j
                  d|fd||f      d
t        j                         v st	        j                  |      rt	        j                  |      nd
t	        j                  |      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      dz  }	dd|	iz  }
t        t	        j                  |
            dx}x}x}}y)u8   커스텀 경로가 올바르게 설정되어야 한다.r   r   r    r!   	my_eventsmy_sessions)r&   r'   r(   r3   )z>%(py2)s
{%(py2)s = %(py0)s.events_dir
} == (%(py4)s / %(py6)s)rL   rK   )r/   r1   r2   r9   zassert %(py9)sr   N)z@%(py2)s
{%(py2)s = %(py0)s.sessions_dir
} == (%(py4)s / %(py6)s))r@   r   r	   r'   rD   rI   rB   rC   rE   rF   rG   rH   r(   )rJ   rK   r   r&   rL   r   rQ   r\   rN   r   @py_format10s              r   test_custom_dirs_acceptedz*TestDefaultPaths.test_custom_dirs_accepted=  sc   C w7!+-!M1

 ~~7K7K!77~!77777~!7777777s777s777~777777777777K7777777;m;8m#;;#;;;;;#;;;;;;;s;;;s;;;;;;;;;8;;;8;;;m;;;;;;;r   N)r   r   r   r   r   r   r   r   r   r   r   r   (  s    lAE<r   r   c                      e Zd ZdZd Zy)#TestEstimateTokensKoreanIntegrationuT   session_auto_compress의 토큰 추정이 한국어 보정을 사용하는지 확인c                   ddl m} d}dt        |      z  }d|dg}d|dg} ||      } ||      }||kD  }|st        j                  d|fd||f      d	t        j                         v st        j                  |      rt        j                  |      nd	d
t        j                         v st        j                  |      rt        j                  |      nd
dz  }	dd|	iz  }
t        t        j                  |
            d}y)ud   한국어 메시지가 같은 길이의 영어 메시지보다 더 많은 토큰으로 추정된다.r   )_estimate_tokens_for_messagesu  안녕하세요 테스트입니다 안녕하세요 테스트입니다 안녕하세요 테스트입니다 안녕하세요 테스트입니다 안녕하세요 테스트입니다 안녕하세요 테스트입니다 안녕하세요 테스트입니다 안녕하세요 테스트입니다 안녕하세요 테스트입니다 안녕하세요 테스트입니다 안녕하세요 테스트입니다 안녕하세요 테스트입니다 안녕하세요 테스트입니다 안녕하세요 테스트입니다 안녕하세요 테스트입니다 안녕하세요 테스트입니다 안녕하세요 테스트입니다 안녕하세요 테스트입니다 안녕하세요 테스트입니다 안녕하세요 테스트입니다 ar   r   r   )z%(py0)s > %(py2)s	ko_tokens	en_tokens)r/   r1   zassert %(py4)sr2   N)r@   r   r6   rD   rI   rB   rC   rE   rF   rG   rH   )rJ   r   ko_texten_textko_msgsen_msgsr  r  r   @py_format3rO   s              r   %test_korean_messages_estimated_higherzITestEstimateTokensKoreanIntegration.test_korean_messages_estimated_higherS  s    M<G$"w78"w781':	1':	9$$$$y9$$$$$$y$$$y$$$$$$9$$$9$$$$$$$r   N)r   r   r   r   r  r   r   r   r   r   P  s
    ^%r   r   )r)   )r   intreturnz
list[dict]) r   
__future__r   builtinsrB   _pytest.assertion.rewrite	assertionrewriterD   r{   r   syspathlibr   unittest.mockr   r   r   r   r   
_WORKSPACEstrr   insertutils.session_monitorr	   r   r   r   r   r   r   r   r   r   <module>r     s    #    	 
  * "**..!13HIJ
z?#(("HHOOAs:' 0 K+ K+fH- H-`H/ H/` <  <P% %r   