""" 태그 파싱 유틸리티""" import re from typing import Tuple, Optional def parse_thinking_response(response: str) -> Tuple[Optional[str], str]: """ 응답에서 태그 추출 Returns: (thinking_content, clean_response) """ if not response: return None, "" # ... 패턴 매칭 pattern = r'(.*?)' match = re.search(pattern, response, re.DOTALL) if match: thinking = match.group(1).strip() # 태그 제거한 클린 응답 clean = re.sub(pattern, '', response, flags=re.DOTALL).strip() return thinking, clean return None, response def format_thinking_for_display(thinking: str) -> str: """Thinking 내용을 마크다운으로 포맷팅""" if not thinking: return "*No thinking process*" # 6단계 구조 하이라이트 (있는 경우) sections = [ "[상황분석]", "[관계단계]", "[캐릭터스타일]", "[밀당결정]", "[금지패턴체크]", "[응답설계]" ] formatted = thinking for section in sections: formatted = formatted.replace( section, f"**{section}**" ) return formatted def extract_response_only(full_response: str) -> str: """Thinking 제거하고 응답만 추출""" _, clean = parse_thinking_response(full_response) return clean def has_thinking_tag(response: str) -> bool: """응답에 태그가 있는지 확인""" pattern = r'.*?' return bool(re.search(pattern, response, re.DOTALL)) def get_thinking_stats(response: str) -> dict: """Thinking 관련 통계""" thinking, clean = parse_thinking_response(response) return { "has_thinking": thinking is not None, "thinking_length": len(thinking) if thinking else 0, "response_length": len(clean), "total_length": len(response), }