Spaces:
Running
Running
import gradio as gr | |
import os | |
from datetime import datetime | |
from huggingface_hub import InferenceClient | |
class DefenseGenerator: | |
def __init__(self): | |
self.api_key = os.getenv("HF_API_KEY") | |
if not self.api_key: | |
raise EnvironmentError("HF_API_KEY não configurada") | |
self.client = InferenceClient(api_key=self.api_key) | |
self.templates = { | |
"resposta_acusacao": { | |
"system": "Você é um advogado criminalista especializado em respostas à acusação.", | |
"sections": { | |
"cabecalho": """EXCELENTÍSSIMO(A) SENHOR(A) DOUTOR(A) JUIZ(A) DE DIREITO DA {vara} VARA CRIMINAL DA COMARCA DE {comarca} | |
Processo nº: {numero_processo}""", | |
"qualificacao": """{nome_reu}, já qualificado nos autos do processo em epígrafe, por seu advogado que esta subscreve, vem, respeitosamente, à presença de Vossa Excelência, apresentar RESPOSTA À ACUSAÇÃO, nos termos do art. 396-A do Código de Processo Penal, pelos fatos e fundamentos a seguir expostos:""", | |
"preliminares": "I - PRELIMINARES\n\n{preliminares}", | |
"merito": "II - MÉRITO\n\n{merito}", | |
"provas": """III - DAS PROVAS\n\nPara provar o alegado, requer-se a produção de todos os meios de prova em direito admitidos, especialmente:\n\n{provas}""", | |
"pedidos": """IV - DOS PEDIDOS\n\nAnte o exposto, requer:\n\n{pedidos} | |
Termos em que, | |
Pede deferimento. | |
{comarca}, {data} | |
Advogado(a) | |
OAB/{estado} {numero_oab}""" | |
} | |
}, | |
"habeas_corpus": { | |
"system": "Você é um advogado criminalista especializado em Habeas Corpus.", | |
"sections": { | |
"cabecalho": """EXCELENTÍSSIMO(A) SENHOR(A) DOUTOR(A) DESEMBARGADOR(A) DO EGRÉGIO TRIBUNAL DE JUSTIÇA DO ESTADO DE {estado}""", | |
"qualificacao": """{nome_reu}, {qualificacao}, vem, por seu advogado que esta subscreve, com fundamento no art. 5º, LXVIII, da Constituição Federal e arts. 647 e seguintes do Código de Processo Penal, impetrar | |
HABEAS CORPUS | |
com pedido liminar | |
em face de ato coator praticado pelo MM. Juiz de Direito da {vara} Vara Criminal da Comarca de {comarca}, pelos fatos e fundamentos a seguir expostos:""", | |
"fundamentos": """I - DOS FATOS E FUNDAMENTOS\n\n{fundamentos}""", | |
"pedidos": """II - DOS PEDIDOS\n\nAnte o exposto, requer:\n\n{pedidos} | |
Termos em que, | |
Pede deferimento. | |
{comarca}, {data} | |
Advogado(a) | |
OAB/{estado} {numero_oab}""" | |
} | |
}, | |
"liberdade_provisoria": { | |
"system": "Você é um advogado criminalista especializado em pedidos de liberdade provisória.", | |
"sections": { | |
"cabecalho": """EXCELENTÍSSIMO(A) SENHOR(A) DOUTOR(A) JUIZ(A) DE DIREITO DA {vara} VARA CRIMINAL DA COMARCA DE {comarca} | |
Processo nº: {numero_processo}""", | |
"qualificacao": """{nome_reu}, já 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 art. 321 do Código de Processo Penal, requerer a | |
LIBERDADE PROVISÓRIA | |
com ou sem fiança | |
pelos motivos de fato e de direito a seguir expostos:""", | |
"fundamentos": """I - DOS FATOS E FUNDAMENTOS\n\n{fundamentos}""", | |
"pedidos": """II - DOS PEDIDOS\n\nAnte o exposto, requer:\n\n{pedidos} | |
Termos em que, | |
Pede deferimento. | |
{comarca}, {data} | |
Advogado(a) | |
OAB/{estado} {numero_oab}""" | |
} | |
} | |
} | |
self.exemplos = { | |
"resposta_acusacao": { | |
"tipo": "resposta_acusacao", | |
"comarca": "São Paulo", | |
"vara": "1ª", | |
"estado": "SP", | |
"numero_oab": "123456", | |
"numero_processo": "0000000-11.2024.8.26.0000", | |
"nome_reu": "João da Silva", | |
"qualificacao": "", | |
"fundamentos": "", | |
"preliminares": """1. Inépcia da denúncia, vez que não descreve adequadamente a conduta imputada ao denunciado; | |
2. Ausência de justa causa para a ação penal, diante da atipicidade da conduta;""", | |
"merito": """No mérito, deve-se destacar que o denunciado não praticou o crime que lhe é imputado. As testemunhas arroladas pela acusação apresentam contradições em seus depoimentos que demonstram a fragilidade da acusação. | |
Além disso, os elementos de prova colhidos na fase investigativa não foram corroborados sob o crivo do contraditório, sendo insuficientes para embasar uma condenação criminal.""", | |
"provas": """1. Oitiva das testemunhas abaixo arroladas; | |
2. Juntada dos documentos em anexo; | |
3. Outras provas admitidas em direito.""", | |
"pedidos": """1. O acolhimento das preliminares arguidas, com o consequente trancamento da ação penal; | |
2. Subsidiariamente, a absolvição do acusado, nos termos do art. 386, incisos III, V ou VII do Código de Processo Penal; | |
3. A produção de todas as provas requeridas.""" | |
}, | |
"habeas_corpus": { | |
"tipo": "habeas_corpus", | |
"comarca": "São Paulo", | |
"vara": "1ª", | |
"estado": "SP", | |
"numero_oab": "123456", | |
"numero_processo": "0000000-11.2024.8.26.0000", | |
"nome_reu": "João da Silva", | |
"qualificacao": "brasileiro, casado, comerciante, RG 12.345.678-9 SSP/SP, CPF 123.456.789-00", | |
"fundamentos": """O paciente encontra-se preso preventivamente desde 10/01/2024, por suposta prática do crime previsto no art. 155, caput, do Código Penal. | |
Contudo, a prisão preventiva carece dos requisitos legais previstos no art. 312 do CPP, vez que: | |
1. O paciente é primário, possui bons antecedentes e residência fixa; | |
2. Não há elementos que indiquem risco à ordem pública ou à instrução criminal; | |
3. A medida é desproporcional ao crime imputado.""", | |
"preliminares": "", | |
"merito": "", | |
"provas": "", | |
"pedidos": """1. A concessão de liminar para determinar a imediata soltura do paciente; | |
2. No mérito, a concessão definitiva da ordem para revogar a prisão preventiva; | |
3. Subsidiariamente, a substituição da prisão por medidas cautelares diversas.""" | |
}, | |
"liberdade_provisoria": { | |
"tipo": "liberdade_provisoria", | |
"comarca": "São Paulo", | |
"vara": "1ª", | |
"estado": "SP", | |
"numero_oab": "123456", | |
"numero_processo": "0000000-11.2024.8.26.0000", | |
"nome_reu": "João da Silva", | |
"qualificacao": "", | |
"fundamentos": """O requerente foi preso em flagrante no dia 10/01/2024, pela suposta prática do crime previsto no art. 155, caput, do Código Penal. | |
Entretanto, estão ausentes os requisitos que autorizam a conversão do flagrante em prisão preventiva, pois: | |
1. Trata-se de réu primário, com bons antecedentes e residência fixa; | |
2. O crime imputado tem pena máxima inferior a 4 anos; | |
3. Não há indicativos de que, em liberdade, prejudicará a instrução criminal.""", | |
"preliminares": "", | |
"merito": "", | |
"provas": "", | |
"pedidos": """1. A concessão da liberdade provisória, preferencialmente sem fiança; | |
2. Subsidiariamente, a fixação de fiança em valor compatível com a situação econômica do requerente; | |
3. A aplicação de medidas cautelares diversas da prisão, se necessário.""" | |
} | |
} | |
def generate_section(self, messages: list, section: str) -> str: | |
try: | |
response = self.client.chat.completions.create( | |
model="mistralai/Mistral-7B-Instruct-v0.3", | |
messages=[*messages, {"role": "user", "content": f"Gere a seção {section}"}], | |
max_tokens=500, | |
temperature=0.3 | |
) | |
return response.choices[0].message["content"] | |
except Exception as e: | |
raise Exception(f"Erro na geração da seção {section}: {str(e)}") | |
def gerar_documento(self, tipo_documento: str, dados: dict) -> str: | |
template = self.templates.get(tipo_documento) | |
if not template: | |
return "Tipo de documento não encontrado" | |
dados['data'] = datetime.now().strftime("%d/%m/%Y") | |
messages = [ | |
{"role": "system", "content": template["system"]}, | |
{"role": "user", "content": f"Dados para geração de {tipo_documento}:\n{str(dados)}"} | |
] | |
documento = "" | |
for section_name, section_template in template["sections"].items(): | |
try: | |
section_content = section_template.format(**dados) | |
documento += section_content + "\n\n" | |
except KeyError: | |
try: | |
section_content = self.generate_section(messages, section_name) | |
documento += section_content + "\n\n" | |
except Exception as e: | |
documento += f"[Erro na seção {section_name}: {str(e)}]\n\n" | |
return documento | |
def interface(): | |
gerador = DefenseGenerator() | |
with gr.Blocks() as demo: | |
gr.Markdown("""# Sistema de Geração de Peças Criminais | |
Este sistema auxilia advogados criminalistas na geração de peças processuais.""") | |
with gr.Row(): | |
tipo_peca = gr.Dropdown( | |
choices=list(gerador.templates.keys()), | |
label="Tipo de Peça", | |
value="resposta_acusacao", | |
info="Selecione o tipo de documento que deseja gerar" | |
) | |
with gr.Row(): | |
with gr.Column(): | |
comarca = gr.Textbox( | |
label="Comarca", | |
placeholder="Ex: São Paulo" | |
) | |
vara = gr.Textbox( | |
label="Vara", | |
placeholder="Ex: 1ª" | |
) | |
estado = gr.Textbox( | |
label="Estado", | |
placeholder="Ex: SP" | |
) | |
numero_oab = gr.Textbox( | |
label="Número OAB", | |
placeholder="Ex: 123456" | |
) | |
numero_processo = gr.Textbox( | |
label="Número do Processo", | |
placeholder="Ex: 0000000-00.0000.0.00.0000" | |
) | |
with gr.Column(): | |
nome_reu = gr.Textbox( | |
label="Nome do(a) Cliente", | |
placeholder="Ex: João da Silva" | |
) | |
qualificacao = gr.Textbox( | |
label="Qualificação", | |
placeholder="Ex: brasileiro, casado, comerciante...", | |
lines=2, | |
visible=False | |
) | |
fundamentos = gr.Textbox( | |
label="Fundamentos", | |
placeholder="Descreva os fundamentos do pedido...", | |
lines=5, | |
visible=False | |
) | |
preliminares = gr.Textbox( | |
label="Preliminares", | |
placeholder="Liste as preliminares...", | |
lines=3 | |
) | |
merito = gr.Textbox( | |
label="Mérito", | |
placeholder="Desenvolva os argumentos de mérito...", | |
lines=5 | |
) | |
provas = gr.Textbox( | |
label="Provas", | |
placeholder="Liste as provas requeridas...", | |
lines=3 | |
) | |
pedidos = gr.Textbox( | |
label="Pedidos", | |
placeholder="Liste os pedidos...", | |
lines=3 | |
) | |
def update_fields(tipo): | |
is_resposta = tipo == "resposta_acusacao" | |
is_hc = tipo == "habeas_corpus" | |
is_liberdade = tipo == "liberdade_provisoria" | |
return { | |
qualificacao: gr.update(visible=(is_hc or is_liberdade)), | |
fundamentos: gr.update(visible=(is_hc or is_liberdade)), | |
preliminares: gr.update(visible=is_resposta), | |
merito: gr.update(visible=is_resposta), | |
provas: gr.update(visible=is_resposta) | |
} | |
tipo_peca.change( | |
fn=update_fields, | |
inputs=tipo_peca, | |
outputs=[qualificacao, fundamentos, preliminares, merito, provas] | |
) | |
def carregar_exemplo(tipo): | |
exemplo = gerador.exemplos.get(tipo, {}) | |
return [ | |
exemplo.get(campo, "") for campo in [ | |
"comarca", "vara", "estado", "numero_oab", "numero_processo", | |
"nome_reu", "qualificacao", "fundamentos", "preliminares", | |
"merito", "provas", "pedidos" | |
] | |
] | |
exemplo_btn = gr.Button("Carregar Exemplo") | |
exemplo_btn.click( | |
fn=carregar_exemplo, | |
inputs=tipo_peca, | |
outputs=[ | |
comarca, vara, estado, numero_oab, numero_processo, | |
nome_reu, qualificacao, fundamentos, preliminares, | |
merito, provas, pedidos | |
] | |
) | |
with gr.Row(): | |
submit_btn = gr.Button("Gerar Peça", variant="primary") | |
clear_btn = gr.Button("Limpar Campos") | |
output = gr.Textbox( | |
label="Documento Gerado", | |
lines=20, | |
show_copy_button=True | |
) | |
def process(tipo, comarca, vara, estado, numero_oab, numero_processo, | |
nome_reu, qualificacao, fundamentos, preliminares, merito, | |
provas, pedidos): | |
dados = { | |
"comarca": comarca, | |
"vara": vara, | |
"estado": estado, | |
"numero_oab": numero_oab, | |
"numero_processo": numero_processo, | |
"nome_reu": nome_reu, | |
"qualificacao": qualificacao, | |
"fundamentos": fundamentos, | |
"preliminares": preliminares, | |
"merito": merito, | |
"provas": provas, | |
"pedidos": pedidos | |
} | |
return gerador.gerar_documento(tipo, dados) | |
def clear(): | |
return [""] * 12 | |
submit_btn.click( | |
fn=process, | |
inputs=[ | |
tipo_peca, comarca, vara, estado, numero_oab, numero_processo, | |
nome_reu, qualificacao, fundamentos, preliminares, merito, | |
provas, pedidos | |
], | |
outputs=output | |
) | |
clear_btn.click( | |
fn=clear, | |
inputs=None, | |
outputs=[ | |
comarca, vara, estado, numero_oab, numero_processo, | |
nome_reu, qualificacao, fundamentos, preliminares, | |
merito, provas, pedidos | |
] | |
) | |
return demo | |
if __name__ == "__main__": | |
demo = interface() | |
demo.launch() |