agentsociety2.skills.literature.formatter 源代码

"""Literature formatting utilities

Functions for formatting literature entries as markdown and managing filenames.
"""

from __future__ import annotations

import re
from datetime import datetime, timezone
from typing import Dict, Any


[文档] def sanitize_filename(filename: str) -> str: """Clean filename by removing illegal characters :param filename: Original filename :returns: Sanitized filename safe for filesystem """ # Remove or replace illegal characters sanitized = re.sub(r'[<>:"/\\|?*]', "_", filename) sanitized = re.sub(r"\s+", "_", sanitized) sanitized = re.sub(r"_{2,}", "_", sanitized) return sanitized[:100] # Limit length
[文档] def format_article_as_markdown(article: Dict[str, Any], query: str) -> str: """Format a single literature article as markdown :param article: Article data dictionary :param query: Search query used to find the article :returns: Markdown formatted string """ lines = [] lines.append(f"# {article.get('title', 'Untitled Article')}") lines.append("") lines.append(f"**Search Query:** {query}") lines.append("") lines.append(f"**Saved At:** {datetime.now(timezone.utc).isoformat()}") lines.append("") if article.get("year"): lines.append(f"**Year:** {article['year']}") lines.append("") if article.get("journal"): lines.append(f"**Journal:** {article['journal']}") lines.append("") # 处理 DOI 和 URL doi = article.get("doi", "") url = article.get("url", "") source = article.get("source", "") if doi: doi_url = f"https://doi.org/{doi}" if not doi.startswith("http") else doi lines.append(f"**DOI:** [{doi}]({doi_url})") lines.append("") if url and not doi: lines.append(f"**URL:** [Open Link]({url})") lines.append("") if source: source_name = article.get("source_name", source) # 为外部数据源添加提示 if source in ["arxiv", "crossref", "openalex"]: lines.append(f"**Source:** {source_name} (external)") else: lines.append(f"**Source:** {source_name}") lines.append("") if article.get("avg_similarity") is not None: lines.append(f"**Score:** {article['avg_similarity']:.3f}") lines.append("") if article.get("authors"): authors = article["authors"] if isinstance(authors, list): lines.append(f"**Authors:** {', '.join(authors)}") else: lines.append(f"**Authors:** {authors}") lines.append("") if article.get("abstract"): lines.append("## Abstract") lines.append("") lines.append(article["abstract"]) lines.append("") # Add chunks if available chunks = article.get("chunks", []) if chunks: lines.append("## Relevant Content") lines.append("") for i, chunk in enumerate(chunks[:3], 1): content = chunk.get("content", "") similarity = chunk.get("similarity", 0) lines.append(f"### Chunk {i} (similarity: {similarity:.3f})") lines.append("") lines.append(content[:1000] + "..." if len(content) > 1000 else content) lines.append("") # Add other fields exclude_fields = {"title", "journal", "doi", "abstract", "avg_similarity", "year", "url", "source", "source_name", "authors", "chunks"} first_extra = True for key, value in article.items(): if key not in exclude_fields and value is not None: if first_extra: lines.append("**Other Fields:**") lines.append("") first_extra = False lines.append(f"- **{key}:** {value}") if not first_extra: lines.append("") return "\n".join(lines)