# Extract and combine content recursively from typing import Dict, Optional, Type from langchain.callbacks.manager import ( AsyncCallbackManagerForToolRun, CallbackManagerForToolRun, ) from langchain.pydantic_v1 import BaseModel as BaseModelV1 from langchain.pydantic_v1 import Field as FieldV1 from langchain_community.document_loaders import PlaywrightURLLoader from langchain_core.tools import BaseTool from logger import get_logger from models import BrainSettings from modules.contact_support.controller.settings import ContactsSettings from packages.emails.send_email import send_email from pydantic import BaseModel logger = get_logger(__name__) class EmailInput(BaseModelV1): text: str = FieldV1( ..., title="text", description="text to send in HTML email format. Use pretty formating, use bold, italic, next line, etc...", ) class EmailSenderTool(BaseTool): user_email: str name = "email-sender" description = "useful for when you need to send an email." args_schema: Type[BaseModel] = EmailInput brain_settings: BrainSettings = BrainSettings() contact_settings: ContactsSettings = ContactsSettings() def _run( self, text: str, run_manager: Optional[CallbackManagerForToolRun] = None ) -> Dict: html_body = f"""
Quivr Logo
""" html_body += f""" {text} """ logger.debug(f"Email body: {html_body}") logger.debug(f"Email to: {self.user_email}") logger.debug(f"Email from: {self.contact_settings.resend_contact_sales_from}") try: r = send_email( { "sender": self.contact_settings.resend_contact_sales_from, "to": self.user_email, "reply_to": "no-reply@quivr.app", "subject": "Email from your assistant", "html": html_body, } ) logger.info("Resend response", r) except Exception as e: logger.error(f"Error sending email: {e}") return {"content": "Error sending email because of error: " + str(e)} return {"content": "Email sent"} async def _arun( self, url: str, run_manager: Optional[AsyncCallbackManagerForToolRun] = None ) -> Dict: """Run the tool asynchronously.""" loader = PlaywrightURLLoader(urls=[url], remove_selectors=["header", "footer"]) data = loader.load() extracted_content = "" for page in data: extracted_content += page.page_content return {"content": extracted_content}