| """<think> ํ๊ทธ ํ์ฑ ์ ํธ๋ฆฌํฐ""" |
|
|
| import re |
| from typing import Tuple, Optional |
|
|
|
|
| def parse_thinking_response(response: str) -> Tuple[Optional[str], str]: |
| """ |
| ์๋ต์์ <think> ํ๊ทธ ์ถ์ถ |
| |
| Returns: |
| (thinking_content, clean_response) |
| """ |
| if not response: |
| return None, "" |
|
|
| |
| pattern = r'<think>(.*?)</think>' |
| 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*" |
|
|
| |
| 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: |
| """์๋ต์ <think> ํ๊ทธ๊ฐ ์๋์ง ํ์ธ""" |
| pattern = r'<think>.*?</think>' |
| 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), |
| } |
|
|