from __future__ import annotations from dataclasses import dataclass, field from datetime import datetime @dataclass class ScratchpadEntry: """도구 실행 기록 항목.""" tool_name: str params: dict result: str timestamp: datetime token_estimate: int class Scratchpad: """도구 실행 이력과 토큰 추정치를 추적합니다.""" def __init__(self) -> None: self.entries: list[ScratchpadEntry] = [] def add(self, tool_name: str, params: dict, result: str) -> None: """도구 실행 결과를 기록합니다. Args: tool_name: 실행된 도구 이름. params: 도구에 전달된 매개변수. result: 도구 실행 결과 문자열. """ token_estimate = max(len(result) // 4, 1) entry = ScratchpadEntry( tool_name=tool_name, params=params, result=result, timestamp=datetime.now(), token_estimate=token_estimate, ) self.entries.append(entry) def total_tokens(self) -> int: """전체 기록의 추정 토큰 수를 반환합니다.""" return sum(e.token_estimate for e in self.entries) def format_history(self) -> str: """도구 실행 이력을 포맷된 문자열로 반환합니다.""" if not self.entries: return "도구 실행 이력 없음" lines: list[str] = [] for i, entry in enumerate(self.entries, 1): lines.append( f"[{i}] {entry.tool_name} " f"({entry.timestamp.strftime('%H:%M:%S')}) " f"토큰≈{entry.token_estimate}" ) lines.append(f" params: {entry.params}") # 결과가 너무 길면 잘라냄 result_preview = entry.result[:200] if len(entry.result) > 200: result_preview += "..." lines.append(f" result: {result_preview}") return "\n".join(lines) def clear(self) -> None: """모든 기록을 삭제합니다.""" self.entries.clear()