| import re |
| from urllib.parse import urlparse |
|
|
| from config import MAX_EVIDENCE_CHARS |
|
|
|
|
| AUDIO_VIDEO_EXTENSIONS = {".mp3", ".wav", ".m4a", ".flac", ".mp4", ".mov", ".webm"} |
| IMAGE_EXTENSIONS = {".png", ".jpg", ".jpeg", ".webp"} |
| SPREADSHEET_EXTENSIONS = {".xlsx", ".xls"} |
| TEXT_EXTENSIONS = {".txt", ".csv", ".json", ".md"} |
|
|
|
|
| def truncate_text(text: str, limit: int = MAX_EVIDENCE_CHARS) -> str: |
| if len(text) <= limit: |
| return text |
| return text[:limit] + "\n\n[内容过长,已截断。]" |
|
|
|
|
| def normalize_answer(answer: str) -> str: |
| """清理模型常见废话,只保留适合提交的最终答案字符串。""" |
| answer = answer.strip() |
| answer = re.sub(r"^```(?:text|markdown)?", "", answer, flags=re.IGNORECASE).strip() |
| answer = re.sub(r"```$", "", answer).strip() |
|
|
| final_markers = [ |
| "final answer:", |
| "final:", |
| "answer:", |
| "submitted_answer:", |
| "最终答案:", |
| "答案:", |
| ] |
| lower_answer = answer.lower() |
| for marker in final_markers: |
| marker_index = lower_answer.rfind(marker) |
| if marker_index != -1: |
| answer = answer[marker_index + len(marker):].strip() |
| break |
|
|
| if "\n" in answer: |
| non_empty_lines = [line.strip() for line in answer.splitlines() if line.strip()] |
| if non_empty_lines: |
| answer = non_empty_lines[-1] |
|
|
| return answer.strip().strip('"').strip("'") |
|
|
|
|
| def normalize_for_compare(value: str) -> str: |
| value = normalize_answer(value).lower() |
| value = re.sub(r"\s*,\s*", ", ", value) |
| value = re.sub(r"\s+", " ", value) |
| return value.strip() |
|
|
|
|
| def extract_urls(text: str) -> list[str]: |
| urls = re.findall(r"https?://[^\s<>\"]+", text) |
| return [url.rstrip(".,);]\"'") for url in urls] |
|
|
|
|
| def is_youtube_url(url: str) -> bool: |
| host = urlparse(url).netloc.lower() |
| return "youtube.com" in host or "youtu.be" in host |
|
|
|
|
| def read_plain_file(file_path, limit: int = 12000) -> str: |
| try: |
| return truncate_text(file_path.read_text(encoding="utf-8", errors="replace"), limit) |
| except Exception as exc: |
| return f"读取文件失败:{exc}" |
|
|