def read_paper(self, paper_id: str, max_pages: int = None) -> Dict[str, Any]:
        """
        Read a paper's content directly by its arXiv ID.
        
        Args:
            paper_id: The arXiv ID of the paper (e.g., '2106.09685')
            max_pages: Maximum number of pages to read (default: None, reads all pages)
            
        Returns:
            Dictionary containing the paper's content and metadata
        """
        import arxiv
        import requests
        import tempfile
        import os
        import PyPDF2
        
        # Create client
        client = arxiv.Client()
        
        # Search for the specific paper
        search = arxiv.Search(id_list=[paper_id])
        
        # Get the paper
        results = list(client.results(search))
        
        if not results:
            return {"error": f"Paper with ID {paper_id} not found"}
        
        paper = results[0]
        
        # Create a temporary directory
        with tempfile.TemporaryDirectory() as temp_dir:
            # Generate filename
            filename = f"{paper_id.replace('/', '_')}.pdf"
            filepath = os.path.join(temp_dir, filename)
            
            # Download the PDF
            try:
                response = requests.get(paper.pdf_url)
                response.raise_for_status()
                
                with open(filepath, 'wb') as f:
                    f.write(response.content)
                
                # Read the PDF content
                with open(filepath, 'rb') as f:
                    pdf_reader = PyPDF2.PdfReader(f)
                    
                    # Get number of pages
                    num_pages = len(pdf_reader.pages)
                    
                    # Limit pages if max_pages is specified
                    if max_pages is not None:
                        num_pages = min(num_pages, max_pages)
                    
                    # Extract text from pages with better handling
                    content = []
                    for page_num in range(num_pages):
                        try:
                            page = pdf_reader.pages[page_num]
                            page_text = page.extract_text()
                            
                            # Skip empty pages or pages with very little content
                            if page_text and len(page_text.strip()) > 20:
                                # Clean up the text
                                page_text = page_text.replace('\n\n', '\n')
                                content.append(f"--- Page {page_num + 1} ---\n{page_text}")
                        except Exception as e:
                            content.append(f"--- Page {page_num + 1} ---\n[Error extracting text: {str(e)}]")
                    
                    # Join all pages with clear separation
                    full_content = "\n\n".join(content)
                    
                    # If we couldn't extract meaningful content, try an alternative approach
                    if not full_content or len(full_content.strip()) < 100:
                        try:
                            # Alternative extraction method
                            full_content = "Content could not be extracted properly. Please try downloading the paper directly."
                            
                            # Include the abstract as a fallback
                            full_content = f"Abstract:\n{paper.summary}\n\n{full_content}"
                        except Exception:
                            full_content = "Failed to extract content from the PDF. Please download the paper directly."
                
                return {
                    "success": True,
                    "paper_id": paper_id,
                    "title": paper.title,
                    "authors": [author.name for author in paper.authors],
                    "summary": paper.summary,
                    "content": full_content,
                    "total_pages": len(pdf_reader.pages),
                    "pages_read": num_pages,
                    "pdf_url": paper.pdf_url
                }
            except Exception as e:
                # If we failed to process the PDF, return the summary at least
                return {
                    "success": False,
                    "paper_id": paper_id,
                    "title": paper.title,
                    "authors": [author.name for author in paper.authors],
                    "summary": paper.summary,
                    "error": str(e),
                    "pdf_url": paper.pdf_url,
                    "note": "Failed to extract content. You can still access the paper directly using the pdf_url."
                }

        Read a paper's content directly by its arXiv ID.
        
        Args:
            paper_id: The arXiv ID of the paper (e.g., '2106.09685')
            max_pages: Maximum number of pages to read (default: None, reads all pages)
            
        Returns:
            Dictionary containing the paper's content and metadata
        
src/upsonic/tools.py