Spaces:
Sleeping
Sleeping
import os | |
import gradio as gr | |
from huggingface_hub import InferenceClient | |
from datetime import datetime | |
import logging | |
from typing import Dict, List, Optional | |
# Configuração do logging | |
logging.basicConfig(level=logging.INFO) | |
logger = logging.getLogger(__name__) | |
# Substitua com sua chave de API | |
HF_API_KEY = "hf_seu_token_aqui" | |
class DocumentManager: | |
"""Gerencia templates e contextos dos documentos""" | |
def create_prompt_messages(doc_type: str, context: Dict[str, str]) -> List[Dict[str, str]]: | |
"""Cria a sequência de mensagens para o modelo""" | |
system_message = { | |
"role": "system", | |
"content": """Você é um advogado criminalista brasileiro altamente experiente, especializado em redigir peças processuais. | |
Gere documentos jurídicos formais, tecnicamente precisos e no formato do direito brasileiro.""" | |
} | |
user_message = { | |
"role": "user", | |
"content": f"""Por favor, gere um {doc_type} completo e tecnicamente preciso com os seguintes dados: | |
QUALIFICAÇÃO: | |
Cliente: {context.get('client_name')} | |
Processo: {context.get('process_number')} | |
Tribunal: {context.get('court')} | |
Comarca: {context.get('jurisdiction')} | |
FATOS: | |
{context.get('facts')} | |
FUNDAMENTOS JURÍDICOS: | |
{context.get('legal_basis')} | |
O documento deve seguir a formatação jurídica padrão, incluindo: | |
1. Cabeçalho com endereçamento correto | |
2. Qualificação completa das partes | |
3. Exposição clara dos fatos | |
4. Fundamentação jurídica sólida | |
5. Pedidos específicos | |
6. Fechamento formal com local, data e espaço para assinatura""" | |
} | |
return [system_message, user_message] | |
class DocumentGenerator: | |
"""Gerencia a geração de documentos usando HuggingFace Inference API""" | |
def __init__(self, api_key: str): | |
self.client = InferenceClient(api_key=api_key) | |
self.model = "mistralai/Mistral-7B-Instruct-v0.2" | |
self.doc_manager = DocumentManager() | |
def generate(self, doc_type: str, context: Dict[str, str]) -> str: | |
"""Gera o documento usando o modelo""" | |
try: | |
# Prepara as mensagens | |
messages = self.doc_manager.create_prompt_messages(doc_type, context) | |
# Faz a chamada à API | |
completion = self.client.chat.completions.create( | |
model=self.model, | |
messages=messages, | |
temperature=0.3, # Mais conservador para documentos formais | |
top_p=0.85, # Mantém coerência | |
max_tokens=2048, # Documento completo | |
) | |
return self._format_output(completion.choices[0].message.content) | |
except Exception as e: | |
logger.error(f"Erro na geração: {str(e)}") | |
return f"Erro na geração do documento: {str(e)}" | |
def _format_output(self, text: str) -> str: | |
"""Formata o texto gerado""" | |
if not text: | |
return "Erro: Nenhum texto gerado" | |
# Remove espaços extras e formata parágrafos | |
lines = [line.strip() for line in text.split('\n') if line.strip()] | |
formatted_text = '\n\n'.join(lines) | |
return formatted_text.strip() | |
class WebInterface: | |
"""Interface Gradio para o gerador de documentos""" | |
def __init__(self): | |
self.generator = DocumentGenerator(api_key=HF_API_KEY) | |
self.create_interface() | |
def create_interface(self): | |
"""Cria a interface web com Gradio""" | |
with gr.Blocks(theme=gr.themes.Soft()) as self.app: | |
gr.Markdown(""" | |
# Criminal.ai - Gerador de Peças Processuais | |
### Sistema Inteligente de Geração de Documentos Jurídicos | |
""") | |
with gr.Row(): | |
with gr.Column(): | |
# Tipo de documento | |
doc_type = gr.Dropdown( | |
choices=[ | |
"Habeas Corpus", | |
"Denúncia Criminal", | |
"Alegações Finais", | |
"Resposta à Acusação", | |
"Recurso em Sentido Estrito", | |
"Apelação Criminal" | |
], | |
label="Tipo de Documento", | |
value="Habeas Corpus", | |
info="Selecione o tipo de peça processual" | |
) | |
# Informações do processo | |
with gr.Group(): | |
gr.Markdown("### Informações do Processo") | |
client_name = gr.Textbox( | |
label="Nome do Cliente", | |
placeholder="Nome completo do cliente/paciente", | |
info="Digite o nome completo" | |
) | |
process_number = gr.Textbox( | |
label="Número do Processo", | |
placeholder="NNNNNNN-NN.NNNN.N.NN.NNNN", | |
info="Número CNJ do processo" | |
) | |
court = gr.Textbox( | |
label="Tribunal", | |
value="TRIBUNAL DE JUSTIÇA DO ESTADO", | |
info="Nome completo do tribunal" | |
) | |
jurisdiction = gr.Textbox( | |
label="Comarca", | |
placeholder="Nome da comarca", | |
info="Comarca onde tramita o processo" | |
) | |
# Detalhes do caso | |
with gr.Group(): | |
gr.Markdown("### Detalhes do Caso") | |
facts = gr.Textbox( | |
label="Fatos", | |
lines=5, | |
placeholder="Descreva os fatos relevantes do caso...", | |
info="Descreva os fatos de forma clara e objetiva" | |
) | |
legal_basis = gr.Textbox( | |
label="Fundamentos Jurídicos", | |
lines=3, | |
placeholder="Indique os fundamentos legais...", | |
info="Artigos, jurisprudência e doutrina aplicáveis" | |
) | |
# Status e botões | |
with gr.Row(): | |
generate_btn = gr.Button( | |
"📝 Gerar Documento", | |
variant="primary", | |
scale=2 | |
) | |
clear_btn = gr.Button( | |
"🗑️ Limpar", | |
variant="secondary", | |
scale=1 | |
) | |
status = gr.Textbox( | |
label="Status", | |
interactive=False, | |
show_label=False | |
) | |
# Coluna de saída | |
with gr.Column(): | |
output = gr.Textbox( | |
label="Documento Gerado", | |
lines=30, | |
show_copy_button=True, | |
show_label=True, | |
container=True | |
) | |
with gr.Row(): | |
copy_btn = gr.Button("📋 Copiar") | |
download_btn = gr.Button("💾 Salvar como .txt") | |
# Exemplos | |
gr.Examples( | |
examples=[ | |
[ | |
"Habeas Corpus", | |
"João da Silva Santos", | |
"0000123-45.2024.8.26.0000", | |
"TRIBUNAL DE JUSTIÇA DO ESTADO DE SÃO PAULO", | |
"São Paulo", | |
"Paciente preso em flagrante no dia 25/12/2024 por suposto furto simples (art. 155, caput, do CP). Não estão presentes os requisitos da prisão preventiva, sendo o paciente primário, com residência fixa e trabalho lícito.", | |
"Art. 5º, LXVIII da CF/88; Art. 647 do CPP; Art. 312 do CPP; Súmula 308 do STJ." | |
] | |
], | |
inputs=[ | |
doc_type, client_name, process_number, | |
court, jurisdiction, facts, legal_basis | |
] | |
) | |
# Eventos | |
generate_btn.click( | |
fn=self._generate_document, | |
inputs=[ | |
doc_type, client_name, process_number, | |
court, jurisdiction, facts, legal_basis | |
], | |
outputs=[output, status] | |
) | |
def clear_inputs(): | |
return [ | |
gr.update(value="") for _ in range(6) | |
] + [gr.update(value="Campos limpos")] | |
clear_btn.click( | |
fn=clear_inputs, | |
inputs=[], | |
outputs=[ | |
client_name, process_number, court, | |
jurisdiction, facts, legal_basis, | |
status | |
] | |
) | |
copy_btn.click( | |
fn=lambda x: gr.update(value=x), | |
inputs=[output], | |
outputs=[output] | |
) | |
def save_document(text): | |
if not text: | |
return "Nenhum documento para salvar" | |
filename = f"documento_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt" | |
with open(filename, 'w', encoding='utf-8') as f: | |
f.write(text) | |
return f"Documento salvo como {filename}" | |
download_btn.click( | |
fn=save_document, | |
inputs=[output], | |
outputs=[status] | |
) | |
def _generate_document( | |
self, doc_type: str, client_name: str, | |
process_number: str, court: str, | |
jurisdiction: str, facts: str, | |
legal_basis: str | |
) -> tuple: | |
"""Gera o documento com os parâmetros fornecidos""" | |
try: | |
# Validação básica | |
if not all([client_name, process_number, facts, legal_basis]): | |
return "⚠️ Erro: Todos os campos obrigatórios devem ser preenchidos", "⚠️ Preencha todos os campos obrigatórios" | |
context = { | |
"client_name": client_name, | |
"process_number": process_number, | |
"court": court, | |
"jurisdiction": jurisdiction, | |
"facts": facts, | |
"legal_basis": legal_basis | |
} | |
# Atualiza status | |
yield "", "⏳ Gerando documento..." | |
# Gera documento | |
result = self.generator.generate(doc_type, context) | |
return result, "✅ Documento gerado com sucesso!" | |
except Exception as e: | |
logger.error(f"Erro: {str(e)}") | |
return "", f"❌ Erro: {str(e)}" | |
def launch(self): | |
"""Inicia a interface web""" | |
self.app.launch(share=True) | |
if __name__ == "__main__": | |
# Verificar token | |
if HF_API_KEY == "hf_seu_token_aqui": | |
print("⚠️ Atenção: Configure sua API key do Hugging Face antes de executar!") | |
print("Substitua 'hf_seu_token_aqui' pela sua chave real.") | |
else: | |
interface = WebInterface() | |
interface.launch() |