Spaces:
Sleeping
Sleeping
Last commit not found
import logging | |
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM | |
import streamlit as st | |
from agno.agent import Agent | |
from agno.tools.arxiv import ArxivTools | |
from agno.tools.pubmed import PubmedTools | |
from agno.models.base import Model | |
from tenacity import retry, stop_after_attempt, wait_exponential | |
import time | |
import datetime | |
import os | |
MODEL_PATH = "google/flan-t5-small" | |
# Simple Response class to wrap the model output | |
class Response: | |
def __init__(self, content): | |
# Ensure content is a string and not empty | |
if content is None: | |
content = "" | |
if not isinstance(content, str): | |
content = str(content) | |
# Store the content | |
self.content = content | |
# Add tool_calls attribute with default empty list | |
self.tool_calls = [] | |
# Add other attributes that might be needed | |
self.audio = None | |
self.images = [] | |
self.citations = [] | |
self.metadata = {} | |
self.finish_reason = "stop" | |
self.usage = {"prompt_tokens": 0, "completion_tokens": 0, "total_tokens": 0} | |
# Add timestamp attributes | |
current_time = time.time() | |
self.created_at = int(current_time) # Convert to integer | |
self.created = int(current_time) | |
self.timestamp = datetime.datetime.now().isoformat() | |
# Add model info attributes | |
self.id = "local-model-response" | |
self.model = "local-huggingface" | |
self.object = "chat.completion" | |
self.choices = [{"index": 0, "message": {"role": "assistant", "content": content}, "finish_reason": "stop"}] | |
# Add additional attributes that might be needed | |
self.system_fingerprint = "" | |
self.is_truncated = False | |
self.role = "assistant" | |
def __str__(self): | |
return self.content if self.content else "" | |
def __repr__(self): | |
return f"Response(content='{self.content[:50]}{'...' if len(self.content) > 50 else ''}')" | |
# Personnalized class for local models | |
class LocalHuggingFaceModel(Model): | |
def __init__(self, model, tokenizer, max_length=512): | |
super().__init__(id="local-huggingface") | |
self.model = model | |
self.tokenizer = tokenizer | |
self.max_length = max_length | |
async def ainvoke(self, prompt: str, **kwargs) -> str: | |
"""Async invoke method""" | |
try: | |
logging.info(f"ainvoke called with prompt: {prompt[:100] if prompt and isinstance(prompt, str) else 'None'}...") | |
return await self.invoke(prompt, **kwargs) | |
except Exception as e: | |
logging.error(f"Error in ainvoke: {str(e)}") | |
return Response(f"Error in ainvoke: {str(e)}") | |
async def ainvoke_stream(self, prompt: str, **kwargs): | |
"""Async streaming invoke method""" | |
try: | |
logging.info(f"ainvoke_stream called with prompt: {prompt[:100] if prompt and isinstance(prompt, str) else 'None'}...") | |
result = await self.invoke(prompt, **kwargs) | |
yield result | |
except Exception as e: | |
logging.error(f"Error in ainvoke_stream: {str(e)}") | |
yield Response(f"Error in ainvoke_stream: {str(e)}") | |
def invoke(self, prompt: str, **kwargs) -> str: | |
"""Synchronous invoke method""" | |
try: | |
logging.info(f"Invoking model with prompt: {prompt[:100] if prompt and isinstance(prompt, str) else 'None'}...") | |
# Check if prompt is None or empty | |
if prompt is None: | |
logging.warning("None prompt provided to invoke method") | |
return Response("No input provided. Please provide a valid prompt.") | |
if not isinstance(prompt, str): | |
logging.warning(f"Non-string prompt provided: {type(prompt)}") | |
try: | |
prompt = str(prompt) | |
logging.info(f"Converted prompt to string: {prompt[:100]}...") | |
except: | |
return Response("Invalid input type. Please provide a string prompt.") | |
if not prompt.strip(): | |
logging.warning("Empty prompt provided to invoke method") | |
return Response("No input provided. Please provide a non-empty prompt.") | |
inputs = self.tokenizer(prompt, return_tensors="pt", padding=True) | |
# Configure generation parameters | |
generation_config = { | |
"max_length": self.max_length, | |
"num_return_sequences": 1, | |
"do_sample": kwargs.get("do_sample", False), | |
"temperature": kwargs.get("temperature", 1.0), | |
"top_p": kwargs.get("top_p", 1.0), | |
} | |
# Generate the answer | |
outputs = self.model.generate(**inputs, **generation_config) | |
decoded_output = self.tokenizer.decode(outputs[0], skip_special_tokens=True) | |
# Check if output is empty | |
if not decoded_output or not decoded_output.strip(): | |
logging.warning("Model generated empty output") | |
return Response("The model did not generate any output. Please try with a different prompt.") | |
logging.info(f"Model generated output: {decoded_output[:100]}...") | |
return Response(decoded_output) | |
except Exception as e: | |
logging.error(f"Error in local model generation: {str(e)}") | |
if hasattr(e, 'args') and len(e.args) > 0: | |
error_message = e.args[0] | |
else: | |
error_message = str(e) | |
return Response(f"Error during generation: {error_message}") | |
def invoke_stream(self, prompt: str, **kwargs): | |
"""Synchronous streaming invoke method""" | |
try: | |
logging.info(f"invoke_stream called with prompt: {prompt[:100] if prompt and isinstance(prompt, str) else 'None'}...") | |
result = self.invoke(prompt, **kwargs) | |
yield result | |
except Exception as e: | |
logging.error(f"Error in invoke_stream: {str(e)}") | |
yield Response(f"Error in invoke_stream: {str(e)}") | |
def parse_provider_response(self, response: str) -> str: | |
"""Parse the provider response""" | |
return response | |
def parse_provider_response_delta(self, delta: str) -> str: | |
"""Parse the provider response delta for streaming""" | |
return delta | |
async def aresponse(self, prompt=None, **kwargs): | |
"""Async response method - required abstract method""" | |
try: | |
# Log detalhado de todos os argumentos | |
logging.info(f"aresponse args: prompt={prompt}, kwargs keys={list(kwargs.keys())}") | |
# Extrair o prompt das mensagens se estiverem disponíveis | |
if prompt is None and 'messages' in kwargs and kwargs['messages']: | |
messages = kwargs['messages'] | |
# Procurar pela mensagem do usuário | |
for message in messages: | |
if hasattr(message, 'role') and message.role == 'user' and hasattr(message, 'content'): | |
prompt = message.content | |
logging.info(f"Extracted prompt from user message: {prompt[:100] if prompt and isinstance(prompt, str) else 'None'}") | |
break | |
# Verificar se o prompt está em kwargs['input'] | |
if prompt is None: | |
if 'input' in kwargs: | |
prompt = kwargs.get('input') | |
logging.info(f"Found prompt in kwargs['input']: {prompt[:100] if prompt and isinstance(prompt, str) else 'None'}") | |
logging.info(f"aresponse called with prompt: {prompt[:100] if prompt and isinstance(prompt, str) else 'None'}...") | |
if not prompt or not isinstance(prompt, str) or not prompt.strip(): | |
logging.warning("Empty or invalid prompt in aresponse") | |
return Response("No input provided. Please provide a valid prompt.") | |
content = await self.ainvoke(prompt, **kwargs) | |
return content if isinstance(content, Response) else Response(content) | |
except Exception as e: | |
logging.error(f"Error in aresponse: {str(e)}") | |
return Response(f"Error in aresponse: {str(e)}") | |
def response(self, prompt=None, **kwargs): | |
"""Synchronous response method - required abstract method""" | |
try: | |
# Log detalhado de todos os argumentos | |
logging.info(f"response args: prompt={prompt}, kwargs keys={list(kwargs.keys())}") | |
# Extrair o prompt das mensagens se estiverem disponíveis | |
if prompt is None and 'messages' in kwargs and kwargs['messages']: | |
messages = kwargs['messages'] | |
# Procurar pela mensagem do usuário | |
for message in messages: | |
if hasattr(message, 'role') and message.role == 'user' and hasattr(message, 'content'): | |
prompt = message.content | |
logging.info(f"Extracted prompt from user message: {prompt[:100] if prompt and isinstance(prompt, str) else 'None'}") | |
break | |
# Verificar se o prompt está em kwargs['input'] | |
if prompt is None: | |
if 'input' in kwargs: | |
prompt = kwargs.get('input') | |
logging.info(f"Found prompt in kwargs['input']: {prompt[:100] if prompt and isinstance(prompt, str) else 'None'}") | |
logging.info(f"response called with prompt: {prompt[:100] if prompt and isinstance(prompt, str) else 'None'}...") | |
if not prompt or not isinstance(prompt, str) or not prompt.strip(): | |
logging.warning("Empty or invalid prompt in response") | |
return Response("No input provided. Please provide a valid prompt.") | |
content = self.invoke(prompt, **kwargs) | |
return content if isinstance(content, Response) else Response(content) | |
except Exception as e: | |
logging.error(f"Error in response: {str(e)}") | |
return Response(f"Error in response: {str(e)}") | |
def response_stream(self, prompt=None, **kwargs): | |
"""Synchronous streaming response method - required abstract method""" | |
try: | |
# Log detalhado de todos os argumentos | |
logging.info(f"response_stream args: prompt={prompt}, kwargs keys={list(kwargs.keys())}") | |
# Extrair o prompt das mensagens se estiverem disponíveis | |
if prompt is None and 'messages' in kwargs and kwargs['messages']: | |
messages = kwargs['messages'] | |
# Procurar pela mensagem do usuário | |
for message in messages: | |
if hasattr(message, 'role') and message.role == 'user' and hasattr(message, 'content'): | |
prompt = message.content | |
logging.info(f"Extracted prompt from user message: {prompt[:100] if prompt and isinstance(prompt, str) else 'None'}") | |
break | |
# Verificar se o prompt está em kwargs['input'] | |
if prompt is None: | |
if 'input' in kwargs: | |
prompt = kwargs.get('input') | |
logging.info(f"Found prompt in kwargs['input']: {prompt[:100] if prompt and isinstance(prompt, str) else 'None'}") | |
logging.info(f"response_stream called with prompt: {prompt[:100] if prompt and isinstance(prompt, str) else 'None'}...") | |
if not prompt or not isinstance(prompt, str) or not prompt.strip(): | |
logging.warning("Empty or invalid prompt in response_stream") | |
yield Response("No input provided. Please provide a valid prompt.") | |
return | |
for chunk in self.invoke_stream(prompt, **kwargs): | |
yield chunk if isinstance(chunk, Response) else Response(chunk) | |
except Exception as e: | |
logging.error(f"Error in response_stream: {str(e)}") | |
yield Response(f"Error in response_stream: {str(e)}") | |
def generate(self, prompt: str, **kwargs): | |
try: | |
inputs = self.tokenizer(prompt, return_tensors="pt", padding=True) | |
# Configure generation parameters | |
generation_config = { | |
"max_length": self.max_length, | |
"num_return_sequences": 1, | |
"do_sample": kwargs.get("do_sample", False), | |
"temperature": kwargs.get("temperature", 1.0), | |
"top_p": kwargs.get("top_p", 1.0), | |
} | |
# Generate the answer | |
outputs = self.model.generate(**inputs, **generation_config) | |
decoded_output = self.tokenizer.decode(outputs[0], skip_special_tokens=True) | |
return decoded_output | |
except Exception as e: | |
logging.error(f"Error in generate method: {str(e)}") | |
if hasattr(e, 'args') and len(e.args) > 0: | |
error_message = e.args[0] | |
else: | |
error_message = str(e) | |
return f"Error during generation: {error_message}" | |
class DummyModel(Model): | |
def __init__(self): | |
super().__init__(id="dummy-model") | |
async def ainvoke(self, prompt: str, **kwargs) -> str: | |
"""Async invoke method""" | |
return await self.invoke(prompt=prompt, **kwargs) | |
async def ainvoke_stream(self, prompt: str, **kwargs): | |
"""Async streaming invoke method""" | |
result = await self.invoke(prompt=prompt, **kwargs) | |
yield result | |
def invoke(self, prompt: str, **kwargs) -> str: | |
"""Synchronous invoke method""" | |
return Response("Sorry, the model is not available. Please try again later.") | |
def invoke_stream(self, prompt: str, **kwargs): | |
"""Synchronous streaming invoke method""" | |
result = self.invoke(prompt=prompt, **kwargs) | |
yield result | |
def parse_provider_response(self, response: str) -> str: | |
"""Parse the provider response""" | |
return response | |
def parse_provider_response_delta(self, delta: str) -> str: | |
"""Parse the provider response delta for streaming""" | |
return delta | |
async def aresponse(self, prompt=None, **kwargs): | |
"""Async response method - required abstract method""" | |
try: | |
# Log detalhado de todos os argumentos | |
logging.info(f"aresponse args: prompt={prompt}, kwargs keys={list(kwargs.keys())}") | |
# Extrair o prompt das mensagens se estiverem disponíveis | |
if prompt is None and 'messages' in kwargs and kwargs['messages']: | |
messages = kwargs['messages'] | |
# Procurar pela mensagem do usuário | |
for message in messages: | |
if hasattr(message, 'role') and message.role == 'user' and hasattr(message, 'content'): | |
prompt = message.content | |
logging.info(f"Extracted prompt from user message: {prompt[:100] if prompt and isinstance(prompt, str) else 'None'}") | |
break | |
# Verificar se o prompt está em kwargs['input'] | |
if prompt is None: | |
if 'input' in kwargs: | |
prompt = kwargs.get('input') | |
logging.info(f"Found prompt in kwargs['input']: {prompt[:100] if prompt and isinstance(prompt, str) else 'None'}") | |
logging.info(f"aresponse called with prompt: {prompt[:100] if prompt and isinstance(prompt, str) else 'None'}...") | |
if not prompt or not isinstance(prompt, str) or not prompt.strip(): | |
logging.warning("Empty or invalid prompt in aresponse") | |
return Response("No input provided. Please provide a valid prompt.") | |
content = await self.ainvoke(prompt, **kwargs) | |
return content if isinstance(content, Response) else Response(content) | |
except Exception as e: | |
logging.error(f"Error in aresponse: {str(e)}") | |
return Response(f"Error in aresponse: {str(e)}") | |
def response(self, prompt=None, **kwargs): | |
"""Synchronous response method - required abstract method""" | |
try: | |
# Log detalhado de todos os argumentos | |
logging.info(f"response args: prompt={prompt}, kwargs keys={list(kwargs.keys())}") | |
# Extrair o prompt das mensagens se estiverem disponíveis | |
if prompt is None and 'messages' in kwargs and kwargs['messages']: | |
messages = kwargs['messages'] | |
# Procurar pela mensagem do usuário | |
for message in messages: | |
if hasattr(message, 'role') and message.role == 'user' and hasattr(message, 'content'): | |
prompt = message.content | |
logging.info(f"Extracted prompt from user message: {prompt[:100] if prompt and isinstance(prompt, str) else 'None'}") | |
break | |
# Verificar se o prompt está em kwargs['input'] | |
if prompt is None: | |
if 'input' in kwargs: | |
prompt = kwargs.get('input') | |
logging.info(f"Found prompt in kwargs['input']: {prompt[:100] if prompt and isinstance(prompt, str) else 'None'}") | |
logging.info(f"response called with prompt: {prompt[:100] if prompt and isinstance(prompt, str) else 'None'}...") | |
if not prompt or not isinstance(prompt, str) or not prompt.strip(): | |
logging.warning("Empty or invalid prompt in response") | |
return Response("No input provided. Please provide a valid prompt.") | |
content = self.invoke(prompt, **kwargs) | |
return content if isinstance(content, Response) else Response(content) | |
except Exception as e: | |
logging.error(f"Error in response: {str(e)}") | |
return Response(f"Error in response: {str(e)}") | |
def response_stream(self, prompt=None, **kwargs): | |
"""Synchronous streaming response method - required abstract method""" | |
try: | |
# Log detalhado de todos os argumentos | |
logging.info(f"response_stream args: prompt={prompt}, kwargs keys={list(kwargs.keys())}") | |
# Extrair o prompt das mensagens se estiverem disponíveis | |
if prompt is None and 'messages' in kwargs and kwargs['messages']: | |
messages = kwargs['messages'] | |
# Procurar pela mensagem do usuário | |
for message in messages: | |
if hasattr(message, 'role') and message.role == 'user' and hasattr(message, 'content'): | |
prompt = message.content | |
logging.info(f"Extracted prompt from user message: {prompt[:100] if prompt and isinstance(prompt, str) else 'None'}") | |
break | |
# Verificar se o prompt está em kwargs['input'] | |
if prompt is None: | |
if 'input' in kwargs: | |
prompt = kwargs.get('input') | |
logging.info(f"Found prompt in kwargs['input']: {prompt[:100] if prompt and isinstance(prompt, str) else 'None'}") | |
logging.info(f"response_stream called with prompt: {prompt[:100] if prompt and isinstance(prompt, str) else 'None'}...") | |
if not prompt or not isinstance(prompt, str) or not prompt.strip(): | |
logging.warning("Empty or invalid prompt in response_stream") | |
yield Response("No input provided. Please provide a valid prompt.") | |
return | |
for chunk in self.invoke_stream(prompt, **kwargs): | |
yield chunk if isinstance(chunk, Response) else Response(chunk) | |
except Exception as e: | |
logging.error(f"Error in response_stream: {str(e)}") | |
yield Response(f"Error in response_stream: {str(e)}") | |
class ModelHandler: | |
""" | |
Classe para gerenciar modelos e gerar respostas. | |
""" | |
def __init__(self): | |
""" | |
Inicializa o ModelHandler. | |
""" | |
self.translator = None | |
self.researcher = None | |
self.presenter = None | |
self.force_default_response = False | |
# Inicializar modelos | |
self._load_models() | |
def _extract_content(self, result): | |
""" | |
Extrai o conteúdo de uma resposta do modelo. | |
Args: | |
result: A resposta do modelo, que pode ser um objeto RunResponse ou uma string | |
Returns: | |
O conteúdo da resposta como string | |
""" | |
try: | |
if result is None: | |
return "" | |
if hasattr(result, 'content'): | |
return result.content | |
return str(result) | |
except Exception as e: | |
logging.error(f"Error extracting content: {str(e)}") | |
return "" | |
def _format_prompt(self, prompt_type, content): | |
""" | |
Formata o prompt de acordo com o tipo. | |
Args: | |
prompt_type: O tipo de prompt (translation, research, presentation) | |
content: O conteúdo a ser incluído no prompt | |
Returns: | |
O prompt formatado | |
""" | |
if not content or not content.strip(): | |
logging.warning(f"Empty content provided to _format_prompt for {prompt_type}") | |
return "No input provided." | |
if prompt_type == "translation": | |
return f"""Task: Translate the following text to English | |
Instructions: | |
Provide a direct English translation of the input text. | |
Input: {content} | |
Output:""" | |
elif prompt_type == "research": | |
return f"""Task: Research Assistant | |
Instructions: | |
You are a research assistant tasked with providing comprehensive information. | |
Please provide a detailed explanation about the topic, including: | |
- Definition and key characteristics | |
- Causes or origins if applicable | |
- Current scientific understanding | |
- Important facts and statistics | |
- Recent developments or research | |
- Real-world implications and applications | |
Aim to write at least 4-5 paragraphs with detailed information. | |
Be thorough and informative, covering all important aspects of the topic. | |
Use clear and accessible language suitable for a general audience. | |
Input: {content} | |
Output:""" | |
elif prompt_type == "presentation": | |
return f"""Task: Presentation Assistant | |
Instructions: | |
You are presenting research findings to a general audience. | |
Please format the information in a clear, engaging, and accessible way. | |
Include: | |
- A clear introduction to the topic with a compelling title | |
- Key points organized with headings or bullet points | |
- Simple explanations of complex concepts | |
- A brief conclusion or summary | |
- Translate the entire response to Portuguese | |
- Add appropriate emojis to make the presentation more engaging | |
- Format the text using markdown for better readability | |
Input: {content} | |
Output:""" | |
else: | |
logging.error(f"Unknown prompt type: {prompt_type}") | |
return f"Unknown prompt type: {prompt_type}" | |
def _load_model(): | |
"""Load the model and tokenizer with retry logic""" | |
# Define retry decorator for model loading | |
def load_with_retry(model_name): | |
try: | |
logging.info(f"Attempting to load model from {model_name}") | |
# Criar diretório de cache se não existir | |
cache_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "model_cache") | |
os.makedirs(cache_dir, exist_ok=True) | |
# Carregar modelo e tokenizer | |
tokenizer = AutoTokenizer.from_pretrained(model_name, cache_dir=cache_dir) | |
model = AutoModelForSeq2SeqLM.from_pretrained(model_name, cache_dir=cache_dir) | |
logging.info(f"Successfully loaded model from {model_name}") | |
return model, tokenizer | |
except Exception as e: | |
logging.error(f"Error loading model {model_name}: {str(e)}") | |
raise | |
# Lista de modelos para tentar, em ordem de preferência | |
model_names = ["google/flan-t5-small", "google/flan-t5-base"] | |
# Tentar carregar cada modelo na lista | |
for model_name in model_names: | |
try: | |
return load_with_retry(model_name) | |
except Exception as e: | |
logging.error(f"Failed to load {model_name}: {str(e)}") | |
continue | |
# Se todos os modelos falharem, retornar None | |
logging.error("All models failed to load") | |
return None, None | |
def _load_models(self): | |
"""Carrega os modelos necessários""" | |
# Inicializar modelo local | |
base_model = self._initialize_local_model() | |
self.translator = Agent( | |
name="Translator", | |
role="You will translate the query to English", | |
model=base_model, | |
goal="Translate to English", | |
instructions=[ | |
"Translate the query to English" | |
] | |
) | |
self.researcher = Agent( | |
name="Researcher", | |
role="You are a research scholar who specializes in autism research.", | |
model=base_model, | |
instructions=[ | |
"You need to understand the context of the question to provide the best answer.", | |
"Be precise and provide detailed information.", | |
"You must create an accessible explanation.", | |
"The content must be for people without autism knowledge.", | |
"Focus on providing comprehensive information about the topic.", | |
"Include definition, characteristics, causes, and current understanding." | |
] | |
) | |
self.presenter = Agent( | |
name="Presenter", | |
role="You are a professional researcher who presents the results of the research.", | |
model=base_model, | |
instructions=[ | |
"You are multilingual", | |
"You must present the results in a clear and engaging manner.", | |
"Format the information with headings and bullet points.", | |
"Provide simple explanations of complex concepts.", | |
"Include a brief conclusion or summary.", | |
"Add emojis to make the presentation more interactive.", | |
"Translate the answer to Portuguese." | |
] | |
) | |
def _initialize_local_model(self): | |
"""Initialize local model as fallback""" | |
model, tokenizer = self._load_model() | |
if model is None or tokenizer is None: | |
# Create a dummy model that returns a helpful message | |
return DummyModel() | |
return LocalHuggingFaceModel(model, tokenizer) | |
def generate_answer(self, query: str) -> str: | |
""" | |
Gera uma resposta baseada na consulta do usuário. | |
Args: | |
query: A consulta do usuário | |
Returns: | |
Uma resposta formatada | |
""" | |
try: | |
if not query or not query.strip(): | |
logging.error("Empty query provided") | |
return "Erro: Por favor, forneça uma consulta não vazia." | |
logging.info(f"Generating answer for query: {query}") | |
# Verificar se os modelos estão disponíveis | |
if not self.translator or not self.researcher or not self.presenter: | |
logging.error("Models not available") | |
return "Desculpe, o serviço está temporariamente indisponível. Por favor, tente novamente mais tarde." | |
# Traduzir a consulta para inglês | |
translation_prompt = self._format_prompt("translation", query) | |
logging.info(f"Translation prompt: {translation_prompt}") | |
try: | |
translation_result = self.translator.run(translation_prompt) | |
logging.info(f"Translation result type: {type(translation_result)}") | |
# Extrair o conteúdo da resposta | |
translation_content = self._extract_content(translation_result) | |
logging.info(f"Translation content: {translation_content}") | |
if not translation_content or not translation_content.strip(): | |
logging.error("Empty translation result") | |
return "Desculpe, não foi possível processar sua consulta. Por favor, tente novamente com uma pergunta diferente." | |
# Se forçar resposta padrão, pular a pesquisa e usar diretamente a resposta padrão | |
if self.force_default_response: | |
logging.info("Forcing default response") | |
research_content = self._get_default_research_content(translation_content) | |
else: | |
# Realizar a pesquisa | |
research_prompt = self._format_prompt("research", translation_content) | |
logging.info(f"Research prompt: {research_prompt}") | |
research_result = self.researcher.run(research_prompt) | |
logging.info(f"Research result type: {type(research_result)}") | |
# Extrair o conteúdo da pesquisa | |
research_content = self._extract_content(research_result) | |
logging.info(f"Research content: {research_content}") | |
# Verificar se a resposta da pesquisa é muito curta | |
research_length = len(research_content.strip()) if research_content and isinstance(research_content, str) else 0 | |
logging.info(f"Research content length: {research_length} characters") | |
if not research_content or not research_content.strip() or research_length < 150: | |
logging.warning(f"Research result too short ({research_length} chars), trying with a more specific prompt") | |
# Tentar novamente com um prompt mais específico | |
enhanced_prompt = f"""Task: Detailed Research | |
Instructions: | |
Provide a comprehensive explanation about '{translation_content}'. | |
Include definition, characteristics, causes, and current understanding. | |
Write at least 4-5 paragraphs with detailed information. | |
Be thorough and informative, covering all important aspects of the topic. | |
Use clear and accessible language suitable for a general audience. | |
Output:""" | |
logging.info(f"Enhanced research prompt: {enhanced_prompt}") | |
research_result = self.researcher.run(enhanced_prompt) | |
research_content = self._extract_content(research_result) | |
research_length = len(research_content.strip()) if research_content and isinstance(research_content, str) else 0 | |
logging.info(f"Enhanced research content: {research_content}") | |
logging.info(f"Enhanced research content length: {research_length} characters") | |
# Se ainda estiver vazio ou muito curto, usar uma resposta padrão | |
if not research_content or not research_content.strip() or research_length < 150: | |
logging.warning(f"Research result still too short ({research_length} chars), using default response") | |
# Usar resposta padrão | |
logging.info("Using default research content") | |
research_content = self._get_default_research_content(translation_content) | |
# Se forçar resposta padrão, pular a apresentação e usar diretamente a resposta padrão | |
if self.force_default_response: | |
logging.info("Forcing default presentation") | |
presentation_content = self._get_default_presentation_content() | |
else: | |
# Apresentar os resultados | |
presentation_prompt = self._format_prompt("presentation", research_content) | |
logging.info(f"Presentation prompt: {presentation_prompt}") | |
presentation_result = self.presenter.run(presentation_prompt) | |
logging.info(f"Presentation type: {type(presentation_result)}") | |
# Extrair o conteúdo da apresentação | |
presentation_content = self._extract_content(presentation_result) | |
logging.info(f"Presentation content: {presentation_content}") | |
# Verificar se a apresentação é muito curta | |
presentation_length = len(presentation_content.strip()) if presentation_content and isinstance(presentation_content, str) else 0 | |
logging.info(f"Presentation content length: {presentation_length} characters") | |
if not presentation_content or not presentation_content.strip() or presentation_length < 150: | |
logging.warning(f"Presentation result too short ({presentation_length} chars), using default presentation") | |
# Usar apresentação padrão | |
logging.info("Using default presentation content") | |
presentation_content = self._get_default_presentation_content() | |
logging.info("Answer generated successfully") | |
return presentation_content | |
except Exception as e: | |
logging.error(f"Error during answer generation: {str(e)}") | |
return f"Desculpe, ocorreu um erro ao processar sua consulta: {str(e)}. Por favor, tente novamente mais tarde." | |
except Exception as e: | |
logging.error(f"Unexpected error in generate_answer: {str(e)}") | |
return "Desculpe, ocorreu um erro inesperado. Por favor, tente novamente mais tarde." | |
def _get_default_research_content(self, topic: str) -> str: | |
""" | |
Retorna um conteúdo de pesquisa padrão para o tópico. | |
Args: | |
topic: O tópico da pesquisa | |
Returns: | |
Conteúdo de pesquisa padrão | |
""" | |
return f"""Information about {topic}: | |
Autism is a complex neurodevelopmental disorder that affects communication, social interaction, and behavior. It is characterized by challenges with social skills, repetitive behaviors, speech, and nonverbal communication. | |
The condition is part of a broader category called autism spectrum disorder (ASD), which reflects the wide variation in challenges and strengths possessed by each person with autism. Some individuals with autism may require significant support in their daily lives, while others may need less support and, in some cases, live entirely independently. | |
Autism is believed to be caused by a combination of genetic and environmental factors. Research suggests that certain genetic mutations may increase the risk of autism, as well as various environmental factors that influence early brain development. There is no single cause for autism, making it a complex condition to understand and treat. | |
Early diagnosis and intervention are important for improving outcomes for individuals with autism. Various therapies and support strategies can help people with autism develop skills and cope with challenges. These may include behavioral therapy, speech therapy, occupational therapy, and educational support. | |
It's important to note that autism is not a disease to be cured but a different way of experiencing and interacting with the world. Many people with autism have exceptional abilities in visual skills, music, math, and art, among other areas.""" | |
def _get_default_presentation_content(self) -> str: | |
""" | |
Retorna um conteúdo de apresentação padrão. | |
Returns: | |
Conteúdo de apresentação padrão | |
""" | |
return """🧠 **Autismo: Entendendo o Espectro** 🧠 | |
## O que é o Autismo? | |
O autismo é uma condição neurológica complexa que afeta a comunicação, interação social e comportamento. É caracterizado por desafios com habilidades sociais, comportamentos repetitivos, fala e comunicação não verbal. | |
## Características Principais: | |
- 🔄 Comportamentos repetitivos e interesses restritos | |
- 🗣️ Dificuldades na comunicação verbal e não verbal | |
- 👥 Desafios nas interações sociais | |
- 🎭 Dificuldade em entender expressões faciais e emoções | |
- 🔊 Sensibilidade sensorial (sons, luzes, texturas) | |
## Causas e Origens: | |
O autismo é causado por uma combinação de fatores genéticos e ambientais. Pesquisas sugerem que certas mutações genéticas podem aumentar o risco, assim como vários fatores ambientais que influenciam o desenvolvimento inicial do cérebro. | |
## Pontos Importantes: | |
- 📊 O autismo afeta cada pessoa de maneira diferente (por isso é chamado de "espectro") | |
- 🧩 Diagnóstico precoce e intervenção melhoram os resultados | |
- 💪 Muitas pessoas com autismo têm habilidades excepcionais em áreas específicas | |
- 🌈 O autismo não é uma doença a ser curada, mas uma forma diferente de experimentar o mundo | |
## Conclusão: | |
Compreender o autismo é essencial para criar uma sociedade mais inclusiva. Cada pessoa com autismo tem suas próprias forças e desafios únicos, e merece apoio e aceitação. | |
*Fonte: Pesquisas científicas atuais sobre transtornos do espectro autista* | |
""" |