Criminal.ai / app.py
DHEIVER's picture
Update app.py
8aff7c3 verified
raw
history blame
11.2 kB
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__)
# Token já definido no ambiente HF Spaces
HF_TOKEN = os.environ.get("HF_TOKEN")
class DocumentGenerator:
"""Gerencia a geração de documentos usando HF Inference API"""
def __init__(self):
self.client = InferenceClient(api_key=HF_TOKEN)
self.model = "mistralai/Mistral-7B-Instruct-v0.2"
def generate(self, doc_type: str, context: Dict[str, str]) -> str:
"""Gera o documento usando o modelo"""
try:
messages = [
{
"role": "system",
"content": """Você é um advogado criminalista brasileiro altamente experiente.
Gere documentos jurídicos seguindo rigorosamente o formato e padrão das peças processuais brasileiras.
Use linguagem formal, técnica e apropriada ao meio jurídico brasileiro."""
},
{
"role": "user",
"content": f"""Gere um {doc_type} seguindo estritamente o formato jurídico brasileiro padrão:
EXCELENTÍSSIMO(A) SENHOR(A) DOUTOR(A) JUIZ(A) DE DIREITO DA VARA CRIMINAL DA COMARCA DE {context.get('jurisdiction').upper()}
Processo nº {context.get('process_number')}
{context.get('client_name')}, brasileiro, devidamente qualificado nos autos do processo em epígrafe, por seu advogado que esta subscreve, vem, respeitosamente, à presença de Vossa Excelência, com fundamento no artigo 5º, LXVIII, da Constituição Federal e artigos 647 e seguintes do Código de Processo Penal, impetrar:
HABEAS CORPUS
com pedido de liminar
em face do constrangimento ilegal sofrido, pelos fatos e fundamentos a seguir expostos:
I - DOS FATOS
{context.get('facts')}
II - DO DIREITO
{context.get('legal_basis')}
III - DOS PEDIDOS
Ante o exposto, requer-se:
a) A concessão de LIMINAR para determinar a imediata expedição de alvará de soltura em favor do paciente;
b) No mérito, a concessão definitiva da ordem para revogar a prisão preventiva, expedindo-se o competente alvará de soltura em favor do paciente, se por outro motivo não estiver preso.
Nestes termos,
Pede deferimento.
{context.get('jurisdiction')}, [DATA]
[Nome do Advogado]
OAB/XX XXX.XXX"""
}
]
completion = self.client.chat.completions.create(
model=self.model,
messages=messages,
temperature=0.1, # Reduzido para maior formalidade
top_p=0.8, # Mantém coerência
max_tokens=2048, # Limite de tamanho
presence_penalty=0.3, # Reduz repetições mantendo formalidade
frequency_penalty=0.5 # Reduz repetições de palavras
)
# Formata a data
result = completion.choices[0].message.content
current_date = datetime.now().strftime('%d de %B de %Y')
result = result.replace('[DATA]', current_date)
return self._format_output(result)
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"
return text.strip()
class WebInterface:
"""Interface Gradio para o gerador de documentos"""
def __init__(self):
self.generator = DocumentGenerator()
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 para Geração de Documentos Jurídicos
""")
with gr.Row():
with gr.Column():
# Seleção do 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"
)
# Dados do processo
with gr.Group():
gr.Markdown("### Informações do Processo")
client_name = gr.Textbox(
label="Nome do Cliente",
placeholder="Nome completo do cliente"
)
process_number = gr.Textbox(
label="Número do Processo",
placeholder="NNNNNNN-NN.NNNN.N.NN.NNNN"
)
court = gr.Textbox(
label="Tribunal",
value="TRIBUNAL DE JUSTIÇA DO ESTADO"
)
jurisdiction = gr.Textbox(
label="Comarca",
placeholder="Nome da comarca"
)
# Detalhes do caso
with gr.Group():
gr.Markdown("### Detalhes do Caso")
facts = gr.Textbox(
label="Fatos",
lines=5,
placeholder="Descreva os fatos relevantes..."
)
legal_basis = gr.Textbox(
label="Fundamentos Jurídicos",
lines=3,
placeholder="Indique os fundamentos legais..."
)
with gr.Row():
generate_btn = gr.Button("Gerar Documento", variant="primary")
clear_btn = gr.Button("Limpar", variant="secondary")
with gr.Column():
output = gr.Textbox(
label="Documento Gerado",
lines=30,
show_copy_button=True
)
status = gr.Textbox(label="Status")
# Exemplos de uso
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, CP). O paciente é primário, possui residência fixa no distrito da culpa e ocupação lícita comprovada. Não estão presentes os requisitos autorizadores da prisão preventiva.",
"Art. 5º, LXVIII, CF/88; Art. 647 do CPP; Ausência dos requisitos do Art. 312 do CPP. Súmula 308 STJ."
],
[
"Denúncia Criminal",
"Pedro Oliveira Lima",
"0000456-78.2024.8.26.0000",
"TRIBUNAL DE JUSTIÇA DO ESTADO DE SÃO PAULO",
"São Paulo",
"No dia 20/12/2024, por volta das 14h, na Rua ABC, o denunciado subtraiu para si uma carteira contendo R$ 500,00, mediante grave ameaça exercida com simulacro de arma de fogo.",
"Art. 157, caput, do Código Penal. Circunstâncias do Art. 59 do CP desfavoráveis."
],
[
"Alegações Finais",
"Maria Santos Costa",
"0000789-10.2024.8.26.0000",
"TRIBUNAL DE JUSTIÇA DO ESTADO DE SÃO PAULO",
"São Paulo",
"A ré foi denunciada por suposto furto (art. 155, CP). As provas produzidas nos autos não confirmam a autoria. As testemunhas não reconheceram a acusada e não há registros de câmeras.",
"Insuficiência probatória. Art. 386, VII do CPP. Princípio in dubio pro reo."
]
],
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_fields():
return [gr.update(value="") for _ in range(6)] + ["Campos limpos"]
clear_btn.click(
fn=clear_fields,
inputs=[],
outputs=[
client_name, process_number, court,
jurisdiction, facts, legal_basis, 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
if not all([client_name, process_number, facts, legal_basis]):
return "Erro: Todos os campos obrigatórios devem ser preenchidos", "⚠️ Campos incompletos"
context = {
"client_name": client_name,
"process_number": process_number,
"court": court,
"jurisdiction": jurisdiction,
"facts": facts,
"legal_basis": legal_basis
}
# 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()
if __name__ == "__main__":
interface = WebInterface()
interface.launch()