Spaces:
Paused
Paused
import os | |
from dotenv import load_dotenv | |
from pinecone import Pinecone | |
from pinecone_plugins.assistant.models.chat import Message | |
from rich.console import Console | |
from rich.panel import Panel | |
from dataclasses import dataclass | |
from typing import List, Optional, Dict, Generator | |
from pathlib import Path | |
from datetime import datetime | |
load_dotenv() | |
class AssistenteConfig: | |
"""Configuração do assistente""" | |
nome: str | |
instrucoes: str | |
class CriaAssistente: | |
"""Classe responsável por criar e configurar assistentes""" | |
def __init__(self): | |
self.pc = Pinecone(api_key=os.getenv('PINECONE_API_KEY')) | |
self.console = Console() | |
def criar(self, config: AssistenteConfig) -> Dict: | |
"""Cria um novo assistente com as configurações especificadas""" | |
try: | |
assistant = self.pc.assistant.create_assistant( | |
assistant_name=config.nome, | |
instructions=config.instrucoes, | |
timeout=30 | |
) | |
self.console.print( | |
f"[green]✓ Assistente '{config.nome}' criado com sucesso![/green]" | |
) | |
return assistant | |
except Exception as e: | |
self.console.print(f"[red]✗ Erro ao criar assistente: {str(e)}[/red]") | |
raise | |
class Assistente: | |
"""Classe para interagir com assistentes existentes""" | |
def __init__(self, assistant_name: str): | |
self.pc = Pinecone(api_key=os.getenv('PINECONE_API_KEY')) | |
self.console = Console() | |
self.nome = assistant_name | |
self.assistente = self.pc.assistant.Assistant(assistant_name=assistant_name) | |
def get_context(self, query: str) -> List[Dict]: | |
"""Busca snippets relevantes para uma query""" | |
try: | |
response = self.assistente.context(query=query) | |
if response is None: | |
return [] | |
# Verificar se response é um dicionário | |
if isinstance(response, dict): | |
return response.get("snippets", []) | |
# Se for uma lista, retornar diretamente | |
elif isinstance(response, list): | |
return response | |
return [] | |
except Exception as e: | |
self.console.print(f"[red]✗ Erro ao buscar contexto: {str(e)}[/red]") | |
return [] | |
def fazer_pergunta(self, pergunta: str) -> Dict: | |
"""Faz uma pergunta ao assistente com contexto""" | |
try: | |
# Primeiro buscar contexto relevante | |
snippets = self.get_context(pergunta) | |
# Fazer a pergunta | |
msg = Message(content=pergunta) | |
response = self.assistente.chat(messages=[msg]) | |
# Extrair conteúdo e citações | |
content = response["message"]["content"] | |
citations = response.get("citations", []) | |
return { | |
"content": content, | |
"citations": citations, | |
"snippets": snippets # Incluir snippets na resposta | |
} | |
except Exception as e: | |
self.console.print(f"[red]✗ Erro ao fazer pergunta: {str(e)}[/red]") | |
raise | |
def _process_stream(self, chunks: Generator) -> Dict: | |
"""Processa o stream de resposta""" | |
content = "" | |
citations = [] | |
for chunk in chunks: | |
if not chunk: | |
continue | |
# Processar diferentes tipos de chunks | |
if isinstance(chunk, dict): | |
chunk_type = chunk.get("type") | |
if chunk_type == "message_start": | |
continue | |
elif chunk_type == "content_chunk": | |
if "delta" in chunk and "content" in chunk["delta"]: | |
content += chunk["delta"]["content"] | |
elif chunk_type == "citation": | |
citations.append(chunk.get("citation", {})) | |
elif chunk_type == "message_end": | |
if chunk.get("finish_reason") == "stop": | |
break | |
else: | |
content += str(chunk) | |
return { | |
"content": content, | |
"citations": citations | |
} | |
def upload_file(self, file_path: str, timeout: Optional[int] = None) -> Dict: | |
"""Faz upload de um arquivo para o assistente""" | |
try: | |
# Adicionar metadados com nome original do arquivo | |
original_name = Path(file_path).name | |
metadata = { | |
"original_name": original_name, | |
"uploaded_on": datetime.now().isoformat() | |
} | |
response = self.assistente.upload_file( | |
file_path=file_path, | |
timeout=timeout, | |
metadata=metadata | |
) | |
return response | |
except Exception as e: | |
self.console.print(f"[red]✗ Erro ao fazer upload: {str(e)}[/red]") | |
raise | |
def get_files(self) -> List[Dict]: | |
"""Retorna a lista de arquivos carregados no assistente""" | |
try: | |
response = self.assistente.list_files() | |
if isinstance(response, list): | |
return response | |
elif isinstance(response, dict): | |
return response.get("files", []) | |
return [] | |
except Exception as e: | |
self.console.print(f"[red]✗ Erro ao listar arquivos: {str(e)}[/red]") | |
return [] | |