from __future__ import annotations """Citation management for source tracking.""" from dataclasses import dataclass, field from typing import Any from urllib.parse import urlparse @dataclass class Citation: """A source citation.""" title: str url: str snippet: str = "" accessed_at: str = "" reliability_score: float = 0.5 class CitationManager: """Manages citations and source tracking.""" def __init__(self): """Initialize the citation manager.""" self._citations: list[Citation] = [] self._url_index: dict[str, int] = {} def add_citation( self, title: str, url: str, snippet: str = "", ) -> int: """Add a citation and return its index. Args: title: Source title url: Source URL snippet: Relevant text snippet Returns: Citation index (1-based) """ # Check if URL already exists if url in self._url_index: return self._url_index[url] # Calculate reliability score based on domain reliability = self._assess_reliability(url) citation = Citation( title=title, url=url, snippet=snippet, reliability_score=reliability, ) self._citations.append(citation) index = len(self._citations) self._url_index[url] = index return index def get_citation(self, index: int) -> Citation | None: """Get a citation by index. Args: index: Citation index (1-based) Returns: Citation or None if not found """ if 1 <= index <= len(self._citations): return self._citations[index - 1] return None def get_all_citations(self) -> list[Citation]: """Get all citations. Returns: List of all citations """ return list(self._citations) def format_inline(self, index: int) -> str: """Format an inline citation reference. Args: index: Citation index Returns: Formatted inline citation [n] """ return f"[{index}]" def format_bibliography(self, style: str = "markdown") -> str: """Format all citations as a bibliography. Args: style: Output style (markdown, plain, html) Returns: Formatted bibliography """ if not self._citations: return "" lines = [] if style == "markdown": lines.append("**Sources:**") for i, cite in enumerate(self._citations, 1): lines.append(f"[{i}] [{cite.title}]({cite.url})") elif style == "plain": lines.append("Sources:") for i, cite in enumerate(self._citations, 1): lines.append(f"{i}. {cite.title}") lines.append(f" {cite.url}") elif style == "html": lines.append("